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.
Related
I am using spring security 3.x, here i need to integrate with JA-SIG CAS server, I can login CAS server through https://localhost:8443/cas/login, but after integrated with spring security, i can not redirect my login page to CAS login URL, and my previous account doesn't use, spring security always tell me login error, googled for lots of times and don't know why? any help will be appreciated. And here is patial of my spring security configuration:
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<!-- 这里的service 必须是一个由CasAuthenticationFilter 监控的URL -->
<property name="service" value="http://localhost:8082/dna/j_spring_cas_security_check" />
<property name="sendRenew" value="false" />
</bean>
<!-- hook up cas entry point -->
<bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<constructor-arg ref="casEntryPoint" />
</bean>
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="authenticationUserDetailsService">
<bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<constructor-arg ref="myUserDetailsService" />
</bean>
</property>
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<!-- 配置cas服务器前缀 -->
<constructor-arg index="0" value="https://localhost:8443/cas-server-webapp-5.0.8/" />
</bean>
</property>
<property name="key" value="casAuthProviderKey" />
</bean>
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:8443/cas-server-webapp-5.0.8/login" />
<property name="serviceProperties" ref="serviceProperties" />
</bean>
<bean id="singleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="https://localhost:8443/cas-server-webapp-5.0.8/cas/logout" />
<constructor-arg>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
</constructor-arg>
<property name="filterProcessesUrl" value="/j_spring_cas_security_logout" />
</bean>
<!-- 目前不需要将ajax请求拒绝 -->
<bean id="authEntryPoint" class="com.gooalgene.common.authority.AjaxAwareLoginUrlAuthenticationEntryPoint" c:loginFormUrl="/login" />
<bean id="authenticationSuccessHandler" class="com.gooalgene.common.handler.AuthenticationSuccessHandlerImpl">
<property name="defaultTargetUrl" value="/dna/index" />
</bean>
<sec:http auto-config='false' use-expressions="true" entry-point-ref="casEntryPoint">
<sec:intercept-url pattern="/managerPage" access="hasRole('ROLE_ADMIN')" />
<sec:intercept-url pattern="/**" access="hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')" />
<sec:form-login authentication-success-handler-ref="authenticationSuccessHandler"
authentication-failure-handler-ref="authenticationFailureHandler"/>
<sec:access-denied-handler error-page="/403" />
<sec:custom-filter ref="casFilter" position="CAS_FILTER" />
<sec:custom-filter ref="singleLogoutFilter" before="CAS_FILTER" />
<sec:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="casAuthenticationProvider" />
</sec:authentication-manager>
And my spring mvc default welcome page is /login.
Here is my debug console log:
INFO [com.gooalgene.common.handler.AuthenticationFailureHandlerImpl]
- 登录失败,异常信息:No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
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.
At first, why I want to use different keyspaces?
Because I want to write JUnit Test, but I need another keyspace for testing.
I am using Spring MVC.
And I use the hectorTemplate autowired in spring.
<!-- cassandra configuration -->
<bean id="cassandraHostConfigurator" class="me.prettyprint.cassandra.service.CassandraHostConfigurator">
<constructor-arg value="${cassandra.url}" />
</bean>
<bean id="cluster" class="me.prettyprint.cassandra.service.ThriftCluster">
<constructor-arg value="${cassandra.cluster}" />
<constructor-arg ref="cassandraHostConfigurator" />
</bean>
<bean id="consistencyLevelPolicy" class="me.prettyprint.cassandra.model.ConfigurableConsistencyLevel">
<property name="defaultReadConsistencyLevel" value="${cassandra.defaultReadConsistencyLevel}"></property>
<property name="defaultWriteConsistencyLevel" value="${cassandra.defaultWriteConsistencyLevel}"></property>
</bean>
<bean id="keyspace" class="me.prettyprint.hector.api.factory.HFactory" factory-method="createKeyspace">
<constructor-arg value="${cassandra.keyspace}" />
<constructor-arg ref="cluster" />
<constructor-arg ref="consistencyLevelPolicy" />
</bean>
<bean id="hectorTemplate" class="me.prettyprint.cassandra.service.spring.HectorTemplateImpl">
<property name="cluster" ref="cluster" />
<property name="keyspace" ref="keyspace" />
<property name="replicationStrategyClass" value="org.apache.cassandra.locator.SimpleStrategy" />
<property name="replicationFactor" value="1" />
</bean>
So I should do what to add another keyspace?
Thanks for the help.(n.n)!!!!!
<!-- Keyspace1 -->
<bean id="keyspace1" class="me.prettyprint.hector.api.factory.HFactory" factory-method="createKeyspace">
<constructor-arg value="${cassandra.keyspace1}" />
<constructor-arg ref="cluster" />
<constructor-arg ref="consistencyLevelPolicy" />
</bean>
<bean id="hectorTemplate1" class="me.prettyprint.cassandra.service.spring.HectorTemplateImpl">
<property name="cluster" ref="cluster" />
<property name="keyspace" ref="keyspace1" />
<property name="replicationStrategyClass" value="org.apache.cassandra.locator.SimpleStrategy" />
<property name="replicationFactor" value="1" />
</bean>
<!-- Keyspace2 -->
<bean id="keyspace2" class="me.prettyprint.hector.api.factory.HFactory" factory-method="createKeyspace">
<constructor-arg value="${cassandra.keyspace2}" />
<constructor-arg ref="cluster" />
<constructor-arg ref="consistencyLevelPolicy" />
</bean>
<bean id="hectorTemplate2" class="me.prettyprint.cassandra.service.spring.HectorTemplateImpl">
<property name="cluster" ref="cluster" />
<property name="keyspace" ref="keyspace2" />
<property name="replicationStrategyClass" value="org.apache.cassandra.locator.SimpleStrategy" />
<property name="replicationFactor" value="1" />
</bean>
For JUnit test, you SHOULD use the same keyspace and use an embedded Cassandra. Check here. There is no reason to create another keyspace just for testing.
am using jsf2 and primefaces 3.5 spring webflow.
My index page does not show the menubar (created by a model) submenus and items. although the pages on webflow show the menu bar.
my code is as follows
root-context
<mvc:annotation-driven />
<mvc:resources mapping="/" location="/resources/**"/>
<faces:resources />
<import resource="controller.xml"/>
<import resource="webflow.xml"/>
<context:component-scan base-package="com.test.testapp"/>
<bean id="faceletsViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".xhtml" />
</bean>
Webflow
<bean class="org.springframework.webflow.scope.ScopeRegistrar"/>
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>
<webflow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices" base-path="/WEB-INF/pages">
<webflow:flow-location-pattern value="/**/*-flow.xml" />
</webflow:flow-registry>
<faces:flow-builder-services id="facesFlowBuilderServices" development="true" />
<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator"/>
<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry"/>
<property name="order" value="0"/>
</bean>
Controller
<mvc:view-controller path="/index" view-name="index" />
<mvc:view-controller path="/login" view-name="login" />
<context:component-scan base-package="com.test.testapp.Controller"/>
thanks
the index
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
template="/WEB-INF/layout/layout.xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<p:menubar model="#{mainMenuModel.model}"/>
<ui:define name="content">
</ui:define>
</ui:composition>
the template
<h:body styleClass="body">
<h:form id="contentForm">
<ui:insert name="menu"/>
<ui:insert name="content"/>
</h:form>
</h:body>
--------------------UPDATE!-------------here is my .jsp withouth unnecessairy buttons
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>Practice</title>
<link rel="stylesheet" type="text/css" href="style/wort.css" />
</head>
<body>
<a href="goToDictionary.html" class="practice_dictionary"><spring:message code="check.the.dictionary" />
</a>
<br>
en
de
<br>
</body>
</html>
----------------------------------Update ends here----------------------------------------
I have set up i18n to my web app using Spring MVC. It does not work.
When I click on the link:
de
nothing happens, only the address bar changes to
http://localhost:8080/wort/register.html?lang=de
but the displayed messages remain the same (english).
Obviously I have the messages_de.properties file next to the messages_en.properties file.
(there is no problem with the english messages' display.)
Do I miss something obvious?
here is my spring configuration:
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:property-placeholder location="classpath:jdbc.properties" />
<context:component-scan base-package="net" />
<mvc:annotation-driven />
<tx:annotation-driven transaction-manager="hibernateTransactionManager" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>net.model.Word</value>
<value>net.model.Category</value>
<value>net.model.Challenge</value>
<value>net.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
here is the solution: I have to remove this from spring-servlet.xml and everything is fine
<mvc:annotation-driven />