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

Я делаю весеннюю паутину. Для метода контроллера я могу использовать 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) 

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

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

5 ответов


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


VTTom это решение правильное, просто измените переменную "value" на array и перечислите все возможности url: value= {"/ ","/{id}"}

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

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

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

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

vttoms ответ не будет работать, так как без id в пути он не будет сопоставлен (i.e не найдет соответствующего HandlerMapping) и, следовательно, контроллер не будет поражен. Скорее вы можете сделать ... --4-->

@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 которые другие упоминали, но для этого требуется Весна 4.1+ и Java 1.8..


существует проблема с использованием "Optional" (@Pathvariable Optional id) или Map (@PathVariable Map pathVariables) в том, что если вы затем попытаетесь создать ссылку HATEOAS, вызвав метод контроллера, он потерпит неудачу, потому что Spring-hateoas кажется pre java8 и не поддерживает "Optional". Он также не может вызвать любой метод с аннотацией карты @PathVariable.

вот пример, который демонстрирует сбой 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;

}