简体   繁体   中英

How to turn on annotation driven validation in Spring 4?

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.

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.3.Final</version>
</dependency>

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:

   public String processRegistration(@Valid Spitter spitter, Errors errors,
        Model model) {
    if (errors.hasErrors()) {
        return "registerForm";
    }
    ...

To:

public String processRegistration(@ModelAttribute("spitter") @Valid Spitter spitter, BindingResult result) {

    if (result.hasErrors()) {
        return "registerForm";
    }
    ...

Try it! ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM