Spring-编码过滤----解析Filter实现原理,Java中高级面试题最新

时间:2021-09-20
本文章向大家介绍Spring-编码过滤----解析Filter实现原理,Java中高级面试题最新,主要包括Spring-编码过滤----解析Filter实现原理,Java中高级面试题最新使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
forceEncoding true
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

### 二、过滤器(Filter)的概念

1.  过滤器位于客户端和web应用程序之间,用于检查和修改两者之间流过的请求和响应。

2.  在请求到达Servlet/JSP之前,过滤器截获请求。

3.  在响应送给客户端之前,过滤器截获响应。

4.  多个过滤器形成一个过滤器链,过滤器链中不同过滤器的先后顺序由部署文件web.xml中过滤器映射的顺序决定。

5.  最先截获客户端请求的过滤器将最后截获Servlet/JSP的响应信息。

### 三、实现过滤器

可以通过实现javax.servlet.Filter类来实现自定义过滤器。

public class MyFilter implements Filter {

public void init(FilterConfig fc) { //过滤器初始化代码 }

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    try { //在这里可以对客户端请求进行检查  //沿过滤器链将请求传递到下一个过滤器。 chain.doFilter(request, response); //在这里可以对响应进行处理 } catch (IOException e) {
        e.printStackTrace();
    } catch (ServletException e) {
        e.printStackTrace();
    }
}

public void destroy( ) { //过滤器被销毁时执行的代码 }

}


### 四、过滤器的链式结构

可以为一个Web应用组件部署多个过滤器,这些过滤器组成一个过滤器链,每个过滤器只执行某个特定的操作或者检查。这样请求在到达被访问的目标之前,需要经过这个过滤器链。
![image.png](https://upload-images.jianshu.io/upload_images/24613101-49be8bf58eae19b4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


### 五、如何实现链式结构

其实Filter的链式结构是使用了Java中的责任链模式。下面我用简单的例子来实现责任链模式,然后再来讲解Spring容器中的实现。下面是我整个的包结构:

![image.png](https://upload-images.jianshu.io/upload_images/24613101-fd74aec051273305.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

然后我再来详细说明每个类的说明: 1、Filter.java。用来模拟Servlet中的Filter.java.

public interface Filter {

void doFilter(Request request, Response response, FilterChain filterChain);

}


2、Request.java。用来模拟Servlet中HttpServletRequest.java。

@Data
public class Request {

private String requestStr;

}


3、Response.java。用来模拟Servlet中的HttpServletResponse.java。

@Data
public class Response {

private String responseStr = "responseStr";

}


4、HtmlFilter.java。用来把”:)”转换成”^-^”,并且标记执行顺序

public class HtmlFilter implements Filter {

@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {
    String newRequestStr = request.getRequestStr().replace(":)", "^-^") + "----HtmlFilter";
    request.setRequestStr(newRequestStr);
    filterChain.doFilter(request, response, filterChain);
    String newResponseStr = response.getResponseStr() + "----HtmlFilter";
    response.setResponseStr(newResponseStr);
}

}


5、TextFilter.java。用来做字符串转换

public class TextFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {
String newRequestStr = request.getRequestStr().replace("中国10.1", "中国") + "----TextFilter";
request.setRequestStr(newRequestStr);
filterChain.doFilter(request, response, filterChain);
String newResponseStr = response.getResponseStr() + "----TextFilter";
response.setResponseStr(newResponseStr);
}
}


6、FilterChain.java。用来模拟Servlet中的FilterChain,只不过这个类是一个接口。这个类同时也是实现了Filter这个接口,这样设计更加精巧。等下我们对比一下Spring中的对ServletChain的实现就可以发现了。

public class FilterChain implements Filter {

private List<Filter> filters = Lists.newArrayList();

private int currentPosition = 0;

public FilterChain addFilter(Filter filter){
    this.filters.add(filter);
    return this;
}

@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {

    if (this.currentPosition == this.filters.size()) {
        return;
    }
    this.currentPosition++;
    Filter nextFilter = this.filters.get(this.currentPosition - 1);
    nextFilter.doFilter(request, response, this);
}

}


7、Client.java。用来测试结果。

public class Client {

public static void main(String[] args) {
    String requestStr = "1111111,2222222:),中国10.1国庆节....";
    Request request = new Request();
    request.setRequestStr(requestStr);
    Response response = new Response();
    FilterChain filterChain = new FilterChain();
    filterChain.addFilter(new HtmlFilter()).addFilter(new TextFilter());
    filterChain.doFilter(request, response, filterChain);
    System.out.println(request.getRequestStr());
    System.out.println(response.getResponseStr());
}

}


我们先来看看运行结果,再来分析实现原理。运行结果如下:



# 总结

蚂蚁面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://ali1024.coding.net/public/P7/Java/git)**

* * *

**经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有**:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。

![蚂蚁金服5面,总结了49个面试题,遇到的面试官都是P7级别以上](https://upload-images.jianshu.io/upload_images/24616006-2b976d3b5a750638?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

原文地址:https://www.cnblogs.com/hgysvadavvc/p/15313914.html