“Offer comes, ask friends to take it! I am participating in the 2022 Spring Recruit Punch card campaign. Click here for more details.”
1. Spring MVC project construction
- Create a Maven project and add Spring MVC dependencies
- Add a Web Application
- Configure web. XML
- Configure the Spring MVC configuration file dispatcher-servlet.xml
- Create a New Controller, add HelloController, add Hello method, return page/success.jsp page
- Create a pages directory in web-INF. Add success.jsp to this directory
- Open the Artifact and create a new lib package that will import all the dependencies into the lib package
- Configure tomcat, start tomcat, enter localhost:8080/hello, and return to the success.jsp page
Data binding in Spring MVC
Spring MVC converts the page request data to a custom type, such as “employeeName= Stark&age =40&gender=1&[email protected]” of the page submitted POST form data to an Employee object.
Spring MVC binds custom objects to page requests by doing the following:
- Data type conversion, the page is submitted to the string, to convert the string into a custom object of different types of properties
- Formatting issues, such as date format conversion, etc
- Data verification, verify the data submitted on the page
Debug How an Employee’s email is assigned to the Employee object when an Employee is added
// Encapsulate the data submitted for the page in Java beans
bindRequestParameters(binder, request);
Copy the code
Data conversion, formatting, and validation occur during encapsulation
WebDataBinder: data binder, responsible for data binding, involving type conversion, formatting, data validation, etc
- ConversionService component: Responsible for data type conversion and formatting
- The Validators component is responsible for data validation
- The bindingResult component: is responsible for storing errors from data validation during data binding resolution
Spring MVC parses the target method through reflection, binding the request data to the input parameter of the processing method. The core of the data binding is DataBinder.
Custom type converters
The ConversionService component is responsible for data conversion and formatting. There are many Converter converters in ConversionService that can convert String data submitted by a page into various types of data. You can also customize type converters by implementing the Converter interface.
Copy the spring-MVC-CRUD project and rename it spring-MVC-data; Add the Add Employee form to the list page and submit data of the type “[email protected]” to the background QuickAdd method
<form action="/quickadd"> <%-- fill in the employee information to automatically encapsulate the object --%> <input name="empinfo" value="[email protected]">
<input type="submit" value="Quick Add">
</form>
Copy the code
Add quickAdd method to Controller method
@RequestMapping("/quickadd")
public String quickAdd(@RequestParam("empinfo") Employee employee){
// The output wrapper object is null
System.out.println("Encapsulated object :"+ employee);
return "redirect:/emps";
}
Copy the code
Restart Tomcat and perform quick add operations on the List page
Spring MVC cannot convert a String “[email protected]” to Employee, so you need to define a type converter to convert String to Employee
Spring defines three types of converter interface, implement as a converter interface can be registered as a custom converter to ConversionServiceFactoryBean:
- Converter
,t>
: Convert S type to T type
- ConverterFactory: Encapsulates multiple homogeneous Converters of the same series and can be used if you want to convert an object of one type to an object of another type and its subclasses
- GenericConverter: Type conversions are performed based on context information in the host class of the source and target class objects
3-1 Implement a custom type converter
The newly built converter package, increase the converter class StringToEmployeeConverter String converted to the Employee
public class StringToEmployeeConverter implements Converter<String.Employee> {
@Autowired
private DepartmentDao departmentDao;
@Override
public Employee convert(String source) {
System.out.println("Convert the submitted String type to Employee");
if(! source.contains("-")) {return null;
}
String[] empInfo = source.split("-");
Employee employee = new Employee();
employee.setLastName(empInfo[0]);
employee.setEmail(empInfo[1]);
employee.setGender(Integer.parseInt(empInfo[2]));
Department department = departmentDao.getDepartment(Integer.parseInt(empInfo[3]));
employee.setDepartment(department);
returnemployee; }}Copy the code
Conversion is achieved by implementing the Converter interface. The interface’s generics are source and target data types. The convert method returns the class to be converted, and implements the String-to-Employee conversion by splitting the String type and assigning it to a newly created Employee object.
Register custom converters
<mvc:annotation-driven conversion-service="conversionServiceFactory"></mvc:annotation-driven>
<! -- Use custom ConverterService-->
<bean id="conversionServiceFactory" class="org.springframework.context.support.ConversionServiceFactoryBean">
<! Add custom converters to converters -->
<property name="converters">
<set>
<bean class="com.citi.converter.StringToEmployeeConverter"></bean>
</set>
</property>
</bean>
Copy the code
Complete the quickAdd method in EmployeeController
@RequestMapping("/quickadd")
public String quickAdd(@RequestParam("empinfo") Employee employee){
// The output wrapper object is null
System.out.println("Encapsulated object :"+ employee);
employeeDao.save(employee);
return "redirect:/emps";
}
Copy the code
Restart Tomcat to add the Tomcat
Custom converter steps
- Realize Converter interface, realize convert method
- Configure the custom Converter in ConversionService
- Register a ConversionService that adds a custom Converter
3-2 MVN: annotation – driven label
The MVN :annotation-driver tag supports the following functions:
- Automatic registration RequestMappingHandlerMapping, RequestMappingHandlerAdapter and ExceptionHandlerExceptionResolver three components
- ConversionService instances are supported for type conversion of form parameters
- Support @NumberFormat and @DatatimeFormat annotations to complete data type formatting
- The @VALID annotation is supported for Bean data validation
- Support @RequstBody and @responseBody annotations
Iv. Data formatting and verification
4-1 Data formatting
- Spring in formatting module defines a FormattingConversionService implementing the ConversionService interface implementation class, the implementation class extends the GenericConversionService, So it also does type conversion and it also does formatting.
- FormattingConversionService have a FormattingConversionServiceFactory factory class, which is used for the Spring context structure.
Using time formatting as an example, add the employee form to the add.jsp page to add the birth property
Add the Birth property column to the list.jsp page and add the Birth property to the Employee entity class
To run add employee, enter the time format yyyY-MM-DD
This parameter can be added only when the time format is YYYY /MM/DD
How to correctly handle YYYY-MM-DD? Use the @datatimeFormate annotation to specify the format of the date
Add the @DateTimeFormat annotation to the Birth property of the Employee entity class to specify the format for the time
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
Copy the code
The addition failed only because the conversionService we are using does not have the formatting function registered in the Spring MVC configuration file
org.springframework.context.support.ConversionServiceFactoryBean
Copy the code
Switch to
org.springframework.format.support.FormattingConversionServiceFactoryBean
Copy the code
<! -- Use custom ConverterService-->
<bean id="conversionServiceFactory" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<! -- No change in middle content -->
</bean>
Copy the code
Retest can add successfully
FormattingConversionServiceFactoryBean internal registration for the following components
- NumberFormatAnnotationFormatterFactory: support the use of the properties of digital type
@NumberFormat
annotations - Using JodaDateTimeFormatAnnotationFormatterFactory: support for date type of attribute
@DateTimeFormat
annotations
The @numerbformat annotation allows you to set attributes of numeric types. The annotation itself has two attributes style: numberFormat. style specifies the style type. Pattern: The type is String. You can customize the pattern, such as “#,###,###”
4-2 Data verification
JSR is Java Specification Requests for validation of Bean data. JSR specifies validation rules for Bean attributes by adding @notnull, @NULL, @max annotations to Bean attributes. In addition, you can customize the verification failure message. Hibernate Validator implements JSR and extends @email, @Length, @Notempty, and @range annotations.
The introduction and use of the verification framework can also refer to whether you have used these programming operations (II) – verification framework parts A, B, AND C
Using the validation framework in Spring MVC starts with the introduction of validation dependencies and Hibernate implementations, as well as the specification and implementation of EL expressions
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1. The Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.16. The Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
Copy the code
After adding dependencies, PUT all the Jar packages into the lib directory
Add validation annotations to attributes of the Employee entity class
@NotEmpty
@Length(min = 5,max = 8)
private String lastName;
@Email
private String email;
Copy the code
Add an @valid annotation to the method input to validate the incoming arguments and use BindingResult to hold the validation result
@RequestMapping(value = "/emp", method = RequestMethod.POST)
public String addEmp(@Valid Employee employee, BindingResult result){
System.out.println("Employee information to add :" + employee);
boolean hasErrors = result.hasErrors();
if (hasErrors){
System.out.println("Attribute verification error");
return "add";
}
employeeDao.save(employee);
// Return to the list page
return "redirect:/emps";
}
Copy the code
The verification result is parsed in the JSP page
LastName:<form:input path="lastName"/><form:errors path="lastName" /><br/>
Email:<form:input path="email"/><form:errors path="email"/><br/> <! --> Birth :<form:input path="birth" /><form:errors path="birth" /><br>
Copy the code
Restart Tomcat to add the Tomcat
How do I retrieve error messages in other ways
Modify the addEmp method to fetch the specific error message and output the error code through the getFieldErrors method of BindingResult
@RequestMapping(value = "/emp", method = RequestMethod.POST)
public String addEmp(@Valid Employee employee, BindingResult result, Model model){
Map<String, Object> errorMap = new HashMap<>();
System.out.println("Employee information to add :" + employee);
boolean hasErrors = result.hasErrors();
if (hasErrors){
System.out.println("Attribute verification error");
// Get detailed error information
List<FieldError> fieldErrors = result.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
System.out.println("Error field is:" + fieldError.getField() + ", error message:" + fieldError.getDefaultMessage());
// Get the error code used as the Key for the internationalization configuration
String[] codes = fieldError.getCodes();
for (String code : codes) {
System.out.println(code);
}
errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
}
model.addAttribute("errorMap", errorMap);
return "add";
}
System.out.println(result);
employeeDao.save(employee);
// Return to the list page
return "redirect:/emps";
}
Copy the code
Restart Tomcat to add the Tomcat
A FieldError object is generated for each property in the event of a data binding and validation error. When a property fails validation, the validation framework generates four message codes for that property, prefixed by the validation annotation class name, Multiple corresponding message codes are generated by combining modelAttribute, attribute name, and attribute type name
The output error messages are in English, which can be configured to display error messages according to the language of the browser. When using Spring MVC, the Spring MVC will check whether the Web context is configured with an internationalization message, and display the internationalization message if so, and display the default message if not
Add internationalization configuration files error_zh_CN. Properties and error_en_us.properties in Chinese and English in the resources directory
Email.email=email wrong, retry
NotEmpty=can't be empty
Length.java.lang.String=length incorrect
Past=must be a past time
Copy the code
Email.email=\u90AE\u7BB1\u4E0D\u5BF9
NotEmpty=\u4E0D\u80FD\u4E3A\u7A7A
Length.java.lang.String= \u957F\u5EA6\u4E0D\u5BF9
Past=\u65F6\u95F4\u5FC5\u987B\u662F\u8FC7\u53BB\u7684
typeMismatch.birth=\u751F\u65E5\u7684\u683C\u5F0F\u4E0D\u6B63\u786E
Copy the code
Add internationalization configuration to the Spring MVC configuration file
<! -- Internationalization configuration -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="error"></property>
</bean>
Copy the code
Restart Tomcat to add the Tomcat
How do I display incorrect field values in error messages?
Take the Internationalization profile in Chinese as an example
Email.email=\u90AE\u7BB1\u4E0D\u5BF9 - {0}
NotEmpty=\u4E0D\u80FD\u4E3A\u7A7A - {0}
Length.java.lang.String= \u957F\u5EA6\u4E0D\u5BF9 - {0} {1} {2}
Past=\u65F6\u95F4\u5FC5\u987B\u662F\u8FC7\u53BB\u7684 - {0}
typeMismatch.birth=\u751F\u65E5\u7684\u683C\u5F0F\u4E0D\u6B63\u786E - {0}
Copy the code
- {0} : always represents the name of the property currently validated
- {1} and {2} represent the values of the attributes set in the annotation, in alphabetical order
Restart Tomcat and perform the add operation