2.一个简单的过滤器
1.任何过滤器都要实现javax.servlet.Filter 接口
2.在web.xml 中对过滤器进行配置,说明Url的范围
3.在过滤器的doFilter()方法中编写过滤器的功能代码
//MyFirstFilter .java
package com.imooc.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;
public class MyFirstFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("过滤器已被销毁");//tomcat停止时,这里会执行
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("过滤器已生效");//每一个请求过来以后,在这里进行拦截处理
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("过滤器初始化成功");//web应用启动时自动执行
}
}
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>first_filter</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>
<!-- filter标签用于说明哪个类是过滤器,并在应用启动时,自动加载 -->
<filter>
<filter-name>MyFirstFilter</filter-name>
<filter-class>com.imooc.filter.MyFirstFilter</filter-class>
</filter>
<!--
filter-mapping 标签用于说明过滤器对URL应用的范围,要点有二:
1.filter-name 过滤器名称与filter.filter-name保持一致
2.url-pattern 说明过滤器作用范围,/* 代表对所有URL进行过滤
-->
<filter-mapping>
<filter-name>MyFirstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
//HelloServlet.java
package com.imooc.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class HelloServlet
*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Hello World");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
只要是访问http://localhost:8080/first_filter/
下的任何有效地址,由于web.xml配置的是/*
,都会执行doFilter方法
,输出过滤器生效
3.过滤器的两种开发方式
3.1 配置形式
3.2 注解形式
xml配置的过滤器优先执行于注解配置的过滤器,但是项目中不要对两种形式混用
//注解形式
package com.imooc.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.annotation.WebFilter;
/**
* Servlet Filter implementation class MyAnnotationFilter
*/
@WebFilter(filterName="MyAnnotationFilter",urlPatterns="/*")
public class MyAnnotationFilter implements Filter {
/**
* Default constructor.
*/
public MyAnnotationFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
System.out.println("注解形式过滤器已经生效");
// pass the request along the filter chain
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
4字符集过滤器
package com.imooc.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;
public class CharacterEncodingFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest)request;
//HttpServletRequest的父接口是ServletRequest
req.setCharacterEncoding("UTF-8");
HttpServletResponse res = (HttpServletResponse)response;
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
其实就是,request和response对于中文字符,都需要命令设置。原来是放在doGet或者doPost中,因为过滤器每条request和response都会在这里处理,因此在可以在过滤器这里设置字符集命令会很方便
5过滤器参数化标签
5.1
如上图,在web.xml中定义参数
如上图,在CharacterEncodingFilter.java 中加载参数,然后使用
过滤器参数化标签的好处,
在web.xml中定义参数,因为web.xml是文本,不用编译,修改参数,重启应用就可以用了,如果在程序中写死,需要重新便宜,而且比较麻烦
5.2 也可以使用注解
6 UrlPattern设置过滤范围
6.1 配置模式
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>url-pattern</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>
<filter>
<filter-name>UrlPatternFilter</filter-name>
<filter-class>com.imooc.filter.UrlPatternFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlPatternFilter</filter-name>
<url-pattern>/test.jsp</url-pattern> <!-- 精准拦截 -->
</filter-mapping>
<filter-mapping>
<filter-name>UrlPatternFilter</filter-name>
<url-pattern>/</url-pattern> <!-- 拦截根目录 -->
</filter-mapping>
<filter-mapping>
<filter-name>UrlPatternFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- 拦截根目录后面的所有 -->
</filter-mapping>
</web-app>
//UrlPatternFilter.jsp
package com.imooc.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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*@WebFilter(filterName="UrlPatternFilter" , urlPatterns= {
"/","/Servlet/*","*.jsp"
})*/
public class UrlPatternFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
System.out.println("拦截到:" + req.getRequestURL());
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
//test.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
I'm test page!
</body>
</html>
//index.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
I'm index.jsp
</body>
</html>
//SampleServlet1 .java
package com.imooc.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class SampleServlet1
*/
@WebServlet("/servlet/sample1")
public class SampleServlet1 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public SampleServlet1() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("I'm "+ this.getClass().getSimpleName());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
//
package com.imooc.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class SampleServlet1
*/
@WebServlet("/")
public class SampleServlet2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public SampleServlet2() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("I'm "+ this.getClass().getSimpleName());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
//SampleServlet2.java
package com.imooc.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class SampleServlet1
*/
@WebServlet("/")
public class SampleServlet2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public SampleServlet2() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("I'm "+ this.getClass().getSimpleName());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
注意:
- index.jsp 是默认首页,在访问
http://localhost:8080/url-pattern/
时会访问默认首页,但是默认首页的存在,会使映射地址也为
@WebServlet("/")
public class SampleServlet2 extends HttpServlet {
的servlet失效,因此,在实际开发中,尽量避免使用默认首页,避免带来一些访问失效的问题
6.2 使用注解
7.过滤链
//FilterB
package com.imooc.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.annotation.WebFilter;
@WebFilter(filterName="FilterB" , urlPatterns="/*")
public class FilterB implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("I'm Filter B");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
//FilterC.java
package com.imooc.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.annotation.WebFilter;
@WebFilter(filterName="FilterC" , urlPatterns="/*")
public class FilterC implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("I'm Filter C");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
//FilterZ.java
package com.imooc.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.annotation.WebFilter;
@WebFilter(filterName="FilterZ" , urlPatterns="/*")
public class FilterZ implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("I'm Filter Z");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
//HelloServlet.java
package com.imooc.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class HelloServlet
*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HelloServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().print("Hello World!");
System.out.println("Hello World!");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>filter-chain</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>
<filter>
<filter-name>FilterA</filter-name>
<filter-class>com.imooc.filter.FilterA</filter-class>
</filter>
<filter>
<filter-name>FilterB</filter-name>
<filter-class>com.imooc.filter.FilterB</filter-class>
</filter>
<filter>
<filter-name>FilterC</filter-name>
<filter-class>com.imooc.filter.FilterC</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterA</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>FilterB</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>FilterC</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
注意:
1.在配置文件web.xml中,是根据·filter-mapping·的顺序决定过滤链的顺序,而在注解中,是根据过滤器的类名的按照名称升序排序,显然前者更靠谱,后者不可控。
2.chain.doFilter(request, response);
可控制是否继续传递,利用它,可以对特定条件的东西判断是否执行该函数。
8.多端设备页面自动设备
思路:不同的设备,如手机和电脑的显示界面是不同的,对于不同设备的request,应该返回适合当前设备的页面
package com.imooc.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;
public class DeviceAdapterFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
//在请求的地址前加上辨识的字符,重构URI
/*
/index.html
PC: /desktop/index.html
MOBILE: /mobile/index.html
/test.html
PC: /desktop/test.html
MOBILE: /mobile/test.html
*/
String uri = req.getRequestURI();
System.out.println("URI:"+uri);
if(uri.startsWith("/desktop") || uri.startsWith("/mobile")) {
//本来就有标识符,那么就直接传递
chain.doFilter(request, response);
}else {
String userAgent = req.getHeader("user-agent");
String targetURI = "";
if(userAgent.indexOf("android")!=-1 || userAgent.indexOf("iphone")!=-1) {
targetURI = "/mobile"+uri;
System.out.println("移动端设备正在访问,重新跳转URI:" + targetURI);
res.sendRedirect(targetURI);
}else {
targetURI = "/desktop"+uri;
System.out.println("移动端设备正在访问,重新跳转URI:" + targetURI);
res.sendRedirect(targetURI);
}
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>device-adapter</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>
<filter>
<filter-name>DeviceAdapterFilter</filter-name>
<filter-class>com.imooc.filter.DeviceAdapterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DeviceAdapterFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
</web-app>