Spring with Thymeleaf view integration - spring

Starting out with Spring MVC and Thymeleaf for a project - But I am facing the issue of loading the index page -
My Controller is as follows -
#Controller
public class HomeController {
#RequestMapping(method=RequestMethod.GET, value="/")
public ModelAndView index(){
ModelAndView mav = new ModelAndView();
mav.setViewName("index");
mav.addObject("user", new UserCredential());
return mav;
}
and my servlet.xml file is
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="web.controller" />
<!-- Enabling Spring MVC configuration through annotations -->
<mvc:annotation-driven />
<!-- Mapping Static Resources -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="order" value="1" />
<property name="viewNames" value="*.html"/>
</bean>
</beans>
My file structure is --
WebContent
-- WEB_INF
-- views
-- index.html
However I get the following exception -
javax.servlet.ServletException: Could not resolve view with name 'index1' in servlet with name 'springMVC'
Am I placing the file in the wrong place or missing something in my controller?

Solved it, I had to return the view name with the extension since I was telling my viewResolver to only resolve to names ending in .html ..
This thread pointed me to the answer http://forum.thymeleaf.org/Issue-with-my-Thymeleaf-Spring-configuration-td4024996.html

Related

Update one column does not works

I want to update one column of my database. The column name is status and the type is Enum('waiting' , 'accepted' , 'rejected')
I want to update this column when I click on link:
Accept
Reject
Vacation.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.terafast.tem.model">
<class name="Vacation" table="vacations" dynamic-update="true">
<id name="id" column="REQUEST_ID">
<generator class="native" />
</id>
<property name="user" column="USER_ID" />
<property name="reason" column="REASON" />
<property name="duration" column="HOW_LONG" />
<property name="status" column="STATUS" />
<property name="start" type="date" column="START_DATE" />
<property name="created" type="date" column="CREATED_AT" />
</class>
</hibernate-mapping>
Controller
#RequestMapping(value = "/requests/action")
public String statuHandler(HttpServletRequest request, Model model) {
int id = Integer.parseInt(request.getParameter("id"));
String status = request.getParameter("a");
vacationDao.actionStatus(id, status);
return "redirect:/admin/requests";
I can successfully get these two GET values. (id , a). My VacationDAOImpl:
#Override
#Transactional
public void actionStatus(int id, String action) {
Session session = sessionFactory.openSession();
Query q = session.createQuery("from Vacation where id = :reqid ");
q.setParameter("reqid", id);
Vacation vacation = (Vacation) q.list().get(0);
vacation.setStatus(action);
session.update(vacation);
}
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<context:component-scan base-package="com.terafast.tem" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="employeeDao" class="com.terafast.tem.dao.EmployeeDAOImpl">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
<bean id="vacationDoa" class="com.terafast.tem.dao.VacationDAOImpl">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
</beans>
I have seen this approach in this tutorial.
When I click on links, everything looks good. But the column value does not change. Could someone explain this problem?

Spring MVC can't access #Autowired fields from #MessageMapping annotated methods

I've been setting up my Spring 4 MVC application to work with STOMP over WebSocket and so far i've succeeded, my servlet can handle and dispatch STOMP messages without problems.
However, i've encountered an annoying problem when handling these messages from #MessageMapping annotated methods inside my controllers: I can't access any of the #Autowired controller's fields from inside these methods (they all are null pointers), but i can access these fields on the same controller from #RequestMapping annotated methods without any problem.
My Dispatcher Servlet Config:
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">
<mvc:annotation-driven/>
<mvc:resources location="assets" mapping="/assets/**"/>
<mvc:resources location="assets/img/favicon.ico" mapping="/favicon.ico" />
<context:component-scan base-package="com.company.web.controller"/>
<security:global-method-security pre-post-annotations="enabled" />
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="contentNegotiationManager">
<bean class="org.springframework.web.accept.ContentNegotiationManager">
<constructor-arg>
<bean class="org.springframework.web.accept.PathExtensionContentNegotiationStrategy">
<constructor-arg>
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="language"/>
<bean class="com.hxplus.web.interceptor.aCustomAwesomeInterceptor"/>
</mvc:interceptors>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" p:defaultLocale="es"/>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="messages"></bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="2"/>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="0"/>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="${upload.limit}" />
</bean>
<context:property-placeholder location="classpath*:upload_config.properties"/>
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/hello/{recipient}">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic" />
</websocket:message-broker>
</beans>
My Controller:
#Controller
public class TheController {
private static final Logger _logger = LoggerFactory.getLogger(TheController.class);
#Autowired private TheService theService;
#Autowired private SimpMessagingTemplate simpMessagingTemplate;
#PreAuthorize("hasRole('GOD')")
#RequestMapping(value = "/something/{id}", method = RequestMethod.GET)
public String show(Model model, #PathVariable("id") Long id) {
//HERE I CAN ACCESS BOTH "theService" AND
//"simpMessagingTemplate" WITHOUT PROBLEMS
}
#MessageMapping("/hello/{recipient}")
private VOID testing(StompEvent event, #DestinationVariable String recipient){
//HERE BOTH "theService" AND "simpMessagingTemplate" ARE NULL
}
}
I found my error and it had nothing to do with Spring Messaging or configuration, it was a pretty dumb error actually so i apologize:
My #MessageMapping annotated method was private and it should have been public.

how to make spring-mvc application multi-language?

I am working on web service with spring-mvc 4, I have to make it multilanguage. Like that: if coming url request contains '..?lang=tr' for turkish and '..?lang=en' for english. I read on stackoverflow that <mvc:annotation-driven /> override LocaleChangeInterceptor. But when I remove that, app is not working.And I was using this tutorial. I didnt find a solution for that yet. For configuration below, messages are always in english even if I switch language. Furthermore I need to get lang messages in java instead of jsp also. But it always return default message there in java class when I syso. I messed up here. and asking for your help.
#Autowired
private MessageSource messageSource;
Locale locale = LocaleContextHolder.getLocale();
String msg = messageSource.getMessage("deneme", null, "Deault Message!", locale);
dispatcher-servlet.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"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"></property>
</bean>
</mvc:interceptors>
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource">
<property name="basename" value="classpath:/messages"></property>
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" id="localeChangeInterceptor">
<property name="paramName" value="lang"></property>
</bean>
<bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver">
<property name="defaultLocale" value="en"></property>
</bean>
<!-- Defining which view resolver to use -->
<bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
add this to your xml to register your localChangeInterceptor and it will work
<mvc:annotation-driven/>
<context:component-scan
base-package="controller">
</context:component-scan>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
</bean>

Spring MVC with multiple view resolvers

I tried to use 2 view resolvers:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.evgeni.dfr.controller" />
<context:annotation-config />
<mvc:annotation-driven />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="cache" value="false" />
<property name="viewClass" value="com.evgeni.drf.faces.FacesView" />
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".xhtml" />
<property name="order" value="1" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
<property name="order" value="0" />
</bean>
</beans>
The application always uses only the one with the lowest order and not the other. In the current case if my controller return "someView" the app will respond with The requested resource (/MyProject/WEB-INF/views/someView.jsp) is not available. even if there is "pages/someView.xhtml".
Spring version - 3.2.3
Edit:
If I have 2 methods in controller and methodA returns "viewA" and methodB returns "viewB". And we have viewA.jsp in 'views' folder and viewB.xhtml in 'pages'.
Case1: UrlBasedViewResolver -> order=1,InternalResourceViewResolver -> order=2
methodA -> The requested resource (/MyProject/WEB-INF/pages/viewA.xhtml) is not available.;
methodB -> OK
Case2: UrlBasedViewResolver -> order=2,InternalResourceViewResolver -> order=1
methodA -> OK ;
methodB -> `The requested resource (/MyProject/WEB-INF/views/viewB.jsp) is not available.`;
I think you misunderstood the order priority. The ViewResolver with the highest order is the last resolver in the chain. Since you gave the InternalResourceViewResolver an order of 0, it will be the first resolver in the chain and the InternalResourceViewResolver will resolve the view whatever view name is returned. So, if you want multiple resolvers, the InternalResourceViewResolver must be the resolver with the highest order.
Change the InternalResourceViewResolver order value to 2 :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.evgeni.dfr.controller" />
<context:annotation-config />
<mvc:annotation-driven />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="cache" value="false" />
<property name="viewClass" value="com.evgeni.drf.faces.FacesView" />
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".xhtml" />
<property name="order" value="1" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
<property name="order" value="2" />
</bean>
</beans>
EDIT :
After checking the javadoc, it seems that these two resolvers cannot be chained since the InternalResourceViewResolver is a UrlBasedViewResolver (InternalResourceViewResolver extends UrlBasedViewResolver). Both resolver always match the returned value. I think you will need something custom to be able to do this.
Chage order in InternalResourceViewResolver from 0 to 1. InternalResourceViewResolver must have largest order (lower priority)

Spring 3 with Thymeleaf config issue

Hello I have the following jars in my build path -
spring-beans-3.1.2.RELEASE.jar
spring-context-3.1.2.RELEASE.jar
spring-core-3.1.2.RELEASE.jar
spring-expression-3.1.2.RELEASE.jar
spring-web-3.1.2.RELEASE.jar
spring-webmvc-3.1.2.RELEASE.jar
thymeleaf-spring3-2.0.13.jar
and my servlet
<?xml version="1.0" encoding="UTF-8"?><br>
<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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="web.controller" />
<!-- Enabling Spring MVC configuration through annotations -->
<mvc:annotation-driven />
<!-- Mapping Static Resources -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="order" value="1" />
<property name="viewNames" value="*.html" />
</bean>
</beans>
The error I get on launching is -
Cannot find class [org.thymeleaf.templateresolver.ServletContextTemplateResolver] for bean with name 'templateResolver' defined in ServletContext resource [/WEB-INF/springMVC-servlet.xml]; nested exception is java.lang.ClassNotFoundException: org.thymeleaf.templateresolver.ServletContextTemplateResolver
Am I missing any other library here? Any help is much appreciated.
You are missing the actual Thymeleaf jar. You included the Spring jar that provides the integration but you missed the actual implementation of it.
Download the jar from here
thymeleaf download site

Resources