繁体   English   中英

如何在 Spring 请求映射中接受多个可选参数,但一次只接受一个?

[英]How do I accept multiple optional parameters in a Spring request mapping, but only one at a time?

编辑:我最终通过更多的实验自己解决了这个问题。 代码看起来很冗长,所以可能有一个更好的解决方案,不涉及将字符串类型转换为其他内容。

答案贴在下面。


对于我的学校作业,我应该创建一个 GET 映射来接收特定类型的所有实体的列表。 如果未提供任何参数,则此 GET 映射应仅返回所有实体,否则它将应用实体存储库中的某些内容以使用 JPQL 查询和提供的参数,该参数用作顺序查询参数来过滤返回的结果。

"如果不提供请求参数,则保留现有的返回所有事件的功能。如果指定了多个请求参数,则应返回错误响应,表示最多可以提供一个参数。如果'?status提供了 =XXX' 参数,状态字符串值与 AEventStatus 枚举不匹配,应返回适当的错误响应。”

我试图将我的 GET 映射更改为具有 3 个可选的 @RequestParameter 变量,但我发现检查是否存在多个参数或不存在参数是乏味的逻辑,然后根据哪个参数的存在再次执行某些操作在那儿。

相反,我尝试了这个(我在这中间,它不完整):

  @RequestMapping(
    value="/aevents",
    method = RequestMethod.GET)
  public ResponseEntity<Object> getAllAEvents(HttpServletRequest request) {
    if (request.getParameterMap().size() == 0) {
      return ResponseEntity.status(HttpStatus.OK).body(repository.findAll());
    }
    if (request.getParameterMap().size() > 1) {
      return new ResponseEntity<>("Can only handle one request paramter: title=, status= or minRegistrastions=", HttpStatus.BAD_REQUEST);
    }
    //incomplete from here
  }

我现在不确定这是否是正确的方法,或者我是否只是忽略了某些东西。 我想我可能能够检查请求中提供的参数的名称,然后如果我发现一些不是有效参数的内容,则再次返回错误的请求响应。 但我不确定如何检查参数映射的参数名称,或者参数映射是否符合我的想法。

提供的参数应该是 int、枚举值或字符串。

我是否忽略了一种更简单的方法来做到这一点? 即一种检查参数数量和签名中参数是否存在的方法,例如:

  @GetMapping("/aevents")
  public List<AEvent> getAllAEvents(@RequestParam(required = false) String title,
                                    @RequestParam(required = false) AEventStatus status,
                                    @RequestParam(required = false) int minRegistrations) {
                                        //Do something here
                                  }

或者我目前的方法是否可行,如果可行,我该如何继续?

是的,您可能会按照自己的方式进行操作:

  1. 你可以直接在 Spring 中注入参数的映射。
  2. 抛出 ResponseStatusException (自 Spring 5 起可用),而不是摸索 ResponseEntity。

     @GetMapping("/aevents") public List<AEvent> getAllAEvents( @RequestParam Map<String, String> allRequestParams){ if(allRequestParams.size() >1){ throw new ResponseStatusException( HttpStatus.BAD_REQUEST,"too many params"); } // do something return list; }

解决后回答我自己的问题:

什么是参数映射? parameterMap 实际上是字符串键和字符串数组的映射。 要获取参数名称(键)的值,您可以获取该键的值,然后像数组一样访问它。 但是,没有必要使用 parameterMap。 相反,最好只使用内置的 Spring 方法,即使用 @RequestParam 注释和方法主体中的简单@RequestParam Map<String, String> params

感谢https://stackoverflow.com/users/2255293/marco-behler给我一个想法并提供了更好的抛出异常的方法。

  @GetMapping("/aevents")
  public List<AEvent> getAllAEvents(@RequestParam Map<String, String> params) {
    if (params.size() == 0) { //Default case, no params
      return repository.findAll();
    }
    if (params.size() > 1) { //Refuse to handle more than one provided param
      throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Can only handle one request parameter: title=, status= or minRegistrations=");
    }
    if (params.containsKey("title")) {
      String value = params.get("title");
      return repository.findByQuery("AEvent_find_by_title", ("%" + value + "%"));
    }
    if (params.containsKey("status")) {
      String stringValue = params.get("status").toUpperCase();
      for (AEventStatus e : AEventStatus.values()) {
        if (e.name().equals(stringValue)) {
          AEventStatus value = AEventStatus.valueOf(stringValue);
          return repository.findByQuery("AEvent_find_by_status", value);
        }
      }
      throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "status=" + stringValue + " is not a valid AEvent status value.");
    }
    if (params.containsKey("minRegistrations")) {
      int value;
      try {
        value = Integer.parseInt(params.get("minRegistrations"));
      } catch (NumberFormatException e) {
        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Provided request parameter was not a valid number.");
      }
      return repository.findByQuery("AEvent_find_by_minRegistrations", value);
    }
    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid query parameters.");
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM