I am working on a web app where I have most of my pages making use of apache tiles (2.1.2), but a few of them need to just be plain jsps.
I am having a problem in that both an InternalResourceViewResolver
and a UrlBasedViewResolver
will try to resolve the view no matter what, so that no matter which ordering I use, it will either fail on the plain JSP pages, or on the tiles pages.
Here is the config:
<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
<property name="order" value="0"/>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="1"/>
</bean>
To make it more clear what I am trying to do, I need to be able to have view states like this:
<view-state id="someState" view="/someDir/foo"><!--render foo.jsp -->
<transition on="foo" to="bar"/>
</view-state>
<view-state id="someState" view="something.core"><!--render tile defintion named 'something.core' -->
<transition on="foo" to="bar"/>
</view-state>
Does anyone know how to configure things so that I can get it to render tiles definitions and plain jsps?
In case you want to use a Multiple View Resolver in a Spring MVC application then priority order can be set using the order property. The following example shows how to use the ResourceBundleViewResolver and the InternalResourceViewResolver in the Spring Web MVC Framework.
Below, we will discuss about three important View Resolver implementations provided by Spring MVC, InternalResourceViewResolver , XmlViewResolver and ResourceBundleViewResolver .
Spring provides view resolvers, which enable you to render models in a browser without tying you to a specific view technology. Out of the box, Spring enables you to use JSPs, Velocity templates and XSLT views, for example.
InternalResourceViewResolver can always map any request to the correct view, hence it has to be given the lowest priority. This way we give other View Resolver chance to resolve the view names.
As you say, you cannot chain these together. The javadoc for both states clearly that they must both be at the end of the resolver chain.
I suggest that if you really need to use these togather, then you write a simple custom implementation of ViewResolver which takes the view name, and decides which of your two "real" view resolvers to delegate to. This assumes that you can tell which resolver to call based on the view name.
So you'd define a custom ViewResolver like this:
public class MyViewResolver implements ViewResolver {
private ViewResolver tilesResolver;
private ViewResolver jspResolver;
public void setJspResolver(ViewResolver jspResolver) {
this.jspResolver = jspResolver;
}
public void setTilesResolver(ViewResolver tilesResolver) {
this.tilesResolver = tilesResolver;
}
public View resolveViewName(String viewName, Locale locale) throws Exception {
if (isTilesView(viewName)) {
return tilesResolver.resolveViewName(viewName, locale);
} else {
return jspResolver.resolveViewName(viewName, locale);
}
}
private boolean isTilesView(String viewName) {
.....
}
}
You'd need to implement the isTilesView method to decide which resolver to delegate to.
In the XML config, define this new view resolver, and make sure it appears before the other ones.
<bean class="MyViewResolver">
<property name="tilesResolver" ref="tilesViewResolver"/>
<property name="jspResolver" ref="viewResolver"/>
</bean>
I've just solved the same problem by splitting the *-servlet.xml
config file in two; in my case the main application uses Tiles, but I want QUnit tests to be simple JSPs.
app-servlet.xml
contains only the Tiles view resolver, tests-servlet.xml
only contains the JSP view resolver and web.xml
mappings are dispatching requests to the correct servlet basing on the URL.
<servlet-mapping>
<servlet-name>app</servlet-name> <!-- will reach app-servlet.xml -->
<url-pattern>/foo</url-pattern> <!-- will use "foo" Tile -->
<url-pattern>/bar</url-pattern> <!-- will use "bar" Tile -->
</servlet-mapping>
<servlet-mapping>
<servlet-name>tests</servlet-name> <!-- will reach tests-servlet.xml -->
<url-pattern>/foo-test</url-pattern> <!-- will use foo-test.jsp -->
<url-pattern>/bar-test</url-pattern> <!-- will use bar-test.jsp -->
</servlet-mapping>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With