java如何从ServletInputStream读取multipart/formdata头并将内容加载到临时文件中
我有一个Web服务在数据库中发布一个文件,我真的需要显示HTTP请求的主体,以检查客户端的实现是否正确。 我在我的Wildfly服务器上尝试了undertow filter配置,它提供了一些信息,但没有提供多部分/表单数据头,因此我使用了一个RequestLoggingFilter类,该类实现了ContainerRequestFilter来记录使用resteasy facade时的正文
我的门面上有这样的注解:
@POST
@Logged
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
它可以工作,但当我使用ServletInputStream来显示主体时,我正在将整个文件加载到RAM中。如果我使用一个“大”文件,我的方法将抛出一个异常,facade将不会获得一个打开的InputStream
11:21:58,943 TRACE [project.ws.utils.RequestLoggingFilter] (default task-1) Error bodyio.undertow.server.RequestTooBigException: UT000020: Connection terminated as request was larger than 10485760
11:21:58,945 TRACE [project.ws.utils.RequestLoggingFilter] (default task-1) --------------------------------------------------------
11:21:58,954 WARN [org.apache.james.mime4j.parser.MimeEntity] (default task-1) Unexpected end of headers detected. Higher level boundary detected or EOF reached.
11:21:58,956 WARN [org.apache.james.mime4j.parser.MimeEntity] (default task-1) Invalid header encountered
11:21:58,960 WARN [org.apache.james.mime4j.parser.MimeEntity] (default task-1) Body part ended prematurely. Boundary detected in header or EOF reached.
11:21:58,970 ERROR [project.ws.handler.exceptions.GlobalExceptionMapper] (default task-1) RESTEASY007500: Could find no Content-Disposition header within part: java.lang.RuntimeException: RESTEASY007500: Could find no Content-Disposition header within part
日志类:
@Logged
@Provider
public class RequestLoggingFilter implements ContainerRequestFilter{
private static final Logger LOGGER = LoggerFactory.getLogger(RequestLoggingFilter.class);
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (!LOGGER.isTraceEnabled()) {
return;
}
LOGGER.trace("--------------------------------------------------------");
LOGGER.trace("URI=" + requestContext.getUriInfo().getPath());
LOGGER.trace("Content length=" + requestContext.getLength());
LOGGER.trace("Content type=" + requestContext.getMediaType());
LOGGER.trace("Methode=:" + requestContext.getMethod());
LOGGER.trace("Cookies=:" + requestContext.getCookies());
LOGGER.trace("MediaTypes=" + requestContext.getAcceptableMediaTypes());
LOGGER.trace("AceptableLanguages=" + requestContext.getAcceptableLanguages());
LOGGER.trace("Date=" + requestContext.getDate());
LOGGER.trace(" Header:");
requestContext.getHeaders().forEach((key, value) -> {
LOGGER.trace(" header=" + key + " : " + value);
});
try {
if (requestContext.hasEntity()) {
String result = IOUtils.toString(requestContext.getEntityStream(), StandardCharsets.UTF_8);
LOGGER.trace(" Body:");
Scanner scanner = new Scanner(result);
while (scanner.hasNextLine()) {
LOGGER.trace(" " + scanner.nextLine());
}
scanner.close();
requestContext.setEntityStream(CharSource.wrap(result).asByteSource(StandardCharsets.UTF_8).openStream());
}
} catch (Exception e) {
LOGGER.trace("Error body" + e);
}
LOGGER.trace("--------------------------------------------------------");
}
}
日志:
--------------------------------------------------------
URI=/reception
Content length=259
Content type=multipart/form-data;boundary="----=_Part_43_341076338.1636107376952"
Methode=:POST
Cookies=:{}
MediaTypes=[*/*]
AceptableLanguages=[]
Date=null
Header:
header=Accept-Encoding : [gzip,deflate]
header=apiKey : [test]
header=Connection : [Keep-Alive]
header=Content-Length : [259]
header=Content-Type : [multipart/form-data; boundary="----=_Part_43_341076338.1636107376952"]
header=Host : [localhost:9000]
header=MIME-Version : [1.0]
header=User-Agent : [Apache-HttpClient/4.1.1 (java 1.5)]
Body:
------=_Part_43_341076338.1636107376952
Content-Type: text/plain; charset=Cp1252; name=file3.tmp
Content-Transfer-Encoding: binary
Content-Disposition: form-data; name="file"; filename="file3.tmp"
------=_Part_43_341076338.1636107376952--
--------------------------------------------------------
如何在ContainerRequestFilter中使用ServletInputStream,而不加载整个文件、记录多部分/表单数据头并让InputStream为facade打开?(Java 8)
共 (0) 个答案