是否可以在 Spring 控制器中拆分请求参数?

Ale*_*ndr 4 java spring spring-mvc spring-restcontroller spring-rest

我有一个请求,例如:

example.com/search?sort=myfield1,-myfield2,myfield3
Run Code Online (Sandbox Code Playgroud)

我想拆分这些参数以List<String>在控制器中绑定排序,或者具有以下字段的类List<SortParam>在哪里:(字符串)和(布尔值)。SortParamnameask

所以最终的控制器看起来像这样:

@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<MyResponse> search(@RequestParam List<String> sort) {

    //...
}
Run Code Online (Sandbox Code Playgroud)

或者

@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<MyResponse> search(@RequestParam List<SortParam> sort) {

    //...
}
Run Code Online (Sandbox Code Playgroud)

有办法制作吗?

更新:

标准的参数传递方式不能满足我的要求。即我无法使用sort=myfield1&sort=-myfield2&sort=myfield3. 我必须使用逗号分隔的名称。
另外,我确实明白我可以@RequestParam String sort在控制器中接受,然后在控制器内分割字符串sort.split(","),但它也不能解决上述问题。

Sha*_*mud 7

这只是一个简单的类型转换任务。Spring定义了SPI(服务提供者接口)来实现类型转换逻辑。对于您的特定问题,您可以通过实现接口来定义类型转换逻辑Converter

@Component
public class StringToListConverter implements Converter<String, List<String>> {

    @Override
    public List<String> convert(String source) {
        return Arrays.asList(source.split(","));
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以根据您的逻辑转换您的请求参数List<SortPram>(但我不确定您问题中的逻辑)。就是这个!现在Spring知道如何将你的请求参数绑定到一个列表。

@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<MyResponse> participants(@RequestParam("sort") List<String> sort) {
     // .. do your logic
}
Run Code Online (Sandbox Code Playgroud)

还有很多方法可以定义自定义数据绑定程序。检查这个


Jon*_*gel 5

是的,你当然可以做到,你就快成功了。

@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<MyResponse> participants(@RequestParam("sort") List<String> sort) {

    //...
}
Run Code Online (Sandbox Code Playgroud)

您现在应该能够像这样调用您的服务(如果搜索位于您的根目录,否则根据您的情况进行调整):

curl "localhost:8080/search?sort=sortField1&sort=sortField2&sort=sortField3"
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

编辑 抱歉,我已阅读您的评论,现在我很清楚您需要什么。我已经为您创建了一个解决方法,我想这几乎就是您想要的。

首先是 SortParams 类:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class SortParams {
  private List<SortParam> sortParamList;

  public SortParams(String commaSeparatedString) {
    sortParamList = Arrays.stream(commaSeparatedString.split(","))
      .map(p -> SortParam.valueOf(p))
      .collect(Collectors.toList());
  }

  public List<SortParam> getSortParamList() {
    return this.sortParamList;
  }

  public enum SortParam {
    FOO, BAR, FOOBAR;
  }
}
Run Code Online (Sandbox Code Playgroud)

那么你的控制器可能看起来像这样:

@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<List<SortParams.SortParam>> search(@RequestParam("sort") SortParams sort) {
    return ResponseEntity.ok(sort.getSortParamList());
}
Run Code Online (Sandbox Code Playgroud)

现在您的 SortParams 对象有一个 SortParam 列表:

curl "localhost:8080/search?sort=FOO,BAR"

["FOO","BAR"]
Run Code Online (Sandbox Code Playgroud)

这样的东西适合您正在寻找的东西吗?