tags:

views:

883

answers:

5

What is a simple way to resolve the path to a JSP file that is not located in the root JSP directory of a web application using SpringMVCs viewResolvers? For example, suppose we have the following web application structure:

web-app
  |-WEB-INF
    |-jsp
      |-secure
        |-admin.jsp
        |-admin2.jsp
      index.jsp
      login.jsp

I would like to use some out-of-the-box components to resolve the JSP files within the jsp root folder and the secure subdirectory. I have a *-servlet.xml file that defines:

an out-of-the-box, InternalResourceViewResolver:

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

a handler mapping:

<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
 <property name="mappings">
  <props>
   <prop key="/index.htm">urlFilenameViewController</prop>
   <prop key="/login.htm">urlFilenameViewController</prop>
   <prop key="/secure/**">urlFilenameViewController</prop>
  </props>
 </property>
</bean>

an out-of-the-box UrlFilenameViewController controller:

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

The problem I have is that requests to the JSPs in the secure directory cannot be resolved, as the jspViewResolver only has a prefix defined as /jsp/ and not /jsp/secure/.

Is there a way to handle subdirectories like this? I would prefer to keep this structure because I'm also trying to make use of Spring Security and having all secure pages in a subdirectory is a nice way to do this.

There's probably a simple way to acheive this but I'm new to Spring and the Spring MVC framework so any pointers would be appreciated.

+1  A: 

You need to set the property as follows:

<property name="prefix" value="/WEB-INF/jsp/"/>

and then you can access the URI secure/admin1.jsp

David Rabinowitz
Sorry that prefix was a typo, I've corrected it now. However, if I got to secure/admin1.jsp (or secure/admin1.htm), that will resolve look up in /WEB-INF/jsp/admin1.jsp and not include the secure folder as this is not part of the prefix (I blieve)
chrisjleu
Which spring version are you using? It should work in 2.5.x
David Rabinowitz
I'm using 2.5.6.SEC01. I've tried it but the problem seems to be in the way the mappings in the SimpleUrlHandlerMapping are specified in my example. Any requests to /secure/** will result in Spring expecting the JSP file to reside in /WEB-INF/jsp/, when of course the actual file is located in /WEB-INF/jsp/secure/. I have discovered a suitable workaround that serves my purposes but it has its limitations. I'll proceed to post that also.
chrisjleu
A: 

You can try giving names of the views in the Controller like

<property name="formView" value="secure/admin"/>
<property name="successView" value="secure/admin2"/>

having prefix and suffix mapped as below

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

This will eventually map to /WEB-INF/jsp/secure/admin.jsp and /WEB-INF/jsp/secure/admin2.jsp

Not sure I understand how the properties formView and successView apply here when I want to use the UrlFilenameViewController.
chrisjleu
formView and successView are the view names which you can inject in your controllers , if you want configurable views. This 2 are by default available to you in case you use SimpleFormController.
No this has nothing to do with forms, they're just JSP pages with little content, and although there are two pages in the example I gave, it is not limited to two. I'm not even using a *form* controller and I think this would be abusing the formView and successView properties if I were to attempt to use it in the way you suggest. Not even sure how it would work anyway.
chrisjleu
A: 

You need to set the alwaysUseFullPath property in in the Handler to true:

<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    ...
    <property name="alwaysUseFullPath" value="true" />
</bean>

This will force the handler to use the '/secure/' part of the URI and then the resolver will include it when looking for a JSP in WEB-INF/jsp.

Donal Boyle
No luck with this. Still looking in the root JSP folder.
chrisjleu
A: 

I haven't been able to discover the exact solution to the question I asked but I do have a workaround that suits my particular requirements. The problem seems to lie in the hander mapping. If specified as in the example in the post, any requests to pages in the secure folder result in a failed attempt to locate the actual JSP file in the /WEB-INF/JSP/ folder when of course the actual file is located in /WEB-INF/jsp/secure/.

However, if specified like so:

 <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/login.htm">loginFormController</prop>
    <prop key="**/*.htm">urlFilenameViewController</prop>
   </props>
  </property>
 </bean>

Then all the pages are resolved correctly. A request to /login.html will go to a specific form controller but requests to all other pages, no matter whether they are in the root JSP directory or a sub directory will be found. For me this is fine because what I was really looking for was a way to avoid specifiying a controller for every page in the application (hmmm... perhaps I should have made that clear in the first post - and perhaps there are better ways to do this anyway(?)) . The **/*.htm acts as a catch-all case and any pages that I want handled by a different controller can be specified explicitly above this property, as demonstrated by /login.htm.

chrisjleu
A: 

Try wiht UrlFilenameViewController or return new ModelAndView("secure/login");

danichelios