过滤器
简介
Filter:过滤器,通过Filter可以拦截访问web资源的请求与响应操作。
Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器。他可以拦截Jsp、Servlet、 静态图片文件、静态 html文件等,从而实现一些特殊的功能。
例如:实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
创建
单个过滤器
1.创建过滤器类并实现Filter接口
public class Filter01 implements Filter {
public Filter01() {
System.out.println("Filter01 -- Filter01()");
}
//初始化方法
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String code = filterConfig.getInitParameter("code");
System.out.println("Filter01 -- init() -- " + code);
}
//过滤方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter01 -- doFilter() -- 前");
//chain过滤器链
//注意:如果拦截后不调用doFilter(),请求将无法传到下一个过滤器或服务器里
filterChain.doFilter(servletRequest,servletResponse); //放行
System.out.println("Filter01 -- doFilter() -- 后");
}
//销毁方法
@Override
public void destroy() {
System.out.println("Filter01 -- destroy()");
}
}
2.在web.xml配置文件中配置过滤器信息
<filter>
<filter-name>Filter01</filter-name>
<filter-class>com.dream.filter.Filter01</filter-class>
//设置参数
<init-param>
<param-name>code</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
</filter-mapping>
注解配置过滤器
@WebFilter(value="/*",initParams={@WebInitParam(name="encode",value="UTF-8")})
public class Filter01 implements Filter {
...
}
多个过滤器
创建顺序:
无序,多线程抢资源
执行顺序:
web.xml配置按照web-----xml中配置的顺序执行
注解配置过滤器-------按照类名的顺序执行
生命周期:
创建:项目启动时 – 无参构造、init()
销毁:服务器正常关闭时 – destroy()
过滤器链
客户端对服务器请求之后,服务器在调用Servlet之前,会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。
学生管理系统改进
编码过滤器
解决请求和响应乱码问题
新建CodeFilter
public class CodeFilter implements Filter {
private String code;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//获取web.xml中该过滤器的初始化属性
code = filterConfig.getInitParameter("code");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding(code);
servletResponse.setContentType("text/html;charset=" + code);
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
web.xml配置
<filter>
<filter-name>CodeFilter</filter-name>
<filter-class>com.qf.filter.CodeFilter</filter-class>
<init-param>
<param-name>code</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
关键字过滤器
添加提交建议
修改index.jsp
<a href="proposal.jsp">提交建议</a>
新增proposal.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>建议页面</h1>
<form action="ProposalServlet" method="post">
建议:<input type="text" name="info"/><br/>
<input type="submit" value="提交"/>
<input type="button" value="返回" onclick="goIndex()"/>
</form>
<script type="text/javascript">
function goIndex(){
window.location = "index.jsp";
}
</script>
</body>
</html>
新增ProposalServlet
用于展示建议的内容
@WebServlet("/ProposalServlet")
public class ProposalServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String info = request.getParameter("info");
response.getWriter().println(info);
}
}
关键字过滤器
解决文档内的一个敏感词汇
新建MyHttpServletRequestWrapper
请求包装类
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
public MyHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
value = value.replaceAll("<", "<");
value = value.replaceAll(">", ">");
//把尖括号替换成字符尖括号,替换后不会认为是html里的尖括号符号
value = value.replaceAll("牛逼", "**");
return value;
}
}
新增SensitiveWordsFilter
public class SensitiveWordsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//创建请求包装类对象(注意:对象中包含了请求对象)
MyHttpServletRequestWrapper myHttpServletRequestWrapper = new MyHttpServletRequestWrapper(request);
filterChain.doFilter(myHttpServletRequestWrapper,response);
}
@Override
public void destroy() {
}
}
登录权限过滤器
直接在地址栏输入跳转的页面地址,如果没有过滤器过滤就会直接跳转
解决权限的统一控制问题,没有登录,就不能直接跳转到其他详情页面
新增LoginFilter
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//获取请求地址
String uri = request.getRequestURI();
System.out.println(uri);
if(uri.equals("/Day19_war_exploded/") ||
uri.contains("register.jsp") ||
uri.contains("RegisterServlet") ||
uri.contains("welcome.html") ||
uri.contains("login.jsp") ||
uri.contains("CodeServlet") ||
uri.contains("LoginServlet") ){
filterChain.doFilter(request,response);
}else{
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username");
String name = (String) session.getAttribute("name");
String role = (String) session.getAttribute("role");
if(username==null || name==null || role==null){
response.sendRedirect("login.jsp");
}else{
if(!role.equals("teacher") && uri.contains("GetStuListServlet")){
response.sendRedirect("login.jsp");
}else{
filterChain.doFilter(request,response);
}
}
}
}
@Override
public void destroy() {
}
}
web.xml配置
<filter>
<filter-name>CodeFilter</filter-name>
<filter-class>com.qf.filter.CodeFilter</filter-class>
<init-param>
<param-name>code</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.qf.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SensitiveWordsFilter</filter-name>
<filter-class>com.qf.filter.SensitiveWordsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SensitiveWordsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>