Spring MVC the default Locale and Locale change doesn't work - java

I am a new Spring developer tried to develop sample web app with two languages support.I want to set the default locale to Arabic language and change the locale when the user clicks the desired language in JSP page.
Here is my mvc-dispatcher-servlet.xml,
<!-- 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/" />
<context:component-scan base-package="com.benchmark.ushers.presentation.controller"/>
<bean id="internalResourceResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- resource bundle configuration-->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:locale/messages" />
<property name="fallbackToSystemLocale" value="false"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="ar" />
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"></property>
</bean>
</mvc:interceptors>
<!-- end of resource bundle configuration-->
And my JSP page as below,
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<%#taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<tiles:insertDefinition name="defaultTemplate">
<tiles:putAttribute name="body">
<div class="body">
<h1>Ushers</h1>
lang : English | Arabic
<h3>
welcome.springmvc :
<spring:message code="footer.content" text="default text" />
</h3>
<h3>
hello :
<spring:message code="footer.hello" text="default text" />
</h3>
</div>
</tiles:putAttribute>
</tiles:insertDefinition>
I do not know what is wrong in my code while the only displayed the English text only.

The above configuration in the question is correct. The problem was in the requested page sets as welcome page in web.xml file so it is executed without any interceptors.
Every thing works fine after comment this part in web.xml
<!-- <welcome-file-list>
<welcome-file>/WEB-INF/pages/adminHome.jsp</welcome-file>
</welcome-file-list>-->

I guess you need DefaultAnnotationHandlerMapping to mapping with #RequestMapping it will check for any locale change request. See also Spring Internationalization.
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
Read this topic to avoid mixing it with <mvc:annotation-driven/>

In my case, I was using the java config version and it didn't worked until I added the "localeResolver" bean name. The internationalization beans I created are listed below. You can check it works by changing the lang parameter in the URL: /some-page.do?lang=ro
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
...
#Bean(name="localeResolver")
public LocaleContextResolver getLocaleContextResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getLocaleChangeInterceptor());
}
#Bean
public LocaleChangeInterceptor getLocaleChangeInterceptor() {
final LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
return interceptor;
}

Related

Locale only getting values for default locale while other locale is not displaying

hi I am working on spring locale but it is still getting values from one locale not from other here is my code so far
dispatcherServlet
<mvc:annotation-driven enable-matrix-variables="true" />
<context:component-scan base-package="com.*" />
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>/com/resources/messages_en</value>
<value>/com/resources/messages_nl</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
</mvc:interceptors>
and this is I am using in my page.jsp
<%# taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
</head>
<body>
<p>
<b><h3>
English| Dutch
</h3></b>
</p>
<spring:message code="tagline"></spring:message>
<hr>
</body>
</html>
For English, everything works fine but while clicking on Dutch its also showing English too, how to resolve that?
this is only data in my files :
1 message_en.properties
tagline=This is English
2 message_nl.properties
tagline=This is dutch
Please Help
Do you have <mvc:annotation-driven /> in you config. Also your <mvc:interceptors> should be like below.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
And MessageSource bean
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean>
Your properties file should be like below.
messages.properties
messages_en_US.properties
messages_zh_CN.properties
Check this post.

How to delete useless JSP

On the website that I'm developping, I'm using a lot of Ajax calls to display informations.
Theses Ajax Call are as follow :
function deleteBookingAjax(rowId) {
$.ajax({
url : "deleteRent.htm",
type : "GET",
data : {
"rentId" : rowId
},
dataType : 'json',
cache : false,
success : function(response) {
if(response.error) {
showPopupMessage(response.error, true);
}
},
statusCode : {
500 : function() {
loggingMessage('Error 500');
reloadBookingTable();
},
404 : function() {
loggingMessage('Error 404');
reloadBookingTable();
}
}
});
}
To perform this call, I have also Controllers as follow :
#RequestMapping(value = "/deleteRent.htm")
public String deleteRent(Long rentId, HttpServletRequest request, HttpServletResponse response) {
if (rentId == null) {
return null;
}
try {
rentService.deleteRent(rentId);
} catch (Exception e) {
LOGGER.error(e);
}
response.setStatus(HttpStatus.SUCCESS);
return ViewNames.BOOKINGS_PAGE;
}
But my problem is that : to perform this Ajax call, I need to create a useless JSP file : WEB-INF/jsp/deleteRent.jsp
<%#page import="net.****.****.web.controllers.RentControllers"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
If I don't create theses files, the Ajax call is not working...
When the file is not in the WEB-INF/ The Ajax call returns :
GET http://127.0.0.1/deleteRent.htm?rowId=1 404 (Not Found)
And the logs are showing :
2015-07-31 10:47:39,084 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Could not complete request
javax.servlet.ServletException: File "/WEB-INF/jsp/deleteRent.jsp" not found
at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:417)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:384)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
....
How can I make it work without theses files (I assume it will be in configurations... but where exactly and how ?), because it's not convinient to have a lot of JSP files but when only few of them have contents...
EDIT
Here is the content of my context.xml, if the errror is located there, we never know :
<!-- resources exclusions from servlet mapping -->
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/scripts/**" location="/scripts/" />
<mvc:resources location="/, classpath:/META-INF/web-resources/" mapping="/resources/**" />
<!-- Enables the Spring MVC #Controller programming model -->
<context:component-scan base-package="net.****.****.web" />
<context:annotation-config />
<mvc:annotation-driven />
<bean id="properties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/META-INF/messages_en.properties</value>
</list>
</property>
</bean>
<bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/jsp directory -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean id="viewResolver" 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" />
<property name="alwaysInclude" value="true" />
<property name="contentType" value="text/html; charset=UTF-8" />
</bean>
<bean id="annotationMethodHandlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
Thanks in advance. :)
I am not quite sure if you are looking for this, but you can include below into your applicationContext.xml or your *****-servlet.xml file.
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
Add this into your pom. Now you can return String from your method.
<!-- Jackson JSON Mapper -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.10</version>
</dependency>
The answer is stupid :) but at least it's fixed now :
Putting : void to the function fixed the problem.
I deleted the empty file and working without :).
#RequestMapping(value = "/deleteRent.htm")
public void deleteRent(Long rentId, HttpServletRequest request, HttpServletResponse response) {
if (rentId == null) {
return null;
}
try {
rentService.deleteRent(rentId);
} catch (Exception e) {
LOGGER.error(e);
}
response.setStatus(HttpStatus.SUCCESS);
}

How to use CDN in Spring MVC

I want to use CDN to serve static content like CSS, JavaScript and images in a project created with Spring MVC. But I didn't how to do it.
I'm new to Spring and I have seen some posts on the web:
JSP/Spring MVC and CDN?
How to use property from property file specified in PropertyPlaceholderConfigurer in JSP
How to show values from property file in JSP in a spring MVC app
http://tshikatshikaaa.blogspot.com/2012/11/serving-static-resources-with-spring-mvc.html
But they didn't explain how to implement it.
For example:
In the past, I use <c:url> tags:
<img src="<c:url value="/path/to/image" />" alt="desc" />
When I use CDN, I may use following code:
<img src="${env.cdnUrl}/mypath/pic.jpg" />
But where should I put ${env.cdnUrl}(in web.xml or dispatcher-servlet.xml(the configuration of Spring MVC))? And how to get the parameter in JSP?
Please help me. Thanks.
I implemented CDN service in Spring using following steps:
Add following lines in dispatcher-servlet.xml (Your Spring Configuration)
<util:properties id="propertyConfigurer" location="classpath:/app.properties"/>
<context:property-placeholder properties-ref="propertyConfigurer" />
Of course, you need to add DOM for spring-util at the top of the file:
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.1.xsd"
Setup in app.properties
cdn.url=//cdn.domain.com/path/to/static/content
Use CDN in JSP files
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<spring:eval expression="#propertyConfigurer.getProperty('cdn.url')" var="cdnUrl" />
<link rel="stylesheet" type="text/css" href="${cdnUrl}/css/semantic.min.css" />
<link rel="stylesheet" type="text/css" href="${cdnUrl}/css/font-awesome.min.css" />
Good luck!
approaches summarized:
use request.setAttribute("env", ) in controller and access the same in jsp.
create a servlet filter and do the same activity described above.
write the env value to properties file and try to access that in jsp pages. if using InternalResourceViewResolver then exposedContextBeanNames can help with exposing properties in jsp.
<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list><value>property_file</value></list>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
<property name="exposeContextBeansAsAttributes" value="true"/>
<property name="exposedContextBeanNames">
<list>
<value>properties</value>
</list>
</property>
</bean>
and access the values in jsp as ${properties.env}
You could also accomplish this via an interceptor.
<mvc:interceptors>
<!-- path interceptor adds servlet path as an attribute -->
<bean class="com.test.myInterceptor" />
Then in the interceptor code, you can have the attribute be set
#Override
public boolean preHandle(final HttpServletRequest request,
final HttpServletResponse response,
final Object handler) {
// set the attribute for URL

How to use default-servlet-handler

I want to configure Spring MVC to serve dynamic files mixed with static files, like this (URL => File):
/iAmDynamic.html => /WEB-INF/views/iAmDynamic.html.ftl
/iAmAlsoDynamic.js => /WEB-INF/views/iAmAlsoDynamic.js.ftl
/iAmStatiHtml => /iAmStatic.html
The DispatchServlet is mapped to /, annotation-based MVC configuration is enabled and I have a view controller like this (Simplified):
#Controller
public class ViewController
{
#RequestMapping("*.html")
public String handleHtml(final HttpServletRequest request)
{
return request.getServletPath();
}
#RequestMapping("*.js")
public String handleJavaScript(final HttpServletRequest request)
{
return request.getServletPath();
}
}
The spring config looks like this:
<context:component-scan base-package="myPackage" />
<mvc:default-servlet-handler />
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views/" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="suffix" value=".ftl" />
</bean>
Unfortunately it doesn't work. When this <mvc:default-servlet-handler /> is active then I can only access the iAmStatic.html file. When I disable the default-servlet-handler then only the dynamic stuff works. But I want both at once and that's exactly what this default-servlet-handler should do, or not? Where is the error here?
I had similar problem, none of the requests were getting mapped to the Spring Controllers:
I discovered I was missing this in spring config xml:
<mvc:annotation-driven/>
It seems with , this is necessary. From documentation, the purpose of doing this is:
Configures the annotation-driven Spring MVC Controller programming model
I will also let DefaultServlet handle static content requests.
So your spring config should look like:
<context:component-scan base-package="myPackage" />
<!-- Define location and mapping of static content -->
<mvc:resources location="/static/" mapping="/static/**"/>
<mvc:default-servlet-handler />
<mvc:annotation-driven/>
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views/" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="suffix" value=".ftl" />
</bean>
Hope this helps!
You need to define two important configurations
<mvc:annotation-driven/>
<mvc:default-servlet-handler />
<mvc:annotation-driven/> will enable your default infrastructure beans where as <mvc:default-servlet-handler /> will configure a handler for serving static resources by forwarding to the Servlet container's default Servlet.
Also don't forget the mvc name space i.e xmlns:mvc="http://www.springframework.org/schema/mvc"
My complete config file (using TilesViewResolver) looks like below
<?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"
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">
<mvc:annotation-driven/>
<!--
Configures a handler for serving static resources by forwarding to the
Servlet container's default Servlet.
-->
<mvc:default-servlet-handler />
<mvc:view-controller path="/" view-name="welcome"/>
<mvc:view-controller path="/home" view-name="welcome"/>
<bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
<property name="order" value="1"/>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="order" value="2"/>
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Also if you have multiple HandlerMapping considering ordering them. For one for which you don't provide order explicitly Spring treats it with lowest precedence.
I think that the view name you are returning from the ViewController is invalid. I expect that request.getServletPath() returns a blank string for all URLs, because the path to your servlet is probably / and the Java documentation says that getServletPath() returns a blank string for that path. Therefore the FreeMarker view resolver is probably ignoring the view name because it wouldn't know what to show.
However using a controller class with #RequestMapping is probably not the ideal way to go about this task anyway. Spring includes a ContentNegotiatingViewResolver which automatically determines the correct view depending on the content type. This overview of ContentNegotiatingViewResolver explains how to set it up.

How to use property from property file specified in PropertyPlaceholderConfigurer in JSP

In my application context I have defined properties file:
<context:property-placeholder location="classpath:application.properties" />
I want to get value of the property defined in that file on JSP page. Is there a way to do that in the way
${something.myProperty}?
PropertyPlaceholderConfigurer can only parse placeholders in Spring configuration (XML or annotations). Is very common in Spring applications use a Properties bean. You can access it from your view this way (assuming you are using InternalResourceViewResolver):
<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list><value>classpath:config.properties</value></list>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
<property name="exposedContextBeanNames">
<list><value>properties</value></list>
</property>
</bean>
Then, in your JSP, you can use ${properties.myProperty} or ${properties['my.property']}.
After Spring 3.1, you can use <spring:eval /> tag with SpEL like this:
<spring:eval expression="#applicationProps['application.version']"
var="applicationVersion"/>
To use with multiple locations in a list which might not be present as can be done with the context:property-placeholder bean:
<beans:bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<beans:property name="ignoreResourceNotFound" value="true" />
<beans:property name="locations">
<beans:list>
<beans:value>classpath:application.properties</beans:value>
<beans:value>classpath:environment.properties</beans:value>
<beans:value>classpath:environment-${env}.properties</beans:value>
</beans:list>
</beans:property>
</beans:bean>
To use recursive property placeholder expansion in views, you need a different solution, take a look at this answer:
https://stackoverflow.com/a/10200249/770303
`<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
id="messageSource"
p:basenames="WEB-INF/i18n/site"
p:fallbackToSystemLocale="false"/>`
Now this is your Properties File
`site.name=Cool Bananas`
And.
Here goes your JSP
`<%# taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<html>
<head>
<title><spring:message code="site.name"/></title>
</head>
<body>
</body>
</html>`
This will show you the tables of the current schema (which you are logged in):
select table_name from user_tables order by table_name;
This will show you the tables of schema , for which you have select rights at least:
select owner, table_name from all_tables where owner='<owner>' order by owner, table_name;

Categories