Как прочитать заголовок составных/форм-данных из потока Servletinput и загрузить содержимое во временный файл

#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. Спасибо Джеймсу, что помог мне.