Spring mvc extension plug-in (1) HandlerMethodArgumentResolver

一、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:
Insert picture description here

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

Guess you like

Origin blog.csdn.net/weixin_46822085/article/details/108992369