48

I have multiple view resolvers in a Spring configuration and wanted to use different view resolvers for different requests.

Example: For URLs starting with report_*, use Birt view resolver, and for ajax calls use Tiles resolver and so on.

Tried setting order property, but all views are resolved by tilesViewResolver.

<beans:bean id="tilesViewResolver" class="org.springframework.js.ajax.AjaxUrlBasedViewResolver">
    <beans:property name="viewClass" value="com.example.example.util.AjaxTiles21View"/>
</beans:bean>

<beans:bean id="birtViewResolver" class="org.eclipse.birt.spring.core.BirtViewResolver">
    ...
    <beans:property name="order" value="2" />
</beans:bean>

<beans:bean id="beanNameResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
    <beans:property name="order" value="1" />
</beans:bean>
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
tangobee
  • 926
  • 7
  • 22

1 Answers1

41

You absolutely can. ViewResolver has a single method, resolveViewName(String) which returns

the View object, or null if not found (optional, to allow for ViewResolver chaining)

Your ViewResolver beans are registered. When a view name is returned by a handler, Spring will iterate through each ViewResolver, invoking their resolveViewName method with the given name. If the method returns non-null, that View is used. If null is returned, then it continues iterating.

So the implementation has to return null if Spring is to skip it.

There are some implementations that never return null. This seems to be the case with your custom ViewResolver classes. If the ViewResolver returns a View, even if that View will eventually fail to be rendered, Spring will use it.

You either need to fix that or order your ViewResolver beans. For example, you can order them with the Ordered interface. Have your classes implement that interface and return an appropriate value.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • how did you call it in your controller (assuming you are using controller)? – Smith Aug 02 '14 at 05:40
  • this is my controller `@RequestMapping(value = {"/report_emp"}) public String reportTest(Model model) {return null;}` – tangobee Aug 02 '14 at 05:42
  • 2
    @tangobee Just FYI: the `@name` thing works more reliably if you remove the spaces, e.g. `@SotiriosDelimanolis`. In this case, it didn't matter, as you don't need the `@name` if you are responding to the person who left the answer. In most cases, the software would have tried to guess who you meant based on who had responded, as it would have ignored the "Delimanolis" part since it came after a space. At least, that's the way I understand it. – trlkly Aug 08 '14 at 08:37
  • @trl the first three letters of the name are sufficient. – Mohammad Jan 10 '15 at 17:47
  • 2
    @mhm If they are unambiguous. Honestly, I just type @, start tying, and when I see only one name, I press tab. – trlkly Jan 11 '15 at 17:32