/* ==================================================================
* Created [2009-4-27 下午11:32:55] by Jon.King
* ==================================================================
* TSS
* ==================================================================
* mailTo:jinpujun@hotmail.com
* Copyright (c) Jon.King, 2009-2012
* ==================================================================
*/
package com.jinhe.tss.core.sso.context;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.jinhe.tss.core.Config;
import com.jinhe.tss.core.sso.IdentityCard;
import com.jinhe.tss.core.sso.SSOConstants;
import com.jinhe.tss.core.util.StringUtil;
import com.jinhe.tss.core.web.RewriteableHttpServletRequest;
import com.jinhe.tss.core.web.wrapper.RewriteableHttpServletRequestWrapper;
/**
* <p> RequestContext.java </p>
* <p>
* 当前请求上下文路径。
*
* RequestContext生命周期基于每次的request请求,每次请求都会起一个新的进程。
* </p>
*
*/
public class RequestContext {
/**
* 用户令牌属性名
*/
public static final String USER_TOKEN = "token";
/**
* 请求所属系统编号属性名
*/
public static final String APPLICATION_CODE = "appCode";
/**
* 用户客户端ID属性名称
*/
public static final String USER_CLIENT_IP = "clientIp";
/**
* 用户身份证对象Session属性名
*/
public static final String IDENTITY_CARD = "identity_card";
/**
* 请求类型参数名称
*/
public static final String ANONYMOUS_REQUEST = "anonymous";
/**
* 被合并的请求标记,即子请求标记:值为true的为子请求,否则为正常请求
*/
public static final String MULTI_REQUEST = "Multi-Request";
private static final String REQUEST_TYPE = "REQUEST-TYPE"; //HTTP请求类型参数名
private static final String XMLHTTP_REQUEST = "xmlhttp"; //XMLHTTP请求的请求类型参数值
private static final String OTHER_APP_PASSWORD = "pwd"; //登录其他系统是要求输入的密码的参数名
private static final String PROXY_REAL_PATH = "realPath"; //需要转发请求的真实访问路径属性名
private static final String USER_INDENTIFIER = "identifier"; //用户身份认证类名属性名
/**
* 获取当前请求HttpServletRequest对象
*/
private RewriteableHttpServletRequest request;
protected RequestContext(HttpServletRequest request) {
this.request = RewriteableHttpServletRequestWrapper.getRewriteableHttpServletRequest(request);
}
public RewriteableHttpServletRequest getRequest() {
return request;
}
/**
* <p>
* 获取请求ServletPath(相对路径 /login.do, /logout.in 等)
* 注:不宜采用本class的request(RewriteableHttpServletRequest)属性,有些情况RequestContext并不会被初始化。
* </p>
*
* @param request
* @return
*/
public static String getServletPath(HttpServletRequest request) {
String contextPath = request.getContextPath(); // http://ip:8088/tss
String servletPath = request.getRequestURI(); // http://ip:8088/tss/login.do
if (contextPath.length() > 1) {
servletPath = servletPath.substring(contextPath.length());
}
return servletPath; // login.do
}
/**
* <p>
* 获取当前请求客户端真实IP
* </p>
*
* @return
*/
public String getClientIp() {
String clientIp = request.getHeader(USER_CLIENT_IP);
if (clientIp == null || "".equals(clientIp)) {
clientIp = request.getRemoteAddr();
}
return clientIp;
}
/**
* <p>
* 获取当前请求对应Session
* </p>
* @return
*/
public HttpSession getSession() {
return request.getSession();
}
/**
* <p>
* 获取当前请求对应SessionID
* </p>
* @return
*/
public String getSessionId() {
HttpSession session = getSession();
return session != null ? session.getId() : null;
}
/**
* <p>
* 获取Session中存放的用户身份证对象
* </p>
* @return
*/
public IdentityCard getIdentityCard() {
HttpSession session = getSession();
return session != null ? (IdentityCard) session.getAttribute(IDENTITY_CARD) : null;
}
/**
* <p>
* 可以使用匿名用户访问此请求,如果用户已登录或自动登录成功,则使用注册用户登录后访问;
* 如果注册用户登录不成功或没有登录,也可以使用匿名用户访问此。
* </p>
* @return
*/
public boolean canAnonymous() {
return "true".equalsIgnoreCase(getValueFromHeaderOrParameter(ANONYMOUS_REQUEST));
}
/**
* <p>
* 销毁
* </p>
*/
protected void destroy() {
request = null;
}
/**
* <p>
* 获取当前请求用户对应的身份认证对象类名
* </p>
* @return
*/
public String getUserIdentifierClassName() {
return getValueFromHeaderOrParameter(USER_INDENTIFIER);
}
/**
* <p>
* 以前请求时的Token值,保留在Session中
* </p>
* @return
*/
public String getAgoToken() {
return (String) getSession().getAttribute(USER_TOKEN);
}
/**
* <p>
* 获取当前请求用户对应令牌(此令牌保存在请求request的header里或cookie里)
* </p>
* @return
*/
public String getUserToken() {
return getValueFromRequest(USER_TOKEN);
}
/**
* <p>
* 按顺序(header,parameter,cookie)获取参数值
* </p>
* @param name
* @return
*/
public String getValueFromRequest(String name) {
String value = getValueFromHeaderOrParameter(name);
if (value != null && !"".equals(value)) {
return value;
}
// cookie
value = getValueFromCookie(name);
if (value != null && !"".equals(value)) {
return value;
}
return null;
}
/**
* <p>
* 从请求Header或参数中获取参数值
* </p>
* @param name
* @return
*/
public String getValueFromHeaderOrParameter(String name) {
// header
String value = getHeader(name);
if (value != null && !"".equals(value)) {
return value;
}
// parameters
value = request.getParameter(name);
if (value != null && !"".equals(value)) {
return value;
}
return null;
}
/**
* <p>
* 从Request中获取Header参数,同时对登录名转换编码(解决中文名登陆需要转码的问题)。
* </p>
* @param name 参数名
* @return 参数值
*/
private String getHeader(String name) {
String value = request.getHeader(name);
if (value != null && SSOConstants.LOGINNAME_IN_SESSION.equalsIgnoreCase((name))) {
//System.out.println("----------------------" + name + ":" + value);
//request中 Header WebSphere/Tomcat默认为"ISO-8859-1"编码,WebLogic8默认为UTF-8
String oldCharSet = "ISO-8859-1";
//TODO 判断是否是WebLogic应用服务器,是的话oldCharSet = "GBK",否则等于"ISO-8859-1"
String isWebLogic = Config.getAttribute("isWebLogic");
if(Config.TRUE.equalsIgnoreCase(isWebLogic)){
oldCharSet = "GBK";
}
String newCharSet;
String browserType = request.getHeader("user-agent");
if(browserType.indexOf("MSIE 7") > 0){
newCharSet = "UTF-8"; // IE7需要转换成UTF-8
} else {
newCharSet = request.getCharacterEncoding();
}
value = StringUtil.convertCoding(value, oldCharSet, newCharSet);
if(value.endsWith("X") || value.endsWith("x")){
// 中文名奇数个字的话从UTF-8转为GBK最后一字乱码,所以默认在后面加一个“X”字母,解码后再去掉
value = value.substring(0, value.length() - 1);
}
//System.out.println("----------------------" + name + ":" + value);
}
return value;
}
/**
* <p>
* 从cookie中尝试获取参数值
* </p>
* @param name
* @return
*/
private String getValueFromCookie(String name) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals(name)) {
return cookie.getValue();
}
}
}
return null;
}
/**
* <p>
* 获取当前请求的系统Code
* </p>
* @return
*/
public String getAppCode() {
return getValueFromHeaderOrParameter(APPLICATION_CODE);
}
/**
* <p>
* 获取真实访问服务路径,用于个别请求访问地址应用转向问题,当真实地址不能匹配过滤器地址时使用此替代方案。
* 允许在header或parameter中指定真正要转向的地址。
* </p>
* @return
*/
public String getRealPath() {
return getValueFromHeaderOrParameter(PROXY_REAL_PATH);
}
/**
* <p>
* 判断请求是否为复合请求,如果是则返回True,否则返回False
* </p>
* @return
*/
public boolean isMultiRequest() {
return Config.TRUE.equalsIgnoreCase(getHeader(MULTI_REQUEST));
}
/**
* <p>
* 判断请求是否为XMLHTTP请求方式
* </p>
* @return
*/
public boolean isXmlhttpRequest() {
return XMLHTTP_REQUEST.equals(getHeader(REQUEST_TYPE));
}
/**
* <p>
* 判断是否为https方式
* </p>
* @return
*/
public boolean isSecure() {
return request.isSecure();
}
/**
* <p>
* 获取为登录其他应用系统用户重新输入的密码
* </p>
* @return
*/
public String getPWD() {
return getValueFromHeaderOrParameter(OTHER_APP_PASSWORD);
}
}