I have been trying to use thymeleaf layout dialect with spring mvc as mentioned in https://github.com/ultraq/thymeleaf-layout-dialect. My spring-servlet as below
<beans:bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<beans:property name="prefix" value="/WEB-INF/templates/" />
<beans:property name="suffix" value=".html" />
<beans:property name="templateMode" value="HTML5" />
</beans:bean>
<beans:bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<beans:property name="templateResolver" ref="templateResolver" />
<!-- These lines add the dialect to Thymeleaf -->
<beans:property name="additionalDialects">
<beans:set>
<beans:bean class="nz.net.ultraq.thymeleaf.LayoutDialect" />
</beans:set>
</beans:property>
</beans:bean>
<beans:bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<beans:property name="templateEngine" ref="templateEngine" />
<beans:property name="characterEncoding" value="UTF-8" />
</beans:bean>
I have kept all the template file in /WEB-INF/templates/. When I use following code to create and use tempting in thymeleaf
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="Layout.html">
I get following error:
[THYMELEAF] * Dialect [1 of 2]: org.thymeleaf.spring3.dialect.SpringStandardDialect
[THYMELEAF] * Prefix: "th"
[THYMELEAF] * Dialect [2 of 2]: nz.net.ultraq.thymeleaf.LayoutDialect
[THYMELEAF] * Prefix: "layout"
[THYMELEAF] TEMPLATE ENGINE CONFIGURED OK
19:32:40,992 INFO [org.thymeleaf.TemplateEngine] (http-localhost-127.0.0.1-8080-1) [THYMELEAF] TEMPLATE ENGINE INITIALIZED
19:32:41,199 ERROR [org.thymeleaf.TemplateEngine] (http-localhost-127.0.0.1-8080-1) [THYMELEAF][http-localhost-127.0.0.1-8080-1] Exception processing template "home": Error resolving template "Layout.html", template might not exist or might not be accessible by any of the configured Template Resolvers (home:4)
19:32:41,202 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/expensemanager].[appServlet]] (http-localhost-127.0.0.1-8080-1) Servlet.service() for servlet appServlet threw exception: org.thymeleaf.exceptions.TemplateInputException: Error resolving template "MainLayout.html", template might not exist or might not be accessible by any of the configured Template Resolvers (home:4)
If I don't layout:decorator="Layout.html" code works perfectly without any error.
Below is the image which shows my project structure
I usually do this:
<beans:bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<beans:property name="characterEncoding" value="UTF-8" />
<beans:property name="templateEngine">
<beans:bean class="org.thymeleaf.spring3.SpringTemplateEngine">
<beans:property name="additionalDialects">
<beans:set>
<beans:bean class="nz.net.ultraq.thymeleaf.LayoutDialect" />
</beans:set>
</beans:property>
<beans:property name="templateResolvers">
<beans:bean class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<beans:property name="prefix" value="/WEB-INF/templates/" />
<beans:property name="suffix" value=".html" />
<beans:property name="templateMode" value="HTML5" />
</beans:bean>
</beans:property>
</beans:bean>
</beans:property>
</beans:bean>
If this does not work, can you post a screenshot of the file and folder structure?
Related
I am facing issue in authenticating with openldap, I dont know how to configure spring security, ldap with Spring 4.0.0 version. Kindly provide sample reference.
<beans:bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg
value="ldap://localhost:389/dc=test,dc=com" />
</beans:bean>
<security:ldap-server id="contextSource"
url="ldap://localhost:389/dc=test,dc=com" />
<beans:bean id="authMgr"
class="org.springframework.security.authentication.ProviderManager">
<beans:constructor-arg>
<beans:list>
<beans:bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.ldap.authentication.BindAuthenticator">
<beans:constructor-arg ref="contextSource" />
<beans:property name="userDnPatterns">
<beans:list>
<beans:value>uid={0},ou=users</beans:value>
</beans:list>
</beans:property>
</beans:bean>
</beans:constructor-arg>
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<security:authentication-manager>
<security:ldap-authentication-provider
server-ref="contextSource" user-search-base="ou=users"
user-search-filter="(uid={0})" group-search-filter="ou=groups">
<security:password-compare hash="{sha}"
password-attribute="userPassword" />
</security:ldap-authentication-provider>
</security:authentication-manager>
Spring Security 4.0 LDAP Reference
LDAP best practise would be to search for the DN of the entry, hence configure
<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value=""/>
<constructor-arg index="1" value="(uid={0})"/>
<constructor-arg index="2" ref="contextSource" />
</bean>
Also typically the LDAP static group entries' naming attribute is cn, hence configure
<bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=groups"/>
<property name="groupRoleAttribute" value="cn"/>
</bean>
instead of the example shown in the guide
How Roolback and commit in spring mvc use JdbcTemplate
jdbc.xml
<tx:annotation-driven transaction-manager="transactionManager"/>
<beans:bean id="ds"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<beans:property name="url"
value="jdbc:oracle:thin:#localhost:1521:db12c" />
<beans:property name="username" value="phutran" />
<beans:property name="password" value="Phut0107" />
</beans:bean>
<beans:bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<beans:property name="dataSource" ref="ds"></beans:property>
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<beans:property name="dataSource" ref="ds"/>
</beans:bean>
who can help me, thank :(.
JdbcTemplate doesn't handle transaction by itself. You should use #Transactional annotation in your code.
Example
I have been trying to configure MyBatis with Spring MVC to work with multiple databases. I have a page which is trying to connect to one of the DB's to fetch data, so that it can be populated into the drop-down boxes.
Now I am not sure what is wrong with this configuration, but I am receiving the following error:
]] Root cause of ServletException. org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLException: ORA-06576: not a valid function or procedure name
I am providing the XML file here for your reference
<bean id="dataSource1"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#1.1.2.5:1529:DITOS" />
<property name="username" value="return" />
<property name="password" value="return" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="p.com.ent.appl.return.dev.dao,p.com.ent.appl.return.dep.dao,p.com.ent.appl.return.dao.otheruser" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1" />
</bean>
<!-- Declare a transaction manager -->
<bean id="cashReturnTx"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource1" />
</bean>
<!-- define the SqlSessionFactory, notice that configLocation is not needed
when you use MapperFactoryBean -->
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
<!-- <property name="mapperLocations" value="classpath:/com/vrn/ent/dev/daoxml/*.xml"
/> -->
<property name="mapperLocations"
value="classpath*:/p/com/ent/appl/return/**/daoxml/*.xml" />
</bean>
<bean id="sqlSession1" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory1" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#4.24.80.15:1522:LM" />
<property name="username" value="RETURN" />
<property name="password" value="OWNER" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage"
value="p.com.ent.appl.return.dev.dao,p.com.ent.appl.return.dep.dao,p.com.ent.appl.return.dao.otheruser" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<bean id="otherUserTx"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- define the SqlSessionFactory, notice that configLocation is not needed
when you use MapperFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
<!-- <property name="mapperLocations" value="classpath:/com/vrn/ent/dev/daoxml/*.xml"
/> -->
<property name="mapperLocations"
value="classpath*:/p/com/ent/appl/return/**/daoxml/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
</beans>
According to the exception: BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLException: ORA-06576: not a valid function or procedure name, a DB is hit.
Read about error ORA-06576.
Issue is likeky be related to how the procedure is called. Right way is { CALL MyProcedure (#arg0, #arg1) }
Configuration shows that same mappers may be used with both datasources, what happens then if target schemas are different?
I am using Freemarker template with Spring MVC. Is there a way to return HTTP Status 500 if there is any error rendering the template?
Currently I am using attempt block to handle error, but would like to throw Internal Server error and allow web server to redirect to a default error page
<#attempt>
attempt block
<#recover>
recover block
</#attempt>
Below is my servlet-context.xml
<beans:bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<beans:property name="cache" value="true" />
<beans:property name="prefix" value="" />
<beans:property name="contentType" value="text/html; charset=UTF-8" />
<beans:property name="suffix" value=".ftl" />
<beans:property name="exposeSessionAttributes" value="true" />
</beans:bean>
Below change in servlet-context.xml resolved the issue. Now it throws HTTP 500 error which is intercepted by web server and I am able to mast the message by redirecting to pre-defined error page.
<beans:bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<beans:property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<beans:property name="freemarkerSettings">
<beans:props>
<beans:prop key="template_exception_handler">rethrow</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
This is the java-based equivalent configuration:
#Bean
public FreeMarkerConfigurer freemarkerConfig() throws TemplateException {
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/views/ftl/");
Properties settings = new Properties();
settings.setProperty(freemarker.template.Configuration.TEMPLATE_EXCEPTION_HANDLER_KEY, "rethrow");
freeMarkerConfigurer.setFreemarkerSettings(settings);
return freeMarkerConfigurer;
}
A simple way to change the mode from "debug" to "rethrow" is to configure it in your application.properties:
spring.freemarker.settings.template_exception_handler=rethrow
I want to create a controller method that can be called from html form or from a standalone client using resttemplate.
The method has this signature:
#RequestMapping(method = RequestMethod.POST)
public ModelAndView save(#RequestBody #ModelAttribute(value = "itemCreateRequest")
ItemCreateRequest request, Model model) throws NoSuchMethodException,
SecurityException, InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
...
}
The problem is, that if I use the HTML form, everything works fine, but when I try to use the standalone client the values in the request parameter come in null.
ItemCreateRequest icr = new ItemCreateRequest();
icr.setItem(new ItemDTO(null, "23", "bla", "bla bla"));
restTemplate.postForLocation("http://localhost:8080/ims_ui/items.xml", icr);
If I try the method without the #ModelAttribute the standalone client works but the HTML form not.
This is the configuration of my servlet-context.xml
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<beans:bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<beans:property name="marshaller" ref="marshaller"/>
<beans:property name="unmarshaller" ref="marshaller"/>
</beans:bean>
<beans:bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<beans:bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<beans:property name="order" value="0" />
<beans:property name="mediaTypes">
<beans:map>
<beans:entry key="jsp" value="application/html" />
<beans:entry key="xml" value="application/xml" />
</beans:map>
</beans:property>
<beans:property name="defaultViews">
<beans:list>
<!-- XML View -->
<beans:bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<beans:constructor-arg ref="marshaller" />
</beans:bean>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<beans:property name="contextPaths">
<beans:array>
<beans:value>net.franciscovillegas.summa.ims.dto</beans:value>
<beans:value>net.franciscovillegas.summa.ims.service.requests</beans:value>
</beans:array>
</beans:property>
</beans:bean>
Thanks in advance!
The answer is in you're post:
If I try the method without the #ModelAttribute the standalone client
works but the HTML form not.
I think that, when you use the html application you send a request to the server with a map where all keys starts with itemCreateRequest.VARIABLE_NAME , but when you use stand alone application you send that request without the declared #ModelAttribute.
The declared ModelAttribute, in you case "itemCreateRequest", should stand in front of each information sent to that controller.
You can try something like this:
restTemplate.postForLocation("http://localhost:8080/ims_ui/items.xml", new HashMap<String, Object>(){
{
put("itemCreateRequest", icr);
}
});