I am working with Spring Framework 4.3.3
I have the following situation for a @Controller
either for POST
or PUT
For example for POST
I have the following:
@PostMapping(value="/save",
consumes=MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces=MediaType.TEXT_HTML_VALUE)
public String saveOne(@Validated @ModelAttribute Persona persona,
BindingResult result,
RedirectAttributes redirectAttributes){
logger.info("saveOne: {}", persona.toString());
if(result.hasErrors()){
logger.error("# Errors: {}", result.getErrorCount());
logger.error("result: {}", result.toString());
return "persona/saveOne";
}
personaRestController.saveOne(persona);
redirectAttributes.addFlashAttribute("message", "process.successful");
return "redirect:/message";
}
The app works how is expected, through a Web Form
this @PostMapping
either saves/persists the data or validates the data and if it is invalid the same web form is shown with the error messages for each field and based about i18n
such as English
, Spanish
and Portuguese
. It related with JSR-439
About Java config infrastructure configuration I have the following:
@Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor localeChangeInterceptor=new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
//localeChangeInterceptor.setHttpMethods("post", "put");
return localeChangeInterceptor;
}
@Bean(name="localeResolver")
public LocaleResolver cookieLocaleResolver(){
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setCookieName("language");
cookieLocaleResolver.setDefaultLocale(new Locale("en","US"));
return cookieLocaleResolver;
}
And
@EnableWebMvc
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
...
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptorConfig.localeChangeInterceptor());
}
The problem is about Spring MVC Test
. I have the following:
@Before
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
...
@Test
public void saveOneHtmlPostInvalidMaxTest() throws Exception {
logger.info("saveOneHtmlPostInvalidMaxTest");
resultActions = mockMvc.perform(post(url)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.locale(locale)
.header("accept-language", locale.toString())
.header("language", locale.toString())
.param("id", personaInvalidMax.getId())
.param("nombre", personaInvalidMax.getNombre())
.param("apellido", personaInvalidMax.getApellido())
....
.andDo(print());
Note observe:
.locale(locale)
.header("accept-language", locale.toString())
.header("language", locale.toString())
Even when some of them have no sense, they are there because I am trying to resolve the following situation:
The validation control from the server side works how is expected until some point.
First
I can confirm through .andDo(print())
method that MockHttpServletRequest
prints
Headers = {Content-Type=[application/x-www-form-urlencoded], accept-language=[pt_BR], language=[pt_BR]}
Observe pt_BR
Second
The @PostMapping
that contains:
if(result.hasErrors()){
logger.error("# Errors: {}", result.getErrorCount());
logger.error("result: {}", result.toString());
return "persona/saveOne";
}
Prints...
7370 [Test worker] ERROR PersonaSaveOneController - result: org.springframework.validation.BeanPropertyBindingResult: 4 errors Field error in object 'persona' on field 'id': rejected value [0]; codes [Size.persona.id,Size.id,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [persona.id,id]; arguments []; default message [id],3,3]; default message [The size for the field must be between 3 and 3]
Observe the default message [id],3,3];
default message [The size for the field must be between 3 and 3]
Here two problems:
- The
locale
oraccept-language
are ignored - The error messages prints always in English
What I need is that the error data prints for example in Portuguese
and Spanish
according the Locale
sent. It should returns the error messages for each field in an expected language, in this case Portuguese
Again, it works when I use directly the Web Form
, but not through the Test. I am assuming that exists an internal Spring component that works through production
and has not been defined for Testing
Therefore, what is need it to accomplish this approach?
BTW: With the following (see I use classpath:
), furthermore my .properties
file are located in src/main/resources
@Bean(name="messageSource")
public ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource() {
ReloadableResourceBundleMessageSource resource = new ReloadableResourceBundleMessageSource();
resource.setBasenames(...
"classpath:/com/manuel/jordan/validation/validation");
resource.setDefaultEncoding("UTF-8");
return resource;
}
My @Test
methods working around with Rest
works fine about show and returning the error message according the Locale
or accept-language
defined (Access to MessageSource
happens in the server side and works fine with the previous configuration). It just fails for non-Rest
controllers