Velocity with tiles 2 and spring-mvc - spring-mvc

I am looking for a way to use velocity with tiles 2 :
in the end I want to switch from jsp / vm like this :
<tiles-definitions>
<definition extends="default" name="view1">
<put-attribute name="body" value="/WEB-INF/views/view1.jspx"/>
</definition>
<definition extends="default" name="view2">
<put-attribute name="body" value="/WEB-INF/views/view2.vm" type="velocity"/>
</definition>
</tiles-definitions>
What I want to do is exaclty explained here :
http://tiles.apache.org/framework/tutorial/integration/velocity.html
The first 2 point are easy but it is not clear what to do in the 3rd point :
I have to override the method : registerAttributeRenderers()
But what is the class to extend ?
Then what should I do with this class, I guess it has to be referenced somewhere in spring...
My current spring-mvc configuration :
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layouts/layouts.xml</value>
<value>/WEB-INF/views/**/views.xml</value>
</list>
</property>
</bean>
thanks for help !

Related

Spring mvc: Controller Result resent to RequestMappingHandlerMapping

I have an abstract Spring Controller class extended by various controllers.
Example method:
#Override
#RequestMapping(value = { "/", "" }, method = RequestMethod.GET)
public String getAllAsView(#RequestParam(required = false) boolean ajax,
Model m) {
String mapping = elementClass.getSimpleName();
m.addAttribute(mapping + "List", getAll());
return mapping + "All" + (ajax ? "Ajax" : "");
}
These are the relevant definitions in my view.xml:
<definition name="maintemplate" template="/WEB-INF/views/main_template.jsp">
<put-attribute name="top" value="/WEB-INF/views/header.jsp" />
<put-attribute name="side" value="/WEB-INF/views/menu.jsp" />
</definition>
<definition name="ajaxtemplate" template="/WEB-INF/views/ajax_template.jsp">
<put-attribute name="top" value="/WEB-INF/views/header.jsp" />
</definition>
<definition name="PersonAll" extends="maintemplate">
<put-attribute name="content" value="/WEB-INF/views/personlist.jsp" />
</definition>
<definition name="PersonAllAjax" template="ajaxtemplate">
<put-attribute name="content" value="/WEB-INF/views/personlist.jsp" />
</definition>
With the ajax parameter only the body content is to return.
Everything works fine without the ajax parameter.
But with the Ajax parameter the return string is used for a new Controller request.
This is the Log:
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /person/6
TRACE: org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod - Invoking [PersonController.getAsView] method with arguments [6, true, {}]
WARN : de.kreth.clubhelperbackend.aspects.DaoLoggerAspect - de.kreth.clubhelperbackend.dao.PersonDao.getById(6) ==> 6: M Kreth
TRACE: org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod - Method [getAsView] returned [PersonGetAjax]
DEBUG: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /person/ajaxtemplate
This is the servlet-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="de.kreth.clubhelperbackend" />
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean
class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String"
value="dd/MM/yyyy HH:mm:ss.SSS Z"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" />
<bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver">
<property name="order" value="1" />
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/views/**/views.xml</value>
</list>
</property>
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
I am stuck finding out what is happening here. I changed the template name and the new name was used for the request.
The problem came up, after I changed nearly all xml files in project. I inserted Doctype tag and changed schema definitions and stuff. Because that caused heavy problems I stepped back to a working version. Before that, the ajax parameter worked.
Ah - and I updated to java-version 1.6.
Any ideas why spring uses the templatename "ajaxtemplate" as a new request and sends it back to the controller?
Best regards
Markus
Stupid mistake: never programm past midnight:
<definition name="PersonAllAjax" template="ajaxtemplate">
<put-attribute name="content" value="/WEB-INF/views/personlist.jsp" />
</definition>
must be
<definition name="PersonAllAjax" extends="ajaxtemplate">
<put-attribute name="content" value="/WEB-INF/views/personlist.jsp" />
</definition>

Spring MVC, Tiles 3, and Freemarker Integration

I have integrated the Freemarker into an existing spring MVC and Tiles 3 application and found that it couldn't read the tiles definition file. It directly reads the content tile, which is one among 3 tiles that configured in the tiles definition file, bypassing the tile definition file. How can I make it to read the tiles definition file? Here are my codes:
applicationContext.xml
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver"/>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tile-defs/view.xml</value>
<value>/WEB-INF/tile-defs/survey.xml</value>
</list>
</property>
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath">
<value>/WEB-INF/views/</value>
</property>
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape"/>
</map>
</property>
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">3</prop>
</props>
</property>
</bean>
<bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true"/>
<property name="prefix" value=""/>
<property name="suffix" value=".ftl"/>
<property name="exposeSpringMacroHelpers" value="true"/>
<property name="exposeRequestAttributes" value="true"/>
<property name="exposeSessionAttributes" value="true"/>
</bean>
tiles-def.xml
<tiles-definitions>
<definition name="template"
template="/WEB-INF/views/main_template.ftl">
<put-attribute name="header"
value="/WEB-INF/views/tiles/header.ftl" />
<put-attribute name="footer"
value="/WEB-INF/views/tiles/footer.ftl" />
</definition>
<definition name="home" extends="template">
<put-attribute name="content" value="/WEB-INF/views/home.ftl" />
</definition>
main_template.ftl
<body>
<!-- Header -->
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="content" />
<!-- Footer Page -->
<tiles:insertAttribute name="footer" />
</body>
home.ftl
<#import "spring.ftl" as spring />
Hello world!
<P> The time on the server is ${serverTime}. </P>
<P> ${message}. </P>
header.ftl
<#import "spring.ftl" as spring />
This is header
I had the same issue. I solved it by adding this to the top of my ftl files
<#assign tiles=JspTaglibs["http://tiles.apache.org/tags-tiles"]>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
and using
<#tiles.insertAttribute name="header" />
to insert something from the tiles definition.

integrating tiles in spring3, getting java.lang.NoSuchFieldError: PATCH exception

Let me know how to initialize tiles from dispatcher and application context and if any changes required in web.xml,
this is my tiles.xml
<definition name="contact" extends="mainLayout">
<put-attribute name="title" value="Contact Manager" />
<put-attribute name="body" value="/WEB-INF/jsp/contact.jsp" />
</definition>
</tiles-definitions>
in application context i have used
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="requestContextAttribute" value="requestContext"/>
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
and dispatcher looks like this
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
indexController</prop>-->
newController
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
<property name="definitions">
<list>
<value>WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="viewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
In Dispatcher-Servlet
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
In web.xml use this code
<listener>
<listener-class>org.apache.tiles.web.startup.simple.SimpleTilesListener</listener-class>
</listener>
rest is not required for spring-tiles application, tiles.xml is depended on your requirement

Error resolving template "pages", template might not exist or might not be accessible by any of the configured Template Resolvers

I did a project using Spring with Thymeleaf and Tiles with the following structure :
I have configured my Spring-Servlet :
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" />
<property name="suffix" value=".html" />
<property name="characterEncoding" value="UTF-8" />
<property name="templateMode" value="HTML5" />
</bean>
<bean id="tilesConfigurer"
class="org.thymeleaf.extras.tiles2.spring4.web.configurer.ThymeleafTilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-defs.xml</value>
</list>
</property>
</bean>
<bean id="tilesViewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="viewClass"
value="org.thymeleaf.extras.tiles2.spring4.web.view.ThymeleafTilesView" />
<property name="templateEngine" ref="templateEngine" />
<property name="characterEncoding" value="UTF-8" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean class="org.thymeleaf.extras.tiles2.dialect.TilesDialect" />
</set>
</property>
</bean>
my Tiles Definition is :
<tiles-definitions>
<definition name="layout" template="layout">
<put-attribute name="header" value="header" />
<put-attribute name="menu" value="menu" />
<put-attribute name="footer" value="footer" />
<put-attribute name="body" />
</definition>
<definition name="usersView" extends="layout">
<put-attribute name="body" value="pages :: users" />
</definition>
</tiles-definitions>
will this give me the following error :
Error resolving template "pages", template might not exist or might not be accessible by any of the configured Template Resolvers
but when i move the users.html page to the templates folder and make my tiles def as
<definition name="usersView" extends="layout">
<put-attribute name="body" value="users" />
</definition>
its working fine .
So the Question is can Thymeleaf accept My Folder Structure? if Yes ,How?
Yes it can be by using the viewNames property
just change your Spring-Servlet.xml to
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".html" />
<property name="characterEncoding" value="UTF-8" />
<property name="templateMode" value="HTML5" />
</bean>
<bean id="tilesConfigurer"
class="org.thymeleaf.extras.tiles2.spring4.web.configurer.ThymeleafTilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-defs.xml</value>
</list>
</property>
</bean>
<bean id="tilesViewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="viewClass"
value="org.thymeleaf.extras.tiles2.spring4.web.view.ThymeleafTilesView" />
<property name="templateEngine" ref="templateEngine" />
<property name="characterEncoding" value="UTF-8" />
<property name="order" value="1" />
<property name="viewNames" value="templates/*,pages/*" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean class="org.thymeleaf.extras.tiles2.dialect.TilesDialect" />
</set>
</property>
</bean>
and your tiles definition to
<tiles-definitions>
<definition name="layout" template="templates/layout">
<put-attribute name="header" value="templates/header" />
<put-attribute name="menu" value="templates/menu" />
<put-attribute name="footer" value="templates/footer" />
<put-attribute name="body" />
</definition>
<definition name="pages/usersView" extends="layout">
<put-attribute name="body" value="pages/users" />
</definition>
</tiles-definitions>
Explanation :
we have defined the root folder in the prefix at the Resolver
<property name="prefix" value="/WEB-INF/" />
and extended it by
<property name="viewNames" value="templates/*,pages/*" />
to the needed folders and any new view folder you create should goes in this property also redirect or forward too
And also make sure that the query written in Repo layer might be not correct. If so please check your query (using CriteriaBuilder, CriteriaQuery, Predicate) once is it satisfying the condition.
Here in my case I tried to getting a value from data base where the condition is not satisfied.

Tiles 2 with Spring MVC not resolving

I am trying to integrate Tiles 2 with Spring MVC but I am getting a specific jsp displayed rather than Tiles View. For ex, If request="about.htm" then I am getting about.jsp which is kept at /jsp/about.jsp . It works as if view is getting resolved through UrlBasedViewResolver.
My Spring-servlet.xml is
<mvc:annotation-driven />
<context:component-scan base-package="com.spring.controller" />
<mvc:resources mapping="/resources*" location="resources/"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="TilesViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver" p:basename="views" />
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" p:definitions="/WEB-INF/tiles-defs.xml" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
<bean id="loginDao" class="com.spring.dao.impl.LoginDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
views.properties kept under classes is
welcome.(class)=org.springframework.web.servlet.view.tiles2.TilesView
welcome.url=welcome
friends.(class)=org.springframework.web.servlet.view.tiles2.TilesView
friends.url=friends
office.(class)=org.springframework.web.servlet.view.tiles2.TilesView
office.url=office
about.(class)=org.springframework.web.servlet.view.JstlView
about.url=/jsp/about.jsp
tiles-defs.xml is
<tiles-definitions>
<definition name="baseLayout" template="/WEB-INF/tiles/baseLayout.jsp">
<put-attribute name="title" value="Template"/>
<put-attribute name="header" value="/WEB-INF/tiles/header.jsp"/>
<put-attribute name="menu" value="/WEB-INF/tiles/menu.jsp"/>
<put-attribute name="body" value="/WEB-INF/tiles/body.jsp"/>
<put-attribute name="footer" value="/WEB-INF/tiles/footer.jsp"/>
</definition>
<definition name="welcome" extends="baseLayout">
<put-attribute name="title" value="Welcome"/>
<put-attribute name="body" value="/jsp/welcome.jsp"/>
</definition>
<definition name="friends" extends="baseLayout">
<put-attribute name="title" value="Friends"/>
<put-attribute name="body" value="/jsp/friends.jsp"/>
</definition>
<definition name="office" extends="baseLayout">
<put-attribute name="title" value="Office"/>
<put-attribute name="body" value="/jsp/office.jsp"/>
</definition>
</tiles-definitions>
Please guide.
It could be a problem with the view resolver order, if you want to give priority to tiles view resolver then add order property for the view resolvers
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="2"/>
</bean>
<bean id="TilesViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver" p:basename="views" p:order="1"/>

Resources