本文共 5931 字,大约阅读时间需要 19 分钟。
提前阅读:
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■↓↓↓↓↓↓↓↓↓ Servlet过滤器 ↓↓↓↓↓↓↓↓↓↓↓■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
Servlet过滤器; 为什么要有? 如果有N多个Servlet要执行一样的操作的时候, 没有必须要在所有的Servlet都进行相同的代码操作, 那样会造成代码冗余性变大,也会使得开发效率低下。 是什么? 是Servlet中的三大组件之一,是由SUN公司制定的标准/接口 过滤器的本质就是一个java应用中的一个对象而已。。。。。。 作用; 过滤器可以在一个请求资源【动态或静态】的资源时, 或者是在响应资源时,执行过滤任务【代码逻辑】 ◆ 因为是在Serlvet业务逻辑之前执行的, 所以可以进行一些关键的操作, 用于提高用户体验,以及提高开发效率 因为没有必须都写在所有要使用 这个业务逻辑代码的Servlet中写, 只是需要把对应的Servlet和 服务器进行关联 如;1.在请求资源和响应资源的时候所有Servlet的编码集 2.用户统一登录的权限,就是只有用户登录了才可以进行访问某些资源。 特点; 需要在web.xml文件中配置 运行在web服务器中 ◆在进行Servlet业务逻辑的之前执行的 -----------------------------------↓↓↓↓↓↓↓Servlet过滤器 —— 开发步骤↓↓↓↓↓↓↓------------------------------------------------ Serlvet过滤器开发步骤; 1.编写一个自定义类,实现Filter接口 2.重写doFilter()核心过滤器方法 代码; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ } 3.在doFilter()方法写需要进行过滤的业务逻辑代码 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 4.使用FilterChain接口的doFilter方法放行 ---> (类似转发) public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ chain.doFilter(request,response); } 5.在web.xml文件中配置过滤器--------------------------------↓↓↓↓↓↓↓Servlet过滤器 —— 运行过程↓↓↓↓↓↓↓------------------------------------------------
过滤器运行过程; 1.在服务器启动加载所有的*.tld文件和web.xml文件的时候 就创建了一个过滤器的对象,而且只创建一次,所以是一个单例的 方法; 会调用Filter接口的init()方法 ---> Filter接口 可以通过这个方法的FilterConfig对象获取到 web.xml文件的<init-param>信息 2.当用户访问与过滤器关联的Servlet的时候会先到过滤器, 的doFilter方法执行过滤器的业务逻辑代码, 在这时是否允许访问Servlet则是由过滤器代码决定的。 a)过滤器逻辑代码通过了允许访问对应的Servlet,---> FiilterChain接口 那么则会调用FiilterChain接口的doFilter方法, 将用户访问的request和response请求带到对应的Servler中 ◆◆ b)当访问了Servlet资源之后要将响应信息返回, 给用户不是直接返回的,而是通过过滤器返回的 方法; 访问与过滤器关联的Servlet的时候都会调用doFilter方法 ---> Filter接口 3.过滤器对象销毁,或者是服务器正常关闭 方法; destroy() ◆◆◆◆◆注;过滤器对象是一个单例的, 过滤器也是一个双向过滤, ◆ 因为请求和响应都需要经过过滤器。--------------------------------↓↓↓↓↓↓↓Servlet过滤器 —— 过滤器链↓↓↓↓↓↓↓------------------------------------------------
过滤器链; 某一个Servlet资源被多个过滤器进行过滤叫做过滤器链。 FilterChain;是一个过滤器类的主要对象 使用执行下一个过滤器 如果当前的过滤器是最后一个过滤器则执行目标资源 也是通过这个接口的doFilter()方法把用户的请求信息和响应信息返回给用户端 --------------------------------↓↓↓↓↓↓↓Servlet过滤器 —— Web文件配置↓↓↓↓↓↓↓------------------------------------------------ 过滤器web.xml文件配置; <filter> <filter-name>自定义标识唯一名</filter-name> <filter-class>过滤器绝对路径【包名+类名】</filter-class> <〓 <init-param>是设置过滤器的初始化过滤参数的 〓> <init-param> <param-name>参数名</param-name> <param-value>参数值</param-value> </init-param> </filter> <filter-mapping> <filter-name>对应的唯一标识名</filter-name> <〓-- 1、url-pattern;是指定需要过滤的serlvet路径 精确过滤;/x ---> http://localhost:8080/xx/xx 模糊过滤;/* ---> http://localhost:8080/xx/yy /包名/* ---> http://localhost:8080/包名/xx * ---> http://localhost:8080/xx/xx *.do ---> http://localhost:8080/xx/xx.do *.html 。。。 ◆◆◆注;在进行模糊过滤查询的时候, 需要是符合url-pattern的语法的时候, 则会执行过滤器,无论是否存在的Servlet 【个人看法】建议不使用模糊过滤,即便写100个url-pattern, 因为耗费服务器资源,过滤器是在服务器执行的 2、servlet-name;是可以根据对应的Servlet在web.xml配置 的name属性值进行关联 3、dispatcher;是设置要进行过滤的请求类型 a_)request是设置过滤请求信息 ---> 默认 b_)include是设置过滤包含信息 c_)forword是设置过滤转发信息 d_)error是设置过滤错误信息 ---> 触发<error-page>标签 --〓> <url-pattern>/过滤的Servlet</url-pattern> <servlet-name>对应的servlet配置名</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>FORWOED</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <〓-- 这个是发生错误的时候,触发的 --〓> <error-page> <error-code>500</error-code> ---> 设置发生错误的码号 <location>/地址</location> ---> 发生错误要进行跳转的地址 </error-page> ■■■■■■■■■■■■■■■■■■■--------------------------↓↓↓↓↓↓↓ 装饰者模式 ↓↓↓↓↓↓↓-------------------------■■■■■■■■■■■■■■■■■■■■ 装饰者模式; 是用于对一个类的特定方法进行增强的, 而这个类只会是实体类,基本不会是抽象类, 因为如果是抽象类则需要实现所有的抽象方法, 也违反了装饰者模式的概念,是对特定的方法增强。 反射和装饰者模式的区别; 反射是用于获取到一个类的方法的访问权, 从而操作这个类的方法,甚至改变这个方法的输出内容, 而反射可以是抽象类等。 装饰者模式只是做一个在原有的基础上进行的增强。 开发所需; 1.被装饰者,需被增强的类 2.装饰者,增强这个方法的类 3.装饰方法,需被增强的方法 开发步骤; 1.编写一个装饰类继承被装饰类【非find】 2.在装饰类中声明一个被装饰类的变量 3.在装饰类的构造方法的形参要求传入一个被装饰类的对象 4.对需要被装饰的方法进行重写 -----------------------------------↓↓↓↓↓↓↓装饰者模式 —— 案例 —— 过滤器链↓↓↓↓↓↓↓------------------------------------------------ 编写一个请求统一编码集的方法。。。。。。 //继承HttpServletRequestWrapper类 public class MyTrimmer extends HttpServletRequestWrapper {//声明一个这个被装饰类的成员变量
private HttpServletRequest request; public MyTrimmer(HttpServletRequest request) { super(request); //获取到这传进来的对象 this.request = request; } /** * 重写被装饰类需要增强功能的getParameter方法 */ @Override public String getParameter(String name) { try { //判断这个提交是否是GET提交 if("GET".equals(request.getMethod())){ //获取到这个参数的值,进行转码操作,因为Get提交默认都是ISO-8859-1 String temp = new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");//返回这个转了码的参数值
return temp; } //否则则是Post提交则设置编码集为UTF-8 request.setCharacterEncoding("UTF-8"); //返回这个参数值 return request.getParameter(name); } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException(); } } /** * 重写这个被装饰类需要增强功能的getParameterValues方法 */ @Override public String[] getParameterValues(String name) { try{ //判断是否是Get提交的 if("GET".equals(request.getMethod())){ //获取到这参数名的所有值 String[] arr = request.getParameterValues(name); //遍历这个数组 for (int i = 0; i < arr.length; i++) { //转换这个数组的每一个元素的编码集 arr[i] = new String(arr[i].getBytes("ISO-8859-1"),"UTF-8"); } //返回这个转换好编码集元素的数组 return arr; } //否则是Post提交则直接设置编码集 request.setCharacterEncoding("UTF-8"); //返回这个原有的数据 return request.getParameterValues(name); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); } } /** * 重写这个被装饰类需要增强功能的getParameterMap方法 */ @Override public Map getParameterMap() { try{ //判断是否是Get提交方法 if("GET".equals(request.getMethod())){ //获取到这个参数的Map集合 Map<String,String[]> map = request.getParameterMap(); //遍历这个集合 for (Entry<String,String[]> en : map.entrySet()) { //遍历这个Entry的Value数组 for (int i = 0; i < en.getValue().length; i++) { //设置转换编码集 en.getValue()[i] = new String(en.getValue()[i].getBytes("ISO-8859-1"),"UTF-8"); } } //返回这个集合 return map; } //否则则是Post提交则直接设置编码集 request.setCharacterEncoding("UTF-8"); //返回这个集合 return request.getParameterMap(); }catch(Exception e ){ e.printStackTrace(); throw new RuntimeException(); } } }转载地址:http://wlmxi.baihongyu.com/