0

Is it possible to have two view technology in Spring MVC.

Let's say i want to have a JSP and Velocity,

on my dispatcher-servlet.xml

<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
    <property name="basename" value="spring-views"/>
</bean>

on my spring-views.properties

item-list.(class)=org.springframework.web.servlet.view.JstlView
item-list.url=/WEB-INF/pages/add-item.jsp

image-list.(class)=org.springframework.web.servlet.view.velocity.VelocityView
image-list.url=/WEB-INF/velocity/image-list.vm
image-list.exposeSpringMacroHelpers=true

I've been search a whole day and I cannot find any answer. Any help is appreciated. Thanks!

Clark
  • 143
  • 1
  • 9
  • possible duplicate of [Spring MVC with multiple view resolvers](http://stackoverflow.com/questions/18215402/spring-mvc-with-multiple-view-resolvers) – BetaRide Jul 28 '14 at 11:35
  • Yes it is as long as paths are seperated. – Stefan Jul 28 '14 at 11:50
  • @Stefan I keep having this error:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'image-list': Initialization of bean failed; nested exception is org.springframework.context.ApplicationContextException: Must define a single VelocityConfig bean in this web application context (may be inherited): VelocityConfigurer is the usual implementation. This bean may be given any name.; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.view.velocity.VelocityConfig] is defin – Clark Jul 28 '14 at 11:59
  • it worked now i moved the .vm file to my classpath. – Clark Jul 28 '14 at 12:40

3 Answers3

2

Add a Velocity config to your dispatcher servlet:

<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
    <property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
</bean>
Stefan
  • 12,108
  • 5
  • 47
  • 66
  • Thanks but now it says Request processing failed; nested exception is org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/WEB-INF/velocity/image-list.vm' – Clark Jul 28 '14 at 12:21
  • Does that file exist? (/WEB-INF/velocity/image-list.vm) – Stefan Jul 28 '14 at 12:24
  • Yeah it exist it seems it's not being read by the controller. This is how it actually looks:List images = userService.getImagesByUserId(userId); ModelAndView modelAndView = new ModelAndView("image-list"); modelAndView.addObject("images", images); modelAndView.addObject("imagePath",imagePath); modelAndView.addObject("userId",userId); return modelAndView; – Clark Jul 28 '14 at 12:27
  • The files cannot be read, because there not in the classpath [(defaults to ClasspathResourceLoader)](http://velocity.apache.org/engine/devel/apidocs/org/apache/velocity/runtime/resource/loader/package-summary.html). You can put them for example, below src/velocity/image-list.vm, or configure a [FileResourceLoader](http://stackoverflow.com/questions/5342704/how-to-set-properly-the-loader-path-of-velocity) to load them from a different directory. – Stefan Jul 28 '14 at 12:35
0

You can use as many view technologies in the application as you want, provided you have configured view resolvers for each and there is no conflict between them (in terms of which should pick up a view returned by a controller). Here is an excellent example with full XML configuration and actual views.

manish
  • 19,695
  • 5
  • 67
  • 91
0

Here is an example of using both a velocity view resolver and an internal view resolver. In addition, I have derived spring VelocityLayoutView to be able to use velocity tools in version 2.0. Order is 10 for velocity resolver and 20 for internal to give velocity resolver a chance to resolve its view before the internal resolver that allways resolve. Output is forced to UTF-8 for velocity views.

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      id="viewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="20">
</bean>

<bean class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver"
      id="vmViewResolver" p:order="10" p:suffix=".vm" p:prefix=""
      p:cache="true" p:contentType="text/html;charset=UTF-8"
      p:exposeRequestAttributes="false" p:exposeSessionAttributes="false"
      p:exposePathVariables="true" p:exposeSpringMacroHelpers="true"
      p:dateToolAttribute="date" p:toolboxConfigLocation="/WEB-INF/toolbox.xml"
      p:viewClass="org.sba.views.Velocity2LayoutView">
    <property name="attributesMap">
        <map>
            <entry key="messageSource" value-ref="messageSource"/>
        </map>
    </property>
</bean>

And here is the modified VelocityView :

public class Velocity2LayoutView extends VelocityLayoutView {
    ViewToolManager toolManager;

    @Override
    protected Context createVelocityContext(Map<String, Object> model,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        ViewToolContext context = toolManager.createContext(request, response);
        context.putAll(model);
        return context;
    }

    @Override
    protected void initTool(Object tool, Context velocityContext) throws Exception {
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        toolManager = new ViewToolManager(getServletContext(), false, false);
        if (getToolboxConfigLocation() != null) {
            XmlFactoryConfiguration config = new XmlFactoryConfiguration();
            config.read(getServletContext()
                    .getResourceAsStream(getToolboxConfigLocation()));
            toolManager.configure(config);
        }
        toolManager.setVelocityEngine(getVelocityEngine());
    }
}
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252