BAEL-4860: Java IllegalStateException: "getInputStream() has already been called for this request" (#14121)

* [BAEL-6203] Deserialize Generic Type with Jackson

* BAEL-4860: Java IllegalStateException: "getInputStream() has already been called for this request"

* BAEL-4860: Move code to new module spring-web-module/spring-mvc-java-3.

* BAEL-4860: update pom

* BAEL-4860: make the test methods public
This commit is contained in:
Forb Yuan
2023-06-12 11:49:15 +08:00
committed by GitHub
parent 680ddfef9c
commit 643f99281f
5 changed files with 112 additions and 0 deletions
@@ -0,0 +1,23 @@
package com.baeldung.filters;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class CacheRequestContentFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
if (request instanceof HttpServletRequest) {
String contentType = request.getContentType();
if (contentType == null || !contentType.contains("multipart/form-data")) {
request = new ContentCachingRequestWrapper((HttpServletRequest) request);
}
}
chain.doFilter(request, response);
}
}
@@ -0,0 +1,47 @@
package com.baeldung.filters;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.Filter;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.*;
public class HttpRequestUnitTest {
@Test
public void givenHttpServletRequest_whenCalling_getReaderAfter_getInputStream_thenThrowIllegalStateException() throws IOException {
HttpServletRequest request = new MockHttpServletRequest();
try (ServletInputStream ignored = request.getInputStream()) {
IllegalStateException exception = assertThrows(IllegalStateException.class, request::getReader);
assertEquals("Cannot call getReader() after getInputStream() has already been called for the current request",
exception.getMessage());
}
}
@Test
public void givenServletRequest_whenDoFilter_thenCanCallBoth() throws ServletException, IOException {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
Filter filter = new CacheRequestContentFilter();
filter.doFilter(req, res, chain);
ServletRequest request = chain.getRequest();
assertTrue(request instanceof ContentCachingRequestWrapper);
// now we can call both getInputStream() and getReader()
request.getInputStream();
request.getReader();
}
}