С помощью Spring я могу сделать необязательную переменную path?
С 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
будет работать
Ответы
Ответ 1
У вас не может быть дополнительных переменных пути, но у вас могут быть два метода контроллера, которые вызывают один и тот же служебный код:
@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();
}
Ответ 2
Если вы используете 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"
}
}
Ответ 3
Не известно, что вы также можете ввести карту переменных пути, используя аннотацию @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();
}
}
Ответ 4
Вы можете использовать:
@RequestParam(value="somvalue",required=false)
для необязательных параметров, а не для pathVariable
Ответ 5
Spring 5/Spring Boot 2 примеры:
блокирование
@GetMapping({"/dto-blocking/{type}", "/dto-blocking"})
public ResponseEntity<Dto> getDtoBlocking(
@PathVariable(name = "type", required = false) String type) {
if (StringUtils.isEmpty(type)) {
type = "default";
}
return ResponseEntity.ok().body(dtoBlockingRepo.findByType(type));
}
реактивный
@GetMapping({"/dto-reactive/{type}", "/dto-reactive"})
public Mono<ResponseEntity<Dto>> getDtoReactive(
@PathVariable(name = "type", required = false) String type) {
if (StringUtils.isEmpty(type)) {
type = "default";
}
return dtoReactiveRepo.findByType(type).map(dto -> ResponseEntity.ok().body(dto));
}
Ответ 6
Проверьте Spring 3 WebMVC - дополнительные переменные пути. В нем показана статья создания расширения AntPathMatcher для включения дополнительных переменных пути и может быть полезной. Все кредиты Себастьян Герольд для публикации статьи.
Ответ 7
Упрощенный пример комментария Николая Эманна и wildloop-ответа (Spring 4.3. 3+), теперь вы можете использовать required = false
:
@RequestMapping(value = {"/json/{type}", "/json" }, method = RequestMethod.GET)
public @ResponseBody TestBean testAjax(@PathVariable(required = false) String type) {
if (type != null) {
// ...
}
return new TestBean();
}
Ответ 8
$.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 ) {}