首先设定实体类
@Data
public class AuthorizeCache {
private String scheme;
private String authorizeKey;
private String userName;
}
设置注解 定义目标范围为参数
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthorizeUser {
}
继承HandlerMethodArgumentResolver
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
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 javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Map;
/**
* @author lifei47
* @Description
* @create 2021-10-28
*/
@Component
public class AuthorizeHandlerResolver implements HandlerMethodArgumentResolver {
private static final String JSON_REQUEST_BODY = "JSON_REQUEST_BODY";
@Autowired
private AuthorizeCacheConfig authorizeCacheConfig;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().isAssignableFrom(AuthorizeCache.class) && methodParameter.hasParameterAnnotation(AuthorizeUser.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
String body=getBodytxt(nativeWebRequest);
Map map=JsonUtil.json2map(body);
String token=(String) map.get("token");
----业务代码---
return authorizeCache;
}
private String getBodytxt(NativeWebRequest nativeWebRequest) throws IOException {
HttpServletRequest request=nativeWebRequest.getNativeRequest(HttpServletRequest.class);
BufferedReader br = request.getReader();
String str, wholeStr = "";
while((str = br.readLine()) != null){
wholeStr += str;
}
return wholeStr;
}
注入到webmvc中
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
import java.util.List;
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Resource
private AuthorizeHandlerResolver authorizeHandlerResolver;
public void MyWebMvcConfigurer() {
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(authorizeHandlerResolver);
}
}
以下两点是为了解决 无法从post方法两次获取值的问题
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Component
@WebFilter(filterName = "channelFilter", urlPatterns = {"/*"})
public class ChannelFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
try {
ServletRequest requestWrapper = null;
if (request instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) request);
}
if (requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
@Override
public void destroy() {
}
}
添加两个文件
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
public class RequestWrapper extends HttpServletRequestWrapper {
//参数字节数组
private byte[] requestBody;
//Http请求对象
private HttpServletRequest request;
public RequestWrapper(HttpServletRequest request) throws IOException {
super(request);
this.request = request;
}
/**
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
/**
* 每次调用此方法时将数据流中的数据读取出来,然后再回填到InputStream之中
* 解决通过@RequestBody和@RequestParam(POST方式)读取一次后控制器拿不到参数问题
*/
if (null == this.requestBody) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(request.getInputStream(), baos);
this.requestBody = baos.toByteArray();
}
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() {
return bais.read();
}
};
}
public byte[] getRequestBody() {
return requestBody;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}