簡體   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