无
package com.fr.web.utils; ... /** * 处理web页面事务的工具类 */ public class WebUtils { private WebUtils() { } /** * 获取HTTP请求中指定名字的参数值 * * @param req HTTP请求 * @param paraName 参数名 * @return 参数值 */ public static String getHTTPRequestParameter(HttpServletRequest req, String paraName) { return NetworkHelper.getHTTPRequestParameter(req, paraName); } /** * 获取第一个不为空的参数 * * @param req HTTP请求 * @param paraNames 参数列表 * @return 参数值 */ public static String getHTTPRequestParameter(HttpServletRequest req, String... paraNames) { return NetworkHelper.getHTTPRequestParameter(req, paraNames); } /** * 把HTTP请求中指定名字的参数值转化为布尔值 * * @param req HTTP请求 * @param paraName 参数名 * @return */ public static boolean getHTTPRequestBoolParameter(HttpServletRequest req, String paraName) { return NetworkHelper.getHTTPRequestBoolParameter(req, paraName); } /** * 把HTTP请求中指定名字的参数值转化为整数,参数为空或不是整数则返回-1 * * @param req HTTP请求 * @param paraName 参数名 * @return */ public static int getHTTPRequestIntParameter(HttpServletRequest req, String paraName) { return getHTTPRequestIntParameter(req, paraName, -1); } /** * 把HTTP请求中指定名字的参数值转化为整数 * * @param req HTTP请求 * @param paraName 参数名 * @param defaultValue 默认值 * @return 返回req中参数的整数值。参数为空或不是整数则返回defaultValue */ public static int getHTTPRequestIntParameter(HttpServletRequest req, String paraName, int defaultValue) { return NetworkHelper.getHTTPRequestIntParameter(req, paraName, defaultValue); } /** * 获取模板的显示标题 * * @param req HTTP请求 * @return 模板在浏览器上显示的标题 */ public static String getReportTitleFromRequest(HttpServletRequest req) { String title = WebUtils.getHTTPRequestParameter(req, ParameterConstants.VIEWLET); if (title == null) { title = WebUtils.getHTTPRequestParameter(req, ParameterConstants.VIEWLETS); } if (title == null) { title = WebUtils.getHTTPRequestParameter(req, ParameterConstants.REPORTLET); } if (title == null) { title = WebUtils.getHTTPRequestParameter(req, ParameterConstants.REPORTLETS); } if (title == null) { title = WebUtils.getHTTPRequestParameter(req, ParameterConstants.RESULTLET); } return title; } /** * 生成一个访问Servelt的相对路径 * * @param req HTTP请求 * @return URL路径 */ public static String createServletURL(HttpServletRequest req) { return NetworkHelper.createServletURL(req); } /** * 生成一个打印输出器 * * @param res HTTP响应 * @return 打印输出器 * @throws IOException */ public static PrintWriter createPrintWriter(HttpServletResponse res) throws IOException { return NetworkHelper.createPrintWriter(res); } /** * 输出到前端的JSON格式的信息 * * @param req HTTP请求 * @param res HTTP响应 * @param data 输出到前端的信息 * @throws Exception 如果输出信息失败则抛出此异常 */ public static void flushSuccessMessageAutoClose(HttpServletRequest req, HttpServletResponse res, JSONObject data) throws Exception { WebUtils.printAsJSON(res, data); } /** * 输出到前端的JSON数组格式的信息 * * @param req HTTP请求 * @param res HTTP响应 * @param data 输出到前端的信息 * @throws Exception 如果输出信息失败则抛出此异常 */ public static void flushSuccessMessageAutoClose(HttpServletRequest req, HttpServletResponse res, JSONArray data) throws Exception { WebUtils.printAsJSON(res, data); } /** * 输出到前端的JSON数组格式的信息,需要手动关闭writer * * @param req HTTP请求 * @param res HTTP响应 * @param writer 输出字符流 * @param data 输出到前端的信息 * @throws Exception 如果输出信息失败则抛出此异常 */ public static void flushSuccessMessage(HttpServletRequest req, HttpServletResponse res, PrintWriter writer, JSONArray data) throws Exception { writer.print(data.toString()); } /** * 输出到前端的JSON格式的信息,需要手动关闭writer * * @param req HTTP请求 * @param res HTTP响应 * @param writer 输出字符流 * @param data 输出到前端的信息 * @throws Exception 如果输出信息失败则抛出此异常 */ public static void flushSuccessMessage(HttpServletRequest req, HttpServletResponse res, PrintWriter writer, JSONObject data) throws Exception { writer.print(data.toString()); } /** * 输出标志失败的信息 * * @param req HTTP请求 * @param res HTTP响应 * @param errorCode 错误码 * @param description 错误码描述 * @throws Exception 如果输出信息失败则抛出此异常 */ public static void flushFailureMessageAutoClose(HttpServletRequest req, HttpServletResponse res, int errorCode, String description) throws Exception { flushFailureMessageAutoClose(req, res, errorCode, description, null); } /** * 输出标志失败的信息 * * @param req HTTP请求 * @param res HTTP响应 * @param errorCode 错误码 * @param description 错误码描述 * @param compatibleData 兼容信息 * @throws Exception 如果输出信息失败则抛出此异常 */ public static void flushFailureMessageAutoClose(HttpServletRequest req, HttpServletResponse res, int errorCode, String description, JSONObject compatibleData) throws Exception { if (StringUtils.isEmpty(description)) { throw new IllegalArgumentException("The description of error code cannot be empty!"); } WebUtils.printAsJSON(res, generateErrorCodeObject(errorCode, description, compatibleData)); } /** * 输出标志失败的信息 * * @param req HTTP请求 * @param writer 输出字符流 * @param errorCode 错误码 * @param description 错误码描述 * @param compatibleData 兼容信息 * @throws Exception 如果输出信息失败则抛出此异常 */ public static void flushFailureMessage(HttpServletRequest req, PrintWriter writer, int errorCode, String description, JSONObject compatibleData) throws Exception { if (StringUtils.isEmpty(description)) { throw new IllegalArgumentException("The description of error code cannot be empty!"); } writer.print(generateErrorCodeObject(errorCode, description, compatibleData).toString()); } private static JSONObject generateErrorCodeObject(int errorCode, String description, JSONObject compatibleData) throws Exception { JSONObject data = JSONObject.create().put("errorCode", errorCode).put("errorMsg", description); if (compatibleData != null) { Iterator it = compatibleData.keys(); while (it.hasNext()) { String key = GeneralUtils.objectToString(it.next()); data.put(key, compatibleData.get(key)); } } return data; } /** * 按指定编码生成打印输出器 * * @param res HTTP响应 * @param charsetName 编码 * @return 打印输出器 * @throws IOException */ public static PrintWriter createPrintWriter(HttpServletResponse res, String charsetName) throws IOException { return NetworkHelper.createPrintWriter(res, charsetName); } /** * 输出JSON类型的字符串 * * @param res HTTP响应 * @param jo JSON对象 * @throws Exception */ public static void printAsJSON(HttpServletResponse res, JSONObject jo) throws Exception { printAsString(res, jo.toString()); } /** * 输出JSON类型的字符串 * * @param res HTTP响应 * @param ja JSON数组对象 * @throws Exception */ public static void printAsJSON(HttpServletResponse res, JSONArray ja) throws Exception { printAsString(res, ja.toString()); } /** * 输出字符串,一般来说是JSON格式 * * @param res HTTP响应 * @param jo JSON样式的字符串 * @throws Exception */ public static void printAsString(HttpServletResponse res, String jo) throws Exception { PrintWriter pw = WebUtils.createPrintWriter(res); pw.print(jo); pw.flush(); pw.close(); } /** * 把一个对象变成可转变为JSON对象的值 * * @param object 原对象 * @return 可转化成JSON对象的值 * @throws JSONException 异常 */ public static Object object2JSONable(Object object) throws JSONException { // alex:如果是Date和Image类型的,特别用JSON方式表示一下 return object2JSONable(object, -1, -1); } /** * 把一个对象变成可转变为JSON对象的值 * * @param object 原对象 * @param cellwidth 宽度k * @param cellheight 高度g * @return 可转化成JSON对象的值 * @throws JSONException 异常 */ public static Object object2JSONable(Object object, int cellwidth, int cellheight) throws JSONException { if (object instanceof Date) { return new JSONObject().put("date_milliseconds", new Long(((Date) object).getTime())); } else if (object instanceof Image) { if (cellheight > 0 && cellwidth > 0) { return AttachmentHelper.addAttachment((Image) object, AttachmentHelper.DEFAULT_IMAGE_FORMAT, cellwidth, cellheight, AttachmentScope.DEFAULT).toConfig(); } else { return AttachmentHelper.addAttachment((Image) object, AttachmentScope.DEFAULT).toConfig(); } } else if (object instanceof Double) { if (((Double) object).isInfinite() || ((Double) object).isNaN()) { return GeneralUtils.objectToString(object); } } else if (object instanceof Float) { if (((Float) object).isInfinite() || ((Float) object).isNaN()) { return GeneralUtils.objectToString(object); } } else if (object instanceof FArray) { return object; } return JSONHolder.hold(object); } /** * 处理一些指定的模板,主要用于替换一个参数等 * * @param resource 模板的路径 * @param response HTTP响应 * @throws IOException */ public static void dealWithTemplate(String resource, HttpServletResponse response) throws IOException { writeOutTemplate(resource, response, java.util.Collections.EMPTY_MAP); } /** * 写出指定的模板 * * @param resource 模板路径 * @param response HTTP响应 * @param map 用于替换模板中参数的的参数集 * @throws IOException */ public static void writeOutTemplate(String resource, HttpServletResponse response, Map map) throws IOException { //debug模式每次都刷新js和css,便于调试 if (StableUtils.isDebug()) { StableFactory.refreshTypeStyleFiles(); StableFactory.refreshJavaScriptFiles(); } PrintWriter writer = WebUtils.createPrintWriter(response); //bug45146,如果因为weblogic/resin服务器没有获取contentType,会把contentType为text/html,这里先再根据resource重新设置下。 WebUtils.setResourceContentType(resource, response); TemplateUtils.dealWithTemplate(resource, writer, map); writer.flush(); writer.close(); } /** * @deprecated use {@link BaseWebUtils#invalidResourcePath} instead. * */ @Deprecated public static boolean invalidResourcePath(String resourcePath) { return BaseWebUtils.invalidResourcePath(resourcePath); } /** * 获取资源文件类型 * * @param resourceName 资源文件路径 * @param res http响应 * @return 返回资源文件类型 */ public static ResourceType setResourceContentType(String resourceName, HttpServletResponse res) { if (StringUtils.isBlank(resourceName)) { return ResourceType.NONE; } return getResourceType(res, resourceName.toLowerCase()); } private static ResourceType getResourceType(HttpServletResponse res, String lowerName) { String charset = ServerConfig.getInstance().getServerCharset(); if (lowerName.endsWith(".png")) { res.setContentType("image/png"); } else if (lowerName.endsWith(".gif")) { res.setContentType("image/gif"); } else if (lowerName.endsWith(".jpg")) { res.setContentType("image/jpeg"); } else if (lowerName.endsWith(".js")) { res.setContentType("text/javascript;charset=" + charset); return ResourceType.FILE; } else if (lowerName.endsWith(".json")) { res.setContentType("text/plain;charset=" + charset); return ResourceType.FILE; } else if (lowerName.endsWith(".map")) { return ResourceType.FILE; } else if (lowerName.endsWith(".css")) { res.setContentType("text/css;charset=" + charset); return ResourceType.FILE; } else if (lowerName.endsWith(".xml")) { res.setContentType("text/xml;charset=" + charset); return ResourceType.NONE; } else if (lowerName.endsWith(".swf")) { res.setContentType("application/x-shockwave-flash"); } else if (lowerName.endsWith(".jnlp")) { res.setContentType("application/x-java-jnlp-file"); } else if (lowerName.endsWith(".xls")) { res.setContentType("application/vnd.ms-excel"); } else if (lowerName.endsWith(".exe")) { res.setContentType("application/x-msdownload"); res.setHeader("extension", "exe"); res.setHeader("Content-disposition", "attachment; filename=AcrobatReader.exe"); } else if (lowerName.endsWith(".ttf")) { res.setContentType(".ttf"); } else if (lowerName.endsWith(".eot")) { res.setContentType(".eot"); } else if (lowerName.endsWith(".woff")) { res.setContentType(".woff"); } else if (lowerName.endsWith(".cur")) { res.setContentType(".cur"); } else if (lowerName.endsWith(".htc")) { res.setContentType("text/x-component"); } else if (lowerName.endsWith(".html")) { res.setContentType("text/html;charset=" + charset); return ResourceType.FILE; } else { res.setContentType("text/html;charset=" + charset); return ResourceType.NONE; } return ResourceType.OTHER; } /** * 生成保存参数的map * * @param req HTTP请求 * @return 参数map * @throws Exception 异常 */ public static Map createSessionIDParameterMap(HttpServletRequest req) throws Exception { HashMap parameterMap = new HashMap(); Enumeration parameterNames = req.getParameterNames(); while (parameterNames.hasMoreElements()) { String parameterName = (String) parameterNames.nextElement(); // 去掉"reportlet",不保存. if (StringUtils.isBlank(parameterName)) { continue; } // 因为这个方法会在第一次访问的时候调用,需要去掉几个内置的参数. if (isSpecificParameters(parameterName)) { continue; } // Encoding text. parameterMap.put(parameterName, WebUtils.getHTTPRequestParameter(req, parameterName)); } return parameterMap; } private static boolean isSpecificParameters(String parameterName) { return "reportlet".equalsIgnoreCase(parameterName) || "format".equalsIgnoreCase(parameterName) || "op".equalsIgnoreCase(parameterName); } /** * carl:将传进来的参数Map进行处理 * 将一些json参数分解出来 * 过滤掉一些内置参数 * <p/> * 传进来的参数Map不变 * * @param paramMap 待处理的map * @return 新的Map */ public static Map<String, Object> dealWithExecuteParamMap(Map<String, Object> paramMap) { // alex:execute时用的Map,先取初始化的Map,再取sessionIDInfor中的Map,先后次序不能颠倒了 Map<String, Object> map4Execute = new HashMap<String, Object>(); if (paramMap != null) { for (String key : paramMap.keySet()) { Object ob = paramMap.get(key); // richer:参数为JSONObject主要是表单提交上来的参数 if (ob instanceof JSONObject) { for (Map.Entry<String, Object> entry : (JSONObject)ob) { String name = entry.getKey(); map4Execute.put(name, ((JSONObject) ob).getValue(name)); } } } map4Execute.putAll(paramMap); } // remove server parameters for (int i = 0; i < ParameterConstants.ALL.length; i++) { map4Execute.remove(ParameterConstants.ALL[i]); } return map4Execute; } /** * 兼容各个web服务器getRealPath方法 * * @param servletContext the servletContext * @return return the WEB-INF Path */ public static String getWebINFPath(ServletContext servletContext) { return BaseWebUtils.getWebINFPath(servletContext); } /** * 生成包括移动参数的map * * @param req 请求 * @return 参数map */ public static Map<String, Object> parameters4SessionIDInforContainMPCache(HttpServletRequest req) { Map<String, Object> map = parameters4SessionIDInfor(req); HttpSession session = req.getSession(false); if (session != null) { Object info = session.getAttribute(ParameterConstants.__MPCACHEID__); if (info != null) { Map<String, Object> tMap = (Map<String, Object>) info; map.putAll(tMap); session.removeAttribute(ParameterConstants.__MPCACHEID__); } } return map; } /** * 将HTTPServletRequest中的所有参数都读取出来,存储在一个Map中,返回出去,主要是为了传给SessionIDInfor * * @param req 请求 q * @return 参数map c */ public static Map<String, Object> parameters4SessionIDInfor(HttpServletRequest req) { Map<String, Object> parameterMap = new HashMap<String, Object>(); if (req == null) { return parameterMap; } ExtraClassManagerProvider pluginProvider = PluginModule.getAgent(PluginModule.ExtraCore); RequestParameterCollector collector = null; if (pluginProvider != null) { collector = pluginProvider.getSingle(RequestParameterCollector.XML_TAG); } if (collector == null) { collector = DefaultRequestParameterCollector.getInstance(); } parameterMap.putAll(collector.getParametersFromSession(req)); parameterMap.putAll(collector.getParametersFromAttribute(req)); parameterMap.putAll(collector.getParametersFromParameter(req)); parameterMap.putAll(collector.getParametersFromJSON(req, parameterMap)); parameterMap.putAll(collector.getParametersFromReqInputStream(req)); // denny: 浏览器国际化 parameterMap.put(Constants.__LOCALE__, WebUtils.getLocale(req)); // carl:设置权限参数,先移除相应的参数,防止url传参等,然后再从session中取再设置 // 原来想就用底层的那套权限控制来处理一下,再设置的,但说不准要做什么变动,暂时就独立出来 if (parameterMap.get(ParameterConstants.REDIRECT_FROM) == null) { String[] FILTER_PARAMS = BaseSessionFilterParameterManager.getFilterParameters(); for (int i = 0; i < FILTER_PARAMS.length; i++) { parameterMap.remove(FILTER_PARAMS[i]); } } SimpleUser user = getCurrentSimpleUserFromRequest(req); if (user == null) { return parameterMap; } else { dealWithDetailUserInfo(user, UserInfoHandleFactory.getUserDetailInfo(), parameterMap); } return parameterMap; } /** * 获取用户对应的详细信息,加入到map中 */ private static void dealWithDetailUserInfo(SimpleUser user, UserDetailInfo userDetailInfoHandler, Map<String, Object> parameterMap) { String username = user.getUsername(); String displayName = user.getDisplayName(); parameterMap.put(ParameterConstants.FINE_USERNAME, username); parameterMap.put(ParameterConstants.FINE_OLD_USERNAME, username); parameterMap.put(ParameterConstants.FINE_DISPLAY_NAME, displayName); if (userDetailInfoHandler != null) { FArray depAndPost = userDetailInfoHandler.getDepartmentAndPost(username); FArray customRole = userDetailInfoHandler.getCustomRole(username); if (depAndPost != null) { parameterMap.put(ParameterConstants.FINE_POSITION, depAndPost); parameterMap.put(ParameterConstants.FINE_OLD_POSITION, depAndPost); } if (customRole != null) { parameterMap.put(ParameterConstants.FINE_ROLE, customRole); parameterMap.put(ParameterConstants.FINE_OLD_ROLE, customRole); } } } /** * 当{@link ServerConfig#isTokenFromCookie()}为true时,优先从cookie取 * 否则先Parameter(REPORT-15581 与TokenResource.HEADER相反) -> Header -> Cookie * @param req request * @return token */ private static String getToken(HttpServletRequest req) { String token; if (ServerConfig.getInstance().isTokenFromCookie()) { token = NetworkHelper.getTokenFromCookie(req); if (!StringUtils.isEmpty(token)) { return token; } } token = NetworkHelper.getTokenFromParameter(req); if (!StringUtils.isEmpty(token)) { return token; } token = NetworkHelper.getTokenFromHeader(req); return StringUtils.isEmpty(token) ? NetworkHelper.getTokenFromCookie(req) : token; } /** * 获取用户名以及显示名字 * * @param request http请求 * @return 用户名和显示名组合对象 */ private static SimpleUser getCurrentSimpleUserFromRequest(HttpServletRequest request) { try { String token = getToken(request); if (StringUtils.isNotBlank(token)) { Claims claims = JwtUtils.parseJWT(token); return SimpleUser.create(claims.getSubject(), claims.getDescription()); } } catch (Exception e) { FineLoggerFactory.getLogger().info("can't find username from request: {}", e.getMessage()); } return null; } /** * 返回发起指定HTTP请求的URL地址 * * @param req HTTP请求 * @return URL地址 */ public static String getOriginalURL(HttpServletRequest req) { return NetworkHelper.getOriginalURL(req); } /** * 获取发起请求的客户端的IP地址 * * @param req HTTP请求 * @return 客户端IP地址 */ public static String getIpAddr(HttpServletRequest req) { String ip = req.getHeader("x-forwarded-for"); if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = req.getHeader("Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = req.getHeader("WL-Proxy-Client-IP"); } if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { ip = req.getRemoteAddr(); } //null还是不return回去了, Apache,Squid等反向代理软件不能获取到客户端的真实IP地址。 return StringUtils.isEmpty(ip) ? "unknown" : ip; } /** * 判断访问模板的IP是否为服务器本机 * * @param ip IP地址 * @return 是服务器本机则返回true,否则返回false */ public static boolean isLocalHost(String ip) { return "127.0.0.1".equals(ip) || "localhost".equals(ip) || (ip != null && ip.startsWith("0:0:0:0:0:0:0:1")); } /** * 从HTTP请求中获取页码信息 * * @param req 请求q * @return 页码y */ public static int receivePageNumber(HttpServletRequest req) { int pn = 0; String pnValue = WebUtils.getHTTPRequestParameter(req, "pn"); if (pnValue != null) { Number num = Utils.string2Number(pnValue); // alex:如果num为null或者intValue小于,有一种可能性是长度过长,所以设置pn为Integer.MAX_VALUE if (num == null || (pn = num.intValue()) < 0) { pn = Integer.MAX_VALUE; } } return pn; } /** * 根据网络请求判定发起请求的设备 * * @param req HTTP请求 * @return 设备类型 */ public static Device getDevice(HttpServletRequest req) { return NetworkHelper.getDevice(req); } public static Format getResponseContentFormat(HttpServletRequest req) { return NetworkHelper.getResponseContentFormat(req); } /** * 获取req中的国际化信息 * * @param req HTTP请求 * @return 国际化语言 * @date 2014-12-1-下午4:39:44 */ public static Locale getLocale(HttpServletRequest req) { if (req == null) { return GeneralContext.getLocale(); } //开放给客户的是fr_locale, 我们内部代码里js还有__fr__locale__ String localeStr = WebUtils.getHTTPRequestParameter(req, Constants.__FR_LOCALE__); localeStr = localeStr == null ? WebUtils.getHTTPRequestParameter(req, "__fr_locale__") : localeStr; //性能, 优先处理并发最常规的. if (StringUtils.isEmpty(localeStr) && "zh_CN".equals(String.valueOf(req.getLocale()))) { return Locale.CHINA; } return GeneralUtils.createLocale(replaceScript4Xss(localeStr), req.getLocale()); } /** * 获取需要Import的css, 并返回html标签 * * @param ca 算子 * @return html标签 * @date 2014-12-3-下午7:45:14 */ public static String getCSSLinks(Calculator ca) { return getCSSLinks(ca, null); } /** * 获取需要Import的css, 并返回html标签 * * @param ca 算子 * @param attr 当前拥有对象 * @return html标签 * @date 2014-12-3-下午7:45:14 */ public static String getCSSLinks(Calculator ca, ImportJsCssProvider attr) { String[] csses = getImportedCSS(attr); StringBuilder cssBuffer = new StringBuilder(); for (String importString : csses) { try { // 替换 importString = TemplateUtils.render(importString, ca); cssBuffer.append("<link rel=\"stylesheet\" type=\"text/css\" href=\""); if (IOUtils.isOnlineUrl(importString)) { cssBuffer.append(importString); } else { cssBuffer.append(SateVariableManager.get(WebServerConstants.FINE_CONTEXT_PATH)) .append(importString.startsWith(CoreConstants.SEPARATOR) ? importString : CoreConstants.SEPARATOR + importString); } cssBuffer.append("\"></link>").append('\n'); } catch (Exception e) { // 模板转换异常 doNothing } } return cssBuffer.toString(); } /** * 获取需要Import的js, 并返回javascript转义字符串 * * @param ca 算子 * @return javascript转义字符串 * @date 2014-12-3-下午7:45:14 */ public static String getJSLinks(Calculator ca) { return getJSLinks(ca, null); } /** * 获取需要Import的js, 并返回javascript转义字符串 * * @param ca 算子 * @param attr 当前拥有对象 * @return javascript转义字符串 * @date 2014-12-3-下午7:45:14 */ public static String getJSLinks(Calculator ca, ImportJsCssProvider attr) { return getJSLinks(ca, attr, false); } /** * 获取需要Import的js, 并返回html标签或者javascript转义字符串 * * @param ca 算子 * @param attr 当前拥有对象 * @param isHtmlTag 是否是html标签 * @return html标签或者javascript转义字符串 * @date 2014-12-3-下午7:45:14 */ public static String getJSLinks(Calculator ca, ImportJsCssProvider attr, boolean isHtmlTag) { String[] jses = getImportedJS(attr); StringBuilder jsBuffer = new StringBuilder(); for (String importString : jses) { try { // 替换 importString = TemplateUtils.render(importString, ca); jsBuffer.append("<script type=\"text/javascript\" src=\""); if (IOUtils.isOnlineUrl(importString)) { jsBuffer.append(importString); } else { jsBuffer.append(SateVariableManager.get(WebServerConstants.FINE_CONTEXT_PATH)) .append(importString.startsWith(CoreConstants.SEPARATOR) ? importString : CoreConstants.SEPARATOR + importString); } jsBuffer.append("\"></script>").append('\n'); } catch (Exception e) { // 模板转换异常 doNothing } } return isHtmlTag ? jsBuffer.toString() : CodeUtils.javascriptEncode(jsBuffer.toString()); } /** * 获取全局的与当前对象需要引入的css * * @param attr 当前对象 * @return 需要引入的css数组 * @date 2014-12-3-下午7:47:10 */ private static String[] getImportedCSS(ImportJsCssProvider attr) { java.util.Set<String> set = new java.util.LinkedHashSet<String>(); // 用Set避免重复 ImportJsCssProvider globalAttr = getGlobalWebAttr(); if (globalAttr != null) { set.addAll(Arrays.asList(globalAttr.getCSSImport())); } if (attr != null) { set.addAll(Arrays.asList(attr.getCSSImport())); } return set.toArray(new String[0]); } /** * 获取全局设置的web属性 * * @return 全局设置的web属性 * @date 2014-12-4-上午8:51:38 */ private static ImportJsCssProvider getGlobalWebAttr() { Class globalAttr = StableFactory.getMarkedClass(ImportJsCssProvider.XML_TAG, ImportJsCssProvider.class); return (ImportJsCssProvider) ConfigContext.getConfigInstance(globalAttr); } /** * 获取全局的与当前对象需要引入的js * * @param attr 当前对象 * @return 需要引入的js数组 * @date 2014-12-3-下午7:47:10 */ private static String[] getImportedJS(ImportJsCssProvider attr) { java.util.Set<String> set = new java.util.LinkedHashSet<String>(); // 用Set避免重复 ImportJsCssProvider globalAttr = getGlobalWebAttr(); if (globalAttr != null) { set.addAll(Arrays.asList(globalAttr.getJSImport())); } if (attr != null) { set.addAll(Arrays.asList(attr.getJSImport())); } return set.toArray(new String[0]); } } |
package com.fr.data; import com.fr.base.ServerConfig; import com.fr.base.TemplateUtils; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralUtils; import com.fr.general.http.HttpClient; import com.fr.general.web.ParameterConstants; import com.fr.plugin.injectable.PluginModule; import com.fr.stable.CodeUtils; import com.fr.stable.EncodeConstants; import com.fr.stable.StringUtils; import com.fr.stable.fun.PrintWriterProcessor; import com.fr.stable.fun.RequestParameterHandler; import com.fr.stable.fun.ServletURLTransformer; import com.fr.stable.plugin.ExtraClassManagerProvider; import com.fr.stable.web.Device; import com.fr.stable.web.Format; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * @author richie * @date 14/11/17 * @since 8.0 */ public class NetworkHelper { /** * 插件中会用到 */ @SuppressWarnings("WeakerAccess") public static final String POST_EMPTY_SESSION = "POST_EMPTY_SESSION"; private static final String DEPRECATED_DEVICE_KEY = "__device__"; private static final String DEVICE_KEY = "deviceType"; /** * 生成一个访问Servelt的相对路径 * * @param req HTTP请求 * @return 当前URL * @date 2014-9-25-下午7:46:46 */ public static String createServletURL(HttpServletRequest req) { return createServletURL(req, ServerConfig.getInstance().getServletName()); } /** * 生成一个访问Servelt的相对路径 * * @param req HTTP请求 * @return 当前URL * @date 2014-9-25-下午7:46:46 */ public static String createServletURL(HttpServletRequest req, String servletName) { StringBuilder urlBuf = new StringBuilder(); // peter:这里必须用相对路径,必须必须, // 比如连云港人民银行那边,如果用户有内外网的防火墙,IP中途会变化的, // 再也找不到原始的IP了,所以必须是相对路径 urlBuf.append(req.getContextPath()); urlBuf.append("/").append(servletName); ExtraClassManagerProvider extra = PluginModule.getAgent(PluginModule.ExtraCore); if (extra != null) { Set<ServletURLTransformer> set = extra.getArray(ServletURLTransformer.XML_TAG); for (ServletURLTransformer transformer : set) { if (transformer.accept(req)) { return transformer.transform(req, urlBuf); } } } return urlBuf.toString(); } /** * 获取req中的 InputStream * * @param req HTTP请求 * @return 输入流 * @date 2014-9-29-下午3:21:14 */ public static InputStream getRequestInputStream(HttpServletRequest req) { //首先从req的REQ_IN的字段中读取,如果读到的是空,说明之前没有被设置 byte[] bytes = (byte[]) req.getAttribute(DataBaseUtils.REQ_IN); if (bytes == null || bytes.length == 0) { //判断输入流有没有被读过,没读的话,返回该输入流 if (req.getAttribute(HttpClient.CLOSED) == null) { try { //直接返回req的接收缓冲区对应的读取流 return req.getInputStream(); } catch (IOException e) { throw new RuntimeException("Network transfer exception", e); } } else { bytes = new byte[0]; } } return new ByteArrayInputStream(bytes); } /** * 获取HTTP请求中指定名字的参数值 * * @param req HTTP请求 * @param paraName 参数名 * @return 参数值 */ public static String getHTTPRequestParameter(HttpServletRequest req, String paraName) { /* * 这个方法用的地方非常多,所有的参数获取都要从这里过 现在对从Browser端过来的参数名与值全部用cjkEncode作处理了 * 由于我们里面自带的很多参数,这些参数的名字都是英文的,就不需要作cjkEncode处理了 * 所以,就先直接用paraName来获取参数值,如果没有能够获得,再cjkEncode一下后从req中读取参数值 */ return getHTTPRequestEncodeParameter(req, paraName, true); } /** * 获取第一个不为空的参数 * * @param req HTTP请求 * @param paraNames 参数列表 * @return 参数值 */ public static String getHTTPRequestParameter(HttpServletRequest req, String... paraNames) { if (paraNames != null) { for (String paraName : paraNames) { String result = getHTTPRequestParameter(req, paraName); if (result != null) { return result; } } } return StringUtils.EMPTY; } /** * 把HTTP请求中指定名字的参数值转化为布尔值 * * @param req HTTP请求 * @param paraName 参数名 * @return boolean 参数值 */ public static boolean getHTTPRequestBoolParameter(HttpServletRequest req, String paraName) { return Boolean.parseBoolean(NetworkHelper.getHTTPRequestParameter(req, paraName)); } /** * 把HTTP请求中指定名字的参数值转化为整数,参数为空或不是整数则返回-1 * * @param req HTTP请求 * @param paraName 参数名 * @return int 参数值 */ public static int getHTTPRequestIntParameter(HttpServletRequest req, String paraName) { return getHTTPRequestIntParameter(req, paraName, -1); } /** * 把HTTP请求中指定名字的参数值转化为整数 * * @param req HTTP请求 * @param paraName 参数名 * @param defaultValue 默认值 * @return 返回req中参数的整数值。参数为空或不是整数则返回defaultValue */ public static int getHTTPRequestIntParameter(HttpServletRequest req, String paraName, int defaultValue) { if (req == null) { return defaultValue; } String parameterValue = getHTTPRequestParameter(req, paraName); Number num = GeneralUtils.string2Number(parameterValue); if (num == null) { return defaultValue; } return num.intValue(); } /** * 获取sessionID * * @param req HTTP请求 * @return session编号 */ public static String getHTTPRequestSessionIDParameter(HttpServletRequest req) { return getHTTPRequestParameter(req, ParameterConstants.SESSION_ID); } /** * 获取文件名 * * @param req HTTP请求 * @return 文件名 */ public static String getHTTPRequestFileNameParameter(HttpServletRequest req) { return getHTTPRequestParameter(req, ParameterConstants.__FILENAME__); } /** * 获取HTTP请求中指定名字的参数值 * * @param req 请求 * @param paraName 参数名 * @param encode 是否 url-decode 解码 * @return String 参数值 */ public static String getHTTPRequestEncodeParameter(HttpServletRequest req, String paraName, boolean encode) { ExtraClassManagerProvider provider = PluginModule.getAgent(PluginModule.ExtraCore); RequestParameterHandler handler; if (provider == null) { handler = DefaultRequestParameterHandler.getInstance(); } else { handler = provider.getSingle(RequestParameterHandler.XML_TAG); if (handler == null) { handler = DefaultRequestParameterHandler.getInstance(); } } Object returnValue = handler.getParameterFromHeader(req, paraName); if (returnValue == null) { returnValue = handler.getParameterFromRequest(req, paraName); } if (returnValue == null) { returnValue = handler.getParameterFromAttribute(req, paraName); } // alex:从req里面找一下有没有typeSensitive的参数名 if (returnValue == null) { returnValue = handler.getParameterFromJSONParameters(req, paraName); } //wei : bug10637,最后才从session中取。 if (returnValue == null) { returnValue = handler.getParameterFromSession(req, paraName); } if (returnValue == null) { // p:首先decode一下.因为传递过来参数名字可能是[4554], 但是name这个参数是中日韩文字的. // alex:所以需要把文字转成[9853]这样的编码再从req中去取 paraName = CodeUtils.cjkEncode(paraName); returnValue = handler.getParameterFromRequest(req, paraName); if (returnValue == null) { returnValue = handler.getParameterFromAttribute(req, paraName); // peter:需要检查一下,是否是通过Struts传递过来的,连云港人民银行要的. if (returnValue == null) { returnValue = handler.getParameterFromSession(req, paraName); } } } return encode ? checkURLDecode(returnValue) : GeneralUtils.objectToString(returnValue); } /** * post的时候, session取数逻辑要断掉, 不能在从其他地方解析sessionid, 直接return null给外部. * 不return POST_EMPTY_SESSION是为了保持兼容, 外部很多地方直接判断sessionid != null && xxxxx(sessionid) * * @param returnValue 参数值 * @return 是否是 {@link NetworkHelper#POST_EMPTY_SESSION} */ @SuppressWarnings("WeakerAccess") protected static boolean isPostEmptySession(Object returnValue) { return POST_EMPTY_SESSION.equals(returnValue); } private static String checkURLDecode(Object str) { if (str == null) { return null; } //url中传参也是一样encodeURIComponent(encodeURIComponent("+")) //传下拉树的值的话有问题,得再decodeText一次 //看原始bug好像没问题先改回 String temp = CodeUtils.decodeText(String.valueOf(str)); try { //8125 29122 js端需要两次encodeURIComponent(默认用的utf-8编码规则) // neil:第一次encode是去掉特殊字符, 变成ascii字符串(STR_ENC1), 第二次encode是因为web容器得到后会去自动解一次, // 容器req.getParameter自动解的这一次,不管是按 GBK 还是 UTF-8 还是 ISO-8859-1 都好,都能够正确的得到 [STR_ENC1], // 如果js只encode一次, 那么容器那边只能按照utf-8解(客户的tomcat可能有多种编码方式), 否则乱码, 最后java端再去URLDecoder.decode return URLDecoder.decode(temp, EncodeConstants.ENCODING_UTF_8); } catch (UnsupportedEncodingException e) { return null; } catch (IllegalArgumentException e) { //URLDecoder出错 return temp; } } /** * 返回发起指定HTTP请求的URL地址 * * @param req HTTP请求 * @return URL地址 */ public static String getOriginalURL(HttpServletRequest req) { return getOriginalURL(req, true); } /** * 返回发起指定HTTP请求的URL地址 * * @param req req HTTP请求 * @param decodeQueryString 是否解码参数queryString * @return URL地址 */ public static String getOriginalURL(HttpServletRequest req, boolean decodeQueryString) { return getOriginal(req, true, decodeQueryString); } /** * 返回请求的uri(去除协议和域名端口的路径) * * @param request http请求 * @param decodeQueryString 是否解码参数 * @return String 原始请求 uri */ @SuppressWarnings("WeakerAccess") public static String getOriginalURI(HttpServletRequest request, boolean decodeQueryString) { return getOriginal(request, false, decodeQueryString); } private static String getOriginal(HttpServletRequest req, boolean withPrefix, boolean decodeQueryString) { if (req == null) { return ""; } StringBuffer sb = withPrefix ? req.getRequestURL() : new StringBuffer(req.getRequestURI()); Map pMap = req.getParameterMap(); Iterator itr = pMap.entrySet().iterator(); boolean isFirst = !sb.toString().contains("?"); while (itr.hasNext()) { Map.Entry entry = (Map.Entry) itr.next(); if (isFirst) { sb.append('?'); isFirst = false; } else { sb.append('&'); } sb.append(entry.getKey().toString()); sb.append('='); sb.append(getHTTPRequestEncodeParameter(req, entry.getKey().toString(), decodeQueryString)); } // 这边不encode, 主要是cjk(会带上[])和encodeURIComponent(会把url中&a=123也一起编码导致参数失效)都不太合适, // 这个url一般是用来做前台跳转的, 只要在前台跳转的时候encodeURI就行了. return sb.toString(); } /** * 写出指定的模板 * * @param resource 模板路径 * @param response HTTP响应 * @param map 用于替换模板中参数的的参数集 * @throws java.io.IOException e */ public static void writeOutTemplate(String resource, HttpServletResponse response, Map map) throws IOException { PrintWriter writer = createPrintWriter(response); TemplateUtils.dealWithTemplate(resource, writer, map); writer.flush(); writer.close(); } /** * 生成一个打印输出器 * * @param res HTTP响应 * @return 打印输出器 * @throws java.io.IOException e */ public static PrintWriter createPrintWriter(HttpServletResponse res) throws IOException { return createPrintWriter(res, ServerConfig.getInstance().getServerCharset()); } /** * 按指定编码生成打印输出器 * * @param res HTTP响应 * @param charsetName 编码 * @return 打印输出器 * @throws java.io.IOException e */ public static PrintWriter createPrintWriter(HttpServletResponse res, String charsetName) throws IOException { PrintWriterProcessor processor = null; ExtraClassManagerProvider provider = PluginModule.getAgent(PluginModule.ExtraCore); if (provider != null) { processor = provider.getSingle(PrintWriterProcessor.MARK_STRING); } if (processor == null) { processor = DefaultPrintWriterProcessor.getInstance(); } return processor.createPrintWriter(res, charsetName); } /** * 清楚缓存设置 * * @param res HTTP响应 */ public static void setCacheSettings(HttpServletResponse res) { //marks:ie6不是嵌在网页中情况下,点保存正常,点打开就出现问题! //marks:要对cache进行配置和给其权限,支持https // carl:设置不用缓存,生存周期设个3秒,不然会导致bug0004207. res.setHeader("Cache-Control", "public"); res.setHeader("Cache-Control", "max-age=3"); // 需要首先reset一下,保证buffer里面没有其他东西. // 在Weblogic里面常常没有清空buffer里面的东西. res.reset(); } /** * 根据网络请求判定发起请求的设备 * * @param req HTTP请求 * @return 设备类型 */ public static Device getDevice(HttpServletRequest req) { String device = getDeviceType(req); if (StringUtils.isNotBlank(device)) { return Device.parse(device); } //wei: 这边判断是不是移动端的逻辑虽然不是很准确,但是现有代码有很多都是根据这个逻辑来的改准确了反而出问题,还是改回原先的写法. return Device.parse(NetworkHelper.getHTTPRequestParameter(req, DEPRECATED_DEVICE_KEY)); } public static Format getResponseContentFormat(HttpServletRequest req) { Device device = getDevice(req); if (device.isMobile()) { return Format.JSON; } return Format.parse(NetworkHelper.getHTTPRequestParameter(req, "__format__")); } /** * 从Cookie获取token * @param request request * @return token */ public static String getTokenFromCookie(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (ComparatorUtils.equals(cookie.getName(), ParameterConstants.TOKEN_NAME)) { return cookie.getValue(); } } } return null; } /** * 从Header Authorization获取token * @param request request * @return token */ public static String getTokenFromHeader(HttpServletRequest request) { String authorization = request.getHeader(ParameterConstants.AUTHORIZATION_HEADER); if (StringUtils.isNotEmpty(authorization)) { return authorization.substring(ParameterConstants.AUTHORIZATION_PREFIX.length()); } else { return StringUtils.EMPTY; } } /** * 从Parameter获取token * @param request request * @return token */ public static String getTokenFromParameter(HttpServletRequest request) { return getHTTPRequestParameter(request, ParameterConstants.TOKEN_NAME); } private static String getDeviceType(HttpServletRequest req) { String deviceType = req.getHeader(DEVICE_KEY); if (StringUtils.isNotBlank(deviceType)) { return deviceType; } deviceType = (String) req.getAttribute(DEVICE_KEY); if (StringUtils.isNotBlank(deviceType)) { return deviceType; } deviceType = NetworkHelper.getHTTPRequestParameter(req, DEVICE_KEY); if (StringUtils.isNotBlank(deviceType)) { return deviceType; } deviceType = req.getHeader(DEPRECATED_DEVICE_KEY); if (StringUtils.isNotBlank(deviceType)) { return deviceType; } return (String) req.getAttribute(DEPRECATED_DEVICE_KEY); } } |
WebUtils是帆软产品内对请求信息获取的工具类封装,该工具类提供了对请求信息进行额外处理的的入口。
com.fr.stable.fun.RequestParameterHandler
无