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

本文介绍如何通过实现HandlerMethodArgumentResolver接口来自定义Spring MVC的参数解析器,以支持自定义注解和对象格式,如自定义时间格式和Map对象解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 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<HandlerMethodArgumentResolver> 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;

/**
 * <p>
 * 
 * </p>
 *
 * @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;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @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;
    }

}

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

目录结构

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值