讲给Android程序员看的前端系列教程(40集免费视频教程+源码)
版权声明
- 本文原创作者:谷哥的小弟
- 作者博客地址:http://blog.csdn.net/lfdfhl
Filter概述
Filter也称之为过滤器,它是JavaWeb三大组件(Servlet、Filter、Listener)之一。它主要用于对用户请求进行预处理和对响应结果进行后处理。也就是说:使用Filter技术可在HttpServletRequest到达Web资源之前拦截客户的HttpServletRequest并根据需要检查HttpServletRequest,亦可修改HttpServletRequest;使用Filter技术可在HttpServletResponse到达客户端之前拦截HttpServletResponse并根据需要检查HttpServletResponse,亦可修改HttpServletResponse;图示如下:
Filter接口常用方法
Servlet API中提供了javax.servlet.Filter接口用于实现过滤器Filter。在此,介绍Filter接口中常用的方法及其作用。
public void init(FilterConfig filterConfig) throws ServletException
该方法用来初始化过滤器。
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException
该方法用于处理过滤。其中,参数request和response为Web服务器或Filter链中的上一个Filter传递过来的请求和响应对象;参数chain代表当前Filter链的对象。
public void destroy( )
该方法用于释放被Filter对象打开的资源;例如:关闭数据库和IO流
小 结
init( )方法和destroy( )方法仅会被调用一次;而doFilter( )方法可能会被多次调用。
Filter入门示例
在此,我们通过示例的方式入门Filter
项目结构
index.html
index.html代码如下:
<!DOCTYPE html>
<!-- 本文作者:谷哥的小弟-->
<!-- 博客地址:https://blog.csdn.net/lfdfhl-->
<html>
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<h2 align="center" style="color: red;">本文作者:谷哥的小弟</h2>
<h2 align="center" style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
</body>
</html>
index.html页面如下:
MyServlet
package cn.com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 638101330297540752L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("Servlet doGet( )");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("Servlet doPost( )");
}
}
FilterImpl
package cn.com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*
* Filter入门示例
*/
public class FilterImpl implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter init( )");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
System.out.println("Filter doFilter( ) before");
//chain.doFilter(request, response);
chain.doFilter(request, response);
System.out.println("Filter doFilter( ) after");
}
@Override
public void destroy() {
System.out.println("Filter destroy( )");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Filter01</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置servlet -->
<!-- 注册servlet -->
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>cn.com.servlet.MyServlet</servlet-class>
</servlet>
<!-- 映射servlet -->
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
<!-- 配置filter -->
<!-- 注册filter -->
<filter>
<filter-name>filterImpl</filter-name>
<filter-class>cn.com.filter.FilterImpl</filter-class>
</filter>
<!-- 映射filter -->
<filter-mapping>
<filter-name>filterImpl</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
请注意:类似于与Servlet,我们需要在配置文件web.xml中配置过滤器filter。
访问index.hmtl
访问地址:http://localhost:8080/Filter01/index.html
访问MyServlet
访问地址:http://localhost:8080/Filter01/myServlet
示例小结
对于客户端请求而言:请求先到达拦截器再到达服务端Web资源
对于服务器响应而言:响应先到达拦截器再到达客户端的浏览器
Filter映射
当在Web应用中开发Filter之后需要在web.xml中对其进行注册和配置;其中,在配置时使用< filter-mapping >标签。在此,对于Filter的注册,不再过多强调;我们来一起看看两种常见的Filter的映射。
url-pattern
在< filter-mapping >标签中可使用子标签< url-pattern >设置拦截路径;常用的为/*表示拦截所有请求。
dispatcher
在< filter-mapping >标签中可使用子标签< dispatcher >用于设置依据访问资源的方式进行拦截。< dispatcher >子标签常用取值如下:
1、REQUEST
目标资源被直接访问或者系统重定向后指向该目标资源时Filter才拦截。这也是默认的值
2、FORWARD
目标资源通过RequestDispatcher.forward(request, response)被调用时Filter才拦截
3、ERROR
目标资源是在系统处理异常时被调用
4、INCLUDE
目标资源通过RequestDispatcher.include(request, response)被调用时Filter才拦截
Filter链
在Web应用程序中可以注册多个Filter程序,每个Filter程序都可针对某具体URL进行拦截。如果多个Filter程序对同一个URL进行拦截,那么这些Filter就会串联成为Filter链(FilterChain滤器链)。Filter链用FilterChain对象来表示,其中的doFilter( )方法表示让Filter链上的当前过滤器放行,使得请求进入下一 Filter,图示如下:
Web服务器根据各Filter在web.xml文件中的注册顺序,依次调用各Filter。在此,以示例形式介绍Filter链的使用。
项目结构
index.html
index.html代码如下:
<!DOCTYPE html>
<!-- 本文作者:谷哥的小弟-->
<!-- 博客地址:https://blog.csdn.net/lfdfhl-->
<html>
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<h2 align="center" style="color: red;">本文作者:谷哥的小弟</h2>
<h2 align="center" style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
</body>
</html>
index.html页面如下:
MyServlet
package cn.com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 638101330297540752L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("Servlet doGet( )");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("Servlet doPost( )");
};
}
FilterImpl1
package cn.com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class FilterImpl1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
System.out.println("Filter1 doFilter( ) before");
//放行
chain.doFilter(request, response);
System.out.println("Filter1 doFilter( ) after");
}
@Override
public void destroy() {
}
}
FilterImpl2
package cn.com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class FilterImpl2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
System.out.println("Filter2 doFilter( ) before");
//放行
chain.doFilter(request, response);
System.out.println("Filter2 doFilter( ) after");
}
@Override
public void destroy() {
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Filter02</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置Servlet -->
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>cn.com.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
<!-- 配置第一个filter -->
<filter>
<filter-name>filterImpl1</filter-name>
<filter-class>cn.com.filter.FilterImpl1</filter-class>
</filter>
<filter-mapping>
<filter-name>filterImpl1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置第二个filter -->
<filter>
<filter-name>filterImpl2</filter-name>
<filter-class>cn.com.filter.FilterImpl2</filter-class>
</filter>
<filter-mapping>
<filter-name>filterImpl2</filter-name>
<url-pattern>/myServlet</url-pattern>
</filter-mapping>
</web-app>
测 试
请求路径:http://localhost:8080/Filter02/myServlet
FilterConfig接口
javax.servlet.FilterConfig接口封装了web.xml配置文件中filter标签下init-param子标签的配置信息。在此,介绍FilterConfig接口中的常用方法及其作用。
public String getFilterName( )
该方法用于获取Filter名字。
public ServletContext getServletContext( )
该方法用于获取ServletContext。
public String getInitParameter(String name)
该方法用于依据初始化参数名称获取其对应的值。
public Enumeration< String > getInitParameterNames( )
该方法用于获取所有初始化参数的名称。
在此,以示例形式介绍FilterConfig的使用。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Filter06</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置servlet -->
<!-- 注册servlet -->
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>cn.com.servlet.MyServlet</servlet-class>
</servlet>
<!-- 映射servlet -->
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
<!-- 配置filter -->
<!-- 注册filter -->
<filter>
<filter-name>filterImpl</filter-name>
<filter-class>cn.com.filter.FilterImpl</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- 映射filter -->
<filter-mapping>
<filter-name>filterImpl</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
FilterImpl
package cn.com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*
* FilterConfig使用示例
*/
public class FilterImpl implements Filter {
private FilterConfig mFilterConfig;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter init( )");
mFilterConfig=filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
System.out.println("Filter doFilter( ) before");
String initParameter = mFilterConfig.getInitParameter("encoding");
System.out.println("initParameter="+initParameter);
chain.doFilter(request, response);
System.out.println("Filter doFilter( ) after");
}
@Override
public void destroy() {
System.out.println("Filter destroy( )");
}
}
Filter应用示例
在此,以示例形式介绍Filter常见应用场景及其技术特点。
利用Filter实现粗粒度权限控制
实现方式概述
- 利用PrivilegeFilter拦截用户对于index.html页面的访问
- 在PrivilegeFilter中判断用户是否已经登录;假若已登录则放行,否则跳转至login.html
- LoginServlet处理登录逻辑
项目结构
index.html
<!DOCTYPE html>
<!-- 本文作者:谷哥的小弟-->
<!-- 博客地址:https://blog.csdn.net/lfdfhl-->
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h2 align="left" style="color: red;">本文作者:谷哥的小弟</h2>
<h2 align="left" style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h2>
<h1>This is index page</h1>
<h1>您已登录 , 欢迎来访</h1>
</body>
</html>
login.html
<!DOCTYPE html>
<!-- 本文作者:谷哥的小弟-->
<!-- 博客地址:https://blog.csdn.net/lfdfhl-->
<html>
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form action="/Filter03/LoginServlet" method="post">
账 户:<input type="text" name="username"/><br/><br/>
密 码:<input type="password" name="password"/><br/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
PrivilegeFilter
package cn.com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*
* 利用Filter实现粗粒度的权限控制
*
* 过滤欲访问index.html的请求
* 1 若已经登陆则放行
* 2 若没有登录则跳转至login.html
*/
public class PrivilegeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
HttpServletRequest httpServletRequest=(HttpServletRequest) request;
HttpSession session = httpServletRequest.getSession();
String username=(String) session.getAttribute("username");
if(username!=null) {
//如果用户名不为空则放行
chain.doFilter(request, response);
} else {
//如果用户名为空则跳转至登录页面
httpServletRequest.getRequestDispatcher("/login.html").forward(request, response);
}
}
@Override
public void destroy() {
}
}
LoginServlet
package cn.com.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = -1498309426781988290L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username=request.getParameter("username");
if(username!=null&&username.length()>=0) {
HttpSession session=request.getSession();
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60 * 30);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
//保存数据至Session中
request.getSession().setAttribute("username", username);
//转发至index.html
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.html");
requestDispatcher.forward(request, response);
}else {
//转发至login.html
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/login.html");
requestDispatcher.forward(request, response);
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Filter03</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.com.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<!-- 拦截访问index.html的请求 -->
<filter>
<filter-name>PrivilegeFilter</filter-name>
<filter-class>cn.com.filter.PrivilegeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrivilegeFilter</filter-name>
<url-pattern>/index.html</url-pattern>
</filter-mapping>
</web-app>
利用Filter解决全站编码问题
实现方式概述
利用EncodingFilter统一处理GET和POST的请求及其响应。
项目结构
index.html
<!DOCTYPE html>
<!-- 本文作者:谷哥的小弟-->
<!-- 博客地址:https://blog.csdn.net/lfdfhl-->
<html>
<head>
<meta charset="UTF-8">
<title>Index</title>
</head>
<body>
<h3 align="left" style="color: red;">本文作者:谷哥的小弟</h3>
<h3 align="left" style="color: red;">博客地址:http://blog.csdn.net/lfdfhl</h3>
<h5>以下为GET方式提交数据至服务器</h5>
<a href="/Filter04/LoginServlet?username=张三&password=123456">提交</a>
<br /><br />
<h5>以下为POST方式提交数据至服务器</h5>
<form action="/Filter04/LoginServlet" method="post">
用户:<input type="text" name="username" /><br /><br />
密码:<input type="password" name="password" /><br /><br />
<input type="submit" value="提交" />
</form>
</body>
</html>
LoginServlet
package cn.com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 8831676289832788100L;
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
String username = request.getParameter("username");
response.getWriter().println(username);
}
}
EncodingFilter
package cn.com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*
*/
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
//将ServletRequest强转为HttpServletRequest
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
//将ServletResponse强转为HttpServletResponse
HttpServletResponse httpServletResponse=(HttpServletResponse) response;
//获取请求方式
String method = httpServletRequest.getMethod();
System.out.println("method="+method);
//设置响应内容的编码方式
httpServletResponse.setContentType("text/html;charset=utf-8");
//设置POST请求时HttpServletRequest的编码方式
httpServletRequest.setCharacterEncoding("utf-8");
//放行
chain.doFilter(httpServletRequest, httpServletResponse);
}
@Override
public void destroy() {
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Filter04</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.com.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<!-- 配置编码过滤器 -->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>cn.com.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
转载:https://blog.csdn.net/lfdfhl/article/details/101977118