@RequestParam vs @PathVariable


355

Qual é a diferença entre @RequestParame @PathVariableao lidar com caracteres especiais?

+foi aceito por @RequestParamcomo espaço.

No caso de @PathVariable, +foi aceito como +.

Respostas:


499

Se o URL http://localhost:8080/MyApp/user/1234/invoices?date=12-05-2013obtiver as faturas do usuário 1234 em 5 de dezembro de 2013, o método do controlador será semelhante a:

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

Além disso, os parâmetros de solicitação podem ser opcionais e, a partir do Spring 4.3.3, as variáveis ​​de caminho também podem ser opcionais . Cuidado, porém, isso pode alterar a hierarquia do caminho da URL e introduzir conflitos de mapeamento de solicitação. Por exemplo, /user/invoicesforneceria as faturas para o usuário nullou detalhes sobre um usuário com o ID "faturas"?


11
@PathVariablepode ser usado em qualquer RequestMethod
Kurai Bankusu

11
@ AlexO: isso não tem nada a ver com o java8, ele funciona mesmo para o java 5 e Spring3.0: o ponto é que o código é compilado com a depuração ativada.
22416 Ralph

2
@ Ralph Correto, isso funciona com depuração antes do Java 8. Desde o Java 8, ele também funciona sem depuração, usando "-parameters": docs.spring.io/spring/docs/current/spring-framework-reference/… docs.oracle .com / javase / tutorial / reflect / member /…
AlexO 27/10

11
@ user3705478: acho que não, porque a primavera precisa saber que esse é um método manipulador de solicitações. (e, é claro: @PathParam só funciona se houver um espaço reservado no modelo uri)
Ralph

2
@ user3705478: @PathParamé uma anotação javax.ws.rs. docs.oracle.com/javaee/7/api/javax/ws/rs/PathParam.html
Ralph

112

A anotação @RequestParam usada para acessar os valores dos parâmetros de consulta da solicitação. Veja o seguinte URL de solicitação:

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

Na solicitação de URL acima, os valores para param1 e param2 podem ser acessados ​​como abaixo:

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

A seguir, é apresentada a lista de parâmetros suportados pela anotação @RequestParam:

  • defaultValue - este é o valor padrão como um mecanismo de fallback, se a solicitação não estiver com o valor ou estiver vazio.
  • nome - nome do parâmetro a ser vinculado
  • obrigatório - se o parâmetro é obrigatório ou não. Se for verdade, a falha no envio desse parâmetro falhará.
  • valor - Este é um alias para o atributo name

@PathVariable

@ PathVariable identifica o padrão usado no URI para a solicitação recebida. Vamos dar uma olhada no URL de solicitação abaixo:

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

A solicitação de URL acima pode ser gravada no seu Spring MVC como abaixo:

@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){
.......
}

A anotação @ PathVariable possui apenas um valor de atributo para vincular o modelo de URI da solicitação. É permitido usar a anotação @ PathVariable múltipla no método único. Mas assegure-se de que não mais de um método tenha o mesmo padrão.

Também há mais uma anotação interessante: @MatrixVariable

http: // localhost: 8080 / spring_3_2 / matrixvars / stocks; BT.A = 276,70, + 10,40, + 3,91; AZN = 236,00, + 103,00, + 3,29; SBRY = 375,50, + 7,60, + 2,07

E o método Controller para isso

 @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";
  }

Mas você deve ativar:

<mvc:annotation-driven enableMatrixVariables="true" >

Uma string, como userNametem um tipo param ou não? Estou inclinado a torná-lo uma variável, mas também pode ser um parâmetro.
cst1992

11

Pode @PathParame @RequestParamser declarado sem usar@RequestMapping
sofs1

29

@RequestParam é usado para o parâmetro de consulta (valores estáticos) como: http: // localhost: 8080 / calculation / pow? Base = 2 & ext = 4

@PathVariable é usado para valores dinâmicos como: http: // localhost: 8080 / calculation / 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;
}

simples e claro @alok
anand krish

12

1) @RequestParamé usado para extrair parâmetros de consulta

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é usado para extrair dados diretamente do 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é mais útil em um aplicativo da web tradicional em que os dados são passados ​​principalmente nos parâmetros de consulta, enquanto @PathVariableé mais adequado para serviços da web RESTful nos quais a URL contém valores.

3) a @RequestParamanotação pode especificar valores padrão se um parâmetro de consulta não estiver presente ou vazio usando um defaultValueatributo, desde que o atributo necessário seja 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

Ambas as anotações se comportam exatamente da mesma maneira.

Apenas 2 caracteres especiais '!' e '@' são aceitos pelas anotações @PathVariable e @RequestParam.

Para verificar e confirmar o comportamento, criei um aplicativo de inicialização por mola que contém apenas 1 controlador.

 @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;
    }
}

Atingindo as seguintes solicitações, obtive a mesma resposta:

  1. localhost: 7000 / pvar /! @ # $% ^ & * () _ + - = [] {} |; ': ",. / <>?
  2. localhost: 7000 / rpvar? param =! @ # $% ^ & * () _ + - = [] {} |; ': ",. / <>?

! @ foi recebido como resposta nos dois pedidos


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.