I am using the annotation validation as below:
public String processRegistration(@Valid Spitter spitter, Errors errors,
Model model) {
if (errors.hasErrors()) {
return "registerForm";
}
...
}
But the errors.hasErrors()
always return false. I guess I didn't turn on some kind of switch for the annotation driven validation. But how can I do it with JavaConfig in Spring 4? I tried to apply the @AnnotationDrivenConfig
to the configuration class, but that type cannot even be resolved.
ADD 1
I already have the following configuration in the servlet-context.xml
, but still doesn't work.
<annotation-driven />
ADD 2
The spitter.java
:
package com.learnspring.mvc.web;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hibernate.validator.constraints.Email;
public class Spitter {
private Long id;
@NotNull
@Size(min = 5, max = 16)
private String username="default name";
@NotNull
@Size(min = 5, max = 25)
private String password;
@NotNull
@Size(min = 2, max = 30)
private String firstName;
@NotNull
@Size(min = 2, max = 30)
private String lastName;
@NotNull
@Email
private String email;
public Spitter() {
}
public Spitter(String username, String password, String firstName,
String lastName, String email) {
this(null, username, password, firstName, lastName, email);
}
public Spitter(Long id, String username, String password, String firstName,
String lastName, String email) {
this.id = id;
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public boolean equals(Object that) {
return EqualsBuilder.reflectionEquals(this, that, "firstName",
"lastName", "username", "password", "email");
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, "firstName",
"lastName", "username", "password", "email");
}
}
The SpitterController.java
package com.learnspring.mvc.web;
import static org.springframework.web.bind.annotation.RequestMethod.*;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.learnspring.mvc.web.Spitter;
import com.learnspring.mvc.web.SpitterRepository;
@Controller
@RequestMapping("/spitter")
public class SpitterController {
private SpitterRepository spitterRepository;
@Autowired
public SpitterController(SpitterRepository spitterRepository) {
this.spitterRepository = spitterRepository;
}
@RequestMapping(value = "/register", method = GET)
public String showRegistrationForm(Model model) {
model.addAttribute("spitter", new Spitter());
return "registerForm";
}
@RequestMapping(value = "/register", method = POST)
public String processRegistration(@Valid Spitter spitter,
Errors errors, Model model) {
if (errors.hasErrors()) {
return "registerForm";
}
if (spitter == null) {
model.addAttribute("ufo", "spitter is null!");
model.addAttribute("mark", "MARKER");
return "forward:/spitter/spitter/registerFail";
}
else if (!spitter.getUsername().contains("ufo")) {
model.addAttribute("ufo", "spitter user name is not ufo!!");
model.addAttribute("mark", "MARKER:" + spitter.getUsername());
model.addAttribute("pwd", "MARKER:" + spitter.getPassword());
return "forward:/spitter/spitter/registerFail";
}
else
return "redirect:/spitter/spitter/registerOK";
}
@RequestMapping(value = "/{username}", method = GET)
public String showSpitterProfile(@PathVariable String username, Model model) {
Spitter spitter = spitterRepository.findByUsername(username);
model.addAttribute(spitter);
return "profile";
}
@RequestMapping(value = "/spitter/registerOK", method = GET)
public String showRegisterOK() {
return "registerOK";
}
@RequestMapping(value = "/spitter/registerFail", method = POST)
public String showRegisterFail() {
return "registerFail";
}
}
The registerForm.jsp
:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="f" %>
<%@ page session="false" %>
<html>
<head>
<title>Spitter</title>
<link rel="stylesheet" type="text/css"
href="<c:url value="/resources/style.css" />" >
</head>
<body>
<h1>Register</h1>
<f:form method="POST" commandName="spitter">
f:First Name: <f:input path="firstName" /><br/>
f-Last Name: <f:input path="lastName" /><br/>
f-Email: <f:input path="email" /><br/>
f-User Name: <f:input path="username" /><br/>
f-Password: <f:input path="password" /><br/>
<input type="submit" value="Register" />
</f:form>
</body>
</html>
The WebConfig.java
:
package com.learnspring.mvc.web;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("com.learnspring.mvc.web")
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// TODO Auto-generated method stub
super.addResourceHandlers(registry);
}
}
The RootConfig.java
package com.learnspring.mvc.config;
import java.util.regex.Pattern;
import com.learnspring.mvc.config.RootConfig.WebPackage;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
@Configuration
@ComponentScan(basePackages = { "com.learnspring.mvc" }, excludeFilters = { @Filter(type = FilterType.CUSTOM, value = WebPackage.class) })
public class RootConfig {
public static class WebPackage extends RegexPatternTypeFilter {
public WebPackage() {
super(Pattern.compile("com.learnspring.mvc\\.web"));
}
}
}
The SpitterWebInitialization.java
package com.learnspring.mvc.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.learnspring.mvc.config.RootConfig;
import com.learnspring.mvc.web.WebConfig;
public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
ADD 3
And the web.xml
: (Actually, everything is commented out.)
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<!--
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
-->
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<!--
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
-->
<!-- Processes application requests -->
<!--
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
-->
</web-app>
Judging from your explanation and the following error
java.lang.ClassNotFoundException: javax.validation.Validator
Spring doesn't see the classes and as such doesn't enable JSF-303 validation.Make sure that the correct jars are on the classpath and that you have an implementation as well. When using maven adding something like the following should do the trick.
This will add the needed jars to the
WEB-INF/lib
directory which in turn lets Spring Web MVC detect it and configure the appropriate bean.For an explanations of the different annotations you might want to check In Hibernate Validator 4.1+, what is the difference between @NotNull, @NotEmpty, and @NotBlank?.
I see two points in your code that may cause de problem.
1) Instead of
<annotation-driven />
use the correct namespace<mvc:annotation-driven/>
.2) On your
@Controller
change your functions parameters from:To:
Try it! ;)