2011-02-04 3 views
140

С Spring 3.0, могу ли я иметь дополнительную переменную пути?С Spring 3.0, могу ли я сделать необязательную переменную пути?

Например

@RequestMapping(value = "/json/{type}", method = RequestMethod.GET) 
public @ResponseBody TestBean testAjax(
     HttpServletRequest req, 
     @PathVariable String type, 
     @RequestParam("track") String track) { 
    return new TestBean(); 
} 

Здесь я хотел бы /json/abc или /json вызвать тот же метод.
Один очевидный обходной путь объявить type в качестве параметра запроса:

@RequestMapping(value = "/json", method = RequestMethod.GET) 
public @ResponseBody TestBean testAjax(
     HttpServletRequest req, 
     @RequestParam(value = "type", required = false) String type, 
     @RequestParam("track") String track) { 
    return new TestBean(); 
} 

, а затем /json?type=abc&track=aa или /json?track=rr будет работать

ответ

147

Вы не можете иметь дополнительные переменные пути, но вы можете иметь два метода контроллера, которые требуют того же код услуги:

@RequestMapping(value = "/json/{type}", method = RequestMethod.GET) 
public @ResponseBody TestBean typedTestBean(
     HttpServletRequest req, 
     @PathVariable String type, 
     @RequestParam("track") String track) { 
    return getTestBean(type); 
} 

@RequestMapping(value = "/json", method = RequestMethod.GET) 
public @ResponseBody TestBean testBean(
     HttpServletRequest req, 
     @RequestParam("track") String track) { 
    return getTestBean(); 
} 
+0

Это, безусловно, хороший способ сделать это. – Shamik

+3

@Shamik: Это убедительная причина * не * использовать переменные пути, на мой взгляд. Комбинаторная пролиферация может быстро выйти из-под контроля. – skaffman

+7

На самом деле не потому, что путь не может быть таким сложным, когда он заполняется дополнительными компонентами. Если у вас есть несколько или более двух дополнительных элементов пути, вам следует серьезно рассмотреть возможность переключения нескольких из них для запроса параметров. –

20

Вы могли бы использовать:

@RequestParam(value="somvalue",required=false) 

необязательных Params, а не pathVariable

+1

Это похоже на версию. Нет смысла использовать Spring 3. –

+4

В настоящее время этот метод используется для проекта весны 3.1, а документы говорят, что он работает на 2,5+, поэтому он определенно работает для Spring 3. EDIT: [source] (http: //static.springsource. орг/весна/документы/3.0.x/API/орг/springframework/веб/привязывать/аннотаций/RequestParam.html). –

+18

Правда, но об этом не говорится. Использование параметров * request * действительно упоминается в вопросе как «Одно очевидное обходное решение» *, но сам вопрос касается параметров * пути *. Это не решение для дополнительных параметров пути. – Arjan

2

Проверьте это Spring 3 WebMVC - Optional Path Variables. В нем показана статья создания расширения AntPathMatcher для включения дополнительных переменных пути и может быть полезной. Все кредиты Sebastian Herold для публикации статьи.

69

Не известно, что вы также можете вводить карту переменных пути, используя аннотацию @PathVariable. Я не уверен, если эта функция доступна в Spring 3.0, или если он был добавлен позже, но вот еще один способ решить пример:

@RequestMapping(value={ "/json/{type}", "/json" }, method=RequestMethod.GET) 
public @ResponseBody TestBean typedTestBean(
    @PathVariable Map<String, String> pathVariables, 
    @RequestParam("track") String track) { 

    if (pathVariables.containsKey("type")) { 
     return new TestBean(pathVariables.get("type")); 
    } else { 
     return new TestBean(); 
    } 
} 
+1

спасибо, весной 4.2 работает как ожидалось – Edgar

+0

Я использую его все время. Это удобно, когда я хочу, чтобы один метод обрабатывал разные типы uri ex: {"/ json/{type}", "/ json/{type}/{xyz} ","/json/{type}/{abc} ","/json/{type}/{abc}/{something} ","/json "} – Vaibs

-3
$.ajax({ 
      type : 'GET', 
      url : '${pageContext.request.contextPath}/order/lastOrder', 
      data : {partyId : partyId, orderId :orderId}, 
      success : function(data, textStatus, jqXHR) }); 

@RequestMapping(value = "/lastOrder", method=RequestMethod.GET) 
public @ResponseBody OrderBean lastOrderDetail(@RequestParam(value="partyId") Long partyId,@RequestParam(value="orderId",required=false) Long orderId,Model m) {} 
+3

Возможно, вы захотите редактировать в некотором тексте в вашем ответе, объясняя * почему * вы считаете, что это способствует решению проблемы (4 года спустя). – Qirel

+0

Не помогло бы. Ответ полностью неправильный. – Phil

67

Если вы используете Spring 4.1 и Java 8 Вы можно использовать java.util.Optional, который поддерживается в @RequestParam, @PathVariable, @RequestHeader и @MatrixVariable в Spring MVC -

@RequestMapping(value = {"/json/{type}", "/json" }, method = RequestMethod.GET) 
public @ResponseBody TestBean typedTestBean(
    @PathVariable Optional<String> type, 
    @RequestParam("track") String track) {  
    if (type.isPresent()) { 
     //type.get() will return type value 
     //corresponds to path "/json/{type}" 
    } else { 
     //corresponds to path "/json" 
    }  
} 
+0

Вы уверены, что это сработает? Ваш собственный ответ [здесь] (http://stackoverflow.com/a/34670775/1345021) предполагает, что контроллер не пострадает, если {path} отсутствует на пути. Я думаю, что PathVariable Map будет лучшим подходом или использованием отдельных контроллеров. –

+3

Да, если у вас просто есть ''/json/{type} "' и type нет, он не будет ударяться (как подсказывает мой связанный ответ), но здесь у вас есть значение = {"/ json/{type}", "/ json"} '. Так что, если кто-то будет соответствовать методу контроллера, он будет удален. –

+0

Возможно ли, что одинаковое значение и т. Д. Будет также RequestParam и RequestParam? – zygimantus

Смежные вопросы