- 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原本不支持的对象格式。