tags: SpringMVC


Validation

In our Struts2, we implement validation by inheriting ActionSupport… It has two ways to implement the function of verification

  • Handwritten code
  • The XML configuration
    • These two methods can also be specific to the method or the entire Action

Whereas SpringMVC uses the JSR-303 validation specification (part of the javaEE6 specification), SpringMVC uses Hibernate Validator (independent of Hibernate’s ORM)

Quick start

Import the jar package

Configuring the Validator



	
	<! -- Validator -->
	<bean id="validator"
		class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
		<! -- Validator -->
		<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
		<! - specifies calibration use resource files, if you do not specify the default classpath ValidationMessages. Under the properties - >
		<property name="validationMessageSource" ref="messageSource" />
	</bean>


Copy the code

Error message verification file configuration


	<! Verify error message configuration file -->
	<bean id="messageSource"
		class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<! -- Resource file name -->
		<property name="basenames">
			<list>
				<value>classpath:CustomValidationMessages</value>
			</list>
		</property>
		<! -- Resource file encoding format -->
		<property name="fileEncodings" value="utf-8" />
		<! Cache time for resource file contents in seconds
		<property name="cacheSeconds" value="120" />
	</bean>
Copy the code

Add to the WebBindingInitializer bound to the custom parameter


	<! Customizing webBinder -->
	<bean id="customBinder"
		class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
		<! -- Configure validator -->
		<property name="validator" ref="validator" />
	</bean>
Copy the code

Finally added to the adapter


	<! -- Annotation adapter -->
	<bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<! Inject a custom property editor and converter into webBindingInitializer -->
		<property name="webBindingInitializer" ref="customBinder"></property>
	</bean>
Copy the code

Create the CustomValidationMessages configuration file

Define the rules

package entity;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;

public class Items {
    private Integer id;

    // The length of the commodity name should be limited to 1 to 30 characters
    @Size(min=1,max=30,message="{items.name.length.error}")
    private String name;

    private Float price;

    private String pic;

    // Please enter the date of production
    @NotNull(message="{items.createtime.is.notnull}")
    private Date createtime;

    private String detail;

    public Integer getId(a) {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }

    public Float getPrice(a) {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public String getPic(a) {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic == null ? null : pic.trim();
    }

    public Date getCreatetime(a) {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getDetail(a) {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail == null ? null: detail.trim(); }}Copy the code

Testing:




<%--
  Created by IntelliJ IDEA.
  User: ozc
  Date: 2017/8/11
  Time: 9:56
  To change this template use File | Settings | File Templates.
--% >
<% @ page contentType="text/html; charset=UTF-8" language="java"% >
<html>
<head>
    <title>Test file upload</title>
</head>
<body>


<form action="${pageContext.request.contextPath}/validation.action" method="post" >Name:<input type="text" name="name">Date:<input type="text" name="createtime">
    <input type="submit" value="submit">
</form>

</body>
</html>



Copy the code

The Controller needs to annotate the Validation parameters with @validation annotations… Get the BindingResult object…


    @RequestMapping("/validation")
    public void validation(@Validated Items items, BindingResult bindingResult) {

        List<ObjectError> allErrors = bindingResult.getAllErrors();
        for(ObjectError allError : allErrors) { System.out.println(allError.getDefaultMessage()); }}Copy the code

Since I turned the date converter off during the test, I was prompted that the string cannot be converted to a date, but the name verification is already out…


Packet check

The purpose of group verification is to make our verification more flexible. Sometimes, we do not need to verify all the properties of the current configuration, but need to verify only some properties of the current method. So at this point, we can use the grouping check…

Steps:

  • Define the interface for grouping [mainly identity]
  • Determine which group the validation rules belong to
  • Define the use of check groups in the Controller method


Unified Exception Handling

Before we use SSH, Struts2 also configured to handle exceptions uniformly…

Here’s how it works:

  • Customize exceptions in the Service layer
  • Custom exceptions are also defined in the Action layer
  • Let’s ignore Dao exceptions for now.
  • The service layer throws an exception. The Action catches the exception of the service layer and determines whether to allow the request to pass
  • If not, then an Action exception is thrown
  • An error message is displayed when you define the global view in the Struts configuration file

Details can be found at blog.csdn.net/hon_3y/arti…

So what is our unified solution to handle exceptions ????

We know that exceptions in Java fall into two categories

  • Compile time exception
  • Run-time anomaly

Runtime exceptions are out of our control and can only be ruled out through code quality, detailed testing during system testing, and so on

For compile-time exceptions, we can handle them manually in our code and we can catch them try/catch them, we can throw them up.

Instead, we can customize a modular exception message, such as an exception for an item category


public class CustomException extends Exception {
	
	// Exception information
	private String message;
	
	public CustomException(String message){
		super(message);
		this.message = message;
		
	}

	public String getMessage(a) {
		return message;
	}

	public void setMessage(String message) {
		this.message = message; }}Copy the code

When we looked at the Spring source code, we found: When the front-end controller DispatcherServlet performs HandlerMapping and calls HandlerAdapter to execute Handler, if an exception occurs, it can customize a unified exception Handler in the system and write its own exception handling code.

We can also learn to define a unified handler class to handle exceptions…

Define a unified exception handler class


public class CustomExceptionResolver implements HandlerExceptionResolver  {

	// The front-end controller DispatcherServlet executes this method if an exception occurs during HandlerMapping and calling HandlerAdapter to execute the Handler
	//handler Specifies the handler to be executed. Its real identity is HandlerMethod
	//Exception ex indicates that an Exception message is received
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		// The output is abnormal
		ex.printStackTrace();
		
		// Unified exception handling code
		// For CustomException, you can directly obtain the exception information from the exception class and display the exception processing on the error page
		// Exception information
		String message = null;
		CustomException customException = null;
		// If ex is a user-defined exception, fetch the exception information directly
		if(ex instanceof CustomException){
			customException = (CustomException)ex;
		}else{
			// For non-CustomException exceptions, reframe this class as a CustomException with the exception message "unknown error"
			customException = new CustomException("Unknown error");
		}

		// Error message
		message = customException.getMessage();
		
		request.setAttribute("message", message);

		
		try {
			// Go to the error page
			request.getRequestDispatcher("/WEB-INF/jsp/error.jsp").forward(request, response);
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return newModelAndView(); }}Copy the code

Configure a unified exception handler

	<! -- Define unified exception handler -->
	<bean class="cn.itcast.ssm.exception.CustomExceptionResolver"></bean>
Copy the code

Conclusion #

  • The validation method used with Spring is to enclose an annotation declaration in front of the property to be validated.
  • Annotate @Validation with the method parameters in the Controller. Then SpringMVC will handle it for us internally (create the bean, load the configuration file)
  • BindingResult will get a hint of our validation errors
  • Grouping validation is what makes our validation more flexible: a method needs to validate this property, and a method doesn’t. So we can use grouping check.
  • For handling exceptions, SpringMVC uses a unified exception handler class. The HandlerExceptionResolver interface is implemented.
  • Subdivide the module into multiple exception classes, which are handled by our unified exception handler class.

If you find this article helpful, give the author a little encouragement