SpringBoot - HttpServletRequest 请求重复读取解决方案
发布日期:2021-06-30 23:28:38 浏览次数:2 分类:技术文章

本文共 5883 字,大约阅读时间需要 19 分钟。

RequestHandler 

package com.chinadaas.platform.servicecenter.mycommon.handler;import com.alibaba.fastjson.JSON;import com.google.common.collect.Maps;import lombok.Getter;import lombok.Setter;import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;import javax.servlet.ReadListener;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import javax.servlet.http.Part;import java.io.*;import java.nio.charset.Charset;import java.util.Collection;import java.util.Map;import java.util.Objects;@Getter@Setterpublic class RequestHandler extends HttpServletRequestWrapper {    private String rawJson;    private String form;    private String query;    public static RequestHandler getInstance(HttpServletRequest request) {        if (request instanceof StandardMultipartHttpServletRequest) {            request = ((StandardMultipartHttpServletRequest) request).getRequest();        }        return (RequestHandler)request;    }    public RequestHandler(HttpServletRequest request) throws IOException {        super(request);        StringBuilder sb = new StringBuilder();        InputStream ins = request.getInputStream();        BufferedReader isr = null;        try{            // rawJson case            if(ins != null){                isr = new BufferedReader(new InputStreamReader(ins, Charset.defaultCharset()));                char[] charBuffer = new char[128];                int readCount;                while((readCount = isr.read(charBuffer)) != -1){                    sb.append(charBuffer,0,readCount);                }                setRawJson(sb.toString());            }            // check getParameterMap            Map
tParamMap = request.getParameterMap(); if (!(Objects.nonNull(tParamMap) && tParamMap.size() > 0)) { return; } Map
paramMap = Maps.newHashMap(); tParamMap.entrySet().forEach(param -> { /* Array T String */ String[] valArr = param.getValue(); StringBuilder sbVal = new StringBuilder(); for (String val : valArr) { sbVal.append(val).append(","); } // clean last "," String val = sbVal.substring(0, sbVal.length()-1); paramMap.put(param.getKey(), val); }); // form case // business try catch try { Collection
parts = request.getParts(); Map
form = Maps.newHashMap(); parts.forEach(part -> { String paramKey = part.getName(); String paramVal = paramMap.get(paramKey); paramMap.remove(paramKey); form.put(paramKey, paramVal); }); setForm(JSON.toJSONString(form)); } catch (Exception e) { e.printStackTrace(); // no form-data } // query case setQuery(JSON.toJSONString(paramMap)); System.out.println(1); } finally { if(isr != null) { isr.close(); } } } @Override public ServletInputStream getInputStream() { try { final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(rawJson.getBytes(Charset.defaultCharset())); return new ServletInputStream() { @Override public int read() { return byteArrayInputStream.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener listener) { } }; }catch (Exception e){ e.printStackTrace(); return null; } } @Override public BufferedReader getReader() { return new BufferedReader(new InputStreamReader(this.getInputStream())); }}
  • 注意:HttpServletRequest 请求中的 body 内容仅能调用 request.getInputStream(), request.getReader() 和request.getParameter("key") 方法读取一次,重复读取会报 java.io.IOException: Stream closed 异常。
  • 原来两个同名参数的值都能在后台拿到,难怪request.getParamterMap()方法的返回值类型是Map<String, String[]>,第二个String[]数组就能很好地处理同名参数。

 

Filter

package com.chinadaas.platform.servicecenter.mycommon.filter;import com.chinadaas.platform.servicecenter.mycommon.handler.RequestHandler;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import java.io.IOException;@WebFilter(filterName = "myFilter", urlPatterns = "/exec/convert/service/*")public final class RequestFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) {    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        RequestHandler request = new RequestHandler((HttpServletRequest) servletRequest);        filterChain.doFilter(request, servletResponse);    }    @Override    public void destroy() {    }}

 

Application

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletComponentScan;/** * @author Lux Sun * @date 2020/7/8 */@SpringBootApplication@ServletComponentScan("com.chinadaas.platform.servicecenter.mycommon")public class DspServiceExecutorApplication {    public static void main(String[] args) {        SpringApplication.run(DspServiceExecutorApplication.class, args);    }}

转载地址:https://lux-sun.blog.csdn.net/article/details/107351149 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:HTTP - Get / Post 请求中,URL & FORM 参数如何分别获取?
下一篇:Java - java.lang.IllegalStateException: No modifications are allowed to a locked ParameterMap

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月24日 08时09分07秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章