通过过滤器filter修改request的body请求数据、拦截器进行token登录验证
过滤器:
1、以stream的方式获取request中body(json)参数。
2、递归获取userIdSet集合并写入request的stream中。
3、重写HttpServletRequestWrapper将保存的reqest保存下来再填充进去;以便controller中@RequestBody再次读取。
拦截器:
1、根据token从redis中获取用户信息验证(登录验证)。
1.过滤器EncryptionFilter
package com.youju.yingxiao.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.youju.yingxiao.entity.User;
import com.youju.yingxiao.params.BasePojo;
import com.youju.yingxiao.service.LoginService;
import com.youju.yingxiao.service.RecursiveService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@WebFilter(urlPatterns = "/*")
public class EncryptionFilter implements Filter {
@Autowired
private LoginService loginService;
@Autowired
private RecursiveService recursiveService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@SneakyThrows
@Override
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String contentType = request.getContentType();
//获取request的body参数
String postContent = getBody(request);
BasePojo basePojo = JSONObject.parseObject(postContent, BasePojo.class);
//获取用户信息、递归
User user = loginService.getLoginUser(request);
recursiveService.getUserIdsByDepts(basePojo, user);
//如果body中存在数据放入HttpServletRequest
if (StringUtils.isNotEmpty(postContent)) {
//参数中放入新的参数
JSONObject jsStr = JSONObject.parseObject(postContent);
jsStr.put("userIdSet", basePojo.getUserIdSet());
postContent = jsStr.toJSONString();
//将参数放入重写的方法中
request = new BodyRequestWrapper(request, postContent);
}
chain.doFilter(request, response);
}
//获取Request的body数据
private String getBody(ServletRequest 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();
}
}
}
return stringBuilder.toString();
}
@Override
public void destroy() {
}
}
2.body形式的包装类
package com.demo.filter.request;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
//更改body中的值
public class BodyRequestWrapper extends HttpServletRequestWrapper {
// 存放JSON数据主体
private String body;
public BodyRequestWrapper(HttpServletRequest request, String context) {
super(request);
body = context;
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
3.拦截器Interceptor
package com.youju.yingxiao.interceptor;
import com.youju.yingxiao.common.JsonUtil;
import com.youju.yingxiao.entity.User;
import com.youju.yingxiao.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private LoginService loginService;
/**
* 在请求处理之前进行调用(Controller方法调用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
User user = loginService.getLoginUser(request);
if (user != null) {
return true;
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out;
Map<String, Object> res = new HashMap<>();
res.put("success", false);
res.put("message", "登录信息已过期,请重新登录!");
out = response.getWriter();
out.append(JsonUtil.getStringByMap(res));
return false;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
/**
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
}