![](/img/trans.png)
[英]Why can the body of the HttpServletRequest not be read multiple times?
[英]How can I read request body multiple times in Spring 'HandlerMethodArgumentResolver'?
我正在嘗試解析RequestMapping
方法的某些特定參數,從請求正文中提取值並驗證它們並將它們注入某些帶注釋的參數中。
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 1, get corresponding input parameter from NativeWebRequest
// 2, validate
// 3, type convertion and assemble value to return
return null;
}
最大的問題是我發現HttpServletRequest
(從NativeWebRequest
獲取)不能多次讀取輸入流(一些參數在請求正文中)。 那么如何多次檢索Inputstream
/ Reader
或請求主體呢?
您可以添加一個過濾器,攔截當前的HttpServletRequest
並將其包裝在自定義的HttpServletRequestWrapper
中。 在您的自定義HttpServletRequestWrapper
中,您讀取請求主體並將其緩存,然后實現getInputStream
和getReader
以從緩存的值中讀取。 由於包裝請求后,緩存值始終存在,您可以多次讀取請求主體:
@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
MultipleReadHttpRequest wrappedRequest = new MultipleReadHttpRequest(currentRequest);
chain.doFilter(wrappedRequest, servletResponse);
}
}
經過這個過濾,大家就會看到wrappedRequest
,它具有被多次讀取的能力:
public class MultipleReadHttpRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedContent;
public MultipleReadHttpRequest(HttpServletRequest request) throws IOException {
// Read the request body and populate the cachedContent
}
@Override
public ServletInputStream getInputStream() throws IOException {
// Create input stream from cachedContent
// and return it
}
@Override
public BufferedReader getReader() throws IOException {
// Create a reader from cachedContent
// and return it
}
}
為了實現MultipleReadHttpRequest
,您可以查看 spring 框架中的ContentCachingRequestWrapper
,它基本上做同樣的事情。
這種方法有其自身的缺點。 首先,它有點低效,因為對於每個請求,請求主體至少被讀取兩次。 另一個重要的缺點是,如果您的請求正文包含10 GB
的流,您將讀取這10 GB
的數據,甚至更糟的是將其放入內存中以供進一步檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.