欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!
实际应用场景中,有时可能会有这样的需求:需要在请求进入应用之前,对请求进行统一处理,增加或减少到达应用的数据量,或者变换应用使用的HttpServletRequest的API,这时就可以创建一个类继承HttpServletRequestWrapper,它可以对HttpServletRequest进行再封装,然后之后的请求都会经过这个类,应用接收到的请求对象也会是这个类。
HttpServletRequestWrapper集成了ServletRequestWrapper,ServletRequestWrapper是对ServletRequest的包装,HttpServletRequestWrapper是对HttpServletRequest的包装,其实查看源码后会发现,ServletRequestWrapper和HttpServletRequestWrapper提供的API完全调用的ServletRequest和HttpServletRequest的API进行实现。在我们进行应用时,使用HttpServletRequestWrapper即可,它同时拥有ServletRequestWrapper和HttpServletRequestWrapper的功能。
ServletRequestWrapper
package javax.servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
/**
* ServletRequestWrapper提供了一个简便实现类,在对ServletRequest有改动需求的时,可以重写此类,之后Request的操作都会经过重写的类.
*/
public class ServletRequestWrapper implements ServletRequest {
/**
* ServletRequestWrapper持有ServletRequest的实例.
*/
private ServletRequest request;
/**
* 构建ServletRequestWrapper,传入ServletRequest的值.
*/
public ServletRequestWrapper(ServletRequest request) {
if (request == null) {
throw new IllegalArgumentException("Request cannot be null");
}
this.request = request;
}
/**
* 获取ServletRequest实例.
*/
public ServletRequest getRequest() {
return this.request;
}
/**
* 设置ServletRequest实例.
* @param request ServletRequest.
*/
public void setRequest(ServletRequest request) {
if (request == null) {
throw new IllegalArgumentException("Request cannot be null");
}
this.request = request;
}
/**
* 获取Servlet的属性.
*/
public Object getAttribute(String name) {
return this.request.getAttribute(name);
}
/**
* 获取所有属性枚举格式.
*/
public Enumeration getAttributeNames() {
return this.request.getAttributeNames();
}
/**
* 返回请求中输入内容的字符编码类型,如果没有定义字符编码类型就返回空值.
* @return 字符编码.
*/
public String getCharacterEncoding() {
return this.request.getCharacterEncoding();
}
/**
* 设置输入内容的字符编码类型.
* @param env 字符编码类型.
* @throws java.io.UnsupportedEncodingException .
*/
public void setCharacterEncoding(String enc) throws java.io.UnsupportedEncodingException {
this.request.setCharacterEncoding(enc);
}
/**
* 请求内容的长度,如果长度未知就返回-1.
* @return 请求内容长度.
*/
public int getContentLength() {
return this.request.getContentLength();
}
/**
* 返回请求数据体的MIME类型CONTENT-TYPE,如果类型未知返回空值.
* @return
*/
public String getContentType() {
return this.request.getContentType();
}
/**
* 返回一个输入流,使用该输入流以二进制方式读取请求正文的内容.
* javax.servlet.ServletInputStream是一个抽象类,继承自InputStream.
* @return .
* @throws IOException .
*/
public ServletInputStream getInputStream() throws IOException {
return this.request.getInputStream();
}
/**
* 根据指定参数名获取参数值.
* @param name 参数名.
* @return 参数值.
*/
public String getParameter(String name) {
return this.request.getParameter(name);
}
/**
* 获取参数的Map形式,包括所有参数.
* @return 参数Map.
*/
public Map getParameterMap() {
return this.request.getParameterMap();
}
/**
* 获取所有参数名的枚举.
* @return 参数名枚举.
*/
public Enumeration getParameterNames() {
return this.request.getParameterNames();
}
/**
* 根据指定属性名获取参数值数组.
* @param name 参数名.
* @return 参数值数组.
*/
public String[] getParameterValues(String name) {
return this.request.getParameterValues(name);
}
/**
* 返回请求使用的协议信息.格式为:协议/主版本号.次版本号.例如:http/1.0.
* @return
*/
public String getProtocol() {
return this.request.getProtocol();
}
/**
* 返回请求所使用的URL的模式.若http、https等.
* @return 模式.
*/
public String getScheme() {
return this.request.getScheme();
}
/**
* 返回请求发送到的服务器的主机名.
* @return 主机名.
*/
public String getServerName() {
return this.request.getServerName();
}
/**
* 返回请求发送到的服务器的端口号.
* @return 端口号.
*/
public int getServerPort() {
return this.request.getServerPort();
}
/**
* 返回BufferedReader对象,以字节数据方式读取请求正文.
* @return .
* @throws IOException .
*/
public BufferedReader getReader() throws IOException {
return this.request.getReader();
}
/**
* 返回发送请求的客户端或最后一个代理服务器的IP地址.
* @return IP地址.
*/
public String getRemoteAddr() {
return this.request.getRemoteAddr();
}
/**
* 返回发送请求的客户端或最后一个代理服务器的主机名.
* @return 主机名.
*/
public String getRemoteHost() {
return this.request.getRemoteHost();
}
/**
* 根据传递的属性名和属性值设置Request属性.
* @param name 属性名.
* @param o 属性值.
*/
public void setAttribute(String name, Object o) {
this.request.setAttribute(name, o);
}
/**
* 从Request中删除指定的属性名对应的值.一般使用此方法.
* @param name 属性名.
*/
public void removeAttribute(String name) {
this.request.removeAttribute(name);
}
/**
* 根据客户端传递的Accept-Language对应的区域设置.
* 若客户端未指定Accept-Language,则返回服务器默认语言环境.
* @return
*/
public Locale getLocale() {
return this.request.getLocale();
}
/**
* 返回Locale对象的枚举,从首选区域开始按降序返回基于Accept-Language头的客户端可接受的区域.
* 如果客户机请求不提供Accept-Language头,此方法返回包含一个Locale的枚举,即是服务器默认语言环境对应的Locale.
* @return
*/
public Enumeration getLocales() {
return this.request.getLocales();
}
/**
* 指示是否使用安全通道(如HTTPS)发出此请求.
*/
public boolean isSecure() {
return this.request.isSecure();
}
/**
* 返回RequestDispatcher对象,作为path所定位的资源的封装.
* RequestDispatcher用于服务器请求转发.
* @param path 相对路径或绝对路径.
* @return RequestDispatcher.
*/
public RequestDispatcher getRequestDispatcher(String path) {
return this.request.getRequestDispatcher(path);
}
/**
* @deprecated
* Servlet API 2.1开始已不推荐使用此API.
* 取得文件在服务器上的绝对路径.
* @param path 相对路径.
* @return 绝对路径.
*/
public String getRealPath(String path) {
return this.request.getRealPath(path);
}
/**
* 返回发送请求的客户端或者最后一个代理服务器的IP源端口, 这个方法是在Servlet 2.4规范中新增的方法.
* @return 端口号.
*/
public int getRemotePort() {
return this.request.getRemotePort();
}
/**
* 返回接收到请求的IP接口的主机名,这个方法是在Servlet 2.4规范中新增的方法.
* @return 主机名.
*/
public String getLocalName() {
return this.request.getLocalName();
}
/**
* 返回接收到请求的网络接口的IP地址,这个方法是在Servlet 2.4规范中新增的方法.
* @return IP地址.
*/
public String getLocalAddr() {
return this.request.getLocalAddr();
}
/**
* 返回接收到请求的网络接口的IP端口号,这个方法是在Servlet 2.4规范中新增的方法.
* @return 端口号.
*/
public int getLocalPort() {
return this.request.getLocalPort();
}
}
HttpServletRequestWrapper
package javax.servlet.http;
import javax.servlet.ServletRequestWrapper;
import java.util.Enumeration;
/**
* HttpServletRequestWrapper提供了一个简便实现不了,在对HttpServletRequest有改动需求的时,可以重写此类,之后Request的操作都会经过重写的类.
*/
public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest {
/**
* Constructs.
*/
public HttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* 获取HttpServletRequest.
* @return HttpServletRequest.
*/
private HttpServletRequest _getHttpServletRequest() {
return (HttpServletRequest) super.getRequest();
}
/**
* 返回认证类型.
* 所有Servlet容器都支持basic、form、client_cert,digest不一定支持.
* 若不支持,则返回null.
*/
public String getAuthType() {
return this._getHttpServletRequest().getAuthType();
}
/**
* 获取请求中带有的Cookie信息.
*/
public Cookie[] getCookies() {
return this._getHttpServletRequest().getCookies();
}
/**
* 以长整数形式返回一个特定的请求头,该长整数代表一个Date对象.
* 该方法可以用在包含时间信息的header中,如:If-Modified-Since.
* @param name 头名称.
* @return 头值.
*/
public long getDateHeader(String name) {
return this._getHttpServletRequest().getDateHeader(name);
}
/**
* 根据指定的头名称获取头的值.
* 若存在多个,则返回第一个.
* @param name 头名称.
* @return 头值.
*/
public String getHeader(String name) {
return this._getHttpServletRequest().getHeader(name);
}
/**
* 根据指定的头名称获取头值的枚举.
* 若没有找到,则返回空的枚举.
* @param name 头名称.
* @return 头值.
*/
public Enumeration getHeaders(String name) {
return this._getHttpServletRequest().getHeaders(name);
}
/**
* 获取所有的头的枚举.
* @return 头的枚举.
*/
public Enumeration getHeaderNames() {
return this._getHttpServletRequest().getHeaderNames();
}
/**
* 根据指定头名称获取int类型的值.若未找到则返回-1,如不是int类型,则会抛出NumberFormatException异常.
* @param name 头名称.
* @return 头值.
*/
public int getIntHeader(String name) {
return this._getHttpServletRequest().getIntHeader(name);
}
/**
* 获取HTTP方法,如:GET、POST、PUT等.
* @return 方法名.
*/
public String getMethod() {
return this._getHttpServletRequest().getMethod();
}
/**
* 官网解释:
* 返回与客户端发出此请求时发送的URL相关联的任何额外路径信息.
* 额外的路径信息跟随servlet路径,但位于查询字符串之前,并以"/"字符开头.
* 例如:url-pattern配置为/demo/*,请求URL为http://localhost/Pro/demo/htm/index.html,则pathInfo为/htm/index.html.
* @return
*/
public String getPathInfo() {
return this._getHttpServletRequest().getPathInfo();
}
/**
* 返回servlet名称之后、
* 查询字符串之前的任何额外路径信息,并将其转换为实际路径.
* 与转换的CGI变量PATH U的值相同
* @return
*/
public String getPathTranslated() {
return this._getHttpServletRequest().getPathTranslated();
}
/**
* 返回项目根路径.
* 例如:url-pattern配置为/demo/*,请求URL为http://localhost/Pro/demo/htm/index.html,则contextPath为/demo.
* @return 项目根路径.
*/
public String getContextPath() {
return this._getHttpServletRequest().getContextPath();
}
/**
* 获得请求中的查询字符串,例如a=1&b=2这样的格式.
* @return 查询字符串.
*/
public String getQueryString() {
return this._getHttpServletRequest().getQueryString();
}
/**
* 如果用户已经过验证,则返回发出此请求的用户的登录信息,如果用户未经过验证,则返回 null.
* 用户名是否随每个后续请求发送取决于浏览器和验证类型,返回的值与 CGI变量REMOTE_USER的值相同.
* @return 用户信息.
*/
public String getRemoteUser() {
return this._getHttpServletRequest().getRemoteUser();
}
/**
* 返回一个 boolean值,指示指定的逻辑"角色"中是否包含经过验证的用户.
* 角色和角色成员关系可使用部署描述符定义.
* 如果用户没有经过验证,则该方法返回 false.
* @param role 角色.
* @return 已验证用户是否属于某种角色.
*/
public boolean isUserInRole(String role) {
return this._getHttpServletRequest().isUserInRole(role);
}
/**
* 返回包含当前已经过验证的用户的名称的 java.security.Principal对象.
* 如果用户没有经过验证,则该方法返回 null.
* @return java.security.Principal或null.
*/
public java.security.Principal getUserPrincipal() {
return this._getHttpServletRequest().getUserPrincipal();
}
/**
* 获取请求对应的sessionId.
* @return sessionId.会话ID.
*/
public String getRequestedSessionId() {
return this._getHttpServletRequest().getRequestedSessionId();
}
/**
* 请求URL的相对地址,包括服务器路径,不包括查询参数.
* @return 请求URL的相对地址.
*/
public String getRequestURI() {
return this._getHttpServletRequest().getRequestURI();
}
/**
* 请求的URL地址,包含协议、主机名、端口和服务器路径,但是不包括查询参数.
* @return 请求URL地址.
*/
public StringBuffer getRequestURL() {
return this._getHttpServletRequest().getRequestURL();
}
/**
* 官方解释:
* 返回此请求的URL中调用servlet的部分.
* 此路径以"/"字符开头,包含servlet名称或到servlet的路径,但不包含任何额外的路径信息或查询字符串.
* 与CGI变量SCRIPT_NAME的值相同.
* 其实真是的意思就是,在配置webx.xml或编程式配置时,配置了url-pattern,请求的URL与url-pattern的有效部分重合部分就是servletPath,
* 也可以理解为url-pattern的有效部分就是servletPath.
* 例如:url-pattern配置为/demo/*,请求URL为http://localhost/Pro/demo/htm/index.html,则servletPath为/demo.
* @return
*/
public String getServletPath() {
return this._getHttpServletRequest().getServletPath();
}
/**
* 获得请求对应的当前sesson.
* 在没有session的情况下:
* 若create=true,则新创建一个session.
* 若create=false,则不创建session,返回null.
* @param create session失效的情况下,是否创建session.
* @return HttpSession实例.
*/
public HttpSession getSession(boolean create) {
return this._getHttpServletRequest().getSession(create);
}
/**
* 获得请求对应的当前sesson.
* 若没有session,则创建一个session.
* @return HttpSession实例.
*/
public HttpSession getSession() {
return this._getHttpServletRequest().getSession();
}
/**
* 返回session是否有效.
* @return session是否有效.
*/
public boolean isRequestedSessionIdValid() {
return this._getHttpServletRequest().isRequestedSessionIdValid();
}
/**
* sessionId是否从Cookie中获得.
* @return 若是从Cookie中获得,返回true,否则返回false.
*/
public boolean isRequestedSessionIdFromCookie() {
return this._getHttpServletRequest().isRequestedSessionIdFromCookie();
}
/**
* sessionId是否从URL中获得.
* @return 若是从URL中获得,返回true,否则返回false.
*/
public boolean isRequestedSessionIdFromURL() {
return this._getHttpServletRequest().isRequestedSessionIdFromURL();
}
/**
* @deprecated
* sessionId是否从URL中获得.
* @return 若是从URL中获得,返回true,否则返回false.
*/
public boolean isRequestedSessionIdFromUrl() {
return this._getHttpServletRequest().isRequestedSessionIdFromUrl();
}
}
若文中存在错误和不足,欢迎指正!
本博微信公众号“超哥说码”,欢迎大家订阅,公众号正在完善中,会及时将更优质的博文推送于您!