Spring Boot - 过滤器
2018-04-17 本文已影响175人
yuanzicheng
Spring MVC中的拦截器和过滤器都是基于AOP实现的,它们比较相似,但也有不同,最明显的差异就是:过滤器可以修改request对象。
在Spring Boot中使用Spring MVC也是相当简单,仅需要创建一个过滤器,实现javax.servlet.Filter接口,添加@WebFilter注解并配置过滤的URL,最后再通过@Component注解来注入IOC容器。
以下示例代码为登录验证过滤器,已登录则放行并在request中添加uid,未登录则返回“未登录”的响应结果。
登录验证过滤器的具体实现,具体的过滤逻辑一般放在doFilter方法中:
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Component
@WebFilter(urlPatterns = "/*",filterName = "loginFilter")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest= (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String path = httpServletRequest.getRequestURI().substring(httpServletRequest.getContextPath().length()).replaceAll("[/]+$", "");
//TODO 排除例外(没有直接可用的方法,需要自己实现)
//登录状态
boolean isLogin = false;
String token = httpServletRequest.getHeader("token");
if (!StringUtils.isEmpty(token)) {
//通过token验证是否登录,并取得uid
String uid = "取得的uid";
if(!StringUtils.isEmpty(uid)){
//将取得的uid添加到request对象中
RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest);
requestWrapper.addParameter("uid",uid);
httpServletRequest = requestWrapper;
//标记登录状态为已登录
isLogin = true;
}
}
if (isLogin) {
chain.doFilter(httpServletRequest,httpServletResponse);
} else {
response.setCharacterEncoding("utf8");
PrintWriter out = response.getWriter();
//Result为自定义的Rest请求的响应结果类
out.print(JSONObject.toJSONString(new Result<>(false, "未登录", null)));
out.close();
}
}
@Override
public void destroy() {
}
}
RequestWrapper用于修改request对象,因为HttpServletRequest本身并不支持直接修改参数
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.HashMap;
import java.util.Map;
public class RequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> params = new HashMap<>();
public RequestWrapper(HttpServletRequest request) {
super(request);
this.params.putAll(request.getParameterMap());
}
public RequestWrapper(HttpServletRequest request, Map<String, Object> extraParams) {
this(request);
addParameters(extraParams);
}
public void addParameters(Map<String, Object> extraParams) {
for (Map.Entry<String, Object> entry : extraParams.entrySet()) {
addParameter(entry.getKey(), entry.getValue());
}
}
@Override
public String getParameter(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
}
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
/**
* 添加参数
*/
public void addParameter(String name, Object value) {
if (value != null) {
if (value instanceof String[]) {
params.put(name, (String[]) value);
} else if (value instanceof String) {
params.put(name, new String[]{(String) value});
} else {
params.put(name, new String[]{String.valueOf(value)});
}
}
}
}