springboot在添加拦截器的时候,拦截完参数后,发现进入方法里面参数为空,后经百度后,发现有很多人遇到了和我一样的问题,现做写个博客,记录和分享解决方法。
1.springboot添加拦截器继承HandlerInterceptorAdapter类,重写preHandle方法,这里我主要是获取requestBody里面和request里面的userId,但是在get和post请求进入方法的时候发现传递的参数是空,所以就要用到filter过滤器做一次参数取值并传值
package smartt.styy.auth.interceptor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import smartt.styy.auth.config.UserConfiguration;
import smartt.styy.auth.model.jwt.IJWTInfo;
import smartt.styy.auth.model.utils.JwtTokenUtil;
import smartt.styy.auth.util.DESEncrypt;
import smartt.styy.auth.util.HttpHelper;
import smartt.styy.auth.util.JsonUtil;
import smartt.styy.common.constant.RestCodeConstants;
import smartt.styy.common.context.BaseContextHandler;
import smartt.styy.common.exception.auth.UserTokenException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author df
*/
@Slf4j
public class UserAuthRestInterceptor extends HandlerInterceptorAdapter {
private Logger logger = LoggerFactory.getLogger(UserAuthRestInterceptor.class);
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private UserConfiguration userConfiguration;
@Value("${3des.key}")
private String desKey;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>> preHandle方法start ...");
String token = request.getHeader(userConfiguration.getUserTokenHeader());
IJWTInfo infoFromToken =null;
try {
infoFromToken = jwtTokenUtil.getInfoFromToken(token);
} catch (ExpiredJwtException e) {
throw new UserTokenException("请求token过期,请稍后重试!");
}
long effectiveTime = infoFromToken.getEffectiveTime();
//token过期
if(effectiveTime <1){
log.error("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>>请求token过期,请稍后重试!");
throw new UserTokenException("请求token过期,请稍后重试!");
}
String body = HttpHelper.getBodyString(request);
String paramUserId = request.getParameter("userId");
String userId =new String();
Map<String, Object> bodyMap =new HashMap<String,Object>();
if(!StringUtils.isEmpty(body)){
bodyMap = JsonUtil.asMapWithStringKey(body, Object.class);
log.info("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>>请求body数据:"+bodyMap);
}
if(bodyMap.get("userId") != null ){
String bodyUserId = bodyMap.get("userId").toString();
try {
userId = DESEncrypt.decryptMode(desKey,bodyUserId);
} catch (Exception e) {
log.error("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>>请求body数据,userId传入错误,请核实!!!");
throw new UserTokenException("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>>请求body数据,userId传入错误,错误信息message:"+
e.getMessage(),RestCodeConstants.TOKEN_ERROR_CODE);
}
if(!userId.equals(infoFromToken.getId())){
logger.error("[认证服务器][auth-server]用户请求认证服务异常,请检查请求参数和header-token信息!");
throw new UserTokenException("[认证服务器][auth-server]用户请求认证服务异常,请检查请求参数和header-token信息!",RestCodeConstants.TOKEN_ERROR_CODE);
}
}else if(paramUserId != null){
log.info("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>>请求parameter-userId参数数据:"+paramUserId);
try {
userId = DESEncrypt.decryptMode(desKey,paramUserId);
} catch (Exception e) {
log.error("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>>请求parameter-解密userId异常,错误message:"+e.getMessage());
throw new UserTokenException("[认证服务器][auth-server]用户请求认证服务异常,请检查请求参数信息,错误信息message:"+
e.getMessage(),RestCodeConstants.TOKEN_ERROR_CODE);
}
if(!userId.equals(infoFromToken.getId())){
logger.error("[认证服务器][auth-server]用户请求认证服务异常,请检查请求参数和header-token信息!");
throw new UserTokenException("[认证服务器][auth-server]用户请求认证服务异常,请检查请求参数和header-token信息!",RestCodeConstants.TOKEN_ERROR_CODE);
}
}else{
logger.error("[认证服务器][auth-server]用户请求认证服务异常,请检查请求参数和header-token信息!");
throw new UserTokenException("[认证服务器][auth-server]用户请求认证服务异常,请检查请求参数和header-token信息!",RestCodeConstants.TOKEN_ERROR_CODE);
}
BaseContextHandler.setUsername(infoFromToken.getUniqueName());
BaseContextHandler.setName(infoFromToken.getNickName());
BaseContextHandler.setUserTypes(infoFromToken.getUserTypes());
BaseContextHandler.setUserID(infoFromToken.getId());
log.info("[认证服务器][auth-server]<<<<<<UserAuthRestInterceptor拦截器>>>>>>验证通过。。。。successful!!!");
return super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
BaseContextHandler.remove();
super.afterCompletion(request, response, handler, ex);
}
}
2.写一个requestfilter实现Filter接口
package smartt.styy.auth.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import smartt.styy.auth.util.RequestWrapper;
public class RequestReplacedFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ServletRequest requestWrapper = null;
if(request instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) request);
}
//获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中。
// 在chain.doFiler方法中传递新的request对象
if(requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
package smartt.styy.auth.util;
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 final String body;
public RequestWrapper(HttpServletRequest request) {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
body = stringBuilder.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
3.实现filter还要在springboot的启动类上将实现的Filter类注入进去
package smartt.styy.auth;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import smartt.styy.auth.filter.RequestReplacedFilter;
/**
* @author df
* 启动方法 ,入口
*/
@SpringBootApplication
@ServletComponentScan
@MapperScan("smartt.styy.auth.mapper")
public class AuthSpringBootApplication
{
public static void main( String[] args ){
SpringApplication.run(AuthSpringBootApplication.class, args);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public FilterRegistrationBean httpServletRequestReplacedRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new RequestReplacedFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("httpServletRequestReplacedFilter");
registration.setOrder(1);
return registration;
}
}
完成以上添加就可以了,再次debug调试就可以了,以上解决方法是参考了csdn上别的大佬的,非常感谢大佬的无私分享
这里,我要说一下,为什么别人把这种问题的解决方案发出来了,我还要在写个类似的呢?
原因: 因为我觉得,好记性不如一个烂笔头,将自己遇到的问题记录下来,自己的博客就相当于自己的错题本,下次再遇到了,就自己翻看自己的博客就有了,第二点就是,多一个人写这类问题解决方法,大家在百度搜索的时候命中率高,直接就可以找到这类问题的解决方法....
如以上方法有错误,或自己理解不到位的地方,欢迎大家指出!!!