/* ================================================================== * 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); } }