I'm trying to change language using <spring:message> tag. But it doesn't get recognized.
language.jsp
<%# taglib prefix="spring"
uri="http://www.springframework.org/tags" %>
<html>
<body>
<h1><spring:message code="home.title" /></h1>
<p><spring:message code="home.intro" /></p>
<p>
English |
French
</p>
</body>
</html>
AppConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.dilini.controller", "com.dilini.service"})
#Import({DatabaseConfig.class, SecurityConfig.class})
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver jspViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public HandlerInterceptor performanceInterceptor() {
PerformanceInterceptor interceptor;
interceptor = new PerformanceInterceptor();
return interceptor;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(performanceInterceptor()).addPathPatterns("/user/*");
registry.addInterceptor(localeChangeInterceptor());
}
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages");
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
#Bean
public HandlerInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
return interceptor;
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(new Locale("en"));
return localeResolver;
}
}
src/main/resources/messages/en.properties
home.title=Home
home.intro= this is my magnificent intro
Likewise the french.
src/main/resources/messages/fr.properties
home.title=Accueil
home.intro=Splendide page d'accueil,
Do I need to add another dependency for this feature? Or there is any issue is the code?
Please help
try this below code
#Bean(name = "localeResolver")
public LocaleResolver getLocaleResolver() {
CookieLocaleResolver resolver= new CookieLocaleResolver();
resolver.setCookieDomain("myAppLocaleCookie");
resolver.setCookieMaxAge(600);
return resolver;
}
#Bean(name = "messageSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageResource= new ReloadableResourceBundleMessageSource();
// For example: i18n/messages_en.properties
// For example: i18n/messages_fr.properties
messageResource.setBasename("classpath:i18n/messages");
messageResource.setDefaultEncoding("UTF-8");
return messageResource;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
localeInterceptor.setParamName("lang");
registry.addInterceptor(localeInterceptor).addPathPatterns("/*");
}
Note : messages_en.properties and messages_fr.properties should be present into src/main/resources/i18n
In your appconfig i don't see the interceptor registration. You simply defined it but you never registered it. You should override the addInterceptors method
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
Try to add it and check if it works
In your src/main/resources/messages/ be sur to create both i18 files (en and fr named as below ):
in your MessageSource you just set the basename to messages => messageSource.setBasename("classpath:/messages");
so your local files should be named messages_[local].properties (spring will search for local names file as set in the as .setBasename() )
as below
messages_en.properties that contains :
home.title=Home
home.intro= this is my magnificent intro
and messages_fr.properties that
home.title=Accueil
home.intro= ceci est ma magnifique intro
It should work
Related
I m trying to combine spring boot , gradle , websocketJS and jsp
the idea is to have app running with jsp and websocket
i have managed to get the spring to serve the index.html file when placing it in : resources\static\
however i m unable to get the spring to serve the jsp files when placing them in :
webapp\WEB-INF\jsp\
You can get my github demo from here
application.properties
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
controller
#Controller
public class MarkerController {
#RequestMapping(value="/map")
public String trafficSpy() {
return "index";
}
** so far the jsp would not work if i go to localhost:8080/map
but localhost:8080 would point to the index.html
but when i try to implement WebMvcConfigurer , none would work
#EnableWebMvc
#Configuration
#ComponentScan({ "com.otot.mikdah" })
public class SpringWebConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("/webjars/");
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
I want to add apache tiles in my spring boot application.
Like we configure prefix and suffix in application.properties file i want to know how we can configure tiles.xml as well.
I have added maven dependency of apache tiles in POM.xml file, But when i am returning the name of the tile definition from my controller its giving 404 error.
This is my POM.xml file
<!-- https://mvnrepository.com/artifact/org.apache.tiles/tiles-jsp -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.8</version>
</dependency>
This is my tiles.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration
3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="home-page"
template="/WEB-INF/layout/layout.jsp">
<put-attribute name="body" value="/WEB-INF/pages/landing-page.jsp" />
<put-attribute name="script" value="" />
<put-attribute name="stylesheet" value="" />
</definition>
</tiles-definitions>
This is my controller method
#Controller
public class LandingPage {
#RequestMapping("/")
public String landingPage() {
return "home-page";
}
}
This is my TilesConfig.java file
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesView;
#Configuration
public class TilesConfig {
#Bean
public UrlBasedViewResolver viewResolver() {
UrlBasedViewResolver tilesViewResolver = new
UrlBasedViewResolver();
tilesViewResolver.setViewClass(TilesView.class);
return tilesViewResolver;
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
String[] tilesXml = { "WEB-INF/tiles.xml" };
tilesConfigurer.setDefinitions(tilesXml);
return tilesConfigurer;
}
}
First thing you need to do is to use #EnableWebMvc in your configuration.I have added in below configuration
Can you try adding the below configuration to your application
public class MvcWebApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
// Load database and spring security configuration
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebAppInitializer.class};
}
// Load spring web configuration
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvcConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "your component scan packages" })
public class WebMvcConfig implements WebMvcConfigurer {
/**
* Initialise Tiles on application startup and identify the location of the tiles configuration file, tiles.xml.
*
* #return tiles configurer
*/
#Bean
public TilesConfigurer tilesConfigurer() {
final TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[] { "WEB-INF/tiles.xml" });
configurer.setCheckRefresh(true);
return configurer;
}
/**
* Introduce a Tiles view resolver, this is a convenience implementation that extends URLBasedViewResolver.
*
* #return tiles view resolver
*/
#Bean
public TilesViewResolver tilesViewResolver() {
final TilesViewResolver resolver = new TilesViewResolver();
resolver.setViewClass(TilesView.class);
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Make sure you have static resources and views are in correct path.
You can configure the tiles view resolver as below.
#Bean
public UrlBasedViewResolver viewResolver() {
UrlBasedViewResolver tilesViewResolver = new UrlBasedViewResolver();
tilesViewResolver.setViewClass(TilesView.class);
return tilesViewResolver;
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
String[] tilesXml = { "WEB-INF/tiles.xml" };
tilesConfigurer.setDefinitions(tilesXml);
return tilesConfigurer;
}
I'm trying to load static resources to thymeleaf html file. But resources aren't loaded.Does anyone knows what Am i doing wrong here....
I'm using Spring Java Config here. This is my Config class
#Configuration
#EnableScheduling
#ComponentScan(basePackages = "test.controller")
public class ControllerConfig extends WebMvcConfigurationSupport {
private static final Logger log = LoggerFactory.getLogger(ControllerConfig.class);
#Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> _converters) {
_converters.add(getMappingJackson2HttpMessageConverter());
addDefaultHttpMessageConverters(_converters);
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(getObjectMapper());
return converter;
}
#Bean
public ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return objectMapper;
}
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCacheable(false);
return templateResolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setOrder(1);
return viewResolver;
}
}
This is my HTML page.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8"/>
<title th:text="'Hello ' + ${name} + '!'"></title>
<link th:href="#{/resources/css/main.css}" rel="stylesheet"/>
</head>
<body>
<h2 class="hello-title" th:text="'Hello ' + ${name} + '!'"></h2>
<script th:src="#{/resources/js/main.js}"></script>
</body>
</html>
This is how my folder structure goes for static resources which needed to be loaded.
I found resources on the internet where WebMvcConfigurerAdapter had been used. but I'm using WebMvcConfigurationSupport instead. I do'nt have the luxury to change this.
Thymeleaf dependency I have added is
compile group: 'org.thymeleaf', name: 'thymeleaf-spring4', version: '2.1.2.RELEASE'
compile "org.springframework:spring-webmvc:${springVersion}"
springVersion = 4.0.6.RELEASE
When I run the project and loaded the HTML file CSS aren't applied. But HTML is loading fine as expected :(
Try configuring your resources like this:
registry.addResourceHandler("/**").addResourceLocations("classpath:/resources/")
And linking your css like this:
<link rel="stylesheet" th:href="#{/css/main.css}"/>
This has been a quite common problem here in stackOverflow, but none of the topics of the same problem solves mine.
We have a template configuration that uses xml config, but now we're trying to move away from that and start using Java config.
So I have a new project using Java config and Spring Boot. We're also using JSP and Tiles 3.
Problem is: it fails to render our admin login page.
Here is the code:
Main config class:
#SpringBootApplication
#EnableScheduling
#Import(OnAdminBeans.class)
public class AppConfig extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AppConfig.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
}
The AppConfig.class is is the main package. Through the #ComponentScan that #SpringBootApplication brings, it scans the other configurations that are on mainpackage.config, so it imports the view config class:
#Configuration
#EnableWebMvc
public class ViewConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/adm/static/**").addResourceLocations("/adm/static/");
}
// #Override
// public void addViewControllers(ViewControllerRegistry registry) {
// registry.addViewController("/adm/login").setViewName("login-template-tiles");
// }
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(viewResolver());
registry.viewResolver(jspViewResolver());
registry.viewResolver(tilesViewResolver());
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setCookieName("locale");
localeResolver.setCookieMaxAge(30);
localeResolver.setDefaultLocale(new Locale("pt", "BR"));
return localeResolver;
}
#Bean
public MultipleViewResolver viewResolver() {
Map<String, ViewResolver> viewsResolvers = new HashMap<String, ViewResolver>();
viewsResolvers.put(MultipleViewResolver.ViewType.JSP.getKey(), jspViewResolver());
viewsResolvers.put(MultipleViewResolver.ViewType.TILES.getKey(), tilesViewResolver());
MultipleViewResolver viewResolver = new MultipleViewResolver();
viewResolver.setViewsResolvers(viewsResolvers);
viewResolver.setOrder(1);
return viewResolver;
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
viewResolver.setOrder(2);
return viewResolver;
}
#Bean
public UrlBasedViewResolver tilesViewResolver() {
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setViewClass(TilesView.class);
viewResolver.setOrder(3);
return viewResolver;
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions("/WEB-INF/tile-defs/tiles-definitions.xml");
return configurer;
}
}
The LoginController.class is defined as:
#Controller
#RequestMapping(value = "/adm")
public class LoginController {
#RequestMapping(value = "/login")
public ModelAndView login() {
return new ModelAndView("login-template-tiles");
}
}
And in tiles-definitions.xml I have the following definition for login-template-tiles:
<definition name="login-template-tiles" template="/WEB-INF/jsp/adm/templates/login-template.jsp">
<put-attribute name="admin-title" value="Admin" />
<put-attribute name="content" value="/WEB-INF/jsp/adm/templates/sections/login/index.jsp" />
</definition>
Note that both files exist.
Given all that the LoginController.login() does get called when i try to access /adm/login. But it fails to find the proper jsp file, aparently.
It returns a 404. With TRACE enabled, I get the following log:
DispatcherServlet with name 'dispatcherServlet' processing GET request for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#2118c09a] in DispatcherServlet with name 'dispatcherServlet'
Looking up handler method for path /WEB-INF/jsp/adm/templates/login-template.jsp
Did not find handler method for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping#2c148974] in DispatcherServlet with name 'dispatcherServlet'
No handler mapping found for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#784c3547] in DispatcherServlet with name 'dispatcherServlet'
No handler mapping found for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping#533e0604] in DispatcherServlet with name 'dispatcherServlet'
Testing handler map [org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping#cfd1b4e] in DispatcherServlet with name 'dispatcherServlet'
No mapping found for HTTP request with URI [/WEB-INF/jsp/adm/templates/login-template.jsp] in DispatcherServlet with name 'dispatcherServlet'
Any suggestions are appreciated!
EDIT:
Ok. By debugging, I found out that it has something to do with the embedded Tomcat. Other than that, I have no clue what is going on.
EDIT 2:
Found that the problem is in org.springframework.web.servlet.DispatcherServlet#getHandler. It simply doesn't find a HandlerMapping for that request. Do I have to register one?
OK! Found the problem.
This link helped me: https://samerabdelkafi.wordpress.com/2014/08/03/spring-mvc-full-java-based-config/
More specifically this configuration:
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
By setting a default handler, I would no longer get a white page but instead the JSP code as html, which clearly tells me that the JSP was being found but not rendered.
So the answer was on this page: JSP file not rendering in Spring Boot web application
I was missing the tomcat-embed-jasper artifact.
Add below dependency to your pom.xml
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
The tips here helped me when I got stuck with a similar problem. I fixed it after adding this fragment on my configuration
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
I'm working on a webapp using Spring MVC and Thymeleaf with Java-configuration. In the template for the html page the language is set to be Swedish through this code:
<html lang="sv">
And the encoding is set to UTF-8 through this meta tag:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
But for some reason, that will not display the swedish letters.
I tried changing the <html> tag to the XHTML version xml:lang="en" but it makes no difference.
Since I'm still very new to Spring and Thymeleaf, I don't know where something might be wrong, or where the language/charset is supposed to be stated/set so I'm giving you the thymeleaf configuration code and the page controller:
#Configuration
public class ThymeleafConfig {
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setOrder(1);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
return engine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
return resolver;
}
}
Controller:
#Controller
public class IndexController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index() {
ModelAndView model = new ModelAndView();
model.setViewName("index");
return model;
}
}
I got proper encoding only when property characterEncoding was added to both ServletContextTemplateResolver and ThymeleafViewResolver.
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
...
<property name="characterEncoding" value="UTF-8"/>
</bean>
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
...
<property name="characterEncoding" value="UTF-8"/>
</bean>
Add the following line to templateResolver in ThymeleafConfig:
resolver.setCharacterEncoding("UTF-8");
As remarked in the docs setCharacterEncoding:
Specifies the character encoding to be set into the response when the
view is rendered.