Spring Boot - 过滤器

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 params = new HashMap<>();

    public RequestWrapper(HttpServletRequest request) {
        super(request);
        this.params.putAll(request.getParameterMap());
    }

    public RequestWrapper(HttpServletRequest request, Map extraParams) {
        this(request);
        addParameters(extraParams);
    }

    public void addParameters(Map extraParams) {
        for (Map.Entry 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)});
            }
        }
    }
}

你可能感兴趣的:(Spring Boot - 过滤器)