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