Ta Sas
Ta Sas

Reputation: 9813

Spring MVC maps parameter to .jsp instead of @RequestMapping

I've created a sample spring-mvc app using maven archetype

mvn archetype:generate -D groupId=test.tool -D artifactId=test-D version=0.1-SNAPSHOT -D archetypeArtifactId=spring-mvc-jpa-archetype -D archetypeGroupId=org.fluttercode.knappsack

I've been trying to read some parameters from an URL:

package test.tool.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


@Controller
@RequestMapping(value = "/testReadRest", method = RequestMethod.GET)
public class TestReadRestController {

private static final Logger logger = LoggerFactory
        .getLogger(TestReadRestController.class);


// No Params
@RequestMapping(method = RequestMethod.GET)
public void getMainModel(Model model) {
    model.addAttribute("varFromClient","[NOT SET]");
    model.addAttribute("tokenFromClient","[NOT SET]");
    return;
}

// http://localhost:8080/test/testReadRest/varPost
// read "varPost"
@RequestMapping(value = "/{varPost}", method = RequestMethod.GET)
public void getVarFromURI(@PathVariable("varPost") String theVar, Model model) {
    model.addAttribute("varFromClient",theVar);
    model.addAttribute("tokenFromClient","[NOT SET]");
    return;
   }
}

but the parameter isn't read when trying http://localhost:8080/test/testReadRest/varPost

instead, I get an error:

Problem accessing /soctoolset/WEB-INF/views/testReadRest/varPost.jsp. Reason: NOT_FOUND

Any suggestions?

[EDIT]

Here are the beans

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"   
    xsi:schemaLocation="
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <!-- Imports user-defined @Controller beans that process client requests -->
    <beans:import resource="controllers.xml" />

</beans:beans>

and controller.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- Scans within the base package of the application for @Components to 
        configure as beans -->
    <context:component-scan base-package="test.tool" />

    <tx:annotation-driven />
    <mvc:annotation-driven />

    <mvc:resources mapping="/resources/**" location="/resources/" />

    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

</beans>

Upvotes: 0

Views: 2755

Answers (1)

Wolfram
Wolfram

Reputation: 8052

I set up a new project with the archetype you used.

You are returning void from the @Controller method, so this section from the docs applies:

void if the method handles the response itself (by writing the response content directly, declaring an argument of type ServletResponse / HttpServletResponse for that purpose) or if the view name is supposed to be implicitly determined through a RequestToViewNameTranslator (not declaring a response argument in the handler method signature).

Thus, the view is resolved based on the path, in your case "varPost" or whatever you put at the end of the path. The extension ".jsp" is appended due to this default configuration:

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

You could add the missing file, but I guess that's not what you want to do. Instead, you can change the handler method's signature and set a view explicitly, like this:

@RequestMapping(value = "/{varPost}", method = RequestMethod.GET)
public String getVarFromURI(@PathVariable("varPost") String theVar,
        Model model) {
    model.addAttribute("varFromClient", theVar);
    model.addAttribute("tokenFromClient", "[NOT SET]");
    return "someview";
}

This results in the following reasonable error:

The requested resource (/testapp/WEB-INF/views/someview.jsp) is not available.

Now, you just need to create that view. You can then use the path variable without it interfering with the view resolution.

If you don't want to render a JSP, you could start by reading the documentation regarding the "Supported method return types". If you want to handle the response completely yourself, you can return void again and add the request and response as arguments.

Upvotes: 5

Related Questions