Zhiqim Httpd即知启蒙WEB容器,是Zhiqim Framework面向WEB开发的多例服务,提供更简洁配置、积木式组件模块和天然的模型模板设计。
HttpRequestAbs.java55KB
/*
* 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
*
* https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
*
* Zhiqim Httpd is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.zhiqim.httpd;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.zhiqim.httpd.model.HttpDomainPortPath;
import org.zhiqim.kernel.model.maps.HashMapSO;
import org.zhiqim.kernel.model.maps.HashMapSS;
import org.zhiqim.kernel.model.maps.MapSO;
import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.util.Amounts;
import org.zhiqim.kernel.util.Arrays;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Classes;
import org.zhiqim.kernel.util.Htmls;
import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Longs;
import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Urls;
import org.zhiqim.kernel.util.Validates;
/**
* HTTP请求抽象类<br><br>
* 1、把公共方法集中在抽象类<br>
* 2、隔离内部方法(仅公开HttpRequest接口)<br>
*
* @version v1.5.0 @author zouzhigang 2018-9-12 新建与整理
*/
public abstract class HttpRequestAbs extends HttpRequestResponse
{
//相关类
protected HttpHeaderAbs header;
protected HttpConnection conn;
protected HttpServer server;
protected HttpContext context;
protected InputStream input;
//四种键值表
protected HashMapSS urlParamMap;
protected HashMapSS cntParamMap;
protected HashMapSS cookieMap;
protected HashMapSO attributeMap;
//内容流
protected ByteArrayInputStream bis;
//会话相关参数
protected HttpSession session;
protected String requestName;
protected transient boolean hasForward;
public HttpRequestAbs(HttpHeaderAbs header)
{
this.header = header;
this.conn = header.getConnection();
this.server = header.getServer();
this.context = header.getContext();
this.input = header.getInputStream();
this.urlParamMap = new HashMapSS();
this.cntParamMap = new HashMapSS();
this.cookieMap = new HashMapSS();
this.attributeMap = new HashMapSO();
}
public abstract boolean parseContent() throws IOException;
/***********************************************************************/
//解析请求头、内容、会话和证书等
/***********************************************************************/
/**
* 解析内容类型、URL和Cookies等,该部分需在context设置之后操作,从parseHeader中分离出来,如果Context没找到,解析也没意义
*/
public void parseHeaderByContextOK() throws HttpException
{
//第七步,检查最大内容长度,如果配置为0表示不检查,>0表示检查大小,默认8M
int maxContentLength = context.getMaxContentLength();
if (maxContentLength > 0)
{
int cLen = getContentLength();
if (cLen > maxContentLength)
throw new HttpException(_413_REQUEST_ENTITY_TOO_LARGE_);
}
//第八步,如果是HTTPS代理,有证书则还原证书,&设置客户端类型
String sslCert = getHeader(_SSL_CERT_);
if (Validates.isNotEmpty(sslCert))
parseHeaderCert(sslCert);
setAttribute(_ZHIQIM_CLIENT_TYPE_, getZhiqimClientType());
//第九步,获取?之后的GET参数,并放置到getParams表中
String queryString = header.getUri().getQuery();
Urls.toMap(queryString, urlParamMap.instance(), header.getCharacterEncoding());
//第十步,解析Cookies,并放置到cookies表中
String cookieString = getHeader(_COOKIE_);
if (Validates.isEmptyBlank(cookieString))
return;
HttpSessionManager sessionManager = context.getSessionManager();
String sessionIdName = sessionManager == null?null:sessionManager.getSessionIdName();
String cookiePrefix = getCookieForcePrefix();
String[] cookieArray = cookieString.split(";");
for (String cookieInfo : cookieArray)
{
String[] cookieNameValue = cookieInfo.split("=");
if (cookieNameValue.length < 2)
continue;
String name = cookieNameValue[0].trim();
String value = cookieNameValue[1].trim();
if (sessionIdName == null || !sessionIdName.equals(name))
{//无会话管理器的和不是sessionId的,相同名称的,目前取第一个,后面的不处理
if (cookiePrefix != null)
{//强制Cookie前缀的
if (!name.startsWith(cookiePrefix))
continue;
name = name.substring(cookiePrefix.length());
}
if (!cookieMap.containsKey(name))
{//强制规定UTF8编码,防止切换编码时读取异常
cookieMap.put(name, Urls.decodeUTF8(value));
}
}
else
{//有会话管理器的,且是sessionId的,判断是否符合本上下文环境的标记
if (!Validates.isLen(value, 48, 48) || cookieMap.containsKey(name))
{//长度不正确不处理,已存在,目前取第一个,后面不处理
continue;
}
String mark = value.substring(32);
if (!sessionManager.chkSessionIdMark(mark, getDomainPortPath()))
{//不符合本上下文环境的标记的不处理
continue;
}
cookieMap.put(name, value);
}
}
}
/**
* 解析Get|Post|Cookie|Session信息,解析必须在context有效之后
*
* @throws IOException IO异常
*/
public void parseGetPostCookieSession() throws IOException
{
//第十一步,解析sesionId,组装session
HttpSessionManager sessionManager = context.getSessionManager();
if (sessionManager == null || !sessionManager.needSession(getPathInContext()))
return;
String sessionId = null;
if (!context.isCookieUse())
sessionId = urlParamMap.get(sessionManager.getSessionIdName());
else
sessionId = cookieMap.get(sessionManager.getSessionIdName());
if (Validates.isEmptyBlank(sessionId) && context.isEncodeable())
sessionId = header.getUri().getSessionId(context.getSessionManager().getSessionIdName());
if (Validates.isEmptyBlank(sessionId) || !sessionManager.hasSession(sessionId))
{//无会话标志或已过期或不一致,新建会话,创建时设置到会话管理器中,如果有浸入式更换sessionId,HttpResponse会重设置
session = sessionManager.newSession(getDomainPortPath(), getRemoteAddr(), getUserAgent());
sessionManager.setSession(session);
}
else
{//有会话标志,设置最后访问时间
session = sessionManager.getSessionByUpdate(sessionId, getRemoteAddr(), getUserAgent());
}
}
/** 解析Nginx的证书 */
private void parseHeaderCert(String sslCert)
{
try
{
sslCert = sslCert.replaceAll("\t", "\n");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream bis = new ByteArrayInputStream(sslCert.getBytes());
X509Certificate cert = (X509Certificate)cf.generateCertificate(bis);
header.setCertificates(new X509Certificate[]{cert});
}
catch (CertificateException e)
{
//不处理
}
}
/***********************************************************************/
//获取监听、服务器、上下文环境、响应、会话相关
/***********************************************************************/
/** 获取连接中的日志对象 */
public Log getLog()
{
return header.getLog();
}
/** 获取发送器 */
public HttpSender getSender()
{
return header.getSender();
}
/** 获取请求编号 */
public String getId()
{
return header.getId();
}
/** 获取产生时间戳 */
public long getTimeMillis()
{
return header.getReceiveTimeMillis();
}
/** 获取对应的HTTP监听器 */
public HttpListener getListener()
{
return header.getListener();
}
/** 获取对应的HTTP监听器监听端口 */
public int getListenerPort()
{
return header.getListener().getPort();
}
/** 获取对应的HTTP服务器,注意只有host有效时才有 */
public HttpServer getServer()
{
return server;
}
/** 获取HTTP连接 */
public HttpConnection getConnection()
{
return header.getConnection();
}
/** 判断是否WebSocket */
public boolean isWebSocket()
{
return header.isWebSocket();
}
/** 获取请求对应的响应对象 */
public HttpResponse getResponse()
{
return header.getResponse();
}
/** 获取请求正在处理的上下文环境 */
public HttpContext getContext()
{
return context;
}
/** 获取上下文环境路径 */
public String getContextPath()
{
return context.getContextPath();
}
/** 获取上下文环境名称 */
public String getContextName()
{
return context.getContextName();
}
/** 获取上下文环境版本 */
public String getContextVersion()
{
return context.getContextVersion();
}
/** 设置上下文环境属性 */
public void setContextAttribute(String key, Object value)
{
context.setAttribute(key, value);
}
/** 设置上下文环境属性值(通过类结构) */
public <T> void setContextAttribute(Class<T> key, T value)
{
context.setAttribute(key, value);
}
/** 获取上下文环境属性值 */
public Object getContextAttribute(String key)
{
return context.getAttribute(key);
}
/** 获取上下文环境属性值(通过类结构) */
public <T> T getContextAttribute(Class<T> key)
{
return context.getAttribute(key);
}
/** 获取上下文环境属性值 */
public Object getContextAttribute(String key, Object defaultValue)
{
return context.getAttribute(key, defaultValue);
}
/** 获取上下文环境属性值字符串 */
public String getContextAttributeString(String key)
{
return context.getAttributeString(key);
}
/** 获取上下文环境属性值字符串 */
public String getContextAttributeString(String key, String defaultValue)
{
return context.getAttributeString(key, defaultValue);
}
/** 获取上下文环境属性值整型 */
public int getContextAttributeInt(String key)
{
return context.getAttributeInt(key);
}
/** 获取上下文环境属性值整型 */
public int getContextAttributeInt(String key, int defaultValue)
{
return context.getAttributeInt(key, defaultValue);
}
/** 获取上下文环境属性值长整型 */
public long getContextAttributeLong(String key)
{
return context.getAttributeLong(key);
}
/** 获取上下文环境属性值长整型 */
public long getContextAttributeLong(String key, long defaultValue)
{
return context.getAttributeLong(key, defaultValue);
}
/** 获取上下文环境属性值布尔型 */
public boolean getContextAttributeBoolean(String key, boolean defaultValue)
{
return context.getAttributeBoolean(key, defaultValue);
}
/** 判断上下文环境是否有属性值 */
public boolean hasContextAttribute(String key)
{
return context.hasAttribute(key);
}
@Override/** 获取当前WEB目录根目录,注意没有/结尾 */
public String getResourcePath()
{
return context.getResourcePath();
}
@Override/** 获取当前WEB目录路径转换成绝对路径 */
public String getRealPath(String path)
{
return context.getRealPath(path);
}
@Override/** 获取上下文环境下绝对路径转为根环境下的绝对路径,如contextPath=/doc,path=/index.htm,得到/doc/index.htm */
public String getRootPath(String path)
{
return context.getRootPath(path);
}
@Override
public X509Certificate[] getCertificates()
{
return header.getCertificates();
}
/***********************************************************************/
//请求状态处理和判断
/***********************************************************************/
@Override /** 是否可读,已读头部之后可读 */
public boolean isRead()
{
return header.isRead();
}
@Override /** 是否可编辑,提交之前可编辑 */
public boolean isEditable()
{
return header.isEditable();
}
@Override /** 是否已提交,提交之后不允许再操作request和response */
public boolean isCommitted()
{
return header.isCommitted();
}
@Override /** 设置拦截中 */
public void setStepInterceptor()
{
header.setStep(_08_INTERCEPTOR_);
}
@Override /** 设置Action处理中 */
public void setStepAction()
{
header.setStep(_09_ACTION_);
}
@Override /** 获取当前处理环节 */
public int getStep()
{
return header.getStep();
}
@Override /** 获取当前处理环节描述 */
public String getStepDesc()
{
return header.getStepDesc();
}
/***********************************************************************/
//设置和获取Session中属性
/***********************************************************************/
/** 获取请求用户名 */
public String getRequestName()
{
return requestName;
}
/** 设置请求用户名 */
public void setRequestName(String name)
{
this.requestName = name;
}
/** 获取请求对应的会话环境 */
public HttpSession getSession()
{
return session;
}
/** 删除会话 */
public void invalidateSession()
{
if (session != null)
context.invalidateSession(session.getId());
session = null;
}
/** 判断是否绑定了登录用户 */
public boolean hasSessionUser()
{
return session != null && session.hasSessionUser();
}
/** 绑定会话登录用户 */
public void bindSessionUser(HttpSessionUser sessionUser)
{
if (session != null){
session.bindSessionUser(sessionUser);
}
}
/** 解绑会话登录用户 */
public void unbindSessionUser()
{
if (session != null){
session.unbindSessionUser();
}
}
/** 获取会话默认的用户信息 */
public HttpSessionUser getSessionUser()
{
return session == null?null:session.getSessionUser();
}
/** 获取会话默认的登录名 */
public String getSessionName()
{
return session == null?null:session.getSessionName();
}
/** 判断是否绑定了登录用户,且指定的会话用户类(HttpSessionUser子类) */
public <T extends HttpSessionUser> boolean hasSessionUser(Class<T> clazz)
{
return session == null?false:session.hasSessionUser(clazz);
}
/** 获取会话用户信息,且指定的会话用户类(HttpSessionUser子类) */
public <T extends HttpSessionUser> T getSessionUser(Class<T> clazz)
{
return session == null?null:session.getSessionUser(clazz);
}
/** 获取会话编号 */
public String getSessionId()
{
assertSession();
return session.getId();
}
/** 设置会话属性 */
public void setSessionAttribute(String name, Object value)
{
assertSession();
session.setAttribute(name, value);
}
/** 获取上下文环境属性值 */
public Object getSessionAttribute(String name)
{
assertSession();
return session.getAttribute(name);
}
/** 获取上下文环境属性值 */
public Object getSessionAttribute(String name, Object defaultValue)
{
assertSession();
return session.getAttribute(name, defaultValue);
}
/** 获取上下文环境属性值字符串 */
public String getSessionAttributeString(String name)
{
assertSession();
return session.getAttributeString(name);
}
/** 获取上下文环境属性值字符串 */
public String getSessionAttributeString(String name, String defaultValue)
{
assertSession();
return session.getAttributeString(name, defaultValue);
}
/** 获取上下文环境属性值整型 */
public int getSessionAttributeInt(String name)
{
assertSession();
return session.getAttributeInt(name);
}
/** 获取上下文环境属性值整型 */
public int getSessionAttributeInt(String name, int defaultValue)
{
assertSession();
return session.getAttributeInt(name, defaultValue);
}
/** 获取上下文环境属性值长整型 */
public long getSessionAttributeLong(String name)
{
assertSession();
return session.getAttributeLong(name);
}
/** 获取上下文环境属性值长整型 */
public long getSessionAttributeLong(String name, long defaultValue)
{
assertSession();
return session.getAttributeLong(name, defaultValue);
}
/** 判断会话是否有属性值 */
public boolean hasSessionAttribute(String name)
{
assertSession();
return session.hasAttribute(name);
}
/** 诊断会话是否存在 */
private void assertSession()
{
Asserts.as(session != null?null:"[HttpSession]未创建或已删除,不允许调用");
}
/***********************************************************************/
//获取Cookie数据或数组
/***********************************************************************/
/** 获取指定名称的Cookie值 */
public String getCookie(String name)
{
return cookieMap.get(name);
}
/** 获取Cookie,如果没有值或值为空字符串返回缺省值 */
public String getCookie(String name, String defaultValue)
{
String value = cookieMap.get(name);
return Validates.isEmpty(value)?defaultValue:value;
}
/** 获取请求中Cookie数组 */
public HttpCookie[] getCookies()
{
HttpCookie[] cookieArr = new HttpCookie[cookieMap.size()];
int i = 0;
for (Entry<String, String> entry : cookieMap.entrySet())
{
HttpCookie cookie = new HttpCookie(entry.getKey(), entry.getValue());
cookieArr[i++] = cookie;
}
return cookieArr;
}
/** 删除请求中的Cookie值 */
public void removeCookie(String name)
{
cookieMap.remove(name);
}
/** 增加Cookie到响应中 */
public void addCookieToResponse(String name, String value)
{
getResponse().addCookie(name, value);
}
/** 增加Cookie到响应中 */
public void addCookieToResponse(String name, String value, int seconds)
{
getResponse().addCookie(name, value, seconds);
}
/** 增加Cookie到响应中 */
public void addCookieToResponse(HttpCookie cookie)
{
getResponse().addCookie(cookie);
}
/** 删除Cookie到响应中 */
public void removeCookieToResponse(String name)
{
getResponse().removeCookie(name);
}
/** 获取Cookie强制前缀 */
public String getCookieForcePrefix()
{
return getDomainPortPath().buildCookiePrefix(context.isCookieForce());
}
/***********************************************************************/
//获取和判断请求行信息,包括协议、方法、版本、URI等
/***********************************************************************/
/** 获取请求行 */
public String getHeaderLine()
{
return header.getHeaderLine();
}
/** 获取请求版本 */
public String getVersion()
{
return header.getVersion();
}
/** 获取URI路径,以/开头,如/test.html,如果没有文件后缀则为'/' */
public String getPath()
{
return header.getPath();
}
/** 获取请求方法 */
public String getMethod()
{
return header.getMethod();
}
/** 是否是HEAD方法 */
public boolean isMethodHead()
{
return header.isMethodHead();
}
/** 是否是OPTIONS方法 */
public boolean isMethodOptions()
{
return header.isMethodOptions();
}
/** 是否是PUT方法 */
public boolean isMethodPut()
{
return header.isMethodPut();
}
/** 是否是DELETE方法 */
public boolean isMethodDelete()
{
return header.isMethodPut();
}
/** 是否是GET方法 */
public boolean isMethodGet()
{
return header.isMethodGet();
}
/** 是否是POST方法 */
public boolean isMethodPost()
{
return header.isMethodPost();
}
/** 判断是否需要响应内容 */
public boolean isMethodResponseContent()
{
return header.isMethodResponseContent();
}
/** 获取客户端IP地址 */
public String getRemoteAddr()
{
return header.getRemoteAddr();
}
/** 获取客户端端口 */
public int getRemotePort()
{
return header.getRemotePort();
}
/** 获取URI信息 */
public String getRequestURI()
{
return header.getUri().toString();
}
/** 获取URL信息 */
public String getRequestURL()
{
String scheme = getScheme();
String hostPort = getHostPort();
return new StringBuilder()
.append(scheme).append("://")
.append(hostPort).append(getRequestURI())
.toString();
}
/** 获取查询串 */
public String getQueryString()
{
return header.getQueryString();
}
/** 获取协议格式 */
public String getScheme()
{
return header.getScheme();
}
/** 获取HOST:PORT */
public String getHostPort()
{
return header.getHostPort();
}
/** 获取端口信息 */
public int getPort()
{
return header.getPort();
}
/** 获取URI虚拟主机信息 */
public String getHostOnly()
{
return header.getHostOnly();
}
/** 获取URI虚拟目录信息 */
public String getVirtualDirectory()
{
return header.getVirtualDirectory();
}
@Override
public HttpDomainPortPath getDomainPortPath()
{
return header.getDomainPortPath();
}
/***********************************************************************/
//获取和判断请求头部信息
/***********************************************************************/
/** 获取头部信息 */
public HashMapSS getHeaderMap()
{
return header.getHeaderMap();
}
/** 获取消息头名称迭代器 */
public Iterator<String> getHeaderNames()
{
return header.getHeaderMap().keySet().iterator();
}
/** 获取请求头字符串 */
public String getHeaderString()
{
StringBuilder strb = new StringBuilder();
for (Map.Entry<String, String> entry : header.getHeaderMap().entrySet())
{
strb.append(entry.getKey()).append(_EQUAL_).append(entry.getValue()).append(_BR_);
}
return strb.toString();
}
/** 获取请求头属性 */
public String getHeader(String key)
{
return header.getHeader(key.toLowerCase());
}
/** 获取请求头属性 */
public String getHeader(String key, String defaultValue)
{
String value = getHeader(key);
return Validates.isEmptyBlank(value)?defaultValue:value;
}
/** 获取请求头属性整型值 */
public int getHeaderInt(String key)
{
return getHeaderInt(key, -1);
}
/** 获取请求头属性整型值 */
public int getHeaderInt(String key, int defaultValue)
{
String value = getHeader(key);
return Validates.isInteger(value)?Ints.toInt(value):defaultValue;
}
/** 获取请求头属性长整型值 */
public long getHeaderLong(String key)
{
return getHeaderLong(key, -1);
}
/** 获取请求头属性长整型值 */
public long getHeaderLong(String key, long defaultValue)
{
String value = getHeader(key);
return Validates.isInteger(value)?Longs.toLong(value):defaultValue;
}
/** 获取请求内容长度 */
public int getContentLength()
{
String sLen = getHeader(_CONTENT_LENGTH_);
if (!Validates.isInteger(sLen))
return 0;
return Integer.parseInt(sLen);
}
/** 获取请求内容类型 */
public String getContentType()
{
return getHeader(_CONTENT_TYPE_);
}
/** 获取请求要求的类型 */
public String getMimeType()
{
return header.getMimeType();
}
/** 判断是否表单提交 */
public boolean isMimeForm()
{
return header.isMimeForm();
}
/** 判断是否文本请求 */
public boolean isMimeTextPlain()
{
return header.isMimeTextPlain();
}
/** 设置请求的编码格式 */
public void setCharacterEncoding(String characterEncoding)
{
header.setCharacterEncoding(characterEncoding);
}
/** 获取请求要求的编码,如果未设置默认UTF-8 */
public String getCharacterEncoding()
{
return header.getCharacterEncoding();
}
/** 获取请求头中的编码,如果未设置默认null */
public String getCharacterEncodingHeader()
{
return header.getCharacterEncodingHeader();
}
/** 获取组装内容类型 */
public String getContentTypeMimeEncoding()
{
return header.getMimeType() + "; charset=" + header.getCharacterEncoding();
}
/** 获取来源地址 */
public String getReferer()
{
return getHeader(_REFERER_);
}
/** 获取知启蒙定义的客户端类型(mobile|www),该值也会设置到request的属性中 */
public String getZhiqimClientType()
{
return isMobile()?_MOBILE_:_WWW_;
}
/** 是否请求内容GZIP */
public boolean isRequestGZip()
{
return header.isRequestGZip();
}
/** 是否响应支持GZIP */
public boolean isResponseGZip()
{
return header.isResponseGZip();
}
/** 是否是异isXMLHttpRequest */
public boolean isXMLHttpRequest()
{
return _XML_HTTP_REQUEST_.equalsIgnoreCase(getHeader(_X_REQUESTED_WITH_));
}
/** 获取浏览器终端标识 */
public String getUserAgent()
{
return header.getUserAgent();
}
/** 是否手机端(含微信客户端) */
public boolean isMobile()
{
String userAgent = getUserAgent();
if (Validates.isEmpty(userAgent))
return false;
return userAgent.toLowerCase().contains(_MOBILE_) || userAgent.toLowerCase().contains(_MICROMESSAGER_);
}
/** 是否微信 */
public boolean isMicroMessenger()
{
String userAgent = getUserAgent();
if (Validates.isEmpty(userAgent))
return false;
return userAgent.toLowerCase().contains(_MICROMESSAGER_);
}
/** 是否IE浏览器 */
public boolean isIE()
{
String userAgent = getUserAgent();
if (Validates.isEmpty(userAgent))
return false;
userAgent = userAgent.toLowerCase();
return userAgent.contains(_MSIE_) || userAgent.contains(_MSTRIDENT_);
}
/** 是否火狐浏览器 */
public boolean isFirefox()
{
String userAgent = getUserAgent();
if (Validates.isEmpty(userAgent))
return false;
return userAgent.toLowerCase().contains(_FIREFOX_);
}
/** 是否是Webkit浏览器 */
public boolean isWebkit()
{
String userAgent = getUserAgent();
if (Validates.isEmpty(userAgent))
return false;
return userAgent.toLowerCase().contains(_WEBKIT_);
}
/** 是否是chrome浏览器 */
public boolean isChrome()
{
String userAgent = getUserAgent();
if (Validates.isEmpty(userAgent))
return false;
return userAgent.toLowerCase().contains(_CHROME_);
}
/** 是否是Safari浏览器 */
public boolean isSafari()
{
String userAgent = getUserAgent();
if (Validates.isEmpty(userAgent))
return false;
userAgent = userAgent.toLowerCase();
return userAgent.contains(_SAFARI_) && !userAgent.contains(_CHROME_);
}
/***********************************************************************/
//获取请求中URL匹配的参数
/***********************************************************************/
/** 获取通配符参数列表 */
@SuppressWarnings("unchecked")
public List<String> getParameterMatch()
{
return (List<String>)getAttribute(_HTTP_REQUEST_PARAM_MATCH_);
}
/**
* 获取通配符参数值
*
* @param index 参数匹配位置
* @return 有过滤的参数值
*/
public String getParameterMatch(int index)
{
return getParameterMatch().get(index);
}
/**
* 获取通配符参数值
*
* @param index 参数匹配位置
* @return 有过滤的参数值
*/
public long getParameterMatchLong(int index)
{
return Longs.toLong(getParameterMatch().get(index));
}
/**
* 获取通配符参数值
*
* @param index 参数匹配位置
* @return 有过滤的参数值
*/
public int getParameterMatchInt(int index)
{
return Ints.toInt(getParameterMatch().get(index));
}
/***********************************************************************/
//获取请求中URL和Content中的数据,包括URL和Content中的数据
/***********************************************************************/
/**
* 获取参数哈唏表(未安全过滤),先填入url中参数表,再用content参数表覆盖,得到全部参数表
*
* @return 得到全部参数表
*/
public HashMapSS getParameterMap()
{
HashMapSS paramMap = new HashMapSS();
paramMap.putAll(urlParamMap);
paramMap.putAll(cntParamMap);
return paramMap;
}
/** 判断是否有参数 */
public boolean hasParameter(String name)
{
return cntParamMap.containsKey(name) || urlParamMap.containsKey(name);
}
/**
* 获取参数值并安全过滤,优先检查content中是否存在,如果不存在才检查url中
*
* @param name 参数名
* @return 有过滤的参数值
*/
public String getParameter(String name)
{
return Htmls.filterAll(hasParameterOnCNT(name)?cntParamMap.get(name):urlParamMap.get(name));
}
/**
* 获取动态参数对象信息
*
* @param clazz 类结构
* @return 返回赋值后的对象
* @throws 异常需要捕捉
*/
public <T> T getParameter(Class<T> clazz) throws IllegalAccessException
{
return Classes.newInstance(clazz, getParameterMap());
}
/**
* 获取参数值(未过滤),优先检查content中是否存在,如果不存在才检查url中
*
* @param name 参数名
* @return 有过滤的参数值
*/
public String getParameterNoFilter(String name)
{
return Strings.trim(hasParameterOnCNT(name)?cntParamMap.get(name):urlParamMap.get(name));
}
/**
* 获取参数值并安全过滤,优先检查content中是否存在,如果不存在才检查url中,都不存在或值为空白返回缺省值
*
* @param name 参数名
* @param defaultValue 不存在或为空时的缺省值
* @return 有过滤的参数值
*/
public String getParameter(String name, String defaultValue)
{
String value = getParameter(name);
return Validates.isEmpty(value)?defaultValue:value;
}
/**
* 获取参数值(未过滤),优先检查content中是否存在,如果不存在才检查url中,都不存在或值为空白返回缺省值
*
* @param name 参数名
* @param defaultValue 不存在或为空时的缺省值
* @return 有过滤的参数值
*/
public String getParameterNoFilter(String name, String defaultValue)
{
String value = getParameterNoFilter(name);
return Validates.isEmpty(value)?defaultValue:value;
}
/**
* 获取参数整型,非整型返回-1的值
*
* @param name 参数名
* @return 整数值
*/
public int getParameterInt(String name)
{
return Ints.toInt(getParameter(name), -1);
}
/**
* 获取参数整型,非整型返回缺省值
*
* @param name 参数名
* @param defaultValue 缺省值
* @return 整数值
*/
public int getParameterInt(String name, int defaultValue)
{
return Ints.toInt(getParameter(name), defaultValue);
}
/**
* 获取参数长整型,非整型返回-1的值
*
* @param name 参数名
* @return 长整型
*/
public long getParameterLong(String name)
{
return Longs.toLong(getParameter(name), -1);
}
/**
* 获取参数长整型,非整型返回-1的值
*
* @param name 参数名
* @param defaultValue 缺省值
* @return 长整型
*/
public long getParameterLong(String name, long defaultValue)
{
return Longs.toLong(getParameter(name), defaultValue);
}
/**
* 获取参数布尔型,非布尔型返回null的值
*
* @param name 参数名
* @return 布尔型
*/
public Boolean getParameterBool(String name)
{
String value = getParameter(name);
if (Validates.isEmptyBlank(value))
return null;
if (_TRUE_.equalsIgnoreCase(value))
return true;
else if (_FALSE_.equalsIgnoreCase(value))
return false;
else
return null;
}
/**
* 获取参数布尔型,!="true"(equalsIgnoreCase)的返回false
*
* @param name 参数名
* @return 布尔型
*/
public boolean getParameterBoolean(String name)
{
return _TRUE_.equalsIgnoreCase(getParameter(name));
}
/**
* 获取参数布尔型,!="true" && !="false"(equalsIgnoreCase)返回defaultValue
*
* @param name 参数名
* @param defaultValue 缺省值
* @return 布尔型
*/
public boolean getParameterBoolean(String name, boolean defaultValue)
{
String value = getParameter(name);
if (Validates.isEmptyBlank(value))
return defaultValue;
if (_TRUE_.equalsIgnoreCase(value))
return true;
else if (_FALSE_.equalsIgnoreCase(value))
return false;
else
return defaultValue;
}
/**
* 获取两位小数的金额值,格式不对返回-1
*
* @param name 参数名
* @return 金额值,如果从请求中获取的格式不对,则返回-1
*/
public int getParameterAmount2R(String name)
{
return Amounts.toFen(getParameter(name), -1);
}
/**
* 获取两位小数的金额值
*
* @param name 参数名
* @param defaultValue 缺省值
* @return 金额值,如果从请求中获取的格式不对,则返回缺省值
*/
public int getParameterAmount2R(String name, int defaultValue)
{
return Amounts.toFen(getParameter(name), defaultValue);
}
/**
* 获取两位小数的金额值长整型,格式不对返回-1
*
* @param name 参数名
* @param defaultValue 缺省值
* @return 金额值,如果从请求中获取的格式不对,则返回-1
*/
public long getParameterAmount2RLong(String name)
{
return Amounts.toFen(getParameter(name), -1L);
}
/**
* 获取两位小数的金额值长整型
*
* @param name 参数名
* @param defaultValue 缺省值
* @return 金额值,如果从请求中获取的格式不对,则返回缺省值
*/
public long getParameterAmount2R(String name, long defaultValue)
{
return Amounts.toFen(getParameter(name), defaultValue);
}
/**
* 获取参数值并安全过滤,并转化为数组(逗号格式),优先检查content中是否存在,如果不存在才检查url中
*
* @param name 参数名
* @return 有过滤后的逗号格式数组值
*/
public String[] getParameterValues(String name)
{
String value = getParameter(name);
return (value == null)?null:Arrays.toStringArray(value);
}
/**
* 获取参数值(未过滤),并转化为数组(逗号格式),优先检查content中是否存在,如果不存在才检查url中
*
* @param name 参数名
* @return 有过滤后的逗号格式数组值
*/
public String[] getParameterValuesNoFilter(String name)
{
String value = getParameterNoFilter(name);
return (value == null)?null:Arrays.toStringArray(value);
}
/***********************************************************************/
//获取请求中URL中的数据
/***********************************************************************/
/** 获取URL参数哈唏表(值未过滤) */
public HashMapSS getParameterMapOnURL()
{
HashMapSS paramMap = new HashMapSS(urlParamMap.size());
paramMap.putAll(urlParamMap);
return paramMap;
}
/** 判断是否有URL参数 */
public boolean hasParameterOnURL(String name)
{
return urlParamMap.containsKey(name);
}
/** 获取URL参数值,并安全过滤 */
public String getParameterOnURL(String name)
{
return Htmls.filterAll(urlParamMap.get(name));
}
/** 获取URL参数值,并安全过滤 */
public String getParameterOnURL(String name, String defaultValue)
{
String value = getParameterOnURL(name);
return Validates.isEmptyBlank(value)?defaultValue:value;
}
/** 获取URL参数值(未过滤) */
public String getParameterNoFilterOnURL(String name)
{
return Strings.trim(urlParamMap.get(name));
}
/** 获取URL参数值(未过滤) */
public String getParameterNoFilterOnURL(String name, String defaultValue)
{
String value = getParameterNoFilterOnURL(name);
return Validates.isEmptyBlank(value)?defaultValue:value;
}
/** 获取URL参数整型,非整型返回-1的值 */
public int getParameterIntOnURL(String name)
{
return Ints.toInt(getParameterOnURL(name), -1);
}
/** 获取URL参数整型,非整型返回缺省值 */
public int getParameterIntOnURL(String name, int defaultValue)
{
return Ints.toInt(getParameterOnURL(name), defaultValue);
}
/** 获取URL参数长整型,非整型返回-1的值 */
public long getParameterLongOnURL(String name)
{
return Longs.toLong(getParameterOnURL(name), -1);
}
/** 获取URL参数长整型,非整型返回-1的值 */
public long getParameterLongOnURL(String name, long defaultValue)
{
return Longs.toLong(getParameterOnURL(name), defaultValue);
}
/** 获取两位小数的金额值 */
public int getParameterAmount2ROnURL(String name, int defaultValue)
{
return Amounts.toFen(getParameterOnURL(name), defaultValue);
}
/** 获取两位小数的金额值长整型 */
public long getParameterAmount2ROnURL(String name, long defaultValue)
{
return Amounts.toFen(getParameterOnURL(name), defaultValue);
}
/** 获取URL参数值数组,并安全过滤 */
public String[] getParameterValuesOnURL(String name)
{
String value = getParameterOnURL(name);
return (value == null)?null:Arrays.toStringArray(value);
}
/** 设置参数值到URL表中 */
public void setParameterOnURL(String name, Object value)
{
urlParamMap.put(name, value == null?null:String.valueOf(value));
}
/** 设置参数值到CNT表中 */
public void setParameterOnCNT(String name, Object value)
{
cntParamMap.put(name, value == null?null:String.valueOf(value));
}
/***********************************************************************/
//获取请求中Content中的数据
/***********************************************************************/
/** 获取内容输入流 */
public InputStream getInputStream()
{
return bis;
}
/** 获取内容输入流字符串 */
public String getInputStreamString()
{
int len = getContentLength();
if (len == 0)
return "";
try
{
byte[] buffer = new byte[len];
bis.read(buffer);
return new String(buffer, getCharacterEncoding());
}
catch (Exception e)
{
throw Asserts.exception("解析请求内容时异常:"+e.getMessage());
}
}
/** 获取内容参数哈唏表(值未过滤) */
public HashMapSS getParameterMapOnCNT()
{
HashMapSS paramMap = new HashMapSS(cntParamMap.size());
paramMap.putAll(cntParamMap);
return paramMap;
}
/** 判断是否有内容参数 */
public boolean hasParameterOnCNT(String name)
{
return cntParamMap.containsKey(name);
}
/** 获取内容参数值,并安全过滤 */
public String getParameterOnCNT(String name)
{
return Htmls.filterAll(cntParamMap.get(name));
}
/** 获取内容参数值,并安全过滤 */
public String getParameterOnCNT(String name, String defaultValue)
{
String value = getParameterOnCNT(name);
return Validates.isEmptyBlank(value)?defaultValue:value;
}
/** 获取内容参数值(未过滤) */
public String getParameterNoFileterOnCNT(String name)
{
return Strings.trim(cntParamMap.get(name));
}
/** 获取内容参数值(未过滤) */
public String getParameterNoFileterOnCNT(String name, String defaultValue)
{
String value = getParameterNoFileterOnCNT(name);
return Validates.isEmptyBlank(value)?defaultValue:value;
}
/** 获取内容参数整型,非整型返回-1的值 */
public int getParameterIntOnCNT(String name)
{
return Ints.toInt(getParameterOnCNT(name), -1);
}
/** 获取内容参数整型,非整型返回缺省值 */
public int getParameterIntOnCNT(String name, int defaultValue)
{
return Ints.toInt(getParameterOnCNT(name), defaultValue);
}
/** 获取内容参数长整型,非整型返回-1的值 */
public long getParameterLongOnCNT(String name)
{
return Longs.toLong(getParameterOnCNT(name), -1);
}
/** 获取内容参数长整型,非整型返回-1的值 */
public long getParameterLongOnCNT(String name, long defaultValue)
{
return Longs.toLong(getParameterOnCNT(name), defaultValue);
}
/** 获取内容参数两位小数的金额值 */
public int getParameterAmount2ROnCNT(String name, int defaultValue)
{
return Amounts.toFen(getParameterOnCNT(name), defaultValue);
}
/** 获取内容参数两位小数的金额值长整型 */
public long getParameterAmount2ROnCNT(String name, long defaultValue)
{
return Amounts.toFen(getParameterOnCNT(name), defaultValue);
}
/** 获取内容参数值数组 */
public String[] getParameterValuesOnCNT(String name)
{
String value = getParameterOnCNT(name);
return (value == null)?null:Arrays.toStringArray(value);
}
/***********************************************************************/
//设置和获取请求中属性
/***********************************************************************/
/** 获取属性列表 */
public MapSO getAttributeMap()
{
return attributeMap;
}
/** 获取属性值 */
public Object getAttribute(String name)
{
return attributeMap.get(name);
}
/** 获取属性值,如果无该属性则返回缺省值 */
public Object getAttribute(String name, Object defaultValue)
{
return (hasAttribute(name))?getAttribute(name):defaultValue;
}
/** 获取属性值字符串*/
public String getAttributeString(String name)
{
return getAttributeString(name, null);
}
/** 获取属性值字符串,如果无该属性则返回缺省值*/
public String getAttributeString(String name, String defaultValue)
{
Object value = attributeMap.get(name);
return (value == null)?defaultValue:String.valueOf(value);
}
/** 获取属性值整型*/
public int getAttributeInt(String name)
{
return Ints.toInt(attributeMap.get(name), -1);
}
/** 获取属性值整型,如果无该属性则返回缺省值*/
public int getAttributeInt(String name, int defaultValue)
{
return Ints.toInt(attributeMap.get(name), defaultValue);
}
/** 获取属性值整型*/
public long getAttributeLong(String name)
{
return Longs.toLong(attributeMap.get(name), -1);
}
/** 获取属性值整型,如果无该属性则返回缺省值*/
public long getAttributeLong(String name, int defaultValue)
{
return Longs.toLong(attributeMap.get(name), defaultValue);
}
/** 判断属性是否存在 */
public boolean hasAttribute(String name)
{
return attributeMap.containsKey(name);
}
/** 设置属性 */
public void setAttribute(String name, Object value)
{
attributeMap.put(name, value);
}
/***********************************************************************/
//获取请求/会话/上下文环境中嵌套属性,有则返回
/***********************************************************************/
/** 获取属性值 */
public Object getNestAttribute(String name)
{
boolean exists = hasAttribute(name);
if (exists)
return getAttribute(name);
exists = hasSessionAttribute(name);
if (exists)
return getSessionAttribute(name);
exists = hasContextAttribute(name);
return exists?getContextAttribute(name):null;
}
/** 获取属性值,如果无该属性则返回缺省值 */
public Object getNestAttribute(String name, Object defaultValue)
{
return hasNestAttribute(name)?getNestAttribute(name):defaultValue;
}
/** 获取属性值字符串 */
public String getNestAttributeString(String name)
{
return getNestAttributeString(name, null);
}
/** 获取属性值字符串,如果无该属性则返回缺省值 */
public String getNestAttributeString(String name, String defaultValue)
{
if (!hasNestAttribute(name))
return defaultValue;
Object val = getNestAttribute(name);
return (val == null)?null:Strings.valueOf(val);
}
/** 获取属性值整型 */
public int getNestAttributeInt(String name)
{
return getNestAttributeInt(name, -1);
}
/** 获取属性值整型,如果无该属性则返回缺省值 */
public int getNestAttributeInt(String name, int defaultValue)
{
return Ints.toInt(getNestAttribute(name), defaultValue);
}
/** 获取属性值整型 */
public long getNestAttributeLong(String name)
{
return getNestAttributeLong(name, -1);
}
/** 获取属性值整型,如果无该属性则返回缺省值 */
public long getNestAttributeLong(String name, int defaultValue)
{
return Longs.toLong(getNestAttribute(name), defaultValue);
}
/** 判断属性是否存在 */
public boolean hasNestAttribute(String name)
{
boolean exists = hasAttribute(name);
if (exists)
return true;
exists = hasSessionAttribute(name);
if (exists)
return true;
return hasContextAttribute(name);
}
/***********************************************************************/
//从请求中设置属性到响应中
/***********************************************************************/
/** 设置响应头不缓存 */
public void setResponseNoCache()
{
HttpResponse response = getResponse();
response.setHeader(_PRAGMA_, _NO_CACHE_);
response.setHeader(_CACHE_CONTROL_, _NO_CACHE_MUST_RV_NO_STORE_);
response.setHeader(_P3P_, _P3P_CP_CAO_PSA_OUR_);
response.setDateHeader(_EXPIRES_, 0);
}
/** 设置响应头私有缓存 */
public void setResponsePrivateCache()
{
getResponse().setCacheControlPrivate();
}
/** 设置响应为UTF8编码*/
public void setResponseEncodingUTF8()
{
HttpResponse response = getResponse();
response.setCharacterEncoding(_UTF_8_);
}
/***********************************************************************/
//内部重定向请求和上下文环境下绝对路径
/***********************************************************************/
/**
* 内部重定向请求,支持从一个Action内部转到新的Action处理
*
* @param pathInContext 上下文内部路径,即对应的新Action的配置路径
* @throws IOException IO异常
* @throws HttpException HTTP异常
*/
public void forwardTo(String pathInContext) throws HttpException, IOException
{
int ind = pathInContext.indexOf("?");
if (ind == -1){
header.setPathInContext(pathInContext);
}else{
Map<String, String> paramMap = Urls.toMapNoEncoded(pathInContext);
this.urlParamMap.putAll(paramMap);
header.setPathInContext(pathInContext.substring(0, ind));
}
HttpResponse response = getResponse();
HttpContext context = getContext();
context.handle(this, response);
//处理完标志为已重定向,并立即提交,不再处理后续数据传送
hasForward = true;
response.commit();
}
/** 是否已标志为已内部重定向 */
public boolean hasForward()
{
return hasForward;
}
/** 获取上下文环境下绝对路径 */
public String getPathInContext()
{
return header.getPathInContext();
}
/** 获取远程方法调用时配置的路径 */
public String getPathInRMI()
{
return header.getPathInRMI();
}
/** 设置远程方法调用时配置的路径 */
public void setPathInRMI(String pathInRMI)
{
header.setPathInRMI(pathInRMI);
}
/** 获取资源文件下绝对路径 */
public String getPathOnResource()
{
return header.getPathOnResource();
}
/** 设置资源文件下绝对路径 */
public void setPathOnResource(String pathOnResource)
{
header.setPathOnResource(pathOnResource);
}
/***********************************************************************/
//toString & destroy
/***********************************************************************/
public String toString()
{
return header.toString();
}
/** 销毁 */
public void destroy()
{
super.destroy();
if (bis != null)
{
try{bis.close();}catch(IOException e){}
bis = null;
}
//map
if (urlParamMap != null)
{
urlParamMap.clear();
urlParamMap = null;
}
if (cntParamMap != null)
{
cntParamMap.clear();
cntParamMap = null;
}
if (cookieMap != null)
{
cookieMap.clear();
cookieMap = null;
}
if (attributeMap != null)
{
attributeMap.clear();
attributeMap = null;
}
//引用置空
header = null;
server = null;
conn = null;
context = null;
input = null;
session = null;
}
}