This question has been asked a lot of times, even after going through all the solutions i wansn't able to get hibernate validator working.
Controller class:-
#RequestMapping(value={"/setReg"},method={RequestMethod.GET,RequestMethod.POST})
public ModelAndView setRegistration( #Valid #ModelAttribute("userDetails") UserDetails userDetails,BindingResult bindingResult){
logger.info("setRegistration :Entry");
if(bindingResult.hasErrors()){
logger.info("binding success");
logger.info(userDetails.getUser_first_name());
logger.info("validation not working");
}
else{
logger.info("binding failure");
}
logger.info("setRegistration :Exit");
return null;
}
servlet-context:-
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<context:component-scan base-package="com.xmith.services"/>
<context:component-scan base-package="com.xmith.dao"/>
<context:component-scan base-package="com.xmith.models"/>
<context:component-scan base-package="com.xmith.sweb" />
<context:annotation-config/>
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
dependency:-
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
validation class:-
public class UserDetails {
private String user_id;
#Size(min=3,max=7,message="user first name must have max length 7")
private String user_first_name;
private String user_last_name;
private String user_age;
private String user_email;
private String user_password;
Note:-
in above code i am trying to validate "user_first_name"(min=3,max=7,message="user first name must have max length 7"), however when i enter input more than 7 it still sets "user_first_name".
output:---
17:33:12.399 [http-bio-8080-exec-1] DEBUG org.hibernate.validator.resourceloading.PlatformResourceBundleLocator - ValidationMessages not found.
17:33:12.401 [http-bio-8080-exec-1] DEBUG org.hibernate.validator.resourceloading.PlatformResourceBundleLocator - ContributorValidationMessages not found.
17:33:12.403 [http-bio-8080-exec-1] DEBUG org.hibernate.validator.resourceloading.PlatformResourceBundleLocator - org.hibernate.validator.ValidationMessages found.
17:33:12.417 [http-bio-8080-exec-1] INFO com.xmith.sweb.HomeController - setRegistration :Entry
17:33:12.418 [http-bio-8080-exec-1] INFO com.xmith.sweb.HomeController - binding success
17:33:12.418 [http-bio-8080-exec-1] INFO com.xmith.sweb.HomeController - qwertyuiiii
17:33:12.418 [http-bio-8080-exec-1] INFO com.xmith.sweb.HomeController - validation not working
17:33:12.418 [http-bio-8080-exec-1] INFO com.xmith.sweb.HomeController - setRegistration :Exit
What am i missing here?
my boolean logic was wrong as pointed by – JB Nizet
Related
I am using Spring MVC and Tiles.
When I try to use spring prefix "redirect:" for the redirection I get a servlet exception
- "Could not resolve view...".
Controller
RequestMapping("/SUPPORT.lz")
public String generateSupportView(HttpServletRequest request)
{
String url="http://"+request.getServerName()+":"+request.getServerPort()+"/APP";
AuthenticatedUser user = getUser();
/*
* Check if a user has the role for the page he is trying to access. If
* not redirect him to default page (home page).
*/
if (user.getRoles() != null && !user.getRoles().contains(new Role(0, Role.RoleType.SUPPORT)))
{
return "redirect:"+url;
}
return "support.tiles";
}
dispatcher-servlet.xml
<bean id="tilesViewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver"
p:order="1"
p:viewNames="*.tiles"
p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView"/>
<bean id="nontilesViewResolver"
class="org.springframework.web.servlet.view.XmlViewResolver"
p:order="2"
p:location="/WEB-INF/app-nontiles-views.xml"/>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
p:definitions="/WEB-INF/app-tiles.xml"/>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="i18n"/>
Solution-
I added internal view resolver in disaptacher servlet.xml and issue got resolved.
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:order="3">
</bean>
I have a bean as follows:
<bean id="myBean" class="MyBeanClass">
<constructor-arg value="\WEB-INF\myfile.dat"/>
</bean>
In the bean's contructor, I need to build the file's full path. To do that, I have to first find the app's root path first.
Thanks and regards.
Update
Per Michael-O's suggestion, here is my solution (so easy).
Spring bean:
<bean id="myBean" class="MyBeanClass">
<constructor-arg value="/myfile.dat"/> <!--under WEB-INF/classes-->
</bean>
Java:
public MyBeanClass(String path) throws Exception {
ClassPathResource file = new ClassPathResource(path);
lookup = new LookupService(file.getFile().getPath(), LookupService.GEOIP_MEMORY_CACHE);
}
Michael, thanks!!!
Use Spring's Resource class in your bean and spring will do the rest for you.
After seeing #curious1's edit, there is a better solution to his answer. Please do not use that. Go with this one:
beans.xml:
<!-- START: Improvement 2 -->
<context:annotation-config />
<bean id="service" class="LookupService">
<constructor-arg value="classpath:/myfile.dat"/> <!--under WEB-INF/classes-->
<constructor-arg>
<util:constant static-field="LookupService.GEOIP_MEMORY_CACHE"/>
</constructor-arg>
</bean>
<!-- END: Improvement 2 -->
<!-- Spring autowires here -->
<bean id="myBean" class="MyBeanClass" />
<!-- START: Improvement 1 -->
<bean id="myBean" class="MyBeanClass" />
<constructor-arg value="classpath:/myfile.dat"/> <!--under WEB-INF/classes-->
</bean>
<!-- END: Improvement 1 -->
Java:
public MyBeanClass(Resource path) throws Exception {
lookup = new LookupService(path.getInputStream(), LookupService.GEOIP_MEMORY_CACHE);
}
This is source-agnostic, does not rely on files and is the Spring way.
Edit 2: Rethinking my code, it can be even better:
public class MyBeanClass {
#Autowired
LookupService service;
}
and configure LookupService in your beans.xml.
Maybe you should consider using:
getClass().getClassLoader().getResourceAsStream()
inside constructor. This will use your classpath, so you "WEB-INF\myfile.dat", will be visible. Next think is use resource directory to put all resources in one directory (default: under root directory in WAR file)
Please note that I have Existing project in struts 1.x and with the following steps I am trying to integrate Spring MVC to it.
I have a maven project which on deployment is able to read servlet and load respective Controller class from jar file on server start-up and gives following info about controller class:
[org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping] Rejected bean name 'SSOController': no URL paths identified
Looks like it is not loading URLS hence I am not able to make any restful web service call on it.
my web.xml has following entry :
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/hello.do</url-pattern>
</servlet-mapping>
Dispatcher Servlet has following entries:
<context:annotation-config />
<context:component-scan base-package="com.ga.action.controller" />
<mvc:resources location = "/resources/" mapping = "/resources/**" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- JAXB2 marshaller. Automagically turns beans into xml -->
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.ga.action.controller.PEMUtil</value>
</list>
</property>
</bean>
Controller class code follows:
#Controller
#RequestMapping("/hello.do")
public class TestController {
#RequestMapping(method = RequestMethod.GET, value = "/")
public #ResponseBody String printTokenMessage(
#RequestParam("nLiveToken") String message,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println(message);
}
}
Use XML configuration instead of #Conteroller annotation for external jar file controllers. Because the #Controller annotation isn't available in the server class loader.
http://forum.spring.io/forum/spring-projects/web/108774-controllers-from-external-jar
Since the exception indicates the use of BeanNameUrlHandlerMapping there should be a bean named /hello.do in your context.
You do use the #RequestMapping annotation so I guess you assumed annotation driven handler mapping would be enabled by default. Which isn't the case. If the ServletDispatcher finds no handler mapping it will create a BeanNameUrlHandlerMapping for you.
If you want to use annotations in your application you should define
<mvc:annotation-driven />
in your context configuration.
I am new to Spring MVC. I went through the basic and everything works fine. Then when I try to hook up Spring MVC to my current project, the Controller did not get called.
Here is my servlet-context.xml
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory-->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="net.nelnet.quikstage.webapp.controller" />
And here is my Controller
package net.nelnet.quikstage.webapp.controller;
#Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
#RequestMapping(value = "/")
public String home(Locale locale, Model model) {
logger.info("Welcome! you are under Home Section "+ locale.toString());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "/WEB-INF/views/home.jsp";
}
}
I separate my project into One parent and two sub-projects. I was trying to implement Spring MVC into one of the sub-projects. I am not sure weather the project structure cause the problem
Thank you guys. my spring config file is fine and no error on server startup. Actually I found the problem. By default, <resources mapping="/resources/**" location="/resources/" />, it doesn't like resource to be empty when there is "**" either delete the '**' or put something under the folder will solve the problem
I'm trying to follow this tutorial and build a RESTful service that can un/marshal an object to/from XML.
http://www.stupidjavatricks.com/?p=54
The marshaller of choice in the article is xStream (I found it to be very easy to use and configure).
The point is, using STS -- Spring's own flavor of Eclipse bundled with tcServer -- I built a project based on the STS template of MVC. This is a legacy project started from Spring version 2.4, and I migrated it to version 3.0. So, the template created all the necessary XML markup, and I added my configuration to point the view to the correct object conversion (to the xstream marshaler).
Here is part of my bean that sends the object to a new view (copied out from the link):
<bean id="bookXmlView" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="autodetectAnnotations" value="true"/>
</bean>
</constructor-arg>
</bean>
It all worked nicely until I installed the latest STS version 2.5.2.RELEASE and created a new MVC project from a template. (The new template does not use urlrewrite.xml anymore, among some other changes).
I set the correct configuration 1 by 1 as the tutorial suggests, but now no matter what, the view is always directed to a JSP, so if my controller looks like this:
#RequestMapping(value = "/authors/{authorId}")
public ModelAndView getAuthorById(#PathVariable String authorId) {
Author author = bookService.getAuthorById(authorId);
ModelAndView mav =new ModelAndView("bookXmlView", BindingResult.MODEL_KEY_PREFIX+"author", author);
return mav;
}
It would always try to return to a author.jsp view and not the object as XML. I tried many things with no success. Any ideas why this happens and how to fix it?
UPDATE -------------------
As noted I added logs:
I set it as DEBUG level and discovered something:
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalRequiredAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'org.springframework.context.annotation.internalCommonAnnotationProcessor': no URL paths identified
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Rejected bean name 'bookXmlView': no URL paths identified
Notice this line: Rejected bean name 'bookXmlView': no URL paths identified.
Searching this indicated maybe a clash between <mvc:annotation-driven /> and my autodetectAnnotations in the xstream settings?
Any case, after invoking the link, I got the following log entry. Notice it forwards the view to /WEB-INF/views/bookXmlView.jsp:
DEBUG: org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for [/test/page_init]
DEBUG: org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapping [/page_init] to HandlerExecutionChain with handler [test.test.test.HomeController#a087de] and 2 interceptors
DEBUG: org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/test/page_init] is: -1
DEBUG: org.springframework.web.bind.annotation.support.HandlerMethodInvoker - Invoking request handler method: public org.springframework.web.servlet.ModelAndView test.test.test.HomeController.getObject()
DEBUG: org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'bookXmlView'
DEBUG: org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'bookXmlView'; URL [/WEB-INF/views/xmlView.jsp]] in DispatcherServlet with name 'appServlet'
DEBUG: org.springframework.web.servlet.view.JstlView - Added model object 'org.springframework.validation.BindingResult.books' of type [test.test.test.ObjectTest] to request in view with name 'bookXmlView'
DEBUG: org.springframework.web.servlet.view.JstlView - Forwarding to resource [/WEB-INF/views/xmlView.jsp] in InternalResourceView 'bookXmlView'
DEBUG: org.springframework.web.servlet.DispatcherServlet - Successfully completed request
Got it at last!
First I tried a different marshaller - JAXB2 but xstream should work as well.
Next thing is the definition - turns out for some reason the configuration uses this (wrong):
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
using only InternalResourceViewResolver
while definition for org.springframework.web.servlet.view.BeanNameViewResolver is ignored. The solution for that is to define them both in one bean called ContentNegotiatingViewResolver as follows:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
</bean>
<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound name="com.mycompany.dashboard.Person" />
</oxm:jaxb2-marshaller>
<bean name="person" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg ref="marshaller" />
</bean>
That configuration solved my problems and person object I played with was not directed to a JSP view but marshaller turn is to an XML:
#RequestMapping(value = "/person", method = RequestMethod.GET)
public ModelAndView addPerson() {
Person person = new Person();
person.setAddress("address 123");
person.setAge(50);
person.setName("Andrew");
System.out.println("new person: " + person);
ModelAndView mav = new ModelAndView("person",BindingResult.MODEL_KEY_PREFIX + "person",person);
return mav;
Hope it would help others in the future too.