views:

993

answers:

2

I'd like to introduce Spring MVC to an application that has up till now used simple direct access to JSP files i.e www.example.com/login.jsp which contains the business logic and presentation details.

I'd like to strip out the business logic and keep only the presentation in the JSP. To do this, I've moved the jsp file from webapp/login.jsp to webapp/WEB-INF/jsp/login.jsp and then mapped all urls with the pattern *.jsp to Spring's DispatchServlet which goes to a Controller and then a view which (should) forward to /WEB-INF/jsp/login.jsp.

The web.xml looks like this:

<servlet>
 <servlet-name>springapp</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
 <servlet-name>springapp</servlet-name>
 <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

springapp-context.xml

<bean id="urlFilenameViewController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /*.jsp=urlFilenameViewController
        </value>
    </property>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
 <property name="prefix" value="/WEB-INF/jsp/"/>
 <property name="suffix" value=".jsp"></property>
</bean>

However, the fundamental problem with this is that I'm mapping external URL requests ending in .jsp to internal web requests that also map to .jsp. The internal .jsp request then goes through the DispatchServlet for a second time which returns an error as it cannot find anything to handle the request:

WARN - DispatcherServlet.noHandlerFound(1077) | No mapping found for HTTP request with URI [/myapp/WEB-INF/jsp/login.jsp] in DispatcherServlet with name 'springapp'

Given that I cannot change the external URLs, is there a way to get round this issue when mapping external file types to the same internal file type?

+2  A: 

We address this in our application by using a different pattern for request URLs (*.htm instead of *.jsp). This avoids the problem and it is good practice anyway because there may not be a 1-to-1 relationship between a URL and a JSP.

Rob H
I'm afraid I cannot choose a different external URL extension as we already have clients that are dependent on the *.jsp URLs. It seems unfortunate that we make this (admittedly bad) decision at the start of the project which cannot be reversed!
Alex Spurling
Perhaps you could do URL rewriting on the incoming requests to switch the extension before the servlet gets it. I have used the UrlRewriteFilter from tuckey.org and it works well. Or, if your application is fronted by an Apache web server, you could use mod_rewrite. Just google for "URL rewriting" to find these and other links. However, this approach requires you to maintain a list of URLs (or URL patterns) to be rewritten. Hopefully it would be temporary.
Rob H
A: 

I suggest you:

  • map Spring MVC requests to a different pattern ( e.g *.do);
  • use a UrlRewriteFilter or your application server's url rewrite functionality to map *.jsp calls to *.do;
Robert Munteanu