@RequestParam в Spring MVC, обрабатывающий необязательные параметры

186

Возможно ли для контроллера Spring обрабатывать оба вида запросов?

1) http://localhost:8080/submit/id/ID123432?logout=true

2) http://localhost:8080/submit/id/ID123432?name=sam&password=543432

Если я определю один контроллер вида:

 @RequestMapping (value = "/submit/id/{id}", method = RequestMethod.GET,   
 produces="text/xml")
public String showLoginWindow(@PathVariable("id") String id,
                              @RequestParam(value = "logout", required = false) String logout,
                              @RequestParam("name") String username,
                              @RequestParam("password") String password,
                              @ModelAttribute("submitModel") SubmitModel model,
                              BindingResult errors) throws LoginException {...}

HTTP-запрос с «выходом из системы» не принят.

Если я определяю два контроллера для обработки каждого запроса по отдельности, Spring жалуется с исключением «Метод bean-компонента« Контроллер »уже ... сопоставлен».

luksmir
источник
2
Прочитайте эту статью: codeflex.co/…
ybonda

Ответы:

224

Вы должны предоставить required = falseдля nameи passwordпараметры запроса , а также. Это потому , что, когда вы предоставляете только logoutпараметр, он на самом деле ожидает nameи passwordтак же , как они по - прежнему является обязательным.

Это сработало, когда вы только что дали nameи passwordпотому что logoutне было обязательным параметром, благодаря required = falseуже предоставленному для logout.

SudoRahul
источник
168

Как часть Spring 4.1.1впереди, теперь у вас есть полная поддержка Java 8 Optional( оригинальная заявка ), поэтому в вашем примере оба запроса будут проходить через конечную точку вашего единого сопоставления, если вы замените required=falseна Optional для выхода из 3 параметров, имени, пароля:

@RequestMapping (value = "/submit/id/{id}", method = RequestMethod.GET,   
 produces="text/xml")
public String showLoginWindow(@PathVariable("id") String id,
                              @RequestParam(value = "logout") Optional<String> logout,
                              @RequestParam("name") Optional<String> username,
                              @RequestParam("password") Optional<String> password,
                              @ModelAttribute("submitModel") SubmitModel model,
                              BindingResult errors) throws LoginException {...}
dimitrisli
источник
2
@VibhavChaddha вы можете использовать что-то вроде этого: if (idOfUser.isPresent ()) {System.out.println ("idOfUser:" + idOfUser.get ()); }
Кассио Сеффрин
10
Intellij предупреждение: «Необязательный <Long>» используется в качестве типа для параметра «requiredTimelineStart» меньше ... (Strg + F1) Информация о проверке: Сообщает о любом использовании java.util.Optional <T>, java.util.OptionalDouble, java. util.OptionalInt, java.util.OptionalLong или com.google.common.base.Optional в качестве типа для поля или параметра. Необязательный был разработан, чтобы обеспечить ограниченный механизм для возвращаемых типов библиотечного метода, где должен был быть ясный способ представить «нет результата». Использование поля с типом java.util.Optional также проблематично, если класс должен быть Serializable, а java.util.Optional - нет.
PeMa
Это должен быть новый правильный ответ с Java 8, я верю.
java-addict301
40

Создайте 2 метода, которые обрабатывают случаи. Вы можете указать @RequestMappingаннотации учитывать определенные параметры при отображении запроса. Таким образом, вы можете разделить это на 2 метода.

@RequestMapping (value="/submit/id/{id}", method=RequestMethod.GET, 
                 produces="text/xml", params={"logout"})
public String handleLogout(@PathVariable("id") String id, 
        @RequestParam("logout") String logout) { ... }

@RequestMapping (value="/submit/id/{id}", method=RequestMethod.GET, 
                 produces="text/xml", params={"name", "password"})
public String handleLogin(@PathVariable("id") String id, @RequestParam("name") 
        String username, @RequestParam("password") String password, 
        @ModelAttribute("submitModel") SubmitModel model, BindingResult errors) 
        throws LoginException {...}
М. Дейн
источник
1
что произойдет, если кто-то передаст оба URL-адреса, имя пользователя и пароль? Просто прочитайте документацию, там написано, !myParam style expressions indicate that the * specified parameter is not supposed to be present in the request.что надо попробовать.
носитель кольца
2
Он найдет наилучшее совпадение, вероятно, попытается использовать, handleLoginиначе он выдаст исключение, сообщающее, что сопоставление не может быть найдено.
М. Дейнм
3
Только одно замечание: с точки зрения безопасности выход должен принимать только запросы POST, поэтому должно быть 2 метода, и тогда нет смысла сохранять их URL-адреса одинаковыми.
Вспышка от Ру