一、HandlerMethodArgumentResolver
The form ----->controller method edit(Users users)
HandlerMethodArgumentResovle is used to process the request parameters passed by the client to the Controller method for automatic parameter binding.
Idea map:
Step 1: Define a @Date annotation:
public @Interface annotation name { //attribute name }
package com.lq.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
//该注解只能在哪里使用 (方法参数上) Type注解只能使用在类上 Method注解只能能用方法上
@Target(ElementType.PARAMETER)
//运行策略 (一般RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Date {
String[] params () default "";
String pattern() default "yyyy-MM-dd HH:mm:ss";
}
Step 2: Use @Date annotation in the Controller method
Format:
@RequestMapping("/edit2")
public String edit(@Date(params="birthday",pattern="yyyy-MM-dd")Users users) {
}
Examples:
@RequestMapping("/edit2")
public String edit(@Date(params="birthday",pattern="yyyy-MM-dd")Users users) {
//1.获取请求参数 String value = request.getParameter("name")【省略】
System.out.println("更新提交--->users:"+users);
//2.调用service的更新用户信息的方法
int restult = IUsersService.edit(users);
//3.跳转页面
if(restult>0) {
return "user/success";
}else {
return "user/error";
}
}
Step 3: Define spring mvc parameter processing extension to connect to HandlerMethodArgumentResolver
package com.lq.annotation.support;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import org.apache.naming.java.javaURLContextFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.lq.annotation.Date;
public class DateHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
private String[] params;
private String pattern;
@Override
public boolean supportsParameter(MethodParameter parameter) {
//1、判断controller方法上是否有Date注解
boolean hasParameterAnnotation = parameter.hasParameterAnnotation(Date.class);
if (!hasParameterAnnotation) {
//不会进入下面的resolveArgument方法进行参数的解析
return false;
}
//2、获取Date注解对象
Date parameterAnnotations = parameter.getParameterAnnotation(Date.class);
//3、获取Date注解的params参数
String[] parameters = parameterAnnotations.params();
if (!StringUtils.isEmpty(parameters)) {
params = parameters;
//4.获取Date注解的pattern参数
pattern = parameterAnnotations.pattern();
//进入下面的resolveArgument方法进行参数的解析
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter methodParam, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//1.获取controller方法参数Users user的类型对象
Object object = BeanUtils.instantiateClass(methodParam.getParameterType());
//2.获取参数类型对象的类信息(Users类的属性和方法)
BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
//3.获取请求对象Request
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
//4.获取Users类类型对象的所有属性描述(获取Users类的所有属性)
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
//5.得到每个属性的名字(Users类的属性名),并根据属性名称得到请求参数的值
String value = request.getParameter(propertyDescriptor.getName());
//6.判断非空
if (!StringUtils.isEmpty(value)) {
//5.得到属性的set方法
Method writeMethod = propertyDescriptor.getWriteMethod();
//6.如果set方法为非公有方法,暴力破解
if (!Modifier.isPublic(writeMethod.getModifiers())) {
writeMethod.setAccessible(true);
}
//7.判断属性名是否为Date指定的params值,如果是params指定值 则进行日期转换
if (propertyDescriptor.getName().equals(params[0])) {
//日期属性
SimpleDateFormat sdf = new SimpleDateFormat(this.pattern);
java.util.Date date = sdf.parse(value);
//调用setBirthday(date)
writeMethod.invoke(object, date);
} else {
//非日期的属性
//属性类型为Integer
if(propertyDescriptor.getPropertyType().equals(Integer.class)) {
writeMethod.invoke(object, Integer.parseInt(value));
//属性类型为字符串
}else {
writeMethod.invoke(object, value);
}
}
}
}
return object;
}
}
Step 4: Inject the implementation class of spring mvc extension plug-in into spring mvc
<!--开启注解扫描 -->
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.lq.annotation.support.DateHandlerMethodArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
Step 5: Testing