springboot自定义注解解析HandlerMethodArgumentResolver通过反射赋值返回

  • HandlerMethodArgumentResolver类似于拦截器,是一个参数解析器,我们可以通过写一个类实现HandlerMethodArgumentResolver接口来实现对COntroller层中方法参数的修改。

自定义解析器需要实现HandlerMethodArgumentResolver接口,HandlerMethodArgumentResolver接口包含两个接口函数:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.method.support;

import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;

public interface HandlerMethodArgumentResolver {
    boolean supportsParameter(MethodParameter var1);

    @Nullable
    Object resolveArgument(MethodParameter var1, @Nullable ModelAndViewContainer var2, NativeWebRequest var3, @Nullable WebDataBinderFactory var4) throws Exception;
}

当supportsParameter返回True时,才会调用supportsParameter。

自定义一个解析器  其中CurrentStudent.class是我自定义的注解

package com.yitianren.yitiantestspringboot.service.impl;

import com.yitianren.yitiantestspringboot.util.CurrentStudent;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Service;
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 java.lang.reflect.*;
import java.util.*;

/**
 * @Description 拦截所有访问,自定义自己需要的业务逻辑
 * @Author yitianRen
 * @Date 2019/9/17 14:33
 * @Version 1.0
 **/
@Service
public class CurrentStudentMethodArgumentResolver implements HandlerMethodArgumentResolver {

    public CurrentStudentMethodArgumentResolver() {
    }

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {

        if (methodParameter.hasParameterAnnotation(CurrentStudent.class)) {
            System.out.println(methodParameter.toString() + ":存在注解CurrentStudent");
            return true;
        }
/*
        if(methodParameter.getParameterType().isAssignableFrom(StudentVo.class)){
            System.out.println(methodParameter.getParameterType()+":有StrudentVo类");
            return true;
        }*/

        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        // 获取Controller中参数的类型
        Class clazz = methodParameter.getParameterType();
        Object target = clazz.newInstance();
        Field f = clazz.getDeclaredField("createDate");
        f.setAccessible(true);
        f.set(target, new Date());
        return target;
    }


}

自定义注解:

package com.yitianren.yitiantestspringboot.util;

import java.lang.annotation.*;

/**
 * @Author: yitianRen
 * @Description:
 * 注解的作用范围:@Target
 * 生命周期:@Retention
 * 作用范围:包、类、字段、方法、方法的参数、局部变量
 * 生命周期:源文件SOURCE、编译CLASS、运行RUNTIME
 * @Date: 14:24 2019/9/17
 * @Param:
 * @Return:
*/

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)//
@Documented
public @interface CurrentStudent {

    String value() default "尼古拉斯赵四";//默认值为 尼古拉斯赵四

}

在使用自定义解析器时,需要把解析器注册到spring容器中,配置文件注册一下:

package com.yitianren.yitiantestspringboot.config;

import com.yitianren.yitiantestspringboot.service.impl.CurrentStudentMethodArgumentResolver;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;

/**
 * @Description TODO
 * @Author yitianRen
 * @Date 2019/9/17 15:41
 * @Version 1.0
 **/
@SpringBootApplication
public class WebConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addArgumentResolvers(List argumentResolvers) {

        // 注册CurrentStudentMethodArgumentResolver的参数分解器
        argumentResolvers.add(new CurrentStudentMethodArgumentResolver());
    }
}

实体类

package com.yitianren.yitiantestspringboot.entity;

import java.util.Date;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableName;

import java.io.Serializable;

/**
 * 

* *

* * @author yitianren * @since 2019-09-10 */ @TableName(value = "STUDENT") public class StudentVo implements Serializable { private static final long serialVersionUID = 1L; @TableField("SId") private String SId; @TableField("Sname") private String Sname; @TableField("Sage") private Date Sage; @TableField("Ssex") private String Ssex; @TableField(exist = false) private Date createDate; public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public String getSId() { return SId; } public void setSId(String SId) { this.SId = SId; } public String getSname() { return Sname; } public void setSname(String Sname) { this.Sname = Sname; } public Date getSage() { return Sage; } public void setSage(Date Sage) { this.Sage = Sage; } public String getSsex() { return Ssex; } public void setSsex(String Ssex) { this.Ssex = Ssex; } @Override public String toString() { return "Student{" + ", SId=" + SId + ", Sname=" + Sname + ", Sage=" + Sage + ", Ssex=" + Ssex + "}"; } }

Controller:

package com.yitianren.yitiantestspringboot.controller;


import com.yitianren.yitiantestspringboot.entity.StudentVo;
import com.yitianren.yitiantestspringboot.service.StudentService;
import com.yitianren.yitiantestspringboot.util.CurrentStudent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 

* 前端控制器 *

* * @author yitianren * @since 2019-09-10 */ @RestController public class StudentController { @Autowired private StudentService studentService; @RequestMapping("/student") public @ResponseBody Object hello() { return studentService.findAllStudent(); } @RequestMapping(value = "/testAnnotation") public @ResponseBody Object testAnnotation(@CurrentStudent StudentVo studentVo) { return studentVo; } }

结果:这里没有对时间进行格式化

springboot自定义注解解析HandlerMethodArgumentResolver通过反射赋值返回_第1张图片

目录结构

springboot自定义注解解析HandlerMethodArgumentResolver通过反射赋值返回_第2张图片

我们可以通过实现HandlerMethodArgumentResolver接口来实现对自定义的参数进行解析。
比如可以解析自定义的时间格式、自定义解析Map对象等这些spring原本不支持的对象格式。

你可能感兴趣的:(spring)