RepeatReadRequestWrapper

 

package cn.service.web.common.filter;

import com.alibaba.fastjson.JSON;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.mock.web.DelegatingServletInputStream;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/**
 * 可以重复读Request
 */
public class RepeatReadRequestWrapper extends HttpServletRequestWrapper {
    private static final Logger logger = LoggerFactory.getLogger(RepeatReadRequestWrapper.class);
    private final byte[] bytes;
    private final Hashtable<String, String[]> parameterMap = new Hashtable<>();
    private final ServletInputStream inputStream;
    private final BufferedReader reader;
    private final Object lock = new Object();
    private boolean isRead = false;

    /**
     *
     * @param request
     * @throws IOException
     */
    public RepeatReadRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        bytes = IOUtils.toByteArray(request.getInputStream());
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        inputStream = new DelegatingServletInputStream(bais);
        reader = new BufferedReader(new InputStreamReader(bais));
    }

    @Override
    public ServletInputStream getInputStream() {
        return inputStream;
    }

    @Override
    public BufferedReader getReader() {
        return reader;
    }

    @Override
    public String getParameter(String name) {
        String[] values = getParameterMap().get(name);
        return values == null || values.length == 0 ? null : values[0];
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        if(!initParameterMap().isEmpty()){
            return parameterMap;
        }
        return super.getParameterMap();
    }

    @Override
    public Enumeration<String> getParameterNames() {
        if(!initParameterMap().isEmpty()){
            parameterMap.keys();
        }
        return super.getParameterNames();
    }

    @Override
    public String[] getParameterValues(String name) {
        return getParameterMap().get(name);
    }

    public Hashtable<String, String[]> initParameterMap(){
        if(!isRead){
            synchronized (lock){
                if(isRead){
                    logger.info("parameterMap has inited, when you step into synchronized block");
                    return parameterMap;
                }
                try {
                /*
                String text = new String(bytes, getCharacterEncoding());
                logger.info("initParameterMap text {}", text);
                String body = URLDecoder.decode(text, DEFAULT_CHARSET);
                */
                    //String body = new String(Base64.getUrlDecoder().decode(bytes), DEFAULT_CHARSET);
                    String body = new String(bytes, getCharacterEncoding());
                    if(StringUtils.isNotBlank(body)){
                        if(getContentType().contains(MediaType.APPLICATION_JSON_VALUE)){
                            Map<String,Object> map = JSON.parseObject(body,Map.class);
                            if(map != null && !map.isEmpty()){
                                map.entrySet().stream().forEach(entry -> {
                                    if(entry.getValue() instanceof JSON){
                                        parameterMap.put(entry.getKey(), new String[]{JSON.toJSONString(entry.getValue())});
                                    } else{
                                        parameterMap.put(entry.getKey(), new String[]{String.valueOf(entry.getValue())});
                                    }
                                });
                            }
                        } else {
                            HashMap<String, List<String>> param = new HashMap<>();
                            String[] pairs = body.split("&");
                            for (String nv : pairs) {
                                String name = nv.split("=")[0];
                                String val = nv.split("=")[1];
                                if (param.containsKey(name)) {
                                    List<String> value = param.get(name);
                                    value.add(val);
                                    param.put(name, value);
                                } else {
                                    List<String> value = new ArrayList<>();
                                    value.add(val);
                                    param.put(name, value);
                                }
                            }
                            Iterator<Map.Entry<String, List<String>>> iterator = param.entrySet().iterator();
                            while (iterator.hasNext()){
                                Map.Entry<String, List<String>> next = iterator.next();
                                parameterMap.put(next.getKey(), next.getValue().toArray(new String[]{}));
                            }
                        }
                    }
                    String queryString = getQueryString();
                    if(StringUtils.isNotBlank(queryString)){
                        String[] pair = queryString.split("&");
                        for (int i = 0; i < pair.length; i++) {
                            String[] kv = pair[i].split("=");
                            if(kv.length>1){
                                parameterMap.put(kv[0], kv[1].split(","));
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("initParameterMap error", e);
                } finally {
                    isRead = true;
                }
            }
        }
        return parameterMap;
    }
}

 

 

package cn.service.web.common.filter;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;

/**
 * service优雅停机:统计正在处理的http请求
 * <p>Created by xxxx on 17/8/02.
 */
public class HttpRequestCounterFilter implements Filter {
    private static Logger logger = LoggerFactory.getLogger(HttpRequestCounterFilter.class);
    private static final List<MediaType> ignoreRepeatReadList = Lists.newArrayList(
            MediaType.APPLICATION_FORM_URLENCODED,
            MediaType.MULTIPART_FORM_DATA);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.debug("cn.fraudmetrix.octopus.service.web.common.filter.HttpRequestCounterFilter.init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletRequest httpRequest = request;
        HttpServletRequest req = null;
        if (request instanceof HttpServletRequest){
            req = (HttpServletRequest) request;
            LocalRunningHttpRequestCounter.in(req);
            if(isRepeatReadRequest(req) && !RequestContextInterceptor.ignoreLoggerURIList.contains(req.getRequestURI())){
                httpRequest = new RepeatReadRequestWrapper(req);
            }
            /*
            Map<String, String[]> parameterMap = request.getParameterMap();
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                sb.append(entry.getKey()+":"+ StringUtils.join(entry.getValue(),",")).append("\n");
            }

            String taskId = request.getParameter(ApiParamConstants.TASK_ID);
            String partnerCode = httpRequest.getHeader(HeaderConstants.PARAMS_PARTNER_CODE);
            String requestURI = httpRequest.getRequestURI();
            logger.info("{} HttpServletRequest filter {}\n{}\n{}",taskId, partnerCode, requestURI, sb);
            */
        }

        try {
            chain.doFilter(httpRequest, response);
        } finally {
            if (req != null)
                LocalRunningHttpRequestCounter.out(req);
        }
    }

    /**
     * 是否是支持可重复读的request
     * @param request
     * @return
     */
    private boolean isRepeatReadRequest(HttpServletRequest request) {
        return ignoreRepeatReadList.stream().filter(mediaType -> mediaType.includes(MediaType.parseMediaType(request.getContentType()))).count() == 0;
    }

    @Override
    public void destroy() {
        logger.debug("destroy");
    }
}

 

posted @ 2021-01-21 23:08  牧之丨  阅读(302)  评论(0编辑  收藏  举报