SpringBoot实现自定义控制器参数注解
Eave
2020.08.16 22:07
有这样一个场景,在某个控制器中的参数中,需要从Request的Header中取到Authorization请求头,其中Authorization是Jwt的身份Token,我们需要取到Token中的uid字段,以用来判断当前的用户身份,在没有使用任何的权限身份管理框架的前提下,那么我们只能在Controller层进行一步步的调取,如果是有多个控制器的话,这样会增加很多的冗余代码,于是我们可以考虑使用自定义注解来实现类似于SpringBoot的参数注入。
一、自定义注解
package com.qianyan.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonBody
{
String name() default "";
}
二、实现HandlerMethodArgumentResolver解析器接口
SpringBoot中已经为我们提供了相关的处理解析器HandlerMethodArgumentResolver
,我们只需要实现接口完成业务逻辑处理即可。
package com.qianyan.resolver;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import javax.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
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.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qianyan.annotation.JsonBody;
import com.qianyan.util.Common;
/**
* 获取POST请求的JSON数据
* @author 路遥
*/
public class JsonBodyResolver implements HandlerMethodArgumentResolver
{
@Override
public boolean supportsParameter(MethodParameter parameter)
{
return parameter.hasParameterAnnotation(JsonBody.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception
{
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
String body = getBody(request);
if(Common.isEmpty(body))
{
throw new Exception("Body数据为空");
}
JSONObject object = JSON.parseObject(body);
if(object == null)
{
throw new Exception("Json格式错误");
}
JsonBody josnBody = parameter.getMethodAnnotation(JsonBody.class);
// 参数类型
Class> clazz = parameter.getParameterType();
// 参数名称
String name = Common.isEmpty(josnBody.name()) ? parameter.getParameterName() : josnBody.name();
if(clazz == JSONArray.class)
{
return object.getJSONArray(name);
}
return object.getJSONObject(name);
}
private String getBody(HttpServletRequest request) throws Exception
{
StringBuffer buffer = new StringBuffer("");
InputStreamReader input = new InputStreamReader(request.getInputStream(), "utf-8");
BufferedReader reader = new BufferedReader(input);
String temp = null;
while((temp = reader.readLine()) != null)
{
buffer.append(temp);
}
reader.close();
return buffer.toString();
}
}
supportsParameter
接口是用于判断是否需要对该参数进行解析,如果该接口的返回值为true
,则会继续执行;
resolveArgument
接口是处理参数的分解,只有supportsParameter
为true
时才会调用此方法;
三、将Resolver注入到SpringMVC的ArgumentResolvers中
package com.qianyan.configurer;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.qianyan.resolver.JsonBodyResolver;
/**
* WebMvc配置类
* @author 路遥
*/
@Configuration
public class WebConfigurer implements WebMvcConfigurer
{
/**
* 添加控制器参数注入注解
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers)
{
resolvers.add(new JsonBodyResolver());
}
}