alexmuller
alexmuller

Reputation: 2237

Spring 3.0.6 MVC @PathVariable and @RequestParam blank/empty in JSP view

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

Answers (4)

Sudhakar
Sudhakar

Reputation: 3180

Assume 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

alexmuller
alexmuller

Reputation: 2237

Aha! Figured it out, finally.

The spring-mvc-showcase is using Spring 3.1, which will automatically expose @PathVariables 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

JB Nizet
JB Nizet

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

duffymo
duffymo

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

Related Questions