package com.wugui.datax.admin.util; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import org.springframework.http.HttpHeaders; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; import java.util.Map.Entry; /** * Http与Servlet工具类 * * @author [email protected] * @version 1.0 * @since 2019/6/15 */ 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; /** * 获取当前请求对象 * controller.xml: <listener><listener-class> * org.springframework.controller.context.request.RequestContextListener * </listener-class></listener> */ 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; } } /** * 获取当前相应对象 * controller.xml: <filter><filter-name>requestContextFilter</filter-name><filter-class> * org.springframework.controller.filter.RequestContextFilter</filter-class></filter><filter-mapping> * <filter-name>requestContextFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> */ public static HttpServletResponse getResponse() { HttpServletResponse response; try { response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); if (response == null) { return null; } } catch (Exception e) { return null; } return response; } /*** * 获取 request 中 json 字符串的内容 * @param request * @return : <code>byte[]</code> * @throws IOException */ public static String getRequestJsonString(HttpServletRequest request) throws IOException { String submitMehtod = request.getMethod(); // GET if (submitMehtod.equals("GET")) { if (StrUtil.isNotEmpty(request.getQueryString())) { return new String(request.getQueryString().getBytes("iso-8859-1"), "utf-8").replaceAll("%22", "\""); } else { return new String("".getBytes("iso-8859-1"), "utf-8").replaceAll("%22", "\""); } // POST } else { return getRequestPostStr(request); } } /** * 描述:获取 post 请求的 byte[] 数组 * <pre> * 举例: * </pre> * * @param request * @return * @throws IOException */ public static byte[] getRequestPostBytes(HttpServletRequest request) throws IOException { int contentLength = request.getContentLength(); if (contentLength < 0) { return null; } byte buffer[] = new byte[contentLength]; for (int i = 0; i < contentLength; ) { int readlen = request.getInputStream().read(buffer, i, contentLength - i); if (readlen == -1) { break; } i += readlen; } return buffer; } /** * 描述:获取 post 请求内容 * <pre> * 举例: * </pre> * * @param request * @return * @throws IOException */ public static String getRequestPostStr(HttpServletRequest request) throws IOException { byte buffer[] = getRequestPostBytes(request); String charEncoding = request.getCharacterEncoding(); if (charEncoding == null) { charEncoding = "UTF-8"; } return new String(buffer, charEncoding); } /** * 是否是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 (StrUtil.containsAnyIgnoreCase(uri, ".json", ".xml")) { return true; } String ajax = request.getParameter("__ajax"); if (StrUtil.containsAnyIgnoreCase(ajax, "json", "xml")) { return true; } return false; } /** * 将字符串渲染到客户端 * * @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<String, Object> getParameters() { return getParameters(getRequest()); } /** * 获得请求参数Map */ public static Map<String, Object> getParameters(ServletRequest request) { if (request == null) { return CollectionUtil.newHashMap(); } return getParametersStartingWith(request, ""); } /** * 取得带相同前缀的Request Parameters, copy from spring WebUtils. * 返回的结果的Parameter名已去除前缀. */ @SuppressWarnings("rawtypes") public static Map<String, Object> getParametersStartingWith(ServletRequest request, String prefix) { Enumeration paramNames = request.getParameterNames(); Map<String, Object> params = new TreeMap<String, Object>(); 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<String, Object> params, String prefix) { StringBuilder queryStringBuilder = new StringBuilder(); String pre = prefix; if (pre == null) { pre = ""; } Iterator<Entry<String, Object>> it = params.entrySet().iterator(); while (it.hasNext()) { Entry<String, Object> 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<String, Object> getExtParams(ServletRequest request) { Map<String, Object> paramMap = null; String params = StrUtil.trim(request.getParameter(DEFAULT_PARAMS_PARAM)); if (StrUtil.isNotBlank(params) && StrUtil.startWith(params, "{")) { paramMap = (Map) JSONUtil.parseObj(params); } 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; } }