我正在查看sitebricks here中HiddenMethodFilter的实现:
在第65行,有以下代码:
try {
String methodName = httpRequest.getParameter(this.hiddenFieldName);
if ("POST".equalsIgnoreCase(httpRequest.getMethod()) && !Strings.empty(methodName)) {
....
它检查是否设置了特定参数并使用它来包装请求。但是,在读取该参数时,它将使用流,最终的servlet将无法读取任何数据。
避免这种情况的最佳方法是什么?我实现了HttpServletRequestWrapper here,它将流的内容读入字节数组。但是,这可能会使用大量内存来存储请求。
private HttpServletRequestWrapper getWrappedRequest(HttpServletRequest httpRequest, final byte[] reqBytes)
throws IOException {
final ByteArrayInputStream byteInput = new ByteArrayInputStream(reqBytes);
return new HttpServletRequestWrapper(httpRequest) {
@Override
public ServletInputStream getInputStream() throws IOException {
ServletInputStream sis = new ServletInputStream() {
@Override
public int read() throws IOException {
return byteInput.read();
}
};
return sis;
}
};
}
有更好的方法吗?我们可以在不消耗流的情况下读取参数吗? (有些东西类似于peek)我们可以重置流吗?
答案 0 :(得分:2)
如果您正在使用POST
请求并从httpRequest
读取参数,这将影响InputStream
,您将在其他需要阅读的部分遇到问题。
这在ServletRequest#getParameter javadoc:
如果参数数据是在请求体中发送的,例如发生 使用HTTP POST请求,然后通过直接读取正文 getInputStream()或getReader()可能会干扰执行 这种方法。
ServletInputStream
源自InputStream
并继承markSupported
reset
等实际上是无操作的,因此您无法重置ServletInputStream
。
这意味着您必须使用它。