@RequestParam vs @PathVariable

355

Was ist der Unterschied zwischen @RequestParamund @PathVariablebeim Umgang mit Sonderzeichen?

+wurde von @RequestParamals Raum akzeptiert .

Im Falle von @PathVariablewurde +als akzeptiert +.

user1857181
quelle

Antworten:

499

Wenn die URL http://localhost:8080/MyApp/user/1234/invoices?date=12-05-2013am 5. Dezember 2013 die Rechnungen für Benutzer 1234 erhält, sieht die Controller-Methode folgendermaßen aus:

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

Außerdem können Anforderungsparameter optional sein, und ab Spring 4.3.3 können auch Pfadvariablen optional sein . Beachten Sie jedoch, dass dies die URL-Pfadhierarchie ändern und Konflikte bei der Anforderungszuordnung verursachen kann. Würden Sie beispielsweise /user/invoicesdie Rechnungen für den Benutzer nulloder Details zu einem Benutzer mit der ID "Rechnungen" bereitstellen ?

Ralph
quelle
11
@PathVariablekann in jeder RequestMethod
Kurai Bankusu
1
@AlexO: Dies hat nichts mit Java8 zu tun, es funktioniert sogar für Java 5 und Spring3.0: Der Punkt ist, dass der Code mit aktiviertem Debugging kompiliert wird.
Ralph
2
@Ralph Richtig, dies funktioniert mit Debugging vor Java 8. Seit Java 8 funktioniert es auch ohne Debugging, stattdessen mit "-parameters": docs.spring.io/spring/docs/current/spring-framework-reference/… docs.oracle .com / javase / tutorial / Reflect / Member /…
AlexO
1
@ user3705478: Ich glaube nicht, weil Spring wissen muss, dass dies eine Request-Handler-Methode ist. (und natürlich: @PathParam funktioniert nur, wenn die Uri-Vorlage einen Platzhalter enthält)
Ralph
2
@ user3705478: @PathParamist eine Annotation von javax.ws.rs. docs.oracle.com/javaee/7/api/javax/ws/rs/PathParam.html
Ralph
112

@ RequestParam- Annotation, die für den Zugriff auf die Abfrageparameterwerte aus der Anforderung verwendet wird. Sehen Sie sich die folgende Anforderungs-URL an:

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

In der obigen URL-Anfrage kann auf die Werte für param1 und param2 wie folgt zugegriffen werden:

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

Im Folgenden finden Sie eine Liste der Parameter, die von der Annotation @RequestParam unterstützt werden:

  • defaultValue - Dies ist der Standardwert als Fallback-Mechanismus, wenn die Anforderung den Wert nicht hat oder leer ist.
  • Name - Name des zu bindenden Parameters
  • erforderlich - Gibt an, ob der Parameter obligatorisch ist oder nicht. Wenn dies der Fall ist, schlägt das Senden dieses Parameters fehl.
  • Wert - Dies ist ein Alias ​​für das Namensattribut

@ PathVariable

@ PathVariable identifiziert das Muster, das im URI für die eingehende Anforderung verwendet wird. Schauen wir uns die folgende Anforderungs-URL an:

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

Die obige URL-Anfrage kann wie folgt in Ihre Spring MVC geschrieben werden:

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

Die Annotation @ PathVariable enthält nur einen Attributwert zum Binden der Anforderungs-URI-Vorlage. Es ist erlaubt, das multiple @ zu verwenden Annotation PathVariable in der einzelnen Methode zu verwenden. Stellen Sie jedoch sicher, dass nicht mehr als eine Methode dasselbe Muster aufweist.

Außerdem gibt es noch eine interessante Anmerkung: @MatrixVariable

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

Und die Controller-Methode dafür

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

Aber Sie müssen aktivieren:

<mvc:annotation-driven enableMatrixVariables="true" >
Xelian
quelle
Wird eine Zeichenfolge, z. B. userNameeinen Typparameter, haben oder nicht? Ich neige dazu, es zu einer Variablen zu machen, aber es könnte auch ein Parameter sein.
cst1992
1
..Und hier ist der ursprüngliche Beitrag: - javabeat.net/spring-mvc-requestparam-pathvariable
Mehraj Malik
Kann @PathParamund @RequestParamkann ohne Verwendung deklariert werden@RequestMapping
sofs1
29

@RequestParam wird für Abfrageparameter (statische Werte) wie: http: // localhost: 8080 / berechnung / pow? Base = 2 & ext = 4 verwendet

@PathVariable wird für dynamische Werte wie http: // localhost: 8080 / berechnung / sqrt / 8 verwendet

@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
quelle
einfach und klar @alok
anand krish
12

1) @RequestParamwird verwendet, um Abfrageparameter zu extrahieren

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 @PathVariablewird verwendet, um Daten direkt aus dem URI zu extrahieren:

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) @RequestParamist nützlicher in einer herkömmlichen Webanwendung, in der Daten meistens in den Abfrageparametern übergeben werden, während @PathVariablees besser für RESTful-Webdienste geeignet ist, in denen URL Werte enthält.

3) @RequestParamAnnotation kann Standardwerte angeben , wenn ein Abfrageparameter nicht vorhanden oder leer ist, indem ein defaultValueAttribut verwendet wird, vorausgesetzt, das erforderliche Attribut lautet 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";
    }

}
Andriy
quelle
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) {

}
Mathew Menalish
quelle
1

Beide Anmerkungen verhalten sich genau gleich.

Nur 2 Sonderzeichen '!' und '@' werden von den Anmerkungen @PathVariable und @RequestParam akzeptiert.

Um das Verhalten zu überprüfen und zu bestätigen, habe ich eine Spring-Boot-Anwendung erstellt, die nur 1 Controller enthält.

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

Bei folgenden Anfragen habe ich die gleiche Antwort erhalten:

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

! @ wurde in beiden Anfragen als Antwort empfangen

Shubham Srivastava
quelle