Reputation: 2237
I have been trying to get an incredibly simple controller/view set up, and just can't make it work. In my web.xml
, I've defined a <servlet>
called servlet-context.xml
, which is running ok. In servlet-context.xml
, I've set:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
<...other stuff in here... />
<mvc:annotation-driven />
among other things. My understanding is this is all that's needed to use @
annotations.
In my controller, I have:
@RequestMapping(value="/student/{username}/", method=RequestMethod.GET)
public String adminStudent(@PathVariable String username, @RequestParam String studentid) {
return "student";
}
And in my student.jsp
view, I have:
<p>This is the page where you would edit the stuff for ${username}.</p>
<p>The URL parameter <code>studentid</code> is set to ${studentid}.</p>
When I make a request to http://localhost:8080/application/student/xyz123/?studentid=456
, I get the view I expect, but all the variables are blank or null:
<p>This is the page where you would edit the stuff for .</p>
<p>The URL parameter <code>studentid</code> is set to .</p>
I suspect it's a problem with the way my web.xml
or servlet-context.xml
are set up, but I can't find the culprit anywhere. There's nothing showing up in any logs as far as I can see.
Update: I was basing my code off this part of the spring-mvc-showcase:
@RequestMapping(value="pathVariables/{foo}/{fruit}", method=RequestMethod.GET)
public String pathVars(@PathVariable String foo, @PathVariable String fruit) {
// No need to add @PathVariables "foo" and "fruit" to the model
// They will be merged in the model before rendering
return "views/html";
}
...which works fine for me. I can't understand why this example works but mine doesn't. Is it because they're doing something different with servlet-context.xml
?
<annotation-driven conversion-service="conversionService">
<argument-resolvers>
<beans:bean class="org.springframework.samples.mvc.data.custom.CustomArgumentResolver"/>
</argument-resolvers>
</annotation-driven>
Upvotes: 11
Views: 72576
Reputation: 3180
@PathVariable
is to obtain some placeholder from the uri (Spring call it an URI Template)
— see Spring Reference Chapter 16.3.2.2 URI Template Patterns@RequestParam
is to obtain an parameter — see Spring Reference Chapter 16.3.3.3 Binding request parameters to method parameters with @RequestParamAssume this Url http://localhost:8080/MyApp/user/1234/invoices?date=12-05-2013
(to get the invoices for user 1234 for today)
@RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
public List<Invoice> listUsersInvoices(
@PathVariable("userId") int user,
@RequestParam(value = "date", required = false) Date dateOrNull) {
model.put("userId", user);
model.put("date", dateOrNull);
}
Upvotes: 1
Reputation: 2237
Aha! Figured it out, finally.
The spring-mvc-showcase
is using Spring 3.1, which will automatically expose @PathVariable
s to the model, according to SPR-7543.
As pointed out by @duffymo and @JB Nizet, adding to the Model with model.put()
is the thing to do for versions of Spring earlier than 3.1.
Ted Young pointed me in the right direction with Spring: Expose @PathVariables To The Model.
Upvotes: 7
Reputation: 691785
@PathVariable
means that the annotated method argument should be extracted from the path of the invoked URL. @RequestParam
means that the annotated method argument must be extracted from the request parameters. None of these annotations cause the annotated arguments to be put in the request, session or application scope.
${username}
means "write the value of the username attribute (found in page, or request, or session, or application scope) in the response". Since you didn't include any username attribute in any of those scopes, it doesn't write anything.
The code would work if the method returned a ModelAndView object, and the model contained a username
attribute and a studentid
attribute.
Upvotes: 4
Reputation: 308813
Create a Model map and add those parameter name/value pairs to it:
@RequestMapping(value="/student/{username}/", method=RequestMethod.GET)
public String adminStudent(@PathVariable String username, @RequestParam String studentid, Model model) {
model.put("username", username);
model.put("studentid", studentid);
return "student";
}
Upvotes: 17