I generated my code as in the example, but unfortunately, when switching between pages, the parameter is not saved in the browser cookies. Why is this parameter not there?
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Bean(name = "localeResolver")
public LocaleResolver getLocaleResolver() {
CookieLocaleResolver resolver= new CookieLocaleResolver();
resolver.setCookieDomain("myAppLocaleCookie");
// 60 minutes
resolver.setCookieMaxAge(60*60);
return resolver;
}
#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: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("/*");
}
}
Needed comment СookieDomain:
#Bean(name = "localeResolver")
public LocaleResolver getLocaleResolver() {
CookieLocaleResolver resolver= new CookieLocaleResolver();
//resolver.setCookieDomain("myAppLocaleCookie");
// 60 minutes
resolver.setCookieMaxAge(60*60);
return resolver;
}
Related
I'm trying to build a Spring MVC application, using no XML. To load the application I am using a tomcat server. I want the homepage "home.html" to load, when I go to http://localhost:8080/.
I have followed many other spring mvc helloworld tutorials, but I can't see what I'm doing wrong. The webpage that loads, when I run the application is completely blank. When I inspect the html, it has an empty body. Any help is much appreciated.
Initialization class
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {ApplicationConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebMvcConfig.class};
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
DelegatingFilterProxy securityFilterChain = new DelegatingFilterProxy("springSecurityFilterChain");
return new Filter[] {characterEncodingFilter, securityFilterChain};
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("defaultHtmlEscape", "true");
registration.setInitParameter("spring.profiles.active", "default");
}
}
MVC configuration
#Configuration
class WebMvcConfig extends WebMvcConfigurationSupport {
private static final String MESSAGE_SOURCE = "/WEB-INF/i18n/messages";
private static final String VIEWS = "/WEB-INF/views/";
private static final String RESOURCES_LOCATION = "/resources/";
private static final String RESOURCES_HANDLER = RESOURCES_LOCATION + "**";
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
requestMappingHandlerMapping.setUseTrailingSlashMatch(false);
return requestMappingHandlerMapping;
}
#Bean(name = "messageSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
return messageSource;
}
#Bean
public ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix(VIEWS);
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new SpringSecurityDialect()); //TODO no using Spring security
templateEngine.addDialect(new Java8TimeDialect());
return templateEngine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(templateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource());
return validator;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(RESOURCES_HANDLER).addResourceLocations(RESOURCES_LOCATION);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* Handles favicon.ico requests assuring no <code>404 Not Found</code> error is returned.
*/
#Controller
static class FaviconController {
#RequestMapping("favicon.ico")
String favicon() {
return "forward:/resources/images/favicon.ico";
}
}
}
Home controller
#Controller
public class HomeController {
#RequestMapping(value = "/")
public String index() {
return "home";
}
}
Here is what my views look like
I have a method that let you comment about customer and after adding a comment redirect you again to site with comments.
#RequestMapping(value="customers/details/{id}", method = RequestMethod.GET)
public String showCustomerComments(#ModelAttribute("commentContent") String commentContent, #PathVariable int id, Model model){
model.addAttribute("comment",commentRepository.getAllComments(id));
return "details";
}
#RequestMapping(value ="customers/details/{id}", method = RequestMethod.POST)
public String processAddCustomerComment(#ModelAttribute("commentContent") String commentContent, #PathVariable int id){
commentRepository.
addComment(commentContent, localDate.now().toString(), id);
return "redirect:/customers/details/{id}";
}
}
everything works fine but in the url appears model veriable:
http://localhost:8080/customers/details/62?commentContent=some_text
I already know the solution but I don't know how to implement it. The solution is to set ignoreDefaultModelOnRedirect true on ignoreDefaultModelOnRedirect. In this topic enter link description here they say to just put sth like <mvc:annotation-driven ignoreDefaultModelOnRedirect="true" /> to our xml file. But How to do this in Java Based configuration?
I have a such class:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.packt.webstore")
public class WebConfiguration extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public CommonsMultipartResolver multipartResolver(){
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(10240000);
return multipartResolver;
}
#Bean
public LocaleResolver localeResolver(){
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(new Locale("en"));
return sessionLocaleResolver;
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
#Bean
public MessageSource messageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("resources/");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
and I thought to add to it:
#Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(){
RequestMappingHandlerAdapter requestMappingHandlerAdapter = new RequestMappingHandlerAdapter();
requestMappingHandlerAdapter.ignoreDefaultModelOnRedirect(true);
return requestMappingHandlerAdapter;
}
but it dosen't work.
I could add to processAddCustomerComment mehtod:
model.asMap().clear();
return "redirect:" + news.getUrl();
but I am not happy with this solution. Because suppose that we have 20 methods like mine and I don't want to put those two lines of code to every of those 20 methods.
How do I solve the problem?
It is possible that your implementation is not working because a RequestMappingHandlerAdapter is already on the context. Adding another one doesn't change the one used de facto. This article suggests that you autowire the existing RequestMappingHandlerAdapter and set the property instead.
#EnableWebMvc
#Configuration
public class MyWebConfig {
#Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
#PostConstruct
public void init() {
requestMappingHandlerAdapter.setIgnoreDefaultModelOnRedirect(true);
}
......
}
All credits go to http://www.logicbig.com/ for the quoted code.
That being said, unless you have a specific reason for using #ModelAttribute, you should perhaps switch to #RequestParam, which is simpler, less strings attached. Here's this topic discussed at length.
I'm trying to implement internationalisation on my project, however I cannot resolve my BaseName, so far this is my AppConfiguration class methods:
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();`
messageSource.setBasename("messages/");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(new Locale("en_US"));
resolver.setCookieName("myLocaleCookie");
resolver.setCookieMaxAge(4800);
return resolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("mylocale");
registry.addInterceptor(interceptor);
}
And this is my project structure:
Project Structure
Any ideas what I'm doing wrong? I also trying to change my baseName to classpath:messages but nothing. Thank you.
try this:
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:/messages/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
and rename your en_us.properties to messages_en_us.properties
just add this line to your application.properties
spring.messages.basename=validation
I'm trying to simply add the version number of an application to a Thymeleaf fragment. I'm using Spring Boot 1.2.5. If I have a file named /resources/messages.properties defined like this:
application.version=1.0.0
And I have a Thymeleaf view with the following fragment:
Application Version: <span th:text="#{application.version}">
It's displaying something like ??application.version_en_US?? instead of 1.0.0. (I also have files named messages_en.properties and messages_en_US.properties in the classpath with the same contents too.) I am really not sure how to resolve this problem... I've spent hours on something which seems incredibly trivial...
Application.java
#SpringBootApplication
#ComponentScan(basePackages = {"org.application"})
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class, ThymeleafAutoConfiguration.class})
#PropertySources(value = {#PropertySource("classpath:website.properties")})
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
WebConfig.java
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public SpelAwareProxyProjectionFactory projectionFactory() {
return new SpelAwareProxyProjectionFactory();
}
#Bean
public SessionHandler sessionHandler() {
return new SessionHandler();
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/web/auth/login").setViewName("auth/login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/resources/");
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
#Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH);
return localeResolver;
}
#Bean
public ResourceBundleMessageSource messageSource() {
return new ResourceBundleMessageSource();
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
// Locale change interceptor
registry.addInterceptor(localeChangeInterceptor());
// Utility interceptor which helps with the "active" link styles in the navigation. --mm
registry.addInterceptor(new BaseInterceptor());
// Expire session after a period of time
registry.addInterceptor(sessionHandler());
}
}
ThymeleafConfig.java
#Configuration
public class ThymeleafConfig {
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
// must use Legacy HTML5 as the template, otherwise Handlebars will not parse!
//
// this should hopefully be fixed in Thymeleaf 3.0
resolver.setTemplateMode("LEGACYHTML5");
resolver.setCacheable(false);
return resolver;
}
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
// Add Spring security
Set<IDialect> dialects = new HashSet<IDialect>();
engine.setAdditionalDialects(dialects);
engine.addDialect(new SpringSecurityDialect());
return engine;
}
#Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[]{"*"});
viewResolver.setCache(false);
return viewResolver;
}
}
Will buy a virtual round of shots to whomever can resolve this issue...
i guess you could always add this in your templateEngine method:
engine.addMessageResolver(new StandardMessageResolver());
or engine.setMessageResolver(new StandardMessageResolver());
Also,from the design perspective,i would suggest you to try using the autoconfiguration for thymeleaf(removing the exclude),and many other stuff which spring boot provides automatically for you.
I am trying to setup a page not found catch in my Spring WebMVCConfig bit its not working..
here is my config:
#Configuration
#EnableWebMvc
#PropertySource("classpath:application.properties")
#Import(DatabaseConfig.class)
#ImportResource("/WEB-INF/spring/applicationContext.xml")
public class WebMVCConfig extends WebMvcConfigurerAdapter {
private static final String MESSAGE_SOURCE = "/WEB-INF/classes/messages";
private static final Logger logger = LoggerFactory.getLogger(WebMVCConfig.class);
#Autowired
Environment env;
#Bean
public ViewResolver resolver() {
UrlBasedViewResolver url = new UrlBasedViewResolver();
url.setPrefix("/WEB-INF/view/");
url.setViewClass(JstlView.class);
url.setSuffix(".jsp");
return url;
}
#Bean(name = "messageSource")
public MessageSource configureMessageSource() {
logger.debug("setting up message source");
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver lr = new SessionLocaleResolver();
lr.setDefaultLocale(Locale.ENGLISH);
return lr;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.debug("setting up resource handlers");
registry.addResourceHandler("/resources/").addResourceLocations("/resources/**");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
logger.debug("configureDefaultServletHandling");
configurer.enable();
}
#Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
}
public #Bean HandlerExceptionResolver exceptionResolver() {
Properties mappings = new Properties();
mappings.put("org.springframework.web.servlet.PageNotFound", "404");
mappings.put(DataAccessException.class.getName(), "dataAccessFailure");
mappings.put(TransactionException.class.getName(), "dataAccessFailure");
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
resolver.setExceptionMappings(mappings);
return resolver;
}
#Bean
public DefaultAnnotationHandlerMapping mapping() {
DefaultAnnotationHandlerMapping m = new DefaultAnnotationHandlerMapping();
m.setDetectHandlersInAncestorContexts(true);
return m;
}
}
now if I put in a URL that is not mapped I would think it would goto my 404.jsp page?
The way to configure a custom error page (for 404 or any other error code) is in the web.xml...
<error-page>
<error-code>404</error-code>
<location>/my-custom-page-not-found.html</location>
</error-page>
The url can be a static page, a custom jsp or even a Spring controller.
You can use #ExceptionHandler annotated method or #ControllerAdvice class.
Several methods are described in this post of the forum.
Alternatively, you can also refer Spring Docs - Handling exceptions section.