@RequestParam vs @PathVariable

355

В чем разница между специальными символами @RequestParamи @PathVariableпри их обработке?

+был принят @RequestParamкак пространство.

В случае @PathVariable, +был принят как +.

user1857181
источник

Ответы:

499

Если URL http://localhost:8080/MyApp/user/1234/invoices?date=12-05-2013получит счета для пользователя 1234 5 декабря 2013 г., метод контроллера будет выглядеть следующим образом:

@RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
public List<Invoice> listUsersInvoices(
            @PathVariable("userId") int user,
            @RequestParam(value = "date", required = false) Date dateOrNull) {
  ...
}

Кроме того, параметры запроса могут быть необязательными, а с весны 4.3.3 переменные пути также могут быть необязательными . Однако остерегайтесь, это может изменить иерархию пути URL и привести к конфликтам сопоставления запросов. Например, будут ли /user/invoicesпредоставляться счета-фактуры для пользователя nullили сведения о пользователе с идентификатором «счета-фактуры»?

Ральф
источник
11
@PathVariableможно использовать в любом RequestMethod
Kurai Bankusu
1
@AlexO: это не имеет ничего общего с java8, оно работает даже для java 5 и Spring3.0: Дело в том, что код скомпилирован с включенной отладкой.
Ральф
2
@Ralph правильно, это работает с отладки , прежде чем Java 8. Поскольку Java 8 также работает без отладки, используя вместо этого «» - параметров: docs.spring.io/spring/docs/current/spring-framework-reference/... docs.oracle .com / Javase / учебник / Reflect / Member /…
AlexO
1
@ user3705478: я так не думаю, потому что Spring нужно знать, что это метод обработчика запросов. (и, конечно: @PathParam работает только в том случае, если в шаблоне uri есть заполнитель)
Ralph
2
@ user3705478: @PathParamэто аннотация javax.ws.rs. docs.oracle.com/javaee/7/api/javax/ws/rs/PathParam.html
Ральф,
112

@RequestParam аннотация, используемая для доступа к значениям параметров запроса из запроса. Посмотрите на следующий URL запроса:

http://localhost:8080/springmvc/hello/101?param1=10&param2=20

В приведенном выше URL-запросе к значениям param1 и param2 можно получить доступ, как показано ниже:

public String getDetails(
    @RequestParam(value="param1", required=true) String param1,
        @RequestParam(value="param2", required=false) String param2){
...
}

Ниже приведен список параметров, поддерживаемых аннотацией @RequestParam:

  • defaultValue - это значение по умолчанию в качестве резервного механизма, если запрос не имеет значения или он пустой.
  • name - имя параметра для привязки
  • обязательный параметр - является ли параметр обязательным или нет. Если это правда, не удастся отправить этот параметр.
  • значение - это псевдоним для атрибута имени

@PathVariable

@ PathVariable указывает шаблон, который используется в URI для входящего запроса. Давайте посмотрим на URL запроса ниже:

HTTP: // локальный: 8080 / SpringMVC / привет / 101 param1 = 10 & param2 = 20

Приведенный выше URL-запрос может быть записан в вашем Spring MVC, как показано ниже:

@RequestMapping("/hello/{id}")    public String getDetails(@PathVariable(value="id") String id,
    @RequestParam(value="param1", required=true) String param1,
    @RequestParam(value="param2", required=false) String param2){
.......
}

Аннотация @ PathVariable имеет только одно значение атрибута для привязки шаблона URI запроса. Разрешается использовать множественную аннотацию @ PathVariable в одном методе. Но убедитесь, что не более одного метода имеют один и тот же шаблон.

Также есть еще одна интересная аннотация: @MatrixVariable

HTTP: // локальный: 8080 / spring_3_2 / matrixvars / запасов; BT.A = 276.70 + 10.40 + 3,91 AZN = 236,00 + 103,00 + 3,29; SBRY = 375,50 + 7,60 + 2,07

И метод контроллера для этого

 @RequestMapping(value = "/{stocks}", method = RequestMethod.GET)
  public String showPortfolioValues(@MatrixVariable Map<String, List<String>> matrixVars, Model model) {

    logger.info("Storing {} Values which are: {}", new Object[] { matrixVars.size(), matrixVars });

    List<List<String>> outlist = map2List(matrixVars);
    model.addAttribute("stocks", outlist);

    return "stocks";
  }

Но вы должны включить:

<mvc:annotation-driven enableMatrixVariables="true" >
Xelian
источник
Будет ли строка типа userNameтипа param или нет? Я склоняюсь к тому, чтобы сделать его переменным, но это тоже может быть параметром.
cst1992
1
..А вот оригинальное сообщение: - javabeat.net/spring-mvc-requestparam-pathvariable
Мехрай Малик
Можно @PathParamи @RequestParamобъявить без использования@RequestMapping
sofs1
29

@RequestParam используется для параметра запроса (статические значения), например: http: // localhost: 8080 / analysis / pow? Base = 2 & ext = 4

@PathVariable используется для динамических значений, таких как: http: // localhost: 8080 / analysis / sqrt / 8

@RequestMapping(value="/pow", method=RequestMethod.GET)
public int pow(@RequestParam(value="base") int base1, @RequestParam(value="ext") int ext1){
    int pow = (int) Math.pow(base1, ext1);
    return pow;
}

@RequestMapping("/sqrt/{num}")
public double sqrt(@PathVariable(value="num") int num1){
    double sqrtnum=Math.sqrt(num1);
    return sqrtnum;
}
Alok
источник
просто и ясно @alok
Ананд Криш
12

1) @RequestParamиспользуется для извлечения параметров запроса

http://localhost:3000/api/group/test?id=4

@GetMapping("/group/test")
public ResponseEntity<?> test(@RequestParam Long id) {
    System.out.println("This is test");
    return ResponseEntity.ok().body(id);
}

while @PathVariableиспользуется для извлечения данных прямо из URI:

http://localhost:3000/api/group/test/4

@GetMapping("/group/test/{id}")
public ResponseEntity<?> test(@PathVariable Long id) {
    System.out.println("This is test");
    return ResponseEntity.ok().body(id);
}

2) @RequestParamболее полезен в традиционном веб-приложении, где данные в основном передаются в параметрах запроса, @PathVariableи больше подходит для веб-служб RESTful, где URL-адрес содержит значения.

3) @RequestParamаннотация может указывать значения по умолчанию, если параметр запроса отсутствует или является пустым с помощью defaultValueатрибута, при условии, что обязательный атрибут false:

@RestController
@RequestMapping("/home")
public class IndexController {

    @RequestMapping(value = "/name")
    String getName(@RequestParam(value = "person", defaultValue = "John") String personName) {
        return "Required element of request param";
    }

}
Андрей
источник
1
@PathVariable - must be placed in the endpoint uri and access the query parameter value from the request
@RequestParam - must be passed as method parameter (optional based on the required property)
 http://localhost:8080/employee/call/7865467

 @RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
 public List<Calls> getAgentCallById(
            @PathVariable(“callId") int callId,
            @RequestParam(value = status", required = false) String callStatus) {

    }

http://localhost:8080/app/call/7865467?status=Cancelled

@RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
public List<Calls> getAgentCallById(
            @PathVariable(“callId") int callId,
            @RequestParam(value = status", required = true) String callStatus) {

}
Мэтью Меналиш
источник
1

Обе аннотации ведут себя точно так же.

Только 2 специальных символа '!' и '@' принимаются аннотациями @PathVariable и @RequestParam.

Чтобы проверить и подтвердить поведение, я создал приложение весенней загрузки, которое содержит только 1 контроллер.

 @RestController 
public class Controller 
{
    @GetMapping("/pvar/{pdata}")
    public @ResponseBody String testPathVariable(@PathVariable(name="pdata") String pathdata)
    {
        return pathdata;
    }

    @GetMapping("/rpvar")
    public @ResponseBody String testRequestParam(@RequestParam("param") String paramdata)
    {
        return paramdata;
    }
}

Нажав на следующие запросы, я получил тот же ответ:

  1. ! Локальный: 7000 / PVAR / @ # $% ^ & * () _ + - = [] {} |; ':», / <>.?
  2. ?! Локальный: 7000 / rpvar пары = @ # $% ^ & * () _ + - = [] {} |; ':», / <>.?

! @ был получен как ответ в обоих запросах

Шубхам Шривастава
источник
0

может случиться так, что тип midia application / x-www-form-urlencoded преобразует пространство в + , а получатель будет декодировать данные путем преобразования + в пробел. проверьте URL для получения дополнительной информации. http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1

Энди
источник