JavaWeb-19
JDBC之过滤器Filter
一、Filter过滤器概述
Filter(过滤器):Web三大组件之一,就是对目标资源进行请求前或请求后.
Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
实际中:过滤器就相当于山大王,作用就是拦截,拦截不拦截,山大王说的算
查看java Servlet文档去查看Filter解释
作用? 实例: 1、动态资源不缓存 2、静态资源缓存 3、中文乱码集中处理 4、特殊字符过滤 5、全站压缩(选做) 6、脚本过滤
- 写法?
1、写类:
类 implements Filter init(FilterConfig) doFilter(ServletRequest,ServletResponse,FilterChain) destory() 在其他里寻找Filter类型的文件来新建,因为这样web.xml可以自动配置,和Servlet一样。 在新建栏里有初始化参数栏(encoding:UTF-8) 还有一个映射栏(filter mappings: /*:代表过滤所有资源),或者在里面写具体的资源,那么就只拦截具体的资源 配置web.xml:由于在新建选择了新建Filter类型的文件,MyEclipse会自动配置web.xml 在服务器启动时,filter已经实例化了,证明filter的生命周期比servlet长,不要直接访问过滤器。 在IE里尝试访问index.jsp 通过web.xml里的设置,会在访问index.jsp里导致filter里的方法执行。
2、在web.xml中进行配置.
格式!!
3、对于Filter中的doFilter与FilterChain中的doFilter的比较?
a、个数不同 Filter接口doFilter是3个参数ServletRequset,ServletResponse,FilterChain FilterChain参数2个:ServletRequset,ServletResponse b、作用不同 Filter接口doFilter拦截作用 FilterChain接口中的doFilter起放行作用。
二、Filter过滤器链执行顺序
1、过滤器一般就是起拦截作用的,不要直接访问过滤器
2、生命周期
1、容器启动时,Filter就会进行实例化(构造方法),初始化(init)--->只有一次机会
2、以后每次访问目标资源时,在符合条件的情况下,过滤器执行doFilter()进行拦截。
3、当应用被卸载或服务停止时,destory()被执行---->只有一次机会
3、拦截的顺序问题?
有多个过滤器就会形成一个(过滤器链),先执行第一个过滤器,再执行第二个过滤器
顺序取决于在web.xml中配置的顺序,看filter-mapping先后顺序,filter-mapping前先过滤。
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/a</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>DirtyWordsFilter</filter-name>
<url-pattern>/b</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>HtmlFilter</filter-name>
<url-pattern>/c</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>/d</url-pattern>
</filter-mapping>
比如上面的web.xml配置文件所配置的Filter执行顺序是:CharacterEncodingFilter-->DirtyWordsFilter-->HtmlFilter-->GzipFilter
三、获取初始化参数
1、配置时
1、/路径名/* (/*)
2、*.扩展名 (*.jsp)
3、具体路径 (/add.jsp)
2、一个过滤器可以有多个过滤路径
<filter-mapping>
<filter-name>filterDemo1</filter-name>
<url-pattern>/add.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>filterDemo1</filter-name>
<url-pattern>/login.jsp</url-pattern>
</filter-mapping>
3、对于初始化参数的配置及读取(FliterConfig)
/*
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
*/
//得到一个参数
/*String value = config.getInitParameter("encoding");
System.out.println(value);
chain.doFilter(request, response);*/
//得到多个参数
Enumeration<String> enums = config.getInitParameterNames();
while(enums.hasMoreElements()){
String paramName = enums.nextElement();
String paramValue = config.getInitParameter(paramName);
System.out.println(paramName+":"+paramValue);
filter讲解:
filterChain讲解
项目:day1900filter
项目架构:
FilterDemo1.java.
package com.itheima.filter;
import java.io.IOException;
import java.util.Enumeration;
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 FilterDemo1 implements Filter {
private FilterConfig config;//用于读取初始化参数 <init-param>中的值
public FilterDemo1() {
System.out.println("FilterDemo1被实例化了");
}
public void destroy() {
System.out.println("FilterDemo1被销毁了");
}
//拦截,放行
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
/*
* <init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
String value = config.getInitParameter("encoding");
System.out.println(value);
*/
Enumeration<String> enumss = config.getInitParameterNames();//取到所有参数名称 <param-name>encoding</param-name>
while(enumss.hasMoreElements()){
String paramName = enumss.nextElement();
String value = config.getInitParameter(paramName);
System.out.println(value);
}
System.out.println("FilterDemo1放行前");
response.getWriter().write("FilterDemo1放行前前");
chain.doFilter(request, response);//放行
System.out.println("FilterDemo1放行后");
}
public void init(FilterConfig fConfig) throws ServletException {
this.config = fConfig;
System.out.println("初始化了");
}
}
FilterDemo2.java
package com.itheima.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;
/**
* Servlet Filter implementation class FilterDemo2
*/
public class FilterDemo2 implements Filter {
/**
* Default constructor.
*/
public FilterDemo2() {
// 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 {
System.out.println("FilterDemo2放行前");
chain.doFilter(request, response);
System.out.println("FilterDemo2放行后");
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="http://blog.163.com/faith_yee/blog/<%=basePath%>">
<title>My JSP ‘index.jsp‘ starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
This is my JSP page. <br>
<%
System.out.println("目标资源:JSP");
%>
</body>
</html>
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>FilterDemo1</filter-name>
<filter-class>com.itheima.filter.FilterDemo1</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>name</param-name>
<param-value>AJ</param-value>
</init-param>
</filter>
<filter>
<display-name>FilterDemo2</display-name>
<filter-name>FilterDemo2</filter-name>
<filter-class>com.itheima.filter.FilterDemo2</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>FilterDemo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
测试:
总结:在filter里如何获得web.xml配置文件的属性值:
由于之前例子发现filter在服务器启动时就已经进行配置文件初始化了,所以自然会执行filter的构造函数和init的方法,该方法的参数是FilterConfig类型,init()方法会读取配置文件给该filter进行初始化,所以我们可以从该方法入手获取FilterConfig类型变量,首先我们定义一个FilterConfig类型的全局变量,然后通过init()方法进行传值到全局变量,然后全局变量就可以获得FilterConfig类型的对象,然后可以执行对象中的方法getInitParameterNames()或getInitParameter()去获取配置文件的属性名或属性值。
四、过滤器解决乱码问题简单版
三个示例:
1、编码过滤
2、动态资源无缓存
3、静态资源缓存
实例 servlet解决乱码:
1、取名
2、输出回jsp,测试有没有乱码
用filter解决编码的问题(集中问题解决)
思考:以后执行servlet时,都通过filter过滤,那么就可以都解决编码乱码的问题了
总结:如果要集中解决问题:用过滤器
五、动态资源不缓存的过滤器
过滤器解决post的乱码
待会再讲解get提交的代码
在dofilter里对强转request和response成HttpServlet的 //以上的技巧叫调包!!在过滤器里经常使用
开始设置不缓存
response.setHeader("Expirse","-1");
response.setHeader("Cache-Control","no-cache");
response.setHeader("pragma","no-cache");
测试:在IE里访问addcustomer.jsp
在IE设置里查看缓存,找到目标后查看文件的过期时间!!对比本地时间去判断!
以此实现动态资源不缓存
六、静态资源缓存的过滤器
然后在过滤器里进一步筛选
在该过滤器的配置器里加参数属性进行筛选 配置文件
思路:
1、因为静态资源过多,所以配置成/**/,但为了只过滤静态资源,所以考虑用参数来区分
2、读取初始化参数,
{
那么我们怎么知道客户端访问的路径是什么?
2、得到用户访问的资源(主要取它的类型,而文件类型由扩展名决定,然后把调包方式复制过来),用来获取后缀名
}
读取初始化参数,以找到这个类型的资源缓存时间
3、设置缓存时间
response.setDateHeader("Expires",System.currentTimeMillis()+Integer.parseInt(time)+60*60*1000);
测试:在测试前准备一些静态资源: 访问index.html-->里面会访问静态资源: 然后去IE设置文件里查看缓存过期时间
项目:day1901filterExample:CharacterEncodingFilter
项目架构:
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name></display-name>
<servlet>
<servlet-name>UserRegistServlet</servlet-name>
<servlet-class>com.itheima.servlet.UserRegistServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>CustomerRegistServlet</servlet-name>
<servlet-class>com.itheima.servlet.CustomerRegistServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserRegistServlet</servlet-name>
<url-pattern>/servlet/UserRegistServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CustomerRegistServlet</servlet-name>
<url-pattern>/servlet/CustomerRegistServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<display-name>CharacterEncodingFilter</display-name>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.itheima.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<display-name>DyncSourceNoNeedCache</display-name>
<filter-name>DyncSourceNoNeedCache</filter-name>
<filter-class>com.itheima.filter.DyncSourceNoNeedCache</filter-class>
</filter>
<filter-mapping>
<filter-name>DyncSourceNoNeedCache</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>DyncSourceNoNeedCache</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
<filter>
<display-name>StaticSourceNeedCache</display-name>
<filter-name>StaticSourceNeedCache</filter-name>
<filter-class>com.itheima.filter.StaticSourceNeedCache</filter-class>
<init-param>
<param-name>html</param-name>
<param-value>1</param-value><!-- 小时 -->
</init-param>
<init-param>
<param-name>css</param-name>
<param-value>2</param-value><!-- 小时 -->
</init-param>
<init-param>
<param-name>js</param-name>
<param-value>3</param-value><!-- 小时 -->
</init-param>
</filter>
<filter-mapping>
<filter-name>StaticSourceNeedCache</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
CharacterEncodingFilter.java
package com.itheima.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;
/**
* Servlet Filter implementation class CharacterEncodingFilter
*/
public class CharacterEncodingFilter implements Filter {
/**
* Default constructor.
*/
public CharacterEncodingFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");//post提交有效
response.setCharacterEncoding("UTF-8");//响应结果的编码
response.setContentType("text/html;charset=UTF-8");//告诉浏览器用什么编码,它也有上一行代码的功能
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
DyncSourceNoNeedCache.java
package com.itheima.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;
/**
* Servlet Filter implementation class DyncSourceNoNeedCache
*/
public class DyncSourceNoNeedCache implements Filter {
/**
* Default constructor.
*/
public DyncSourceNoNeedCache() {
// 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 req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request ;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) resp;
//调包
response.setHeader("Expires", "-1");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("non-http request or response");
}
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
StaticSourceNeedCache.java
package com.itheima.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 StaticSourceNeedCache implements Filter {
private FilterConfig config;
public StaticSourceNeedCache() {
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
//1.因为静态资源过多,所以配置成/*,但为了只过滤静态资源,所以考虑用参数来区分
HttpServletRequest request ;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) resp;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("non-http request or response");
}
//2.得到用户访问的资源(主要取它的类型,而文件类型由扩展名决定)
String path = request.getRequestURI();//资源名 /dsfdsfsdfds/dsfdsfs/a.html
String extensionName = path.substring(path.lastIndexOf(".")+1);//得到扩展名
//3.读取初始化参数,以找到这个类型的资源缓存时间
String time ="0";
String time1 = config.getInitParameter(extensionName);
if(time1!=null){
time = time1;
}
//4.设置缓存时间
response.setDateHeader("Expires", System.currentTimeMillis()+Integer.parseInt(time)*60*60*1000);//单位:毫秒
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
this.config = fConfig;
}
}
CustomerRegistServlet.java
package com.itheima.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CustomerRegistServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*request.setCharacterEncoding("UTF-8");//post提交有效
response.setCharacterEncoding("UTF-8");//响应结果的编码
response.setContentType("text/html;charset=UTF-8");//告诉浏览器用什么编码,它也有上一行代码的功能
*/
String value = request.getParameter("name");
response.getWriter().write(value);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
UserRegistServlet.java
package com.itheima.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserRegistServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/* request.setCharacterEncoding("UTF-8");//post提交有效
response.setCharacterEncoding("UTF-8");//响应结果的编码
response.setContentType("text/html;charset=UTF-8");//告诉浏览器用什么编码,它也有上一行代码的功能
*/
String value = request.getParameter("name");
response.getWriter().write(value);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
addCustomer.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>客户注册</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/CustomerRegistServlet" method="post">
<input name="name"/><input type="submit" value="保存"/>
</form>
</body>
</html>
addUser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用户注册</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/UserRegistServlet" method="post">
<input name="name"/><input type="submit" value="保存"/>
</form>
</body>
</html>
index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>index.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/css/main.css">
<script type="text/javascript" src="http://blog.163.com/faith_yee/blog/js/1.js"></script>
</head>
<body>
hello ,good morning.
</body>
</html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="http://blog.163.com/faith_yee/blog/<%=basePath%>">
<title>My JSP ‘index.jsp‘ starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
This is my JSP page. <br>
</body>
</html>
测试addCustomer
测试addUser
测试 DyncSourceNoNeedCache
测试 StaticSourceNeedCache
七、自动登录
示例4、自动登录
分析资料:
项目:day1902autoLogin
项目架构:
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name></display-name>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.itheima.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/servlet/LoginServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<display-name>CharacterEncodingFilter</display-name>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.itheima.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<display-name>AutoLoginFilter</display-name>
<filter-name>AutoLoginFilter</filter-name>
<filter-class>com.itheima.filter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AutoLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
User.java
package com.itheima.domain;
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String password;
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public User() {
super();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserDB.java
package com.itheima.domain;
import java.util.ArrayList;
import java.util.List;
public class UserDB {
private static List<User> users = new ArrayList<User>();
static{
users.add(new User("郭女士","123"));
users.add(new User("丁先生","123"));
users.add(new User("fj","123"));
}
public static User findUser(String username,String password){
for(User u:users){
if(username.equals(u.getUsername())&&password.equals(u.getPassword())){
return u;
}
}
return null;
}
public static User findUser(String username){
for(User u:users){
if(username.equals(u.getUsername())){
return u;
}
}
return null;
}
}
AutoLoginFilter.java
package com.itheima.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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.itheima.domain.User;
import com.itheima.domain.UserDB;
import com.itheima.util.Base64Util;
import com.itheima.util.Md5Util;
/**
* Servlet Filter implementation class AutoLoginFilter
*/
public class AutoLoginFilter implements Filter {
/**
* Default constructor.
*/
public AutoLoginFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//读取session中的值
User u = (User)request.getSession().getAttribute("user");
if(u==null){
//2.没有登录,可以读Cookie
Cookie cs [] = request.getCookies();
//3.遍历
if(cs==null){
return ;
}
Cookie userCookie = null;
if(cs!=null && cs.length>0){
for (int i = 0; i < cs.length; i++) {
Cookie c = cs[i];
if("userinfo".equals(c.getName())){
//如果找到了你想的cookie
userCookie = c;
break;
}
}
}
//4.说明存在要找的Cookie
if(userCookie!=null){
String username_pwd = userCookie.getValue();
String b64username = username_pwd.split("_")[0];//取b64编码后的用户名
String md5pwd = username_pwd.split("_")[1];//取md5加密后的密码
//5.还原用户名
String trueUsername = Base64Util.decode(b64username);
//6.根据用户名,到UserDB中查找,得到一个User对象
User uu = UserDB.findUser(trueUsername);
if(uu!=null){
if(md5pwd.equals(Md5Util.encode(uu.getPassword()))){
request.getSession().setAttribute("user", uu);
}
}
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
CharacterEncodingFilter.java
package com.itheima.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;
/**
* Servlet Filter implementation class CharacterEncodingFilter
*/
public class CharacterEncodingFilter implements Filter {
/**
* Default constructor.
*/
public CharacterEncodingFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");//post提交有效
response.setCharacterEncoding("UTF-8");//响应结果的编码
response.setContentType("text/html;charset=UTF-8");//告诉浏览器用什么编码,它也有上一行代码的功能
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
LoginServlet.java
package com.itheima.servlet;
import java.io.IOException;
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 com.itheima.domain.User;
import com.itheima.domain.UserDB;
import com.itheima.util.Base64Util;
import com.itheima.util.Md5Util;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.获取参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String expires = request.getParameter("expires");
//2.验证用户的合法性
User u = UserDB.findUser(username, password);
//3.判断是非法用户,直接返回到登录页
if(u==null){
response.getWriter().write("登录失败,2秒后请重新登录");
response.setHeader("Refresh", "2;URL="+request.getContextPath()+"/login.jsp");
return;
}
//4.合法用户,将用户信息存入session
request.getSession().setAttribute("user", u);
//5.产生一个Cookie,用于保存登录用户的用户名_密码 (base64username_md5password)
Cookie c = new Cookie("userinfo",Base64Util.encode(u.getUsername())+"_"+Md5Util.encode(u.getPassword()));
//6.设置cookie的path路径
c.setPath(request.getContextPath());//代表当前应用请求时,cookie信息都发送给服务器
//7.设置cookie的存活时间
if("never".equals(expires)){
c.setMaxAge(0);
}else if("month".equals(expires)){
c.setMaxAge(30*24*60*60);//秒
}else if("year".equals(expires)){
c.setMaxAge(365*24*60*60);
}else if("forever".equals(expires)){
c.setMaxAge(Integer.MAX_VALUE);
}
//8.发送给浏览器
response.addCookie(c);
//9重定向到index.jsp
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
Base64Util.java
package com.itheima.util;
import java.io.IOException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Base64Util {
//编码
public static String encode(String oldStr){
BASE64Encoder b64Encoder = new BASE64Encoder();
return b64Encoder.encode(oldStr.getBytes());
}
//解码
public static String decode(String oldStr){
try {
BASE64Decoder b64Decoder = new BASE64Decoder();
byte []newStr = b64Decoder.decodeBuffer(oldStr);
return new String(newStr);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
Md5Util.java
package com.itheima.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
public class Md5Util {
public static String encode(String oldStr){
try {
MessageDigest md5 = MessageDigest.getInstance("md5");
byte [] newStr = md5.digest(oldStr.getBytes());
BASE64Encoder b64 = new BASE64Encoder();
return b64.encode(newStr);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
for(int i=1;i<20;i++){
String newString = Md5Util.encode("abc"+i);
System.out.println(newString);
}
}
}
bbs.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
${sessionScope.user.username}
</body>
</html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>XX网站</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
<c:if test="${sessionScope.user==null}">
<a href="http://blog.163.com/faith_yee/blog/${pageContext.request.contextPath}/login.jsp">登录</a>
</c:if>
<c:if test="${sessionScope.user!=null}">
欢迎您:${user.username}<a href="http://blog.163.com/faith_yee/blog/#">注销</a>
</c:if>
<hr/>
XX网站
<a href="http://blog.163.com/faith_yee/blog/${pageContext.request.contextPath}/bbs.jsp">帖子</a>
</body>
</html>
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
登录有效期:<input type="radio" name="expires" value="never" checked="checked">无
<input type="radio" name="expires" value="month">一个月
<input type="radio" name="expires" value="year">一年
<input type="radio" name="expires" value="forever">永久<br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
测试:
util-->Base64Util
//编码
public static String encode(oldStr){
BASE64Encoder b64Encode = new BASE64Encoder();
return b64Encoder.encode(oldStr.getBytes());
}
//解码
public static String decode(String oldStr){
BASE64Decoder b64Decoder = new BASE64Decoder();
byte []newStr = b64Decoder.decodeBuffer(oldStr);//stream类型
return new String(newStr);
}
该工具类把用户名编码进行编码传输!
util--->Md5Util
Md5不可逆
public static String encode (String oldStr){
MessageDigest md5 = MessageDigest.getInstance("md5");
byte[] newStr = md5.digest(oldStr.getBytes());
//return new String (newStr);
//以上这种加密不好使,会产生一些无厘头的中文,所以为了传输这md5产生的加密文件,所以结合上面的Base64util来给加密文件都进行编码!!传输到另一方进行解码!!
}
测试工具类
以上主要是为了通过客户端发来用户名和密码,发送给客户端,通过md5把密码加密后传输到服务器端,服务器端经过匹配md5加密后的密码去取出数据库中的用户资料,这个传输过程使用base64编码解码进行传输。。
Base64Util是3字节变成4字节
八、实例
1、全站编码过滤器
问题是,我们输入的那么多jsp,怎么弄一个功能更强大的filter去解决get/post的乱码问题
在web.xml里加上<init-param>属性配置
改进CHaracterEncodingFilter
把代码写活,适用型强
调包-->新类MyHttpServletRequset(内部类):!!!调包后换了一个功能更强大的
包装设计模式
2、包装设计模式解释
包装设计模式
MyBufferReader extends BufferdReader{
private BufferedReader reader ;
public MyBufferedReader(Reader in){
super(in);
this.reader =(BufferedReader)in;
}
public String readLine() throws IOException{
String content = reader.readLine();
if(content!=null)
return (i++)+content;
return super.readLine();
}
}
//包装模式包装的是对象(本身就是一个包装类,此时可以简化写法)
在super()完以前的继承类后,就改写要加强的方法就OK
3、脏话过滤器
首先要有一个脏话数据库 在filter--->DirtyWordsFilter--->过滤路径:全部
在doFilter
{
String woeds[]={"叫兽","禽兽","FUCK"};
调包
形成过滤器链
目的:改写方法
}
4、html过滤器
写Html过滤器filter-->HtmlFilter
在tomcat里的example里找一个Html的filter去复制里面的代码
替换-->令标签代码无效
以下的所有示例都是换包再发送出去,这就是包装设计模式
项目:day1903advanceExample-->CharacterEncodingFilter
项目架构:
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name></display-name>
<servlet>
<servlet-name>UserRegistServlet</servlet-name>
<servlet-class>com.itheima.servlet.UserRegistServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>GzipDemo1</servlet-name>
<servlet-class>com.itheima.servlet.GzipDemo1</servlet-class>
</servlet>
<servlet>
<servlet-name>GzipDemo2</servlet-name>
<servlet-class>com.itheima.servlet.GzipDemo2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserRegistServlet</servlet-name>
<url-pattern>/servlet/UserRegistServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GzipDemo1</servlet-name>
<url-pattern>/servlet/GzipDemo1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GzipDemo2</servlet-name>
<url-pattern>/servlet/GzipDemo2</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<display-name>CharacterEncodingFilter</display-name>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.itheima.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<display-name>DirtyWordsFilter</display-name>
<filter-name>DirtyWordsFilter</filter-name>
<filter-class>com.itheima.filter.DirtyWordsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DirtyWordsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<display-name>HtmlFilter</display-name>
<filter-name>HtmlFilter</filter-name>
<filter-class>com.itheima.filter.HtmlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HtmlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<display-name>GzipFilter</display-name>
<filter-name>GzipFilter</filter-name>
<filter-class>com.itheima.filter.GzipFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
CharacterEncodingFilter.java
package com.itheima.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
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.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
public class CharacterEncodingFilter implements Filter {
private FilterConfig config;
public CharacterEncodingFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
String encode = "UTF-8";
String paramValue = config.getInitParameter("encode");
if(paramValue!=null){
encode =paramValue;
}
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
request.setCharacterEncoding(encode);//post提交有效
response.setCharacterEncoding(encode);//响应结果的编码
response.setContentType("text/html;charset="+encode);//告诉浏览器用什么编码,它也有上一行代码的功能
//调包
MyHttpServletRequest myrequest = new MyHttpServletRequest(request);
chain.doFilter(myrequest, response);
}
public void init(FilterConfig fConfig) throws ServletException {
this.config = fConfig;
}
//包装设计模式
public class MyHttpServletRequest extends HttpServletRequestWrapper {
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
String method = super.getMethod();//得到请求的类型 get/post
if("get".equalsIgnoreCase(method)){
try {
value = new String(value.getBytes("iso-8859-1"),super.getCharacterEncoding());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return value;
}
}
}
DirtyWordsFilter.java
package com.itheima.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.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
public class DirtyWordsFilter implements Filter {
public DirtyWordsFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//调包,这样下一层在用时,就会使用重写之后的getParameter()方法
MyHttpServletRequestDirtyWords mydirtywordsrequest= new MyHttpServletRequestDirtyWords(request);
chain.doFilter(mydirtywordsrequest, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
public class MyHttpServletRequestDirtyWords extends HttpServletRequestWrapper{
public MyHttpServletRequestDirtyWords(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String words []= {"叫兽","禽兽","FUCK"};
String oldParam = super.getParameter(name);
if(oldParam!=null)
for(String word:words){
oldParam =oldParam.replace(word, "***");//只替换脏话
}
return oldParam;
}
}
}
HtmlFilter.java
package com.itheima.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.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet Filter implementation class HtmlFilter
*/
public class HtmlFilter implements Filter {
/**
* Default constructor.
*/
public HtmlFilter() {
// 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 req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//< < > >
MyHttpServletHtmlRequest htmlRequest = new MyHttpServletHtmlRequest(request);
chain.doFilter(htmlRequest, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
public class MyHttpServletHtmlRequest extends HttpServletRequestWrapper {
public MyHttpServletHtmlRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return filter(value);
}
public String filter(String message) {
if (message == null)
return (null);
char content[] = new char[message.length()];
message.getChars(0, message.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for (int i = 0; i < content.length; i++) {
switch (content[i]) {
case ‘<‘:
result.append("<");
break;
case ‘>‘:
result.append(">");
break;
case ‘&‘:
result.append("&");
break;
case ‘"‘:
result.append(""");
break;
default:
result.append(content[i]);
}
}
return (result.toString());
}
}
}
UserRegistServlet.java
package com.itheima.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserRegistServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
//name = new String(name.getBytes("iso-8859-1"),"UTF-8");
System.out.println(name);
response.getWriter().write(name);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
addCustomer.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>客户注册</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/CustomerRegistServlet" method="post">
<input name="name"/><input type="submit" value="保存"/>
</form>
</body>
</html>
addUser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用户注册</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!--
<link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
-->
</head>
<body>
<form action="${pageContext.request.contextPath}/servlet/UserRegistServlet" method="post">
<input name="name"/><input type="submit" value="保存"/>
</form>
</body>
</html>
总结:
CharacterEncodingFilter.java
DirtyWordsFilter.java
HtmlFilter.java
都是使用了包装设计模式:在filter里使用了自定义的内部类,利用子父类的关系把request发给继承了子类的自定义类去进行包装增强功能,并返回一个实现了自己新的功能方法的返回给新的自定义类,最后放行的时候就返回新的包装后的对象。提供给servlet去使用。