뭐든 즐기면서 ;)

request.getInputstream 여러 번 하는 방법 본문

BACK/JAVA

request.getInputstream 여러 번 하는 방법

Tada.*+ 2023. 7. 20. 19:30
728x90

오류 내용

getInputStream() has already been called for this request

해결 방법

getReader()를 여러 번 할 수 있도록 하는 방법으로 'HttpServletRequestWrapper' 클래스를 상속은 클래스를 하나 작성해 줍니다.

package ai.maum.data.edit.wrapper;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author bhr
 */
public class RereadableRequestWrapper extends HttpServletRequestWrapper {

    private final Charset encoding;
    private byte[] rawData;

    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request The request to wrap
     * @throws IllegalArgumentException if the request is null
     */
    public RereadableRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);

        String characterEncoding = request.getCharacterEncoding();
        if(StringUtils.isBlank(characterEncoding)) {
            characterEncoding = StandardCharsets.UTF_8.name();
        }
        this.encoding = Charset.forName(characterEncoding);

        try {
            InputStream inputStream = request.getInputStream();
            this.rawData = inputStream.readAllBytes();
        } catch (IOException e) {
            throw e;
        }

    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.rawData);
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }

            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream(), this.encoding));
    }

    @Override
    public ServletRequest getRequest() {
        return super.getRequest();
    }
}

Body를 읽어 json 형식의 Map으로 변환하는 util

...
public static Map<String, Object> getBody(HttpServletRequest request) throws IOException {
    BufferedReader br = request.getReader();
    StringBuilder sb = new StringBuilder();
    String line;
    while((line = br.readLine()) != null) sb.append(line);
    return om.readValue(sb.toString(), new TypeReference<>() {});
}

실 사용 코드(Filter)

...
public void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws IOException, ServletException {
	RereadableRequestWrapper rereadableRequestWrapper = new RereadableRequestWrapper((HttpServletRequest)request);
	...
	String workspaceId = StringUtil.valueOf( ParsingUtil.getBody(rereadableRequestWrapper).get("workspace_id") );
	...
	filterChain.doFilter(rereadableRequestWrapper, response);
}

 

728x90

'BACK > JAVA' 카테고리의 다른 글

JAVA Docker 실행  (0) 2023.12.12
FFmpeg window 설치  (0) 2023.10.20
Tomcat java version 확인  (0) 2023.05.25
HashMap getOrDefault 함수  (0) 2022.07.05
JAVA SortedSet 정렬 방법 / JAVA SortedSet Comparable  (0) 2022.06.28
Comments