#java #inputstream #resteasy #undertow
Вопрос:
У меня есть веб-сервис для размещения файла в базе данных, и мне действительно нужно отобразить тело HTTP-запроса, чтобы проверить правильность реализации клиента. Я попробовал конфигурацию фильтра undertow на своем сервере Wildfly, она дает некоторую информацию, но не заголовок данных из нескольких частей/форм, поэтому я использовал класс RequestLoggingFilter, который реализует ContainerRequestFilter для регистрации тела при использовании фасада resteasy.
Мой фасад помечен этим :
@POST @Logged @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN)
Это работает, но когда я использую ServletInputStream для отображения тела, я загружаю весь файл в оперативную память. В случае, если я использую «большой» файл, мой метод выдаст исключение, и фасад не получит открытый входной поток.
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) -gt; { 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-- --------------------------------------------------------
Как я могу использовать поток ввода servletin в фильтре Containerrequest, не загружая весь файл, регистрируя заголовок составных данных/данных формы и позволяя потоку ввода открываться для фасада ? (Java 8)
Комментарии:
1. Ваш единственный вариант-считывать входной поток по частям и, возможно, просто останавливаться после того, как буфер станет слишком большим.
2. Спасибо Джеймсу, что помог мне.