装饰 HttpServletRequest 对象
需求:在 HttpServletRequest 对象到达 Servlet 之前把用户输入的多余空格都去掉
情景:因为 HttpServletRequest 对象里的请求参数都实际包含在 java.util.Map 对象里,而Map是不允许修改的,所以包含在 HttpServletRequest 对象里的请求参数不能被修改
解决方案:采取 Decorator(装饰器)模式
为何使用装饰模式增强HttpServletRequest(为何使用HttpServletRequestWrapper )? 先看下面实现敏感内容处理的过滤器的实现:
package org.rabbitx.web.javaweb.filter.example; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.rabbitx.web.javaweb.filter.HttpFilter; import org.rabbitx.web.javaweb.filter.MyHttpServletRequest; public class ContentFilter extends HttpFilter{ public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { //1. 获取请求 content 参数的值 String content = request.getParameter("content"); //2. 把其中 fuck, shit 等字符串替换换为 **** if(content.contains(" fuck ")){ //ServletRequest, HttpServletRequest 中并没有提供诸如 setParameter(paramName, paramValue) //类似于这样的方法. //目标: 改变 HttpServletRequest 的 getParameter(String) 方法的行为: 若该方法的返回值中 //包含 " fuck ", 则替换为 " **** " } //3. 转到目标页面 filterChain.doFilter(req, response); } }
实现中发现一个问题,ServletRequest, HttpServletRequest 中并没有提供诸如 setParameter(paramName, paramValue)类似于这样的方法.所以我们只能尝试重写getParameter(String)方法:
1. 若对于一个类的方法不满意, 需要进行重写, 最常见的方式是, 继承父类, 重写方法. 若实现则需要继承 org.apache.catalina.connector.RequestFacade, 而这仅是 Tomcat服务器的实现, 若更换服务器, 该方案将无法使用. 与具体容器耦合,没有移植性.
2. 直接写一个 HttpServletRequest 接口的实现类: 很麻烦,而且也需要和具体的容器相耦合.
发现上面两种方法都不理想,来看下第三种方法:
装饰目前的 HttpServletRequest 对象: 装饰其 getParameter 方法, 而其他方法还和其实现相同.创建一个类, 该类实现 HttpServletRequest 接口, 把当前 doFilter 中的 request 传入到该类中, 作为其成员变量, 使用该成员变量去实现接口的全部方法. 对无需要增强或改变的方法,可以在装饰类中重写。
具体实现
package org.rabbitx.web.javaweb.filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class MyHttpServletRequest extends HttpServletRequestWrapper{ public MyHttpServletRequest(HttpServletRequest request) { super(request); } @Override public String getParameter(String name) { String val = super.getParameter(name); if(val != null && val.contains(" fuck ")){ val = val.replace("fuck", "****"); } return val; } }
package org.rabbitx.web.javaweb.filter.example; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.rabbitx.web.javaweb.filter.HttpFilter; import org.rabbitx.web.javaweb.filter.MyHttpServletRequest; public class ContentFilter extends HttpFilter{ public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { //1. 获取请求 content 参数的值 String content = request.getParameter("content"); //此处为实现 HttpServletRequest req = new MyHttpServletRequest(request); //3. 转到目标页面 filterChain.doFilter(req, response); } }
HttpServletWrapper 和 HttpServletResponseWrapper
1). Servlet API 中提供了一个 HttpServletRequestWrapper 类来包装原始的 request 对象,
HttpServletRequestWrapper 类实现了 HttpServletRequest 接口中的所有方法,
这些方法的内部实现都是仅仅调用了一下所包装的的 request 对象的对应方法
//包装类实现 ServletRequest 接口.
public class ServletRequestWrapper implements ServletRequest {
//被包装的那个 ServletRequest 对象
private ServletRequest request;
//构造器传入 ServletRequest 实现类对象
public ServletRequestWrapper(ServletRequest request) {
if (request == null) {
throw new IllegalArgumentException("Request cannot be null");
}
this.request = request;
}
//具体实现 ServletRequest 的方法: 调用被包装的那个成员变量的方法实现。
public Object getAttribute(String name) {
return this.request.getAttribute(name);
}
public Enumeration getAttributeNames() {
return this.request.getAttributeNames();
}
//...
}
相类似 Servlet API 也提供了一个 HttpServletResponseWrapper 类来包装原始的 response 对象
2). 作用: 用于对 HttpServletRequest 或 HttpServletResponse 的某一个方法进行修改或增强.
public class MyHttpServletRequest extends HttpServletRequestWrapper{
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String val = super.getParameter(name);
if(val != null && val.contains(" fuck ")){
val = val.replace("fuck", "****");
}
return val;
}
}
3). 使用: 在 Filter 中, 利用 MyHttpServletRequest 替换传入的 HttpServletRequest
HttpServletRequest req = new MyHttpServletRequest(request);
filterChain.doFilter(req, response);
此时到达目标 Servlet 或 JSP 的 HttpServletRequest 实际上是 MyHttpServletRequest
Decorator 模式
因为继承的关系,当需要改变某个对象的行为时,只须扩展这个对象所属的类并重写其有关的方法就可以达到目的。但是,当想要改变其行为的对象是由应用程序里的另一个子系统(例如:一个对象工厂或是一个Servlet 容器)负责构造,继承机制将无能为力
Decorator 模式----情景
已知:Messager 类的定义(可以从它派生处一个之类);Messager 对象总是来自一个对象工厂(MessagerFactory),该工厂可以对它创建的每一个 Messager 对象进行初始化----通过调用 getMessage() 方法而获得的 message 属性也不例外(即不能对 Messager 对象进行初始化)
假设:需要使用 Messager 类的 getMessage() 方法。有一个Util的使用工具类,该类中有如下方法:
public static void broadcast(Message messager){
System.out.println(messager.getMessage());
}
Decorator 模式----需求,方案
需求:让 broadcast 方法打印的字母都是大写字母
方案:从 Messager 类派生一个子类,把子类对象传递给 broadcast 方法。因为只有对象工厂知道如何初始化 Messager 对象,所以该方案无意义
Decorator 模式:
从 Messager 类派生一个子类 MessagerDecorator,把子类对象传递给 broadcast 方法
在 MessagerDecorator 类里实现构造器:接受一个 Messager 对象作为输入参数,而这个 Messager 就是想要装饰的对象:public MessagerDecorator(Messager messager)
重写 getMessage 方法,让重写的方法用大写字母来返回 message 属性
HttpServletRequestWrapper 类
Servlet API 中提供了一个 HttpServletRequestWrapper 类来包装原始的 request 对象, HttpServletRequestWrapper 类实现了 HttpServletRequest 接口中的所有方法,这些方法的内部实现都是仅仅调用了一下所包装的的 request 对象的对应方法
相类似 Servlet API 也提供了一个 HttpServletResponseWrapper 类来包装原始的 response 对象
相关推荐
HttpServletRequest 对象是 JavaWeb 开发中最常用的对象之一,它提供了一系列方法来获取 HTTP 请求的相关信息。在本文中,我们将详细介绍 HttpServletRequest 对象的使用方法和应用场景。 获取请求行信息的方法 在...
在JavaWeb开发中,`HttpServletRequest`对象和会话管理是两个关键的概念,它们构成了Web应用程序交互的基础。这次我们将深入探讨这两个主题,特别是关于Cookie的使用。 `HttpServletRequest`对象是Servlet API的一...
JavaWeb04-内置对象与include指令.rar JavaWeb05-购物车.rar JavaWeb06-Servlet.rar JavaWeb07-javaWeb模式.rar JavaWeb08-DBUtil.rar JavaWeb09-EL与JSTL.rar JavaWeb10-分页应用.rar JavaWeb11-图片验证码.rar ...
JavaWeb开发技术-HttpServletResponse对象 JavaWeb开发技术中,HttpServletResponse对象是Servlet容器提供的一个对象,用于向客户端发送响应信息。在每次Servlet请求时,Web服务器都会创建一个HttpServletResponse...
JavaWeb课程实验主要聚焦在JSP(JavaServer Pages)技术的应用,特别是JSP的内置对象。JSP是一种基于Java的动态网页技术,它允许开发者在HTML代码中嵌入Java代码,使得网页具备处理服务器端逻辑的能力。这次实验的...
JavaWeb04-内置对象与include指令.rar JavaWeb05-购物车.rar JavaWeb06-Servlet.rar JavaWeb07-javaWeb模式.rar JavaWeb08-DBUtil.rar JavaWeb09-EL与JSTL.rar JavaWeb10-分页应用.rar JavaWeb11-图片验证码.rar ...
- 在Servlet或JSP脚本中,使用`HttpServletRequest`的`getSession()`方法获取`session`对象,然后进行数据的读写操作。 - 最后,将处理后的数据通过`request.setAttribute()`传递回JSP页面,用EL(Expression ...
本资源摘要信息将详细阐述北大青鸟javaweb相关知识点,涵盖JSP隐式对象、输入/输出对象、作用域通信对象、Servlet相关对象、错误对象等内容。 JSP隐式对象 JSP隐式对象是Web容器加载的一组类,不需要使用“new”...
在JavaWeb中,"四种属性范围 内置对象.pdf"可能会详细讲解四大作用域(page、request、session、application)以及它们对应的内置对象,如PageContext、HttpServletRequest、HttpSession和ServletContext。这些对象...
javaweb传值对象.xlsjavaweb传值对象.xlsjavaweb传值对象.xls
在JavaWeb_07这个压缩包中,很可能包含了实现上述功能的示例代码,你可以通过查看这些代码来加深对`HttpServlet`和`HttpServletRequest`的理解。这些代码可能包括了创建自定义Servlet、覆盖处理方法、获取和处理请求...
JavaWeb04-内置对象与include指令.rar JavaWeb05-购物车.rar JavaWeb06-Servlet.rar JavaWeb07-javaWeb模式.rar JavaWeb08-DBUtil.rar JavaWeb09-EL与JSTL.rar JavaWeb10-分页应用.rar JavaWeb11-图片验证码.rar ...
JavaWeb04-内置对象与include指令.rar JavaWeb05-购物车.rar JavaWeb06-Servlet.rar JavaWeb07-javaWeb模式.rar JavaWeb08-DBUtil.rar JavaWeb09-EL与JSTL.rar JavaWeb10-分页应用.rar JavaWeb11-图片验证码.rar ...
JavaWeb技术是构建互联网应用程序的一种强大工具,它基于Java平台,为开发动态、交互式的Web应用提供了丰富的功能。本讲义将重点介绍JavaWeb的基本概念、核心组件以及常用框架。 一、JavaWeb应用概述 JavaWeb应用是...
李兴华javaweb之JSP基础语法(上)笔记
javaWEB 人力资源管理系统源码javaWEB 人力资源管理系统源码javaWEB 人力资源管理系统源码javaWEB 人力资源管理系统源码javaWEB 人力资源管理系统源码javaWEB 人力资源管理系统源码javaWEB 人力资源管理系统源码...
JavaWeb04-内置对象与include指令.rar JavaWeb05-购物车.rar JavaWeb06-Servlet.rar JavaWeb07-javaWeb模式.rar JavaWeb08-DBUtil.rar JavaWeb09-EL与JSTL.rar JavaWeb10-分页应用.rar JavaWeb11-图片验证码.rar ...
【JavaWeb程序设计入门课件Cookie对象共6页.pdf.zip】是一个压缩文件,其中包含了关于JavaWeb开发中Cookie对象的基础教程。Cookie是Web应用程序中用于存储客户端信息的一种机制,它是HTTP协议无状态特性的一种补充。...
RequestDispatcher 对象在 JavaWeb 开发中的应用 RequestDispatcher 对象是 JavaWeb 开发中的一种重要对象,它允许开发者在服务器端将请求从一个资源传递给另一个资源,以实现更灵活的请求处理机制。在本文中,我们...