Spring MVC: как указать, требуется ли переменная пути или нет?

Я делаю веб-сайт Spring. Для метода контроллера я могу использовать RequestParam для указания того, нужен ли параметр или нет. Например:

@RequestMapping({"customer"}) 
public String surveys(HttpServletRequest request, 
@RequestParam(value="id", required = false) Long id,            
Map<String, Object> map)

Я хотел бы использовать PathVariable, например следующее:

@RequestMapping({"customer/{id}"}) 
public String surveys(HttpServletRequest request, 
@PathVariable("id") Long id,            
Map<String, Object> map) 

Как указать, требуется ли переменная пути или нет? Мне нужно сделать это необязательным, потому что при создании нового объекта отсутствует соответствующий идентификатор, пока он не будет сохранен.

Спасибо за помощь!

Ответ 1

Невозможно сделать это необязательным, но вы можете создать два метода с одним, у которого есть аннотация @RequestMapping({"customer"}), а другая - @RequestMapping({"customer/{id}"}), а затем действовать соответственно в каждом.

Ответ 3

Я знаю, что это старый вопрос, но поиск "необязательной переменной пути" ставит этот ответ высоко, поэтому я подумал, что стоит отметить, что с Spring 4.1 с использованием Java 1.8 это возможно с помощью java.util. Необязательный класс.

пример будет (обратите внимание, что значение должно отображать все возможные маршруты, которые должны совпадать, т.е. с переменной пути id и без нее. Подходит для @martin-cmarko для указания этого)

@RequestMapping(method=GET, value={"/", "/{id}"})
public void get(@PathVariable Optional<Integer> id) {
  if (id.isPresent()) {
    id.get()   //returns the id
  }
}

Ответ 4

Ответ VTToms не будет работать, так как без id в пути он не будет соответствовать (т.е. не будет найден соответствующий HandlerMapping), и, следовательно, контроллер не будет удален. Скорее вы можете сделать -

@RequestMapping({"customer/{id}","customer"}) 
public String surveys(HttpServletRequest request, @PathVariable Map<String, String> pathVariablesMap, Map<String, Object> map) {
    if (pathVariablesMap.containsKey("id")) {
        //corresponds to path "customer/{id}"
    }
    else {
        //corresponds to path "customer"
    }
}

Вы также можете использовать java.util.Optional, о котором говорили другие, но для этого требуются Spring 4.1+ и Java 1.8..

Ответ 5

Возникает проблема с использованием опции "Необязательный" (необязательный идентификатор @PathVariable) или Map (@PathVariable Map pathVariables), поскольку если вы затем попытаетесь создать ссылку HATEOAS, вызвав метод контроллера, она потерпит неудачу, потому что Spring - Кажется, что renoas является pre java8 и не поддерживает "Необязательный". Он также не может вызвать какой-либо метод с аннотацией @PathVariable Map.

Вот пример, демонстрирующий сбой Map

   @RequestMapping(value={"/subs","/masterclient/{masterclient}/subs"}, method = RequestMethod.GET)
   public List<Jobs>  getJobListTest(
         @PathVariable  Map<String, String> pathVariables,
         @RequestParam(value="count", required = false, defaultValue = defaultCount) int count) 
   {

      if (pathVariables.containsKey("masterclient")) 
      {
         System.out.println("Master Client = " + pathVariables.get("masterclient"));
      } 
      else 
      {
         System.out.println("No Master Client");
      }




  //Add a Link to the self here.
  List list = new ArrayList<Jobs>();
  list.add(linkTo(methodOn(ControllerJobs.class).getJobListTest(pathVariables, count)).withSelfRel());

  return list;

}