目录
一、listener(了解) 监听器 filter(★) 过滤器
2-8-1 filterConfig:(了解)同 servletConfig
3-1-3 加强request.getParameter(String key)
3-1-4 最后将包装过的request对象(MyRequest)传递给servlet即可
-
一、listener(了解) 监听器 filter(★) 过滤器
-
1-1 listener
监听器
作用:
监听web中中的域对象 ServletContext ServletRequest HttpSession
-
1-1-1 监听内容
监听三个对象的创建和销毁(生命周期)
监听三个对象属性的变化
监听session中javabean的状态
注意:listener全部是接口 (规范)
-
1-2 监听三个对象的创建和销毁
ServletContextListener
ServletRequestListener
HttpSessionListener
-
1-3 监听三个对象属性的变化
ServletContextAttributeListener
ServletRequestAttributeListener
HttpSessionAttributeListener
-
1-4 监听session中javabean的状态
HttpSessionActivationListener(钝化和活化)写入磁盘,写进内存
HttpSessionBindingListener(绑定和解绑)是否放入session中
-
1-5 使用步骤
- 编写一个类 实现接口
- 重写方法
- 编写配置文件(大部分都是)
-
1-6 演示各个监听器
-
1-6-1 监听三个对象的创建和销毁
- ServletContextListener
创建:服务器启动的时候,会为每一个项目都创建一个servletContext
销毁:服务器关闭的时候,或者项目被移除的时候public class MyServletContextLis implements ServletContextListener{ @Override public void contextInitialized(ServletContextEvent sce) { //创建操作 System.out.println("servletcontext创建了"); } @Override public void contextDestroyed(ServletContextEvent sce) { //销毁操作 System.out.println("servletcontext销毁了."); } }
<listener> <listener-class>com.itheima.a_listener.a_hello_servletcontext.MyServletContextLis</listener-class> </listener>
以后用来加载配置文件(项目初始化操作)(spring框架内)
- ServletRequestListener <!-- 创建一个jsp页面,每次访问,为一次请求-->
创建:请求来的时候
销毁:响应生成的时候public class MyRequestLis implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("请求已销毁~~~"); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("请求创建了~~~"); } }
<!-- 创建一个jsp页面,每次访问,为一次请求--> <body> request声明周期的测试 </body>
<listener> <listener-class>com.itheima.a_listener.b_life.MyRequestLis</listener-class> </listener>
- HttpSessionListener
创建:
java中第一次调用request.getSession的时候
jsp访问的时候创建(jsp的内置对象,访问就创建)
销毁:
三种情况:
session超时
手动销毁session
服务器非正常关闭public class MySessionLis implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("session 创建了..........."); } @Override public void sessionDestroyed(HttpSessionEvent se) { // TODO Auto-generated method stub System.out.println("session 销毁了~~~~~~~~"); } }
<body> <% session.invalidate(); %> session已销毁! </body>
-
1-6-2 监听三个对象属性的变化(添加 替换 删除)
ServletContextAttributeListener
ServletRequestAttributeListener
HttpSessionAttributeListener<body><!--设置属性--> <% application.setAttribute("username", "tom"); %> </body> <!--修改属性--> <body> <% application.setAttribute("username", "tom"); %> </body> <!--移除属性--> <body> <% application.removeAttribute("username"); %> </body> xml <listener> <listener-class>com.itheima.a_listener.c_attr.MyServletContextAttrLis</listener-class> </listener>
public class MyServletContextAttrLis implements ServletContextAttributeListener { @Override //添加 public void attributeAdded(ServletContextAttributeEvent scab) { System.out.println("在serveltcontext中添加了一个属性,属性为:"+scab.getName()); } @Override //移除 public void attributeRemoved(ServletContextAttributeEvent scab) { System.out.println("在serveltcontext中移除了一个属性,属性为:"+scab.getName()); } @Override //替换 public void attributeReplaced(ServletContextAttributeEvent scab) { System.out.println("在serveltcontext中替换了一个属性,属性为:"+scab.getName()); } }
-
1-6-3 监听session中javabean的状态
注意:这两个接口需要javabean实现.是让javabean感知到自己的状态
HttpSessionBindingListener(绑定和解绑)
检测java是否添加到session或者从session中移除<body> 将person对象添加到session中 <% session.setAttribute("p", new Person(1,"tom")); %> </body> <body> 将person对象从session中移除 <% session.removeAttribute("p"); %> </body>
public class Person implements HttpSessionBindingListener{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person() { } public Person(int id, String name) { this.id = id; this.name = name; } @Override //绑定到了session中 public void valueBound(HttpSessionBindingEvent event) { System.out.println("person对象绑定到了session中"); } @Override //从session中移除 public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("person对象从session中移除了~~"); } }
HttpSessionActivationListener(钝化和活化)钝化:javabean从session中序列化(持久化)到磁盘上
活化:javabean从磁盘上加载到了session中
可以通过配置文件修改javabean什么时候钝化
修改一个项目
只需要在项目下/meta-info创建一个context.xml
内容如下:
<Context>
<!--
maxIdleSwap :1分钟 如果session不使用就会序列化到硬盘.
directory :itheima 序列化到硬盘的文件存放的位置.
-->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="itheima"/>
</Manager>
</Context><body> 将person和person2对象添加到session中 <% /* session.setAttribute("p", new Person(1,"tom")); */ session.setAttribute("p2", new Person2(2,"jack")); %> </body> <body> ${p2.name } </body> <?xml version="1.0" encoding="UTF-8"?> <Context> <!-- maxIdleSwap :1分钟 如果session不使用就会序列化到硬盘. directory :itheima 序列化到硬盘的文件存放的位置. --> <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"> <Store className="org.apache.catalina.session.FileStore" directory="itheima" /> </Manager> </Context>
public class Person2 implements HttpSessionActivationListener,Serializable{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person2() { } public Person2(int id, String name) { this.id = id; this.name = name; } @Override //钝化 public void sessionWillPassivate(HttpSessionEvent se) { System.out.println("person对象 写入磁盘 钝化"); } @Override //活化 public void sessionDidActivate(HttpSessionEvent se) { System.out.println("person对象 活化了~~~"); } }
-
二、 案例1-自动登录
需求:
登录的时候,勾选自动登录,登录成功之后,关闭浏览器,下一次访问网站的时候完成登录操作(自动登录).
技术分析:
filter
cookie
-
2-1 filter:过滤器
过滤请求和响应
作用:
- 自动登录.
- 统一编码.
- 过滤关键字
....
Filter是一个接口
-
2-2 编写filter步骤
-
2-2-1 编写一个类
a.实现filter接口
b.重写方法public class HelloFilter 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("过滤器 hello filter 收到了请求~~~"); //放行 chain.doFilter(request, response); System.out.println("过滤器 hello filte 收到了响应~~~"); } @Override public void destroy() { } }
/** * filter 入门 */ public class Demo1Servlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("demo1 servlet执行了"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
-
2-2-2 编写配置文件
a.注册filter
b.绑定路径<filter> <filter-name>HelloFilter</filter-name> <filter-class>com.itheima.b_filter.d_hello.HelloFilter</filter-class> </filter> <filter-mapping> <filter-name>HelloFilter</filter-name> <url-pattern>/demo1</url-pattern> </filter-mapping> <servlet> <description></description> <display-name>Demo1Servlet</display-name> <servlet-name>Demo1Servlet</servlet-name> <servlet-class>com.itheima.b_filter.d_hello.Demo1Servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Demo1Servlet</servlet-name> <url-pattern>/demo1</url-pattern> </servlet-mapping>
-
2-2-3 测试
<a href="${pageContext.request.contextPath }/demo1">filter入门</a><br>
-
2-3 Filter接口的方法
- init(FilterConfig config):初始化操作
- doFilter(ServletRequest request, ServletResponse response, FilterChain chain):处理业务逻辑
//放行——执行servlet chain.doFilter(request, response);
- destroy() :销毁操作
-
2-4 filter的生命周期(了解)
filter单实例多线程
filter在服务器启动的时候 服务器创建filter 调用init方法 实现初始化操作(servlet 是默认第一次访问的时候)
请求来的时候,创建一个线程 根据路径调用dofilter 执行业务逻辑
当filter被移除的时候或者服务器正常关闭的时候 调用destory方法 执行销毁操作.<a href="${pageContext.request.contextPath }/demo2">filter生命周期</a><br> <filter> <filter-name>LifeFilter</filter-name> <filter-class>com.itheima.b_filter.e_life.LifeFilter</filter-class> </filter> <filter-mapping> <filter-name>LifeFilter</filter-name> <url-pattern>/demo2</url-pattern> </filter-mapping>
public class LifeFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("filter 55555555555555555555555"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("filter 6666666666666666666666666666"); chain.doFilter(request, response); } @Override public void destroy() { System.out.println("filter 444444444444444444444444"); } }
-
2-5 FilterChain:过滤链
通过chain的dofilter方法,可以将请求放行到下一个过滤器,直到最后一个过滤器放行才可以访问到servlet|jsp
doFilter()放行方法
-
2-6 ★url-pattern配置
3种
完全匹配 必须以"/" 开始 例如: /a/b
目录匹配 必须以"/" 开始 以"*"结束 例如:/a/b/*
后缀名匹配 以"*."开始 以字符结束 例如 : *.jsp *.do *.action
例如:
afilter 路径 /*
bFilter 路径 /demo4
★一个资源有可能被多个过滤器匹配成功,多个过滤器的执行顺序是按照web.xml中filter-mapping的顺序执行的<a href="${pageContext.request.contextPath }/a/b/demo3">filterchain执行顺序</a><br> <filter> <filter-name>AFilter</filter-name> <filter-class>com.itheima.b_filter.f_chain.AFilter</filter-class> </filter> <filter-mapping> <filter-name>AFilter</filter-name> <url-pattern>/a/b/*</url-pattern> </filter-mapping> <filter> <filter-name>BFilter</filter-name> <filter-class>com.itheima.b_filter.f_chain.BFilter</filter-class> </filter> <filter-mapping> <filter-name>BFilter</filter-name> <url-pattern>/a/*</url-pattern> </filter-mapping>
public class AFilter 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 { System.out.println("afilter 收到请求"); //放行 chain.doFilter(request, response); System.out.println("afilter 收到响应"); } @Override public void destroy() { // TODO Auto-generated method stub } }
public class BFilter 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 { System.out.println("bfilter 收到请求"); //放行 chain.doFilter(request, response); System.out.println("bfilter 收到响应"); } @Override public void destroy() { // TODO Auto-generated method stub } }
public class Demo3Servlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("demo3 servlet 执行了!!!"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
-
2-7 步骤分析
-
2-7-1 数据库和表
create database day16;
use day16;
create table user(
id int primary key auto_increment,
username varchar(20),
password varchar(20)
);
insert into user values(null,'tom','123');
-
2-7-2 web项目
jar包 工具类 配置文件
-
2-7-3 新建一个登录页面 表单
<body>
<form method="post" action="${pageContext.request.contextPath }/login">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username" ></td>
</tr>
<tr>
<td>密码</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td colspan="1"><input type="checkbox" name="saveName" value="ok">记住用户名</td>
<td colspan="1"><input type="checkbox" name="autoLogin" value="ok">自动登录</td>
</tr>
<tr>
<td colspan="2"><input type="submit"></td>
</tr>
</table>
</form>
<script type="text/javascript">
onload=function(){
var s="${cookie.savename.value }";
s=decodeURI(s);//js全局对象中的解码
alert(s);
//将解码后的用户名付给username的文本框
document.getElementsByName("username")[0].value=s;
}
</script>
</body>
-
2-7-4 表单提交 loginservlet
接受用户名和密码
调用service完成登录操作,返回值User
判断user是否为空
若不为空,将user放入session中
判断是否勾选了自动登录
若勾选了:
需要将用户名和密码写回浏览器/** *登录 */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0.设置编码 request.setCharacterEncoding("utf-8"); //1.获取用户名和密码 String username=request.getParameter("username"); String password=request.getParameter("password"); //2.调用service' User user=null; try { user = new UserService().login(username,password); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } //3.判断user是否为空 if(user==null){ request.setAttribute("msg", "用户名和密码不匹配"); request.getRequestDispatcher("/login.jsp").forward(request, response); return; }else{ //若不为空,将user放入session中 request.getSession().setAttribute("user", user); //判断是否勾选了自动登录 若勾选了需要将用户名和密码放入cookie中, 写回浏览器 if(Constant.IS_AUTO_LOGIN.equals(request.getParameter("autoLogin"))){ //创建cookie 注意中文 Cookie c=new Cookie("autologin", username+"-"+password); c.setMaxAge(3600); c.setPath(request.getContextPath()+"/"); response.addCookie(c); } //判断是否勾选了记住用户名 若勾选了需要将用户名放入cookie中 写回浏览器 if(Constant.IS_SAVE_NAME.equals(request.getParameter("saveName"))){ //创建cookie Cookie c=new Cookie("savename", URLEncoder.encode(username, "utf-8")); c.setMaxAge(3600); c.setPath(request.getContextPath()+"/"); response.addCookie(c); } //页面重定向 response.sendRedirect(request.getContextPath()+"/success.jsp"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
2-7-5 下次访问网站的时候
过滤器拦截任意请求
判断有无指定的cookie
有cookie,获取用户名和密码
调用service完成登录操作,返回user
当user不为空的时候将user放入session中.
当我们换用jack登录的时候发现登录的是tom
自动登录只需要登录一次:当session中没有用户的时候
访问有些资源是不需要自动登录的(和登录还有注册相关的资源)
修改filter的逻辑:
首先判断session中是否有user
若没有 并且访问的路径不是和登录注册相关的时候
才去获取指定的cooki使用了request 域,必须使用 请求转发
其他任意,
但是访问站外资源,必须使用重定向
<filter> <filter-name>AutoLoginFilter</filter-name> <filter-class>com.itheima.web.filter.AutoLoginFilter</filter-class> </filter> <filter-mapping> <filter-name>AutoLoginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
public class AutoLoginFilter implements Filter{ @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //1.强转 HttpServletRequest request =(HttpServletRequest) req; HttpServletResponse response =(HttpServletResponse) resp; //2.完成自动登录 //2.1 判断session中有无登录登录用户 没有的话继续自动登录 User user=(User) request.getSession().getAttribute("user"); if(user==null){ //没有用户 需要自动登录 //2.2 判断访问的资源是否和登录注册相关,若相关则不需要自动登录 String path = request.getRequestURI();// /day1601/xxx if(!path.contains("/login")){ //2.3获取指定的cookie Cookie c = CookUtils.getCookieByName("autologin", request.getCookies()); //判断cookie是否为空 //若不为空 获取值(username和passowrd) 调用serivce完成登录 判断user是否为空 不为空 放入session if(c!=null){ String username=c.getValue().split("-")[0]; String password=c.getValue().split("-")[1]; //调用serivce完成登录 //user=null; try { user = new UserService().login(username, password); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(user!=null){ //将user放入session中 request.getSession().setAttribute("user", user); } } } } //3.放行 chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }
-
2-7-6 扩展-cookie中写入中文
//创建cookie 时将数据编码
Cookie c=new Cookie("savename", URLEncoder.encode(username, "utf-8"));
页面获取中文需要解码
<script type="text/javascript">
onload=function(){
var s="${cookie.savename.value }";
s=decodeURI(s);//js全局对象中的解码
alert(s);
//将解码后的用户名付给username的文本框
document.getElementsByName("username")[0].value=s;
}
</script>
-
2-8 filter总结
-
2-8-1 filterConfig:(了解)同 servletConfig
过滤器的配置对象
作用:
获取全局管理者
获取当前filter的名称
获取当前filter的初始化参数
-
2-8-2 filter-mapping的子标签(理解)
servlet-name:匹配那个servlet ,值写的是serlvet标签中servlet-name的值
建议:不要在一个filter中重复的匹配servlet(会执行两次过滤器)
例如: serlvet的url-pattern为 /a/b/hello serlvetname:HelloServlet
如果filter中的url-pattern /*(包含下面的 匹配)
最好不要在写 servlet-name:HelloServlet<filter> <filter-name>Name4ServletFilter</filter-name> <filter-class>com.itheima.b_filter.g_servletname.Name4ServletFilter</filter-class> </filter> <!--拦截 Demo11Servlet--> <filter-mapping> <filter-name>Name4ServletFilter</filter-name> <servlet-name>Demo11Servlet</servlet-name> </filter-mapping>
dispatcher:(可以出现任意次)
匹配哪种请求
默认的是REQUEST,一旦显式的写出来哪种请求,默认就不起作用了
理解
REQUEST:从浏览器发送过来的请求(默认) 理解(请求转发的内容不拦截)
FORWARD:转发过来的请求 理解<filter> <filter-name>DispatcherFilter</filter-name> <filter-class>com.itheima.b_filter.h_dispather.DispatcherFilter</filter-class> </filter> <filter-mapping> <filter-name>DispatcherFilter</filter-name> <url-pattern>/e/*</url-pattern> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping>
了解
ERROR:因服务器错误而发送过来的请求<body> 亲,不好意思,你访问页面不存在~~ </body> <error-page> <error-code>404</error-code> <location>/404.jsp</location> </error-page>
INCLUDE:包含过来的请求
-
三、案例2-统一字符编码
需求:
以前我们开发的时候若有参数,第一步都是设置编码,才不会出现乱码,通过过滤器设置,到servlet或者jsp上的时候已经没有乱码问题
技术分析:
filter 配置路径/* 过滤器的第一个位置
在filter中重写getParameter(加强)
-
3-1 步骤分析
我们只需要在filter中 对request进行加强(例如:只对request.getParameter()进行加强)
-
3-1-1 方法加强
1.继承(获取构造器)
2.装饰者模式(静态代理)
3.动态代理
-
3-1-2 装饰者书写步骤
1.要求装饰者和被装饰者实现同一个接口或者继承同一个类
2.装饰者中要有被装饰者的引用
3.对需要加强方法进行加强
4.对不需要加强的方法调用原来的方法即可
-
3-1-3 加强request.getParameter(String key)
首先请求的方式不同,处理的方式也不同
获取请求的方法
若是get请求
new String(value.getBytes("iso8859-1"),"utf-8");
若是post请求
只需要设置一句话
request.setCharacterEncoding("utf-8");public class EncodingFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //1.强转 HttpServletRequest request=(HttpServletRequest) req; HttpServletResponse response=(HttpServletResponse) resp; //2.放行 将包装过的request传递 chain.doFilter(new MyRequest(request), response); } @Override public void destroy() { // TODO Auto-generated method stub } } class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest request; public MyRequest(HttpServletRequest request) { super(request); this.request=request; } @Override public String getParameter(String name) { //获取请求方式 String m = request.getMethod(); if("get".equalsIgnoreCase(m)){ //get请求 String value = request.getParameter(name); try { return new String(value.getBytes("iso8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { } }else if("post".equalsIgnoreCase(m)){ try { request.setCharacterEncoding("utf-8"); } catch (UnsupportedEncodingException e) { } return request.getParameter(name); } return super.getParameter(name); } }
/** * Servlet implementation class LoginServlet */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取用户名和密码 String username = request.getParameter("username"); String password = request.getParameter("password"); //2.打印在控制台 System.out.println(username+"::"+password); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
3-1-4 最后将包装过的request对象(MyRequest)传递给servlet即可
//2.放行 将包装过的request传递
chain.doFilter(new MyRequest(request), response);
-
3-2 关于获取参数的方法
String getParameter(String name);// arr[0]
String[] getParameterValues(String name);// map.get(name)
Map<String,String[]> getParameterMap();/** * 统一编码 * @author Administrator * */ public class EncodingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { //1.强转 HttpServletRequest request=(HttpServletRequest) req; HttpServletResponse response=(HttpServletResponse) resp; //2.放行 chain.doFilter(new MyRequest(request), response); } @Override public void destroy() { // TODO Auto-generated method stub } } class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest request; private boolean flag=true; public MyRequest(HttpServletRequest request) { super(request); this.request=request; } @Override public String getParameter(String name) { if(name==null || name.trim().length()==0){ return null; } String[] values = getParameterValues(name); if(values==null || values.length==0){ return null; } return values[0]; } @Override /** * hobby=[eat,drink] */ public String[] getParameterValues(String name) { if(name==null || name.trim().length()==0){ return null; } Map<String, String[]> map = getParameterMap(); if(map==null || map.size()==0){ return null; } return map.get(name); } @Override /** * map{ username=[tom],password=[123],hobby=[eat,drink]} */ public Map<String,String[]> getParameterMap() { /** * 首先判断请求方式 * 若为post request.setchar...(utf-8) * 若为get 将map中的值遍历编码就可以了 */ String method = request.getMethod(); if("post".equalsIgnoreCase(method)){ try { request.setCharacterEncoding("utf-8"); return request.getParameterMap(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else if("get".equalsIgnoreCase(method)){ Map<String,String[]> map = request.getParameterMap(); if(flag){ for (String key:map.keySet()) { String[] arr = map.get(key); //继续遍历数组 for(int i=0;i<arr.length;i++){ //编码 try { arr[i]=new String(arr[i].getBytes("iso8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } flag=false; } //需要遍历map 修改value的每一个数据的编码 return map; } return super.getParameterMap(); }
-
总结
- 1 listener 监听器
监听javaweb中的三个域对象
监听三个对象的创建和销毁
ServletContextListener
ServletRequestListener
HttpSessionListener
监听三个对象属性的变化
ServletContextAttributeListener
ServletRequestAttributeListener
HttpSessionAttributeListener
监听javabean在session中的状态
注意: javabean实现的接口 不需要在web.xml中配置
HttpSessionActivationListener(javabean的活化和钝化)
HttpSessionBindingListener(添加到session中还是从session中移除)
编写步骤:
1.编写一个类 实现接口
2.编写配置文件
<listener>
<listener-class>....
</listener>
- 2 filter 接口,过滤请求和响应
编写步骤:
1.编写一个类
实现filter 重写三个方法
2.编写配置文件
注册filter 绑定路径
filter的生命周期(了解)
url-pattern配置(和servlet一样)
一个路径匹配到多个filter的时候,执行顺序有有web.xml中filter-mapping的顺序来决定的
FilterChain
必须放行才有可能到下一个Filter或者资源上