Giriş
Şu satırı dahil ederiz
import org.springframework.web.util.ContentCachingRequestWrapper;
Problem Nedir
Açıklaması şöyle
Imagine that you have implemented a logging mechanism, for example, AOP techniques, to log each HTTP request details. This way, the body will be consumed.Then you have a RestController with a method that tries to read the HttpServletRequest body. This time, the getInputStream() will be empty.
ContentCachingRequestWrapper Sınıfının Eksikleri
Açıklaması şöyle
Spring provides a ContentCachingRequestWrapper class. This class provides a method, getContentAsByteArray() to read the body multiple times.This class has a limitation, though: We can't read the body multiple times using the getInputStream() and getReader() methods.This class caches the request body by consuming the InputStream. If we read the InputStream in one of the filters, then other subsequent filters in the filter chain can't read it anymore. Because of this limitation, this class is not suitable in all situations.
Alternatif
Örnek
Elimizde şöyle bir kod olsun. Bu kod InputStream nesnesini tüketir ve saklar. Her getInputStream() çağrısında yeni bir ByteArrayInputStream ile tekrar bize verir.
class CachedRequestHttpServletRequest extends HttpServletRequestWrapper { private final byte[] cachedBody; public CachedRequestHttpServletRequest(HttpServletRequest request) throws IOException { super(request); this.cachedBody = StreamUtils.copyToByteArray(request.getInputStream()); } @Override public ServletInputStream getInputStream() { ByteArrayInputStream inputStream = new ByteArrayInputStream(this.cachedBody); return new ServletInputStream() { @Override public boolean isFinished() { return inputStream.available() == 0; } @Override public boolean isReady() { return true; } @Override public int read() { return inputStream.read(); } @Override public void setReadListener(ReadListener readListener) { throw new UnsupportedOperationException(); } }; } }
Şöyle yaparız. Yani cache yapan nesneyi filtre içinde kullandık
@Component @Slf4j public class HttpRequestCustomFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { CachedRequestHttpServletRequest cachedRequestHttpServletRequest = new CachedRequestHttpServletRequest((HttpServletRequest) servletRequest); chain.doFilter(cachedRequestHttpServletRequest, servletResponse); } }
ve filtreyi takmak için şöyle yaparız.
@Configuration @Slf4j public class HttpRequestConfiguration { @Bean public FilterRegistrationBean<HttpRequestCustomFilter> loggingFilter() { FilterRegistrationBean<HttpRequestCustomFilter> bean = new FilterRegistrationBean<>(); bean.setFilter(new HttpRequestCustomFilter()); bean.addUrlPatterns("/demo/*"); return bean; } }
Hiç yorum yok:
Yorum Gönder