前言
前面我做了一个简单的jwt校验token的demo案例,再后来的开发过程中我遇到一个问题:我们前台在调用后台接口时,用的最多的contentType是
application/x-www-form-urlencoded、application/josn
两种类型。当是application/x-www-form-urlencoded类型下,我们在拦截中可以直接使用
request.getParameter(“token”)
获取token,而application/josn类型下参数存在body中,我们可以用流进行读取,但是到controller后就无法获取参数了,因为springmvc是这样定义的。我找了一些资料,发现可以使用自定义过滤器,通过改造过滤器的request进行解决。
代码
1.RequestWrapper
mport 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) {
ex.printStackTrace();
} 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() {
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() {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
自定义过滤器
@Component
@WebFilter(urlPatterns = "/*", filterName = "channelFilter")
public class ChannelsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (servletRequest instanceof HttpServletRequest) {
//关注点
if (servletRequest.getContentType().equals("application/json")) {
requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
}
}
if (requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
@Override
public void destroy() {
}
}
token校验拦截器
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.foxconn.response.ResponseEntity;
import com.foxconn.util.JwtUtil;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* 拦截器拦截进行token验证
*/
public class JwtHandlerInterceptor extends HandlerInterceptorAdapter {
/**
* 在请求处理之前进行调用(Controller方法调用之前)
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String contentType = request.getHeader("content-type");
String token = "";
//关注点
if (contentType.equals("application/x-www-form-urlencoded")) {
token = request.getParameter("token");
} else if (contentType.equals("application/json")) {
RequestWrapper requestWrapper = new RequestWrapper(request);
String body = requestWrapper.getBody();
JSONObject datas = JSONObject.parseObject(body);
token = (String) datas.get("token");
}
ResponseEntity res = JwtUtil.parseToken(token);
if (res.getCode() == 200) return true;
else {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println(JSON.toJSONString(res));
return false;
}
}
}
记得在springboot启动类上加上filter扫描注解@ServletComponentScan
参考:
https://www.jianshu.com/p/69c6fba08c92
版权声明:本文为qq_34869990原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。