Multilanguage Option in Spring MVC Project - java

This code I have put in the Header.JSP, this dropdown will appear on all pages
<li class="dropdown">Language
<ul class="dropdown-menu">
<li>Hindi</li>
<li>English</li>
<li>Tamil</li>
messages_en.properties
label.our_objective = Our Objective
label.our_objective1 =Internet Banking site provides personal banking and corporate banking services that gives you complete control over all your banking demands online.
Likes this messages_hin.properties for Hindi languages are used.
the code below is used in JSP for language change.
<spring:message code="label.account_summary" />
This is SpringMVCConfig.java
public class WebMvcConfig extends WebMvcConfigurerAdapter {
// Static Resource Config
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Default..
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
localeInterceptor.setParamName("lang");
registry.addInterceptor(localeInterceptor).addPathPatterns("/*");
}
}
public class WebMvcConfig extends WebMvcConfigurerAdapter {
// Static Resource Config
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Default..
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
localeInterceptor.setParamName("lang");
registry.addInterceptor(localeInterceptor).addPathPatterns("/*");
}
}
This is ApplicationContextConfig.java
#ComponentScan("com.cedge.*")
public class ApplicationContextConfig {
#Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/resources/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean(name = "messageSource")
public MessageSource getMessageResource() {
ReloadableResourceBundleMessageSource messageResource= new ReloadableResourceBundleMessageSource();
// Read i18n/messages_xxx.properties file.
// For example: i18n/messages_en.properties
messageResource.setBasename("classpath:property/message");
messageResource.setDefaultEncoding("UTF-8");
return messageResource;
}
#Bean(name = "localeResolver")
public LocaleResolver getLocaleResolver() {
CookieLocaleResolver resolver= new CookieLocaleResolver();
//resolver.setCookieDomain("myAppLocaleCookie");
// 60 minutes
resolver.setDefaultLocale(Locale.ENGLISH);
//resolver.setCookieMaxAge(0);
return resolver;
}
}
This is SpringWebAppInitializer.java
public class SpringWebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.register(ApplicationContextConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("SpringDispatcher",new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
// UtF8 Charactor Filter.
FilterRegistration.Dynamic fr = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);
fr.setInitParameter("encoding", "UTF-8");
fr.setInitParameter("forceEncoding", "true");
fr.addMappingForUrlPatterns(null, true, "/*");
}}
I want to change the whole project language.
I referred to this link:https://o7planning.org/11227/create-a-multiple-languages-web-application-with-spring-mvc
My problem is When I logout and login again with the same user or the other the language chosen last time gets reflected even for another user. I don't want that to happen. When I logout and login again the application language should default to English.
There is this link that deals with my issue it uses config.language
https://dzone.com/articles/learn-how-to-internationalize-and-localize-your-ja
but I don't know how to implement it.
Please Help.

Related

Why are WebMvcConfigurer override methods not working?

I created a project with Spring Boot. I am configuring the basic config, but there is a problem in implementing WebMvcConfigurer.
addInterceptors works well, but addViewControllers and addResourceHandlers don't work. There are no errors, but these two methods don't apply.
I think I set it all right, but I can not find the cause. Can I see why?
[Project Structure]
java
--me
----eastglow
------sample
--------controller
----------SampleController.java
------config
--------RootContextConfig.java
--------Application.java
--------DispatcherServletConfig.java
[RootContextConfig.java]
#Configuration
#ComponentScan(
basePackages = {"me.eastglow.*"},
excludeFilters = {#Filter(Controller.class)}
)
public class RootContextConfig {
}
[Application.java]
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
#Override
public void onStartup(ServletContext container) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootContextConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
dispatcherServlet.register(DispatcherServletConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("appServlet", new DispatcherServlet(dispatcherServlet));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.json");
dispatcher.addMapping("*.do");
}
}
[DispatcherServletConfig.java]
#Configuration
#ComponentScan(
basePackages={"me.eastglow.*"},
useDefaultFilters = false,
includeFilters={#Filter(Controller.class)},
excludeFilters={#Filter(Service.class), #Filter(Repository.class)}
)
#EnableWebMvc
#PropertySource(
value={"classpath:application-${spring.profiles.active}.properties", "classpath:log4jdbc.log4j2.properties"},
ignoreResourceNotFound = true)
public class DispatcherServletConfig implements WebMvcConfigurer {
private final static String[] RESOURCE_HANDLER_PATH = {"/favicon.ico"
, "/image/**"
, "/js/**"};
private final static String[] RESOURCE_HANDLER_LOCATION = {"/resources/favicon.ico"
, "/resources/image/"
, "/resources/js/"};
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
CacheControl cacheControl = CacheControl.empty().cachePrivate();
registry.addResourceHandler(RESOURCE_HANDLER_PATH).addResourceLocations(RESOURCE_HANDLER_LOCATION).setCacheControl(cacheControl);
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/member/login.do");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BusinessInterceptor()).addPathPatterns("/**");
}
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
List<ViewResolver> resolvers = new ArrayList<>();
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/WEB-INF/views/");
internalResourceViewResolver.setSuffix(".jsp");
resolvers.add(internalResourceViewResolver);
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setViewResolvers(resolvers);
resolver.setContentNegotiationManager(manager);
return resolver;
}
}
[Updated]
public class DispatcherServletConfig implements WebMvcConfigurer {
private final static String[] RESOURCE_HANDLER_PATH = {"/favicon.ico"
, "/image/**"
, "/js/**"};
private final static String[] RESOURCE_HANDLER_LOCATION = {"/resources/favicon.ico"
, "/resources/image/"
, "/resources/js/"};
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
CacheControl cacheControl = CacheControl.empty().cachePrivate();
registry.addResourceHandler(RESOURCE_HANDLER_PATH).addResourceLocations(RESOURCE_HANDLER_LOCATION).setCacheControl(cacheControl);
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/member/login.do");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BusinessInterceptor()).addPathPatterns("/**");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new FormHttpMessageConverter());
converters.add(jacksonMessageConverter()); //Json Message Converter
converters.add(new StringHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter()); // File Transfer Message Converter
}
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
List<ViewResolver> resolvers = new ArrayList<>();
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/WEB-INF/views/");
internalResourceViewResolver.setSuffix(".jsp");
internalResourceViewResolver.setOrder(2);
resolvers.add(internalResourceViewResolver);
JsonViewResolver jsonViewResolver = new JsonViewResolver();
resolvers.add(jsonViewResolver);
resolvers.add(beanNameViewResolver());
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setViewResolvers(resolvers);
resolver.setContentNegotiationManager(manager);
return resolver;
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[]{"/WEB-INF/tiles/tiles.xml"});
configurer.setCheckRefresh(true);
return configurer;
}
#Bean
public TilesViewResolver tilesViewResolver() {
TilesViewResolver viewResolver = new TilesViewResolver();
viewResolver.setOrder(1);
return viewResolver;
}
class JsonViewResolver implements ViewResolver {
#Override
public View resolveViewName(String viewName, Locale locale) {
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setPrettyPrint(true);
view.setContentType("application/json;charset=UTF-8");
view.setDisableCaching(true);
return view;
}
}
#Bean(name="beanNameViewResolver")
public BeanNameViewResolver beanNameViewResolver(){
BeanNameViewResolver beanNameViewResolver = new BeanNameViewResolver();
beanNameViewResolver.setOrder(0);
return beanNameViewResolver;
}
#Bean(name="jacksonMessageConverter")
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
return new MappingJackson2HttpMessageConverter();
}
#Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
You are working around Spring Boot instead of using it.
For starters remove the onStartup method of your Application class. Spring Boot takes care of all of that.
Next ditch your RootContextConfig.
2 cleanup your DispatcherServletConfig
#Configuration
#PropertySource(
value={"classpath:log4jdbc.log4j2.properties"},
ignoreResourceNotFound = true)
public class DispatcherServletConfig implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/member/login.do");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BusinessInterceptor());
}
}
Now in your application.properties (or create one) add the following
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
spring.resources.cache.cache-private=true
The mappings should work by default else place your js and images inside src/main/resources/static or src/main/resources/public.
This is all you need if you properly use Spring Boot (instead of working around it).

Get Locale from session object

I am noob and want to make internationalization for a spring boot app. This is what I have tried but can not get it to work :
#SpringBootApplication
public class CarriersApplication extends WebMvcConfigurerAdapter {
#Autowired WebContextHolder webContextHolder;
public static void main(String[] args) {
SpringApplication.run(CarriersApplication.class, args);
}
#Bean
public RestTemplate createRestTemplate() {
return new RestTemplate();
}
#Bean
public LocaleResolver localeResolver() {
HttpSession session = webContextHolder.getSession();
String lang = ((Merchant) session.getAttribute( "principal" )).getLanguage();
// the code above is an attempt to get language from session object to set the
// default locale
// ex: lang = en,fr
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale( new Locale( lang) );
return slr;
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor( localeChangeInterceptor());
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
My question is: Is there a possibility to get the locale from 'principal' session object in this manner, when I define localeResolver() method?
You can get the locale from LocaleContextHolder as folows :
#Bean
public LocaleResolver localeResolver() {
Locale locale = LocaleContextHolder.getLocale();
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(locale);
return slr;
}

Spring 4 with Java config: Overriding createDispatcherServlet for custom 404 page not working

I am running Spring 4.3.7 in combination with Spring Security 4.2.2 and configured it using Java config, so no web.xml. Now I want to get a custom 404 page and the way to go seems to be overwriting the createDispatcherServlet Method as described here and here to throw an exception if a page cannot be resolved. I want to use a SimpleMappingExceptionResolver to handle it and return my custom 404 page, but throwing the exception does not even work for me yet. I hope the configurations given below are enough.
MvcWebApplicationInitializer.java
public class MvcWebApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("resourceUrlEncodingFilter",
new ResourceUrlEncodingFilter());
filterRegistration.setInitParameter("encoding", "UTF-8");
filterRegistration.setInitParameter("forceEncoding", "true");
filterRegistration.addMappingForUrlPatterns(null, true, "/*");
}
#Override
protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext)
{
DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
AppConfig.java
#EnableWebMvc
#Configuration
#ComponentScan(...)
#EnableTransactionManagement
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
[...]
}
#Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
#PostConstruct
public void init() {
requestMappingHandlerAdapter.setIgnoreDefaultModelOnRedirect(true);
}
#Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver exceptionResolver = new MappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("UserNotAccessibleException", "access");
mappings.setProperty("VersionsModelCreationException", "versions");
exceptionResolver.setExceptionMappings(mappings);
exceptionResolver.setDefaultErrorView("index");
exceptionResolver.setExceptionAttribute("exception");
return exceptionResolver;
}
[...]
}
I still only get a
WARN in DispatcherServlet.java:noHandlerFound:1172: No mapping found for HTTP request with URI [/root/notexisting] in DispatcherServlet with name 'dispatcher'
instead of an exception that I might handle with my SimpleMappingExceptionResolver. Any advice?

404Not Found error returned for Spring REST calls

I am trying to expose my existing web application through web services. For this I have created a REST controller to handle rest calls. I am not sure if I need to change the existing web configurations for web services to work. Below is the URL I am using to access the resources.
http://localhost:9090/HospitalProject/rest/patient/Solo100
#RestController
#RequestMapping("/rest/patient")
public class PatientRESTController {
#RequestMapping(path="/{name}", produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Patient> getPatientByName(#PathVariable("name") String name){
Patient patient = patientService.findPatient(name);
return new ResponseEntity<Patient>(patient, HttpStatus.OK);
}
}
public class ApplicationIntializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext springContext= new AnnotationConfigWebApplicationContext();
springContext.register(ApplicationConfig.class);
springContext.setServletContext(servletContext);
ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet("dispatcher", new DispatcherServlet(springContext));
dispatcherServlet.setLoadOnStartup(1);
dispatcherServlet.addMapping("/");
}
}
#Configuration
#ComponentScan(basePackages={"com.hp"})
#EnableWebMvc
public class ApplicationConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}

Spring Security 4.0.3: Custom login form pops up basic 'Authentication Required' dialog when submitted

I'm using Spring Security 4.0.3 with a custom login form and Spring MVC 4.1.1, running in Glassfish 4.1.
My custom login page is presented correctly when I ask for a secured URL (/app/**). However, when the login form is submitted (POST /j_security_check), this request results in a basic authentication dialog being displayed. It seems that something feels that /j_security_check is a resource which is protected by basic authentication at the Glassfish level, since I get a 401 Unauthorized page from Glassfish when I hit Cancel on the dialog.
Here is my MVC initializer:
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { MvcConfiguration.class, SecurityConfiguration.class, PersistenceConfiguration.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "*.html", "/j_security_check" };
}
}
My MVC Config:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.elemenopy.wishlist"})
public class MvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/*
* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("messages", "validationMessages");
return source;
}
#Bean
#Override
public Validator getValidator() {
LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
factory.setValidationMessageSource(messageSource());
return factory;
}
#Bean
public MessageSourceAccessor messageSourceAccessor() {
return new MessageSourceAccessor(messageSource());
}
}
My security config:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("bill#example.com").password("abc123").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/static/**", "/*.jsp").permitAll()
.antMatchers("/").permitAll()
.antMatchers("/home.html").permitAll()
.antMatchers("/start.html").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login.html").permitAll()
.and()
.logout().logoutUrl("/logout.html").permitAll();
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authManager() throws Exception {
return authenticationManagerBean();
}
}
Any help would be greatly appreciated. Thanks!
Don't know why I didn't find this while I was searching before, but it turns out with Spring Security 4, your login form post URI has to be consistent with the URI of the login page itself. Not a hardcoded URI like /j_security_check.
spring security 4 custom login page

Categories