ReloadableResourceBundleMessageSource: No message found under code 'Size.userForm.username' - spring

Help me please. I use Spring MVC and Freemarker 2.3.27 in my web application and I can't catch bindingResult.errors on my FTL page. When I attempt to create wrong user with empty username, I have error: No message found under code 'Required' for locale 'ru'. But when i create user with short name (<6 characters) the message displays in my registration form. Why is this happening? Here is my code:
#Component
public class UserValidator implements Validator {
#Autowired
private UserService userService;
#Override
public boolean supports(Class<?> aClass) {
return User.class.equals(aClass);
}
#Override
public void validate(Object o, Errors errors) {
User user = (User) o;
ValidationUtils.rejectIfEmptyOrWhitespace(errors,"username","Required");
if(user.getUsername().length()<6||user.getUsername().length()>32){
errors.rejectValue("username","Size.userForm.username");
}
if(userService.findByUsername(user.getUsername())!=null){
errors.rejectValue("username","Duplicate.userForm.username");
}
ValidationUtils.rejectIfEmptyOrWhitespace(errors,"password","Required");
if(user.getPassword().length()<6||user.getPassword().length()>32){
errors.rejectValue("password","Size.userForm.password");
}
if(!user.getConfirmPassword().equals(user.getPassword())){
errors.rejectValue("confirmPassword","Different.userForm.password");
}
}
}
#Controller
#RequestMapping("/")
public class UserController {
....
#GetMapping("/registration")
public String goToRegistrationForm(Model model){
model.addAttribute("userForm", new User());
return "registration";
}
#PostMapping("/registration")
public String registration(#ModelAttribute("userForm")User userForm, BindingResult bindingResult, Model model){
userValidator.validate(userForm, bindingResult);
if(bindingResult.hasErrors()){
return "registration";
}
userService.saveUser(userForm);
securityService.autologIn(userForm.getUsername(),userForm.getPassword());
return "redirect:/hello";
}
}
My WebConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "aquaplant")
public class WebConfig extends WebMvcConfigurerAdapter {
.....
#Bean(name = "messageSource")
public ReloadableResourceBundleMessageSource getMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new
ReloadableResourceBundleMessageSource();
messageSource.setBasenames("validation");
messageSource.setDefaultEncoding("UTF-8");
//messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
}
My project structure:
{main
resources
Resource Bundle 'validation'
validation_en.properties
validation_ru.properties}

The problem was in my validation_ru.properties. I saved this file in UTF format in Notepad, but Notepad adds an invisible Unicode character BOM to the beginning of the file.....

Related

SecurityContextHolder.getContext().getAuthentication() always return 'anonymousUser'

I created Spring boot application with the following configuration:
Spring boot 2.1.0.RELEASE
OpenJdk 11
I have an AuditConfiguration class in my project that looks like:
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class AuditConfiguration {
#Bean
public AuditorAware<String> auditorProvider() {
return new AuditorAwareImpl();
}
class AuditorAwareImpl implements AuditorAware<String> {
#Override
public Optional<String> getCurrentAuditor() {
Principal principal =
SecurityContextHolder.getContext().getAuthentication();
return Optional.of(principal.getName());
}
}
}
and SecurityContextHolder.getContext().getAuthentication() always returns anonymousUser.
However, the following code returns the correct user name.
#RestController
#RequestMapping("/history")
public class HistoryEndpoint {
#RequestMapping(value = "/username", method = RequestMethod.GET)
#ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
}
I need your help for resolving this issue.
I got authenticared user using following class. i had problem with JPA Auditing.
#CreatedBy always saved null. then i tried to get authenticated user SecurityContextHolder.getContext().getAuthentication() using this method. that method returned annonymousUser. however my issue is fixed.
#ManagedBean
#EnableJpaAuditing
public class SpringSecurityAuditorAware implements AuditorAware<String> {
private final HttpServletRequest httpServletRequest;
public SpringSecurityAuditorAware(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
#Override
public Optional<String> getCurrentAuditor() {
return Optional.ofNullable(httpServletRequest.getUserPrincipal())
.map(Principal::getName);
}
}

How to solve `No message found under code 'good.morning.message' for locale 'us'`?

I'm trying to test a internationalization but I keep getting the message "No message found under code 'good.morning.message' for locale 'us'." each time I make a GET request.
I'm using Netbeans IDE for my project. Below are my codes
#SpringBootApplication
public class RestfulWebServicesApplication {
public static void main(String[] args) {
SpringApplication.run(RestfulWebServicesApplication.class, args);
}
#Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
#Bean
public ReloadableResourceBundleMessageSource bundleMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
ControllerClass
#RestController
public class HelloWorldController {
#Autowired
private MessageSource messageSource;
#GetMapping("/hello-world-internationalized")
public String helloWorldInternationalized(#RequestHeader(name="Accept-Language", required=false) Locale locale) {
return messageSource.getMessage("good.morning.message", null, locale);
//return "Good morning";
}
}
Here's my messages.properties file:
good.morning.message=Good Morning
And here's the link to my folder structure
Change bundleMessageSource() name to messageSource().

Controller are not working in Spring

I unable to understand why my controller are not redirecting to my html. Anyone can help me please?
WebConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.udemy.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix("");
return resolver;
}
}
HelloWorldController.java
#Controller
#RequestMapping("/example")
public class HelloWorldController {
public static final String EXAMPLE_VIEW = "example.html";
#GetMapping("/")
public String fileUploadForm(Model model) {
return "fileDownloadView";
}
#GetMapping("/helloworld")
public String helloWorld(){
return "helloworld";
}
// #RequestMapping(value="/exampleString", method=RequestMethod.GET)
#GetMapping("/exampleString")
public String exampleString(Model model){
model.addAttribute("name","John");
return EXAMPLE_VIEW;
}
// #RequestMapping(value="/exampleMAV", method=RequestMethod.GET)
#GetMapping("/exampleMAV")
public ModelAndView exampleMAV() {
ModelAndView mav= new ModelAndView(EXAMPLE_VIEW);
mav.addObject("name", "Mike");
return mav;
}
AppInitializer
public class MyWebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
My project structure is well done. So my html and jsps, are inside of the root WEB-INF/views. Also, the anotation #ComponentScan, are detecting the controller. So, its not a problem of root. Anyone can tell me, why im am not redirecting to the .html , please..
Error says:
ADVERTENCIA: No mapping found for HTTP request with URI [/spring-mvc-download-example/WEB-INF/views/example.html] in DispatcherServlet with name 'dispatcher'
In your controller class, above the
#RequestMapping("/example")
Insert:
#Controller
Gonna be:
#Controller
#RequestMapping("/example")
you have to annotate class HelloWorldController with #Controller or #RestController, only then it will be picked by #Componentscan annotation.

Issue in calling validator automic with #Valid in Spring controller

I am trying to call validator from controller using #Valid annotation, but control is not going to validator and proceeding without validating.
Controller
#Controller
#RequestMapping(value="/event")
public class EventController {
#Autowired
private EventService eventService;
#Autowired
EventValidator eventValidator;
#InitBinder
private void initBinder(WebDataBinder binder) {
binder.setValidator(eventValidator);
}
#RequestMapping(value="/add_event",method = RequestMethod.POST,produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<AjaxJSONResponse> postAddEventForm(#Valid #RequestPart("event") Event event, MultipartHttpServletRequest request) {
Boolean inserted = eventService.addEvent(event);
String contextPath = request.getContextPath();
String redirectURL = StringUtils.isEmpty(contextPath)?"/event":contextPath+"/event";
return new ResponseEntity<AjaxJSONResponse>(new AjaxJSONResponse(inserted,"Event Added Successfully",redirectURL), HttpStatus.OK);
}
}
Validator
#Component
public class EventValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return Event.class.isAssignableFrom(clazz);
}
#Override
public void validate(Object target, Errors errors) {
Event event = (Event)target;
if (event.getEventName() == null ||!StringUtils.hasText(event.getEventName())) {
errors.rejectValue("eventName", "", "Event Name is empty");
}
}
}
Please help on this.
Thank in advance

springmvc jsr303 validator co-exist with spring WebDataBinder validator in one action

Since springmvc 3.x now supports jsr303 and old spring style validator, i want to mix them in my sample apps. But there is only one method enabled for a specified controller, is that the limit of spring framework or JSR standard?
Here is my sample code.
User.java, stands for the domain model, uses JSR303 for validation.
public class User{
#Size(max = 16, message = "user loginId max-length is 16")
private String loginId;
//omit getter and setter
}
UserValidator.java, implements the org.springframework.validation.Validator interface to support user validation.
public class UserValidator implements Validator {
private UserService userService;
public boolean supports(Class<?> clazz) {
return User.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
User u = (User) target;
// loginName check for new user
if (u.getUserId() == null && !userService.isLoginIdUnique(u.getLoginId(), null)) {
errors.rejectValue("loginId", "user.loginId.unique", new Object[] { u.getLoginId() }, null);
}
}
#Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
UserController.java, uses InitBinder annotation to inject UserValidator into WebDataBinder.
#Controller("jspUserController")
#RequestMapping("/sys/users")
public class UserController {
private UserValidator userValidator;
#Autowired
public void setUserValidator(UserValidator userValidator) {
this.userValidator = userValidator;
}
/*#InitBinder("user")
public void initBinderUser(WebDataBinder binder) {
binder.setValidator(userValidator);
}*/
#RequestMapping(value = "/save")
public String save(#Valid User user, BindingResult bindingResult, Model model, HttpServletRequest request) {
if (bindingResult.hasErrors()) {
return "/sys/user/edit";
}
userService.saveUser(user);
return "redirect:/sys/users/index";
}
}
If I uncomment the #InitBinder("user") in UserController, the JSR303 validation will be disabled. While the current commented code will use JSR validator to do the validation.
Can anyone give me a workaround to mix them in one controller?
You can ADD your validator instead of SETTING it :
#InitBinder("user")
public void initBinderUser(WebDataBinder binder) {
binder.addValidators(userValidator);
}
This will execute the JSR303 validations first and then your custom validator. No need then to call the validator directly in the save method.
You can use your validator directly and let the global LocalValidatorFactoryBean (JSR-303) do its work as well:
#Controller("jspUserController")
#RequestMapping("/sys/users")
public class UserController {
private UserValidator userValidator;
#Autowired
public void setUserValidator(UserValidator userValidator) {
this.userValidator = userValidator;
}
#RequestMapping(value = "/save")
public String save(#Valid User user, BindingResult bindingResult, Model model, HttpServletRequest request) {
this.userValidator.validate(user, bindingResult);
if (bindingResult.hasErrors()) {
return "/sys/user/edit";
}
userService.saveUser(user);
return "redirect:/sys/users/index";
}
}

Resources