Data fetching from database on each hit not from the cache - spring-mvc

This is the Application.java class
#Configuration
#SpringBootApplication
//#EnableGlobalMethodSecurity(prePostEnabled=true)
#EnableTransactionManagement
#EnableCaching
#EnableJpaRepositories(basePackages="om.gov.moh.irs.dao.repos",repositoryImplementationPostfix="CustomImpl")
public class Application extends SpringBootServletInitializer {
#Autowired
Environment env;
#Bean
#ConfigurationProperties("spring.datasource")
public ComboPooledDataSource dataSource() {
return new ComboPooledDataSource();
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("messages"); // name of the resource bundle
source.setUseCodeAsDefaultMessage(true);
return source;
}
#Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize(env.getProperty("multipart.maxFileSize"));
factory.setMaxRequestSize(env.getProperty("multipart.maxRequestSize"));
return factory.createMultipartConfig();
}
}
This is the dto class which Im trying to cache.
public class PaginationDto implements Serializable {
private static final long serialVersionUID = 1L;
public Integer totalRecords;
public List<?> paginatedList;
//constructor and getter setter here
}
Controller class
#RequestMapping(value="categories", method=RequestMethod.POST, produces = { "application/json" })
public #ResponseBody ResultDecorator searchCategories(#RequestBody CategoryDto categoryDto) int pageSize, #RequestParam("sort") String sortOrder) throws BusinessException{
return handler.resolveResult(categoryService.searchCategory(categoryDto), OperationEnum.SEARCH);
}
Service class where #cacheable is defined.
#Override
#Cacheable("category")
public PaginationDto searchCategory(CategoryDto categoryDto) throws CategoryException {
System.out.println("#######category");
PaginationDto paginationDtoResponse = null;
paginationDtoResponse = categoryRepoCustom.fetchCategories(categoryDto);
return paginationDtoResponse;
}
Defined ehcache.xml file
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"
updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<cache name="category"
maxElementsInMemory="100" eternal="false"
overflowToDisk="false"
timeToLiveSeconds="30000" timeToIdleSeconds="0"
memoryStoreEvictionPolicy="LFU" transactionalMode="off">
</cache>
</ehcache>
On hitting this http://localhost:9190/isa/categories each time console log is printing, which means data is not fetching from the cache.

Related

jquery datatables with thymleaf and <style> tag issue

My issue is I have a jquery datatables in my page which belongs to a web app using springboot 2.3.2.RELEASE and Java 11 and Thymleaf.
In order to have the same behaviour as the following : Jquery datatables Row details
I have my png files as follows :
and in my Configuration class :
#Configuration
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurationSupport {
#Bean
static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Override
public RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
RequestMappingHandlerMapping requestMappingHandlerMapping = super.createRequestMappingHandlerMapping();
requestMappingHandlerMapping.setUseTrailingSlashMatch(false);
return requestMappingHandlerMapping;
}
#Bean(name = "messageSource")
public MessageSource configureMessageSource() {
// default message source
ReloadableResourceBundleMessageSource defaultMessageSource = new ReloadableResourceBundleMessageSource();
defaultMessageSource.setBasename("classpath:i18n/messages");
defaultMessageSource.setDefaultEncoding("UTF-8");
defaultMessageSource.setCacheSeconds(5000);
return defaultMessageSource;
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(new Locale("fr"));
resolver.setCookieName("localeCookie");
resolver.setCookieMaxAge(5000);
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
registry.addInterceptor(interceptor);
}
#Bean
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver result = new ClassLoaderTemplateResolver();
result.setPrefix("/templates/");
result.setSuffix(".html");
result.setTemplateMode("HTML");
result.setOrder(1);
result.setCacheable(true);
return result;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
// templateEngine.addDialect(new SpringSecurityDialect());
templateEngine.addDialect(new nz.net.ultraq.thymeleaf.LayoutDialect());
return templateEngine;
}
#Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(templateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
}
#Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
In developer console I have 404 on the link http://localhost:8080/tsp/details_open.png
I'm struggling in vain. Unless I'm mistaken, It's related to static resources handling.
The tsp is coming from the following application.yml file :
server:
port: 8080
servlet:
context-path: /tsp
I have made a seperate test projet, isolated the issue which was my MvcConfig
Any help please ?
I fixed my issue by updating the MvcConfig class as follows :
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
...
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(
"/img/**",
"/webfonts/**",
"/css/**",
"/js/**")
.addResourceLocations(
"classpath:/static/img/",
"classpath:/static/webfonts/",
"classpath:/static/css/",
"classpath:/static/js/");
}
#Bean
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver result = new ClassLoaderTemplateResolver();
result.setPrefix("/templates/");
result.setSuffix(".html");
result.setTemplateMode(TemplateMode.HTML);
result.setOrder(1);
result.setCacheable(false);
return result;
}
...
}
Which means, I changed WebMvcConfigurationSupport by WebMvcConfigurer and delete useless custom code.
What is weired is that, according to spring documentation, static folder should be automatically loaded...but it's not...this is why I added the resouce handlers.
To optimize, the performance, I copied all js/css/map files locally.

How to bind a Store using Spring Cloud Stream and Kafka?

I'd like to use a Kafka state store of type KeyValueStore in a sample application using the Kafka Binder of Spring Cloud Stream.
According to the documentation, it should be pretty simple.
This is my main class:
#SpringBootApplication
public class KafkaStreamTestApplication {
public static void main(String[] args) {
SpringApplication.run(KafkaStreamTestApplication.class, args);
}
#Bean
public BiFunction<KStream<String, String>, KeyValueStore<String,String>, KStream<String, String>> process(){
return (input,store) -> input.mapValues(v -> v.toUpperCase());
}
#Bean
public StoreBuilder myStore() {
return Stores.keyValueStoreBuilder(
Stores.persistentKeyValueStore("my-store"), Serdes.String(),
Serdes.String());
}
}
I suppose that the KeyValueStore should be passed as the second parameter of the "process" method, but the application fails to start with the message below:
Caused by: java.lang.IllegalStateException: No factory found for binding target type: org.apache.kafka.streams.state.KeyValueStore among registered factories: channelFactory,messageSourceFactory,kStreamBoundElementFactory,kTableBoundElementFactory,globalKTableBoundElementFactory
at org.springframework.cloud.stream.binding.AbstractBindableProxyFactory.getBindingTargetFactory(AbstractBindableProxyFactory.java:82) ~[spring-cloud-stream-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.cloud.stream.binder.kafka.streams.function.KafkaStreamsBindableProxyFactory.bindInput(KafkaStreamsBindableProxyFactory.java:191) ~[spring-cloud-stream-binder-kafka-streams-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.cloud.stream.binder.kafka.streams.function.KafkaStreamsBindableProxyFactory.afterPropertiesSet(KafkaStreamsBindableProxyFactory.java:103) ~[spring-cloud-stream-binder-kafka-streams-3.0.3.RELEASE.jar:3.0.3.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
I found the solution about how to use a store reading an unit test in Spring Cloud Stream.
The code below is how I applied that solution to my code.
The transformer uses the Store provided by Spring bean method "myStore"
#SpringBootApplication
public class KafkaStreamTestApplication {
public static final String MY_STORE_NAME = "my-store";
public static void main(String[] args) {
SpringApplication.run(KafkaStreamTestApplication.class, args);
}
#Bean
public Function<KStream<String, String>, KStream<String, String>> process2(){
return (input) -> input.
transformValues(() -> new MyValueTransformer(), MY_STORE_NAME);
}
#Bean
public StoreBuilder<?> myStore() {
return Stores.keyValueStoreBuilder(
Stores.persistentKeyValueStore(MY_STORE_NAME), Serdes.String(),
Serdes.String());
}
}
public class MyValueTransformer implements ValueTransformer<String, String> {
private KeyValueStore<String,String> store;
private ProcessorContext context;
#Override
public void init(ProcessorContext context) {
this.context = context;
store = (KeyValueStore<String, String>) this.context.getStateStore(KafkaStreamTestApplication.MY_STORE_NAME);
}
#Override
public String transform(String value) {
String tValue = store.get(value);
if(tValue==null) {
store.put(value, value.toUpperCase());
}
return tValue;
}
#Override
public void close() {
if(store!=null) {
store.close();
}
}
}

Autowired in Spring MVC getting error : Error creating bean with name 'userService': Injection of autowired dependencies

I am having this error for few days and seem to get no luck. Tried googling but still can't get it working. Looking on the log it keeps on telling me that there is something wrong with my "Injection of autowired dependencies" but I just can't get it. Hope to hear from you.
Error Logs.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sesame.repository.UserRepository com.sesame.service.UserService.userRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sesame.repository.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:117)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:108)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:68)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
.......
Controller class
#Controller
#RequestMapping(value = "/protected/users")
public class UsersControl {
private static final String DEFAULT_PAGE_DISPLAYED_TO_USER = "0";
#Autowired
private UserService userService;
#Autowired
private MessageSource messageSource;
#Value("5")
private int maxResults;
#RequestMapping(method = RequestMethod.GET)
public ModelAndView welcome() {
return new ModelAndView("contactsList");
}
#RequestMapping(method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<?> listAll(#RequestParam int page, Locale locale) {
return createListAllResponse(page, locale);
}
private UserListVO listAll(int page) {
return userService.findAll(page, maxResults);
}
private ResponseEntity<UserListVO> returnListToUser(UserListVO contactList) {
return new ResponseEntity<UserListVO>(contactList, HttpStatus.OK);
}
private ResponseEntity<?> createListAllResponse(int page, Locale locale) {
return createListAllResponse(page, locale, null);
}
private ResponseEntity<?> createListAllResponse(int page, Locale locale, String messageKey) {
UserListVO UserListVO = listAll(page);
addActionMessageToVO(UserListVO, locale, messageKey, null);
return returnListToUser(UserListVO);
}
private UserListVO addActionMessageToVO(UserListVO UserListVO, Locale locale, String actionMessageKey, Object[] args) {
if (StringUtils.isEmpty(actionMessageKey)) {
return UserListVO;
}
UserListVO.setActionMessage(messageSource.getMessage(actionMessageKey, args, null, locale));
return UserListVO;
}
}
service is existing:
#Service("userService")
#Transactional
public class UserService {
#Autowired
private UserRepository userRepository;
#Transactional(readOnly = true)
public UserListVO findAll(int page, int maxResults) {
Page<User> result = executeQueryFindAll(page, maxResults);
if(shouldExecuteSameQueryInLastPage(page, result)){
int lastPage = result.getTotalPages() - 1;
result = executeQueryFindAll(lastPage, maxResults);
}
return buildResult(result);
}
private Page<User> executeQueryFindAll(int page, int maxResults) {
final PageRequest pageRequest = new PageRequest(page, maxResults, sortByNameASC());
System.out.println("Now in ExectueQuery"+pageRequest);
return userRepository.findAll(pageRequest);
}
private Sort sortByNameASC() {
return new Sort(Sort.Direction.ASC, "name");
}
private UserListVO buildResult(Page<User> result) {
return new UserListVO(result.getTotalPages(), result.getTotalElements(), result.getContent());
}
private boolean shouldExecuteSameQueryInLastPage(int page, Page<User> result) {
return isUserAfterOrOnLastPage(page, result) && hasDataInDataBase(result);
}
private boolean isUserAfterOrOnLastPage(int page, Page<User> result) {
return page >= result.getTotalPages() - 1;
}
private boolean hasDataInDataBase(Page<User> result) {
return result.getTotalElements() > 0;
}
}
I've added the repository
#Repository("userRepository")
public interface UserRepository extends JpaRepository<User, Integer> {
Page<User> findByUserNameLike(Pageable pageable, String UserName);
}
WebConfiguration
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.sesame")
#EnableAutoConfiguration
#PropertySource(value = { "classpath:application.properties" })
#EnableScheduling
#EnableAspectJAutoProxy
#EnableCaching
public class WebConfig extends WebMvcConfigurerAdapter {
#Autowired
private Environment env;
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
return resolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor changeInterceptor = new LocaleChangeInterceptor();
changeInterceptor.setParamName("language");
registry.addInterceptor(changeInterceptor);
}
#Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix("/");
return resolver;
}
#Bean public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public JavaMailSenderImpl javaMailSenderImpl() {
JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();
mailSenderImpl.setHost(env.getProperty("smtp.host"));
mailSenderImpl.setPort(env.getProperty("smtp.port", Integer.class));
mailSenderImpl.setProtocol(env.getProperty("smtp.protocol"));
mailSenderImpl.setUsername(env.getProperty("smtp.username"));
mailSenderImpl.setPassword(env.getProperty("smtp.password"));
Properties javaMailProps = new Properties();
javaMailProps.put("mail.smtp.auth", true);
javaMailProps.put("mail.smtp.starttls.enable", true);
mailSenderImpl.setJavaMailProperties(javaMailProps);
return mailSenderImpl;
}
#Bean public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
#Bean
public ServletRegistrationBean dispatcherRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(
dispatcherServlet());
registration.addUrlMappings("/");
registration.addUrlMappings("*.pdf");
registration.addUrlMappings("*.json");
registration.addUrlMappings("*.js");
registration.addUrlMappings("*.xml");
registration.addUrlMappings("*.css");
return registration;
}
#Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/pdfs/**").addResourceLocations(
"/WEB-INF/pdf/");
registry.addResourceHandler("/resources/js/**").addResourceLocations(
"/WEB-INF/resources/js/");
registry.addResourceHandler("/resources/css/**").addResourceLocations(
"/WEB-INF/resources/css/");
registry.addResourceHandler("/resources/img/**").addResourceLocations(
"/WEB-INF/resources/img/");
}
#Bean
public ViewResolver tilesViewResolver() {
return new TilesViewResolver();
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tiles = new TilesConfigurer();
tiles.setDefinitions(new String[] {"/WEB-INF/tiles.xml"});
tiles.setCheckRefresh(true);
return tiles;
}
}
Create a JPA Config Class as below :
#Configuration
#EnableJpaRepositories(basePackages="com.sesame.repository")
#EntityScan(basePackages="com.sesame.model")
public class JpaConfiguration {
}

Can not work internationalization in spring mvc with thymeleaf

I have started a project with Spring MVC with thymeleaf. I want to that it is internationalize. I had copied official spring tutorial. But When I click tr button , words aren't changed. I am pasting my codes. I assumed that getLabel function of ResourceManager service is getting label current language. But I am not sure. How can I proceed?
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.yummynoodlebar.web.controller","com.yummynoodlebar.web.service","com.yummynoodlebar.web.domain"})
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(StringUtils.parseLocaleString("en"));
return cookieLocaleResolver;
}
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
//NB, selecting HTML5 as the template mode.
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
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;
}
#Bean(name = "labelSource")
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("classpath:i18n/labels");
// if true, the key of the message will be displayed if the key is not
// found, instead of throwing a NoSuchMessageException
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
// # -1 : never reload, 0 always reload
messageSource.setCacheSeconds(0);
return messageSource;
}
}
#Component
public class ResourceManager {
#Resource(name = "labelSource")
private MessageSource messageSource;
public String getLabel(String code) {
return messageSource.getMessage(code, null, Locale.getDefault());
}
}
I have solved my problem. I had changed getLabel function. New code is following
public String getLabel(String code) {
return messageSource.getMessage(code, null, LocaleContextHolder.getLocale());
}

Spring MVC doesn't handle the error came from hibernate validator

I create form and controller this form have some validation constrains using Hibernate validator. I face problem when starting test the validation constrains but I got Blue Exception page with the attributemodel with the rejected.
This the configuration
#Configuration
#ComponentScan(basePackages = {"com.whatever.core.web"})
#EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurationSupport {
private static final String MESSAGE_SOURCE = "/WEB-INF/classes/messages";
private static final String TILES = "/WEB-INF/tiles/tiles.xml";
private static final String VIEWS = "/WEB-INF/views/**/views.xml";
private static final String RESOURCES_HANDLER = "/resources/";
private static final String RESOURCES_LOCATION = RESOURCES_HANDLER + "**";
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping requestMappingHandlerMapping = super.requestMappingHandlerMapping();
requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
requestMappingHandlerMapping.setUseTrailingSlashMatch(false);
return requestMappingHandlerMapping;
}
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJacksonHttpMessageConverter());
}
#Bean(name = "messageSource")
public MessageSource configureMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
return messageSource;
}
#Bean
public TilesViewResolver configureTilesViewResolver() {
return new TilesViewResolver();
}
#Bean
public TilesConfigurer configureTilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[] {TILES, VIEWS});
return configurer;
}
#Override
public Validator getValidator() {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(configureMessageSource());
return validator;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(RESOURCES_HANDLER).addResourceLocations(RESOURCES_LOCATION);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
and the controller here
if(result.hasErrors()){
return null; OR "view name"
}
User user = new User();
user.setUsername(userModel.getUsername());
user.setFirstName(userModel.getFirstName());
user.setLastName(userModel.getLastName());
user.setGender(userModel.getGender());
user.setLocation(userModel.getLocation());
user.setPassword(passwordEncoder.encodePassword(userModel.getPassword(),null));
userRepository.save(user);
doAutoLogin(userModel.getUsername(),userModel.getPassword(),request);
return "redirect:/home";
NOTE: I use springMVC, spring security, tiles, and hibernate validator
I used SpringMVC with hibernate validator with XML configuration and portal environment and work fine I don't know what the wrong here!!
I Found the issue! the signature of the method controller should be like this
public String signup(#ModelAttribute("userModel") #Valid SignupForm userModel,BindingResult result,HttpServletRequest request,HttpServletResponse response,ModelMap model)
as what I read in sprinsource forum, the BindingResult should follow the modelAttribute and work find. I didn't find any official documentation for this but its work now.
to see the thread of springsource forum check this link http://forum.springsource.org/showthread.php?85815-BindException-Thrown-on-bind-errors-(instead-of-returning-errors-to-controller-method

Resources