首页 > 解决方案 > 使用自定义请求对象时带有可选参数的 Spring @RequestMapping

问题描述

你好我想在我的控制器上做一个可选参数,id到目前为止看起来像这样

    @ApiOperation(value = "get runs by date in order to paginate")
    @ApiResponses({ @ApiResponse(code = 200, message = "Success"),
            @ApiResponse(code = 500, message = "Unexpected failure") })
    @RequestMapping(value = "/time/{date}/to/{toPage}/from/{fromPage}",
                    params = {"pageSize", "id"},
                    method = RequestMethod.GET)
    public RunCollection getPolicyByDate(GetPolicyByDateRequest request) {
        return serviceImpl.getListOfRunsByDate(request);
    }

但这意味着该参数是必需的。我希望它是可选的。我看到了这个答案,他们使用@RequestParam 带有可选参数的 Spring @RequestMapping,但我想将它包含在我的GetPolicyByDateRequest对象中。这可能吗?spring 文档没有提到关闭 required 属性。我可以用吗Optional

标签: javaspringcontroller

解决方案


2个选项:

  1. 如果您GetPolicyByDateRequest没有原始属性,它们应该由 Spring 插入到您的对象中。如果您的参数未设置(即pageSize您的 url 中没有),那么 Spring 在您的属性中注入 NULL。
public class GetPolicyByDateRequest {

    private String date;
    private int toPage;
    private int fromPage;
    private Integer pageSize;
    private Integer id;

    public GetPolicyByDateRequest() {
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public int getToPage() {
        return toPage;
    }

    public void setToPage(int toPage) {
        this.toPage = toPage;
    }

    public int getFromPage() {
        return fromPage;
    }

    public void setFromPage(int fromPage) {
        this.fromPage = fromPage;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "MyRequest{" +
                "date='" + date + '\'' +
                ", toPage=" + toPage +
                ", fromPage=" + fromPage +
                ", pageSize=" + pageSize +
                ", id=" + id +
                '}';
    }
}

奇怪的是,我认为这是 Spring 中的一些错误之王,即使使用时Optional如果未提供 requestParam 中的参数,您也会得到一个空对象。

  1. 如果要获取所有参数,则需要在您的情况下使用@PathVariablewith @RequestParam。以下是获取参数的方法:
 @RequestMapping(value = "/time/{date}/to/{toPage}/from/{fromPage}", method = RequestMethod.GET)
    public RunCollection getPolicyByDate(@PathVariable String date, @PathVariable int toPage, @PathVariable int fromPage, @RequestParam(required = false) Optional<Integer> pageSize, @RequestParam(required = false) Optional<Integer> id) {
        // then use your parameters the way you to use then.
    }

请注意 :

  • @PathVariable检索 URL 中的参数,其中值介于 之间{},如{date}->@PathVariable String date
  • @RequestParam检索?URL 中 之后的参数。?pageSize=10-> @RequestParam int pageSize
  • 这两个注释都作为参数,除其他外,required=true|false. 将参数标记为不需要时,请确保您不使用原始类型,如 int,否则,您可以将此对象设置为 null,您的代码将在运行时失败。这就是我使用Optional<Integer>, 来允许类型的原因。但是 Spring 很聪明,如果它检测到您的参数中的,Optional那么您将被迫使用required=false.@RequestParam

如果你想填充你的GetPolicyByDateRequest,那么你应该做一个POST映射,并使用注释@RequestBody GetPolicyByDateRequest request,并在你的请求中发送一个 JSON 主体,以使 Spring(实际上是 Jackson)将你的 JSON 转换为一个GetPolicyByDateRequest对象。

希望能帮助到你


推荐阅读