С помощью Spring я могу сделать необязательную переменную path? - PullRequest
167 голосов
/ 05 февраля 2011

Могу ли я иметь дополнительную переменную пути в 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 будут работать

Ответы [ 8 ]

173 голосов
/ 05 февраля 2011

У вас не может быть необязательных переменных пути, но вы можете иметь два метода контроллера, которые вызывают один и тот же сервисный код:

@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();
}
95 голосов
/ 08 января 2016

Если вы используете 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"
    }       
}
73 голосов
/ 13 марта 2015

Не очень хорошо известно, что вы также можете вставить Map переменных пути, используя аннотацию @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();
    }
}
24 голосов
/ 21 августа 2012

Вы можете использовать:

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

для необязательных параметров, а не pathVariable

6 голосов
/ 11 апреля 2018

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));
}
3 голосов
/ 10 октября 2014

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

1 голос
/ 16 апреля 2019

Упрощенный пример комментария Николая Эманна и 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();
  }
0 голосов
/ 13 октября 2015
$.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 ) {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...