diff --git a/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java b/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java index bc037d19..4d6041de 100644 --- a/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java +++ b/common/src/main/java/com/jeesite/common/web/http/ServletUtils.java @@ -1,439 +1,439 @@ -/** - * Copyright (c) 2013-Now http://jeesite.com All rights reserved. - */ -package com.jeesite.common.web.http; - -import java.io.IOException; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.StringTokenizer; -import java.util.TreeMap; - -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.Validate; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import com.jeesite.common.collect.MapUtils; -import com.jeesite.common.io.PropertiesUtils; -import com.jeesite.common.lang.StringUtils; -import com.jeesite.common.mapper.JsonMapper; -import com.jeesite.common.mapper.XmlMapper; - -/** - * Http与Servlet工具类. - * @author ThinkGem - * @version 2014-8-19 - */ -public class ServletUtils { - - public static final String DEFAULT_PARAMS_PARAM = "params"; // 登录扩展参数(JSON字符串)优先级高于扩展参数前缀 - public static final String DEFAULT_PARAM_PREFIX_PARAM = "param_"; // 扩展参数前缀 - - // 定义静态文件后缀;静态文件排除URI地址 - private static String[] staticFiles; - private static String[] staticFileExcludeUri; - - /** - * 获取当前请求对象 - * web.xml: - * org.springframework.web.context.request.RequestContextListener - * - */ - public static HttpServletRequest getRequest(){ - HttpServletRequest request = null; - try{ - request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); - if (request == null){ - return null; - } - return request; - }catch(Exception e){ - return null; - } - } - - /** - * 获取当前相应对象 - * web.xml: requestContextFilter - * org.springframework.web.filter.RequestContextFilter - * requestContextFilter/* - */ - public static HttpServletResponse getResponse(){ - HttpServletResponse response = null; - try{ - response = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getResponse(); - if (response == null){ - return null; - } - }catch(Exception e){ - return null; - } - return response; - } - - /** - * 是否是Ajax异步请求 - * @param request - */ - public static boolean isAjaxRequest(HttpServletRequest request){ - - String accept = request.getHeader("accept"); - if (accept != null && accept.indexOf("application/json") != -1){ - return true; - } - - String xRequestedWith = request.getHeader("X-Requested-With"); - if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1){ - return true; - } - - String uri = request.getRequestURI(); - if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")){ - return true; - } - - String ajax = request.getParameter("__ajax"); - if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")){ - return true; - } - - return false; - } - - /** - * 判断访问URI是否是静态文件请求 - * @throws Exception - */ - public static boolean isStaticFile(String uri){ - if (staticFiles == null){ - PropertiesUtils pl = PropertiesUtils.getInstance(); - try{ - staticFiles = StringUtils.split(pl.getProperty("web.staticFile"), ","); - staticFileExcludeUri = StringUtils.split(pl.getProperty("web.staticFileExcludeUri"), ","); - }catch(NoSuchElementException nsee){ - ; // 什么也不做 - } - if (staticFiles == null){ - try { - throw new Exception("检测到“jeesite.yml”中没有配置“web.staticFile”属性。" - + "配置示例:\n#静态文件后缀\nweb.staticFile=.css,.js,.png,.jpg,.gif," - + ".jpeg,.bmp,.ico,.swf,.psd,.htc,.crx,.xpi,.exe,.ipa,.apk"); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - if (staticFileExcludeUri != null){ - for (String s : staticFileExcludeUri){ - if (StringUtils.contains(uri, s)){ - return false; - } - } - } - if (StringUtils.endsWithAny(uri, staticFiles)){ - return true; - } - return false; - } - - /** - * 返回结果JSON字符串(支持JsonP,请求参数加:__callback=回调函数名) - * @param result Global.TRUE or Globle.False - * @param message 执行消息 - * @param data 消息数据 - * @return JSON字符串:{result:'true',message:''} - */ - public static String renderResult(String result, String message) { - return renderResult(result, message, null); - } - - /** - * 返回结果JSON字符串(支持JsonP,请求参数加:__callback=回调函数名) - * @param result Global.TRUE or Globle.False - * @param message 执行消息 - * @param data 消息数据 - * @return JSON字符串:{result:'true',message:'', if map then key:value,key2:value2... else data:{} } - */ - @SuppressWarnings("unchecked") - public static String renderResult(String result, String message, Object data) { - Map resultMap = MapUtils.newHashMap(); - resultMap.put("result", result); - resultMap.put("message", message); - if (data != null){ - if (data instanceof Map){ - resultMap.putAll((Map)data); - }else{ - resultMap.put("data", data); - } - } - HttpServletRequest request = ServletUtils.getRequest(); - String uri = request.getRequestURI(); - if (StringUtils.endsWithIgnoreCase(uri, ".xml")){ - return XmlMapper.toXml(resultMap); - }else{ - String functionName = request.getParameter("__callback"); - if (StringUtils.isNotBlank(functionName)){ - return JsonMapper.toJsonp(functionName, resultMap); - }else{ - return JsonMapper.toJson(resultMap); - } - } - - } - - /** - * 直接将结果JSON字符串渲染到客户端(支持JsonP,请求参数加:__callback=回调函数名) - * @param response 渲染对象:{result:'true',message:'',data:{}} - * @param result Global.TRUE or Globle.False - * @param message 执行消息 - * @return null - */ - public static String renderResult(HttpServletResponse response, String result, String message) { - return renderString(response, renderResult(result, message), null); - } - - /** - * 直接将结果JSON字符串渲染到客户端(支持JsonP,请求参数加:__callback=回调函数名) - * @param response 渲染对象:{result:'true',message:'',data:{}} - * @param result Global.TRUE or Globle.False - * @param message 执行消息 - * @param data 消息数据 - * @return null - */ - public static String renderResult(HttpServletResponse response, String result, String message, Object data) { - return renderString(response, renderResult(result, message, data), null); - } - - /** - * 将对象转换为JSON字符串渲染到客户端(支持JsonP,请求参数加:__callback=回调函数名) - * @param response 渲染对象 - * @param object 待转换JSON并渲染的对象 - * @return null - */ - public static String renderObject(HttpServletResponse response, Object object) { - HttpServletRequest request = ServletUtils.getRequest(); - String uri = request.getRequestURI(); - if (StringUtils.endsWithIgnoreCase(uri, ".xml")){ - return XmlMapper.toXml(object); - }else{ - String functionName = request.getParameter("__callback"); - if (StringUtils.isNotBlank(functionName)){ - return renderString(response, JsonMapper.toJsonp(functionName, object)); - }else{ - return renderString(response, JsonMapper.toJson(object)); - } - } - } - - /** - * 将字符串渲染到客户端 - * @param response 渲染对象 - * @param string 待渲染的字符串 - * @return null - */ - public static String renderString(HttpServletResponse response, String string) { - return renderString(response, string, null); - } - - /** - * 将字符串渲染到客户端 - * @param response 渲染对象 - * @param string 待渲染的字符串 - * @return null - */ - public static String renderString(HttpServletResponse response, String string, String type) { - try { -// response.reset(); // 先注释掉,否则以前设置的Header会被清理掉,如ajax登录设置记住我Cookie - response.setContentType(type == null ? "application/json" : type); - response.setCharacterEncoding("utf-8"); - response.getWriter().print(string); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - /** - * 获得请求参数值 - */ - public static String getParameter(String name) { - HttpServletRequest request = getRequest(); - if (request == null){ - return null; - } - return request.getParameter(name); - } - - /** - * 获得请求参数Map - */ - public static Map getParameters() { - return getParameters(getRequest()); - } - - /** - * 获得请求参数Map - */ - public static Map getParameters(ServletRequest request) { - if (request == null){ - return MapUtils.newHashMap(); - } - return getParametersStartingWith(request, ""); - } - - /** - * 取得带相同前缀的Request Parameters, copy from spring WebUtils. - * 返回的结果的Parameter名已去除前缀. - */ - @SuppressWarnings("rawtypes") - public static Map getParametersStartingWith(ServletRequest request, String prefix) { - Validate.notNull(request, "Request must not be null"); - Enumeration paramNames = request.getParameterNames(); - Map params = new TreeMap(); - String pre = prefix; - if (pre == null) { - pre = ""; - } - while (paramNames != null && paramNames.hasMoreElements()) { - String paramName = (String) paramNames.nextElement(); - if ("".equals(pre) || paramName.startsWith(pre)) { - String unprefixed = paramName.substring(pre.length()); - String[] values = request.getParameterValues(paramName); - if (values == null || values.length == 0) { - values = new String[]{}; - // Do nothing, no values found at all. - } else if (values.length > 1) { - params.put(unprefixed, values); - } else { - params.put(unprefixed, values[0]); - } - } - } - return params; - } - - /** - * 组合Parameters生成Query String的Parameter部分,并在paramter name上加上prefix. - */ - public static String encodeParameterStringWithPrefix(Map params, String prefix) { - StringBuilder queryStringBuilder = new StringBuilder(); - String pre = prefix; - if (pre == null) { - pre = ""; - } - Iterator> it = params.entrySet().iterator(); - while (it.hasNext()) { - Entry entry = it.next(); - queryStringBuilder.append(pre).append(entry.getKey()).append("=").append(entry.getValue()); - if (it.hasNext()) { - queryStringBuilder.append("&"); - } - } - return queryStringBuilder.toString(); - } - - /** - * 从请求对象中扩展参数数据,格式:JSON 或 param_ 开头的参数 - * @param request 请求对象 - * @return 返回Map对象 - */ - public static Map getExtParams(ServletRequest request) { - Map paramMap = null; - String params = StringUtils.trim(request.getParameter(DEFAULT_PARAMS_PARAM)); - if (StringUtils.isNotBlank(params) && StringUtils.startsWith(params, "{")) { - paramMap = JsonMapper.fromJson(params, Map.class); - } else { - paramMap = getParametersStartingWith(ServletUtils.getRequest(), DEFAULT_PARAM_PREFIX_PARAM); - } - return paramMap; - } - - /** - * 设置客户端缓存过期时间 的Header. - */ - public static void setExpiresHeader(HttpServletResponse response, long expiresSeconds) { - // Http 1.0 header, set a fix expires date. - response.setDateHeader(HttpHeaders.EXPIRES, System.currentTimeMillis() + expiresSeconds * 1000); - // Http 1.1 header, set a time after now. - response.setHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=" + expiresSeconds); - } - - /** - * 设置禁止客户端缓存的Header. - */ - public static void setNoCacheHeader(HttpServletResponse response) { - // Http 1.0 header - response.setDateHeader(HttpHeaders.EXPIRES, 1L); - response.addHeader(HttpHeaders.PRAGMA, "no-cache"); - // Http 1.1 header - response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0"); - } - - /** - * 设置LastModified Header. - */ - public static void setLastModifiedHeader(HttpServletResponse response, long lastModifiedDate) { - response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModifiedDate); - } - - /** - * 设置Etag Header. - */ - public static void setEtag(HttpServletResponse response, String etag) { - response.setHeader(HttpHeaders.ETAG, etag); - } - - /** - * 根据浏览器If-Modified-Since Header, 计算文件是否已被修改. - * 如果无修改, checkIfModify返回false ,设置304 not modify status. - * @param lastModified 内容的最后修改时间. - */ - public static boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response, - long lastModified) { - long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); - if ((ifModifiedSince != -1) && (lastModified < ifModifiedSince + 1000)) { - response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - return false; - } - return true; - } - - /** - * 根据浏览器 If-None-Match Header, 计算Etag是否已无效. - * 如果Etag有效, checkIfNoneMatch返回false, 设置304 not modify status. - * @param etag 内容的ETag. - */ - public static boolean checkIfNoneMatchEtag(HttpServletRequest request, HttpServletResponse response, String etag) { - String headerValue = request.getHeader(HttpHeaders.IF_NONE_MATCH); - if (headerValue != null) { - boolean conditionSatisfied = false; - if (!"*".equals(headerValue)) { - StringTokenizer commaTokenizer = new StringTokenizer(headerValue, ","); - - while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { - String currentToken = commaTokenizer.nextToken(); - if (currentToken.trim().equals(etag)) { - conditionSatisfied = true; - } - } - } else { - conditionSatisfied = true; - } - - if (conditionSatisfied) { - response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); - response.setHeader(HttpHeaders.ETAG, etag); - return false; - } - } - return true; - } - -} +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + */ +package com.jeesite.common.web.http; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; +import java.util.TreeMap; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.Validate; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import com.jeesite.common.collect.MapUtils; +import com.jeesite.common.io.PropertiesUtils; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.mapper.JsonMapper; +import com.jeesite.common.mapper.XmlMapper; + +/** + * Http与Servlet工具类. + * @author ThinkGem + * @version 2014-8-19 + */ +public class ServletUtils { + + public static final String DEFAULT_PARAMS_PARAM = "params"; // 登录扩展参数(JSON字符串)优先级高于扩展参数前缀 + public static final String DEFAULT_PARAM_PREFIX_PARAM = "param_"; // 扩展参数前缀 + + // 定义静态文件后缀;静态文件排除URI地址 + private static String[] staticFiles; + private static String[] staticFileExcludeUri; + + /** + * 获取当前请求对象 + * web.xml: + * org.springframework.web.context.request.RequestContextListener + * + */ + public static HttpServletRequest getRequest(){ + HttpServletRequest request = null; + try{ + request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); + if (request == null){ + return null; + } + return request; + }catch(Exception e){ + return null; + } + } + + /** + * 获取当前相应对象 + * web.xml: requestContextFilter + * org.springframework.web.filter.RequestContextFilter + * requestContextFilter/* + */ + public static HttpServletResponse getResponse(){ + HttpServletResponse response = null; + try{ + response = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getResponse(); + if (response == null){ + return null; + } + }catch(Exception e){ + return null; + } + return response; + } + + /** + * 是否是Ajax异步请求 + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request){ + + String accept = request.getHeader("accept"); + if (accept != null && accept.indexOf("application/json") != -1){ + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1){ + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")){ + return true; + } + + String ajax = request.getParameter("__ajax"); + if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")){ + return true; + } + + return false; + } + + /** + * 判断访问URI是否是静态文件请求 + * @throws Exception + */ + public static boolean isStaticFile(String uri){ + if (staticFiles == null){ + PropertiesUtils pl = PropertiesUtils.getInstance(); + try{ + staticFiles = StringUtils.split(pl.getProperty("web.staticFile"), ","); + staticFileExcludeUri = StringUtils.split(pl.getProperty("web.staticFileExcludeUri"), ","); + }catch(NoSuchElementException nsee){ + ; // 什么也不做 + } + if (staticFiles == null){ + try { + throw new Exception("检测到“jeesite.yml”中没有配置“web.staticFile”属性。" + + "配置示例:\n#静态文件后缀\nweb.staticFile=.css,.js,.png,.jpg,.gif," + + ".jpeg,.bmp,.ico,.swf,.psd,.htc,.crx,.xpi,.exe,.ipa,.apk"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + if (staticFileExcludeUri != null){ + for (String s : staticFileExcludeUri){ + if (StringUtils.contains(uri, s)){ + return false; + } + } + } + if (StringUtils.endsWithAny(uri, staticFiles)){ + return true; + } + return false; + } + + /** + * 返回结果JSON字符串(支持JsonP,请求参数加:__callback=回调函数名) + * @param result Global.TRUE or Globle.False + * @param message 执行消息 + * @param data 消息数据 + * @return JSON字符串:{result:'true',message:''} + */ + public static String renderResult(String result, String message) { + return renderResult(result, message, null); + } + + /** + * 返回结果JSON字符串(支持JsonP,请求参数加:__callback=回调函数名) + * @param result Global.TRUE or Globle.False + * @param message 执行消息 + * @param data 消息数据 + * @return JSON字符串:{result:'true',message:'', if map then key:value,key2:value2... else data:{} } + */ + @SuppressWarnings("unchecked") + public static String renderResult(String result, String message, Object data) { + Map resultMap = MapUtils.newHashMap(); + resultMap.put("result", result); + resultMap.put("message", message); + if (data != null){ + if (data instanceof Map){ + resultMap.putAll((Map)data); + }else{ + resultMap.put("data", data); + } + } + HttpServletRequest request = ServletUtils.getRequest(); + String uri = request.getRequestURI(); + if (StringUtils.endsWithIgnoreCase(uri, ".xml")){ + return XmlMapper.toXml(resultMap); + }else{ + String functionName = request.getParameter("__callback"); + if (StringUtils.isNotBlank(functionName)){ + return JsonMapper.toJsonp(functionName, resultMap); + }else{ + return JsonMapper.toJson(resultMap); + } + } + + } + + /** + * 直接将结果JSON字符串渲染到客户端(支持JsonP,请求参数加:__callback=回调函数名) + * @param response 渲染对象:{result:'true',message:'',data:{}} + * @param result Global.TRUE or Globle.False + * @param message 执行消息 + * @return null + */ + public static String renderResult(HttpServletResponse response, String result, String message) { + return renderString(response, renderResult(result, message), null); + } + + /** + * 直接将结果JSON字符串渲染到客户端(支持JsonP,请求参数加:__callback=回调函数名) + * @param response 渲染对象:{result:'true',message:'',data:{}} + * @param result Global.TRUE or Globle.False + * @param message 执行消息 + * @param data 消息数据 + * @return null + */ + public static String renderResult(HttpServletResponse response, String result, String message, Object data) { + return renderString(response, renderResult(result, message, data), null); + } + + /** + * 将对象转换为JSON字符串渲染到客户端(支持JsonP,请求参数加:__callback=回调函数名) + * @param response 渲染对象 + * @param object 待转换JSON并渲染的对象 + * @return null + */ + public static String renderObject(HttpServletResponse response, Object object) { + HttpServletRequest request = ServletUtils.getRequest(); + String uri = request.getRequestURI(); + if (StringUtils.endsWithIgnoreCase(uri, ".xml")){ + return XmlMapper.toXml(object); + }else{ + String functionName = request.getParameter("__callback"); + if (StringUtils.isNotBlank(functionName)){ + return renderString(response, JsonMapper.toJsonp(functionName, object)); + }else{ + return renderString(response, JsonMapper.toJson(object)); + } + } + } + + /** + * 将字符串渲染到客户端 + * @param response 渲染对象 + * @param string 待渲染的字符串 + * @return null + */ + public static String renderString(HttpServletResponse response, String string) { + return renderString(response, string, null); + } + + /** + * 将字符串渲染到客户端 + * @param response 渲染对象 + * @param string 待渲染的字符串 + * @return null + */ + public static String renderString(HttpServletResponse response, String string, String type) { + try { +// response.reset(); // 先注释掉,否则以前设置的Header会被清理掉,如ajax登录设置记住我Cookie + response.setContentType(type == null ? "application/json" : type); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 获得请求参数值 + */ + public static String getParameter(String name) { + HttpServletRequest request = getRequest(); + if (request == null){ + return null; + } + return request.getParameter(name); + } + + /** + * 获得请求参数Map + */ + public static Map getParameters() { + return getParameters(getRequest()); + } + + /** + * 获得请求参数Map + */ + public static Map getParameters(ServletRequest request) { + if (request == null){ + return MapUtils.newHashMap(); + } + return getParametersStartingWith(request, ""); + } + + /** + * 取得带相同前缀的Request Parameters, copy from spring WebUtils. + * 返回的结果的Parameter名已去除前缀. + */ + @SuppressWarnings("rawtypes") + public static Map getParametersStartingWith(ServletRequest request, String prefix) { + Validate.notNull(request, "Request must not be null"); + Enumeration paramNames = request.getParameterNames(); + Map params = new TreeMap(); + String pre = prefix; + if (pre == null) { + pre = ""; + } + while (paramNames != null && paramNames.hasMoreElements()) { + String paramName = (String) paramNames.nextElement(); + if ("".equals(pre) || paramName.startsWith(pre)) { + String unprefixed = paramName.substring(pre.length()); + String[] values = request.getParameterValues(paramName); + if (values == null || values.length == 0) { + values = new String[]{}; + // Do nothing, no values found at all. + } else if (values.length > 1) { + params.put(unprefixed, values); + } else { + params.put(unprefixed, values[0]); + } + } + } + return params; + } + + /** + * 组合Parameters生成Query String的Parameter部分,并在paramter name上加上prefix. + */ + public static String encodeParameterStringWithPrefix(Map params, String prefix) { + StringBuilder queryStringBuilder = new StringBuilder(); + String pre = prefix; + if (pre == null) { + pre = ""; + } + Iterator> it = params.entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + queryStringBuilder.append(pre).append(entry.getKey()).append("=").append(entry.getValue()); + if (it.hasNext()) { + queryStringBuilder.append("&"); + } + } + return queryStringBuilder.toString(); + } + + /** + * 从请求对象中扩展参数数据,格式:JSON 或 param_ 开头的参数 + * @param request 请求对象 + * @return 返回Map对象 + */ + public static Map getExtParams(ServletRequest request) { + Map paramMap = null; + String params = StringUtils.trim(request.getParameter(DEFAULT_PARAMS_PARAM)); + if (StringUtils.isNotBlank(params) && StringUtils.startsWith(params, "{")) { + paramMap = JsonMapper.fromJson(params, Map.class); + } else { + paramMap = getParametersStartingWith(ServletUtils.getRequest(), DEFAULT_PARAM_PREFIX_PARAM); + } + return paramMap; + } + + /** + * 设置客户端缓存过期时间 的Header. + */ + public static void setExpiresHeader(HttpServletResponse response, long expiresSeconds) { + // Http 1.0 header, set a fix expires date. + response.setDateHeader(HttpHeaders.EXPIRES, System.currentTimeMillis() + expiresSeconds * 1000); + // Http 1.1 header, set a time after now. + response.setHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=" + expiresSeconds); + } + + /** + * 设置禁止客户端缓存的Header. + */ + public static void setNoCacheHeader(HttpServletResponse response) { + // Http 1.0 header + response.setDateHeader(HttpHeaders.EXPIRES, 1L); + response.addHeader(HttpHeaders.PRAGMA, "no-cache"); + // Http 1.1 header + response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0"); + } + + /** + * 设置LastModified Header. + */ + public static void setLastModifiedHeader(HttpServletResponse response, long lastModifiedDate) { + response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModifiedDate); + } + + /** + * 设置Etag Header. + */ + public static void setEtag(HttpServletResponse response, String etag) { + response.setHeader(HttpHeaders.ETAG, etag); + } + + /** + * 根据浏览器If-Modified-Since Header, 计算文件是否已被修改. + * 如果无修改, checkIfModify返回false ,设置304 not modify status. + * @param lastModified 内容的最后修改时间. + */ + public static boolean checkIfModifiedSince(HttpServletRequest request, HttpServletResponse response, + long lastModified) { + long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE); + if ((ifModifiedSince != -1) && (lastModified < ifModifiedSince + 1000)) { + response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + return false; + } + return true; + } + + /** + * 根据浏览器 If-None-Match Header, 计算Etag是否已无效. + * 如果Etag有效, checkIfNoneMatch返回false, 设置304 not modify status. + * @param etag 内容的ETag. + */ + public static boolean checkIfNoneMatchEtag(HttpServletRequest request, HttpServletResponse response, String etag) { + String headerValue = request.getHeader(HttpHeaders.IF_NONE_MATCH); + if (headerValue != null) { + boolean conditionSatisfied = false; + if (!"*".equals(headerValue)) { + StringTokenizer commaTokenizer = new StringTokenizer(headerValue, ","); + + while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) { + String currentToken = commaTokenizer.nextToken(); + if (currentToken.trim().equals(etag)) { + conditionSatisfied = true; + } + } + } else { + conditionSatisfied = true; + } + + if (conditionSatisfied) { + response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + response.setHeader(HttpHeaders.ETAG, etag); + return false; + } + } + return true; + } + +} diff --git a/web/db/oracle/core.sql b/web/db/oracle/core.sql new file mode 100644 index 00000000..cadf227c --- /dev/null +++ b/web/db/oracle/core.sql @@ -0,0 +1,136 @@ + +/* Drop Tables */ + +DROP TABLE test_data CASCADE CONSTRAINTS; +DROP TABLE test_data_child CASCADE CONSTRAINTS; +DROP TABLE test_tree CASCADE CONSTRAINTS; + + + + +/* Create Tables */ + +-- test_data +CREATE TABLE test_data +( + id varchar2(64) NOT NULL, + test_input varchar2(200), + test_textarea varchar2(200), + test_select varchar2(10), + test_select_multiple varchar2(200), + test_radio varchar2(10), + test_checkbox varchar2(200), + test_date timestamp, + test_datetime timestamp, + test_user_code varchar2(64), + test_office_code varchar2(64), + test_company_code varchar2(64), + status char(1) DEFAULT '0' NOT NULL, + create_by varchar2(64) NOT NULL, + create_date timestamp NOT NULL, + update_by varchar2(64) NOT NULL, + update_date timestamp NOT NULL, + remarks nvarchar2(500), + PRIMARY KEY (id) +); + + +-- test_data_child +CREATE TABLE test_data_child +( + id varchar2(64) NOT NULL, + test_sort number(10,0), + test_data_id varchar2(64), + test_input varchar2(200), + test_textarea varchar2(200), + test_select varchar2(10), + test_select_multiple varchar2(200), + test_radio varchar2(10), + test_checkbox varchar2(200), + test_date timestamp, + test_datetime timestamp, + test_user_code varchar2(64), + test_office_code varchar2(64), + test_company_code varchar2(64), + PRIMARY KEY (id) +); + + +-- test_tree +CREATE TABLE test_tree +( + id varchar2(64) NOT NULL, + parent_code varchar2(64) NOT NULL, + parent_codes varchar2(2000) NOT NULL, + tree_sort number(10) NOT NULL, + tree_sorts varchar2(1200) NOT NULL, + tree_leaf char(1) NOT NULL, + tree_level number(4) NOT NULL, + tree_names varchar2(2000) NOT NULL, + tree_name nvarchar2(200) NOT NULL, + status char(1) DEFAULT '0' NOT NULL, + create_by varchar2(64) NOT NULL, + create_date timestamp NOT NULL, + update_by varchar2(64) NOT NULL, + update_date timestamp NOT NULL, + remarks nvarchar2(500), + PRIMARY KEY (id) +); + + + +/* Comments */ + +COMMENT ON TABLE test_data IS 'test_data'; +COMMENT ON COLUMN test_data.id IS '编号'; +COMMENT ON COLUMN test_data.test_input IS '单行文本'; +COMMENT ON COLUMN test_data.test_textarea IS '多行文本'; +COMMENT ON COLUMN test_data.test_select IS '下拉框'; +COMMENT ON COLUMN test_data.test_select_multiple IS '下拉多选'; +COMMENT ON COLUMN test_data.test_radio IS '单选框'; +COMMENT ON COLUMN test_data.test_checkbox IS '复选框'; +COMMENT ON COLUMN test_data.test_date IS '日期选择'; +COMMENT ON COLUMN test_data.test_datetime IS '日期时间选择'; +COMMENT ON COLUMN test_data.test_user_code IS '用户选择'; +COMMENT ON COLUMN test_data.test_office_code IS '部门选择'; +COMMENT ON COLUMN test_data.test_company_code IS '公司选择'; +COMMENT ON COLUMN test_data.status IS '状态(0正常 1删除 2停用)'; +COMMENT ON COLUMN test_data.create_by IS '创建者'; +COMMENT ON COLUMN test_data.create_date IS '创建时间'; +COMMENT ON COLUMN test_data.update_by IS '更新者'; +COMMENT ON COLUMN test_data.update_date IS '更新时间'; +COMMENT ON COLUMN test_data.remarks IS '备注信息'; +COMMENT ON TABLE test_data_child IS 'test_data_child'; +COMMENT ON COLUMN test_data_child.id IS '编号'; +COMMENT ON COLUMN test_data_child.test_sort IS '排序号'; +COMMENT ON COLUMN test_data_child.test_data_id IS '父表主键'; +COMMENT ON COLUMN test_data_child.test_input IS '单行文本'; +COMMENT ON COLUMN test_data_child.test_textarea IS '多行文本'; +COMMENT ON COLUMN test_data_child.test_select IS '下拉框'; +COMMENT ON COLUMN test_data_child.test_select_multiple IS '下拉多选'; +COMMENT ON COLUMN test_data_child.test_radio IS '单选框'; +COMMENT ON COLUMN test_data_child.test_checkbox IS '复选框'; +COMMENT ON COLUMN test_data_child.test_date IS '日期选择'; +COMMENT ON COLUMN test_data_child.test_datetime IS '日期时间选择'; +COMMENT ON COLUMN test_data_child.test_user_code IS '用户选择'; +COMMENT ON COLUMN test_data_child.test_office_code IS '部门选择'; +COMMENT ON COLUMN test_data_child.test_company_code IS '公司选择'; +COMMENT ON TABLE test_tree IS 'test_tree'; +COMMENT ON COLUMN test_tree.id IS '编号'; +COMMENT ON COLUMN test_tree.parent_code IS '父级编号'; +COMMENT ON COLUMN test_tree.parent_codes IS '所有父级编号'; +COMMENT ON COLUMN test_tree.tree_sort IS '本级排序号(升序)'; +COMMENT ON COLUMN test_tree.tree_sorts IS '所有级别排序号'; +COMMENT ON COLUMN test_tree.tree_leaf IS '是否最末级'; +COMMENT ON COLUMN test_tree.tree_level IS '层次级别'; +COMMENT ON COLUMN test_tree.tree_names IS '全节点名'; +COMMENT ON COLUMN test_tree.tree_name IS '树节点名'; +COMMENT ON COLUMN test_tree.status IS '状态(0正常 1删除 2停用)'; +COMMENT ON COLUMN test_tree.create_by IS '创建者'; +COMMENT ON COLUMN test_tree.create_date IS '创建时间'; +COMMENT ON COLUMN test_tree.update_by IS '更新者'; +COMMENT ON COLUMN test_tree.update_date IS '更新时间'; +COMMENT ON COLUMN test_tree.remarks IS '备注信息'; + + + diff --git a/web/db/test.erm b/web/db/test.erm index deff4b53..4d02e4f3 100644 --- a/web/db/test.erm +++ b/web/db/test.erm @@ -12,7 +12,7 @@ 0 1.0 0 - 0 + 48 128 128