All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.hasor.web.invoker.HttpParameters Maven / Gradle / Ivy

There is a newer version: 4.2.5
Show newest version
/*
 * Copyright 2008-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.hasor.web.invoker;
import net.hasor.utils.StringUtils;
import net.hasor.utils.function.ESupplier;
import net.hasor.web.Invoker;
import net.hasor.web.Mapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Http 参数解析,对参数的操作不会影响到 request 和 response
 * @version : 2020-06-28
 * @author 赵永春 ([email protected])
 */
public final class HttpParameters {
    private static final Logger                                 logger            = LoggerFactory.getLogger(InvokerCaller.class);
    private static final ThreadLocal                   invokerLocal      = new ThreadLocal<>();
    private static final ThreadLocal>> headerParamLocal  = new ThreadLocal<>();
    private static final ThreadLocal>> cookieParamLocal  = new ThreadLocal<>();
    private static final ThreadLocal>> pathParamLocal    = new ThreadLocal<>();
    private static final ThreadLocal>> queryParamLocal   = new ThreadLocal<>();
    private static final ThreadLocal>> requestParamLocal = new ThreadLocal<>();

    protected static  T executeWorker(Invoker invoker, ESupplier worker) throws Throwable {
        Objects.requireNonNull(invoker, "invoker is null.");
        try {
            invokerLocal.set(invoker);
            init(invoker, invoker.getHttpRequest());
            return worker.eGet();
        } finally {
            invokerLocal.remove();
            headerParamLocal.remove();
            cookieParamLocal.remove();
            pathParamLocal.remove();
            queryParamLocal.remove();
        }
    }

    private static void init(Invoker invoker, HttpServletRequest httpRequest) {
        //
        // cookie
        Map> cookieMap = new HashMap<>();
        Cookie[] cookies = httpRequest.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                String cookieName = cookie.getName();
                List cookieValue = cookieMap.computeIfAbsent(cookieName, key -> {
                    return new ArrayList<>();
                });
                cookieValue.add(cookie.getValue());
            }
        }
        cookieParamLocal.set(cookieMap);
        //
        // header
        Map> headerMap = new HashMap<>();
        Enumeration headerNames = httpRequest.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String header = headerNames.nextElement();
                Enumeration headers = httpRequest.getHeaders(header);
                if (headers == null) {
                    continue;
                }
                List headerValue = new ArrayList<>();
                while (headers.hasMoreElements()) {
                    headerValue.add(headers.nextElement());
                }
                headerMap.put(header, headerValue);
            }
        }
        headerParamLocal.set(headerMap);
        //
        // query
        String queryString = httpRequest.getQueryString();
        Map> queryMap = new HashMap<>();
        if (StringUtils.isNotBlank(queryString)) {
            String[] params = queryString.split("&");
            for (String pData : params) {
                String encoding = httpRequest.getCharacterEncoding();
                String[] kv = pData.split("=");
                if (kv.length < 2) {
                    continue;
                }
                String k = kv[0].trim();
                String v = kv[1];
                if (StringUtils.isNotBlank(encoding)) {
                    k = urlDecoder(encoding, k);
                    v = urlDecoder(encoding, v);
                }
                //
                List pArray = queryMap.get(k);
                pArray = pArray == null ? new ArrayList<>() : pArray;
                if (!pArray.contains(v)) {
                    pArray.add(v);
                }
                queryMap.put(k, pArray);
            }
        }
        queryParamLocal.set(queryMap);
        //
        // path
        Map> pathMap = new HashMap<>();
        if (invoker != null) {
            Mapping ownerMapping = invoker.ownerMapping();
            if (ownerMapping != null) {
                String requestPath = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
                String matchVar = ownerMapping.getMappingToMatches();
                String matchKey = "(?:\\{(\\w+)\\}){1,}";//  (?:\{(\w+)\}){1,}
                Matcher keyM = Pattern.compile(matchKey).matcher(ownerMapping.getMappingTo());
                Matcher varM = Pattern.compile(matchVar).matcher(requestPath);
                ArrayList keyArray = new ArrayList<>();
                ArrayList varArray = new ArrayList<>();
                while (keyM.find()) {
                    keyArray.add(keyM.group(1));
                }
                varM.find();
                for (int i = 1; i <= varM.groupCount(); i++) {
                    varArray.add(varM.group(i));
                }
                //
                for (int i = 0; i < keyArray.size(); i++) {
                    String k = keyArray.get(i);
                    String v = varArray.get(i);
                    List pArray = pathMap.get(k);
                    pArray = pArray == null ? new ArrayList<>() : pArray;
                    if (!pArray.contains(v)) {
                        pArray.add(v);
                    }
                    pathMap.put(k, pArray);
                }
            }
        }
        pathParamLocal.set(pathMap);
        //
        // request
        Map> requestMap = new HashMap<>();
        Map parameterMap = httpRequest.getParameterMap();
        if (parameterMap != null) {
            parameterMap.forEach((key, value) -> {
                requestMap.put(key, Arrays.asList(value));
            });
        }
        requestParamLocal.set(requestMap);
    }

    private static String urlDecoder(String encoding, String oriData) {
        try {
            if (StringUtils.isNotBlank(oriData)) {
                encoding = URLDecoder.decode(oriData, encoding);
            }
            return encoding;
        } catch (Exception e) {
            logger.warn("use '{}' decode '{}' error.", encoding, oriData);
            return encoding;
        }
    }

    private static Map mapList2Map(Map> mapList) {
        if (mapList == null) {
            return Collections.emptyMap();
        }
        Set headerNames = mapList.keySet();
        Map headerMap = new HashMap<>();
        for (String headerName : headerNames) {
            List stringList = mapList.get(headerName);
            if (!stringList.isEmpty()) {
                headerMap.put(headerName, stringList.get(stringList.size() - 1));
            }
        }
        return headerMap;
    }

    /** 清空并合并, */
    private static boolean clearReplaceMap(Map> target, Map> newData) {
        if (newData == null) {
            return false;
        }
        target.clear();
        target.putAll(newData);
        return true;
    }

    /** 替换并合并, */
    private static boolean mergeReplaceMap(Map> target, Map> newData) {
        if (newData == null) {
            return false;
        }
        target.putAll(newData);
        return true;
    }

    /** 追加合并, */
    private static boolean appendMap(Map> target, Map> newData) {
        if (newData == null) {
            return false;
        }
        Map> listMap = target;
        newData.forEach((key, val) -> {
            List merge = listMap.merge(key, val, (first, second) -> {
                HashSet hashSet = new HashSet<>(first);
                hashSet.addAll(second);
                return Arrays.asList(hashSet.toArray(new String[0]));
            });
        });
        target.putAll(newData);
        return true;
    }
    // ---------------------------------------------------------------------------

    /** 获取 cookie ,数据是 Map 形式 */
    public static Map cookieMap() {
        return mapList2Map(cookieParamLocal.get());
    }

    /** 获取 cookie ,Map 的 Value 是数组 */
    public static Map> cookieArrayMap() {
        return cookieParamLocal.get();
    }

    /** 清空并替换 cookie */
    public static boolean clearReplaceCookieArrayMap(Map> newCookie) {
        return clearReplaceMap(cookieParamLocal.get(), newCookie);
    }

    /** 将 newCookie 合并到 cookie 中,遇到冲突 key 用新的进行替换 */
    public static boolean mergeReplaceCookieArrayMap(Map> newCookie) {
        return mergeReplaceMap(cookieParamLocal.get(), newCookie);
    }

    /** 将 newCookie 合并到 cookie 中,遇到冲突 key 合并它们 */
    public static boolean appendCookieArrayMap(Map> newCookie) {
        return appendMap(cookieParamLocal.get(), newCookie);
    }
    // ---------------------------------------------------------------------------

    /** 获取 Invoker */
    public static Invoker localInvoker() {
        return invokerLocal.get();
    }

    /** 获取 header ,数据是 Map 形式 */
    public static Map headerMap() {
        return mapList2Map(headerParamLocal.get());
    }

    /** 获取 header ,Map 的 Value 是数组 */
    public static Map> headerArrayMap() {
        return headerParamLocal.get();
    }

    /** 清空并替换 newHeader */
    public static boolean clearReplaceHeaderArrayMap(Map> newHeader) {
        return clearReplaceMap(headerParamLocal.get(), newHeader);
    }

    /** 将 newHeader 合并到 header 中,遇到冲突 key 用新的进行替换 */
    public static boolean mergeReplaceHeaderArrayMap(Map> newHeader) {
        return mergeReplaceMap(headerParamLocal.get(), newHeader);
    }

    /** 将 newHeader 合并到 header 中,遇到冲突 key 合并它们 */
    public static boolean appendHeaderArrayMap(Map> newHeader) {
        return appendMap(headerParamLocal.get(), newHeader);
    }
    // ---------------------------------------------------------------------------

    /** 获取 URL "?" 后面的查询参数 ,数据是 Map 形式 */
    public static Map queryMap() {
        return mapList2Map(queryParamLocal.get());
    }

    /** 获取 URL "?" 后面的查询参数 ,Map 的 Value 是数组 */
    public static Map> queryArrayMap() {
        return queryParamLocal.get();
    }

    /** 清空并替换 `查询参数` */
    public static boolean clearReplaceQueryArrayMap(Map> newQuery) {
        return clearReplaceMap(queryParamLocal.get(), newQuery);
    }

    /** 将 newQuery 合并到 `查询参数` 中,遇到冲突 key 用新的进行替换 */
    public static boolean mergeReplaceQueryArrayMap(Map> newQuery) {
        return mergeReplaceMap(queryParamLocal.get(), newQuery);
    }

    /** 将 newQuery 合并到 `查询参数` 中,遇到冲突 key 合并它们 */
    public static boolean appendQueryArrayMap(Map> newQuery) {
        return appendMap(queryParamLocal.get(), newQuery);
    }
    // ---------------------------------------------------------------------------

    /** 获取 URL 请求路径上的查询参数 ,数据是 Map 形式 */
    public static Map pathMap() {
        return mapList2Map(pathParamLocal.get());
    }

    /** 获取 URL 请求路径上的查询参数 ,Map 的 Value 是数组 */
    public static Map> pathArrayMap() {
        return pathParamLocal.get();
    }

    /** 清空并替换 `查询参数` */
    public static boolean clearReplacePathArrayMap(Map> newPath) {
        return clearReplaceMap(pathParamLocal.get(), newPath);
    }

    /** 将 newPath 合并到 `查询参数` 中,遇到冲突 key 用新的进行替换 */
    public static boolean mergeReplacePathArrayMap(Map> newPath) {
        return mergeReplaceMap(pathParamLocal.get(), newPath);
    }

    /** 将 newPath 合并到 `查询参数` 中,遇到冲突 key 合并它们 */
    public static boolean appendPathArrayMap(Map> newPath) {
        return appendMap(pathParamLocal.get(), newPath);
    }
    // ---------------------------------------------------------------------------

    /** 获取 Http 标准的请求参数 ,数据是 Map 形式 */
    public static Map requestMap() {
        return mapList2Map(requestParamLocal.get());
    }

    /** 获取 Http 标准的请求参数 ,Map 的 Value 是数组 */
    public static Map> requestArrayMap() {
        return requestParamLocal.get();
    }

    /** 清空并替换 `请求参数` */
    public static boolean clearReplaceRequestArrayMap(Map> newRequestParam) {
        return clearReplaceMap(requestParamLocal.get(), newRequestParam);
    }

    /** 将 newPath 合并到 `请求参数` 中,遇到冲突 key 用新的进行替换 */
    public static boolean mergeReplaceRequestArrayMap(Map> newRequestParam) {
        return mergeReplaceMap(requestParamLocal.get(), newRequestParam);
    }

    /** 将 newPath 合并到 `请求参数` 中,遇到冲突 key 合并它们 */
    public static boolean appendRequestArrayMap(Map> newRequestParam) {
        return appendMap(requestParamLocal.get(), newRequestParam);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy