2016-09-26 2 views
0

У меня есть служба REST, разработанная с использованием Spring Boot, которая пытается отправить обратно данные изображения клиенту, которые затем будут отображаться в браузере. Однако, когда я пытаюсь это, я получаю следующее сообщение об ошибке:Слишком большой заголовок запроса при отправке изображения в ответ REST

2016-09-26 08:40:31.897 INFO 6435 --- [nio-8080-exec-7] o.a.coyote.http11.Http11NioProcessor  : Error parsing HTTP request header 
Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level. 

java.lang.IllegalArgumentException: Request header is too large 
    at org.apache.coyote.http11.InternalNioInputBuffer.fill(InternalNioInputBuffer.java:111) ~[tomcat-embed-core-8.0.36.jar!/:8.0.36] 
    at org.apache.coyote.http11.AbstractNioInputBuffer.parseRequestLine(AbstractNioInputBuffer.java:267) ~[tomcat-embed-core-8.0.36.jar!/:8.0.36] 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1013) ~[tomcat-embed-core-8.0.36.jar!/:8.0.36] 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670) [tomcat-embed-core-8.0.36.jar!/:8.0.36] 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) [tomcat-embed-core-8.0.36.jar!/:8.0.36] 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) [tomcat-embed-core-8.0.36.jar!/:8.0.36] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_60] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_60] 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.36.jar!/:8.0.36] 
    at java.lang.Thread.run(Unknown Source) [na:1.8.0_60] 

Мой сервисный код выглядит следующим образом:

@RequestMapping(method = RequestMethod.POST, value = "/com") 
     public String handleCompare(@RequestParam("testid") String test, 
            RedirectAttributes redirectAttributes, Model model) throws IOException { 

     File f=new File("Sampletest.jpg"); 
     BufferedImage origImg=ImageIO.read(f); 
     ByteArrayOutputStream baos=new ByteArrayOutputStream(); 
     ImageIO.write(origImg, "jpg", baos); 
     byte[] imageInByte=baos.toByteArray(); 
     byte[] encoded= Base64.encodeBase64(imageInByte); 
     String encodedString = new String(encoded); 
     model.addAttribute("webcamattr", encodedString); 
     return "resp"; 
     } 

Соответствующая часть «resp.html» выглядит следующим образом:

<table> 
      <tr> 
       <td align="center"><b>Response Image</b></td> 
      </tr> 
      <tr th:each="webfile : ${webcamattr}"> 
       <td> <img width="300" height="300" src="data:image/jpeg;base64" th:src="${webcamattr}"></img></td> 
      </tr> 
     </table> 

Мой application.properties файл выглядит следующим образом:

multipart.maxFileSize=10Mb 
multipart.maxRequestSize=10Mb 

Файл, который я пытаюсь отправить, имеет размер только 19 КБ, но я не уверен, почему он бросает большую ошибку заголовка запроса. Не могли бы вы помочь в определении того, что я делаю неправильно? Передаются ли данные изображения в заголовок запроса? Если да, то как я могу отправить его в тело ответа?

+0

Почему вы показываете нам 'resp.html'? Запрос POST на 'http: // server/context/com' отклоняется * перед тем, как вызывается ваш метод' handleCompare() '. Клиент отправляет плохие данные, поэтому проверьте код клиента и/или запишите заголовки запросов. – Andreas

+0

@ Аndreas запрос не отклоняется. Вызов handleCompare успешный, поскольку я это проверил. Эта ошибка встречается, когда ответ отправляется в «resp.html» – seriousgeek

+0

Действительно? Потому что этот стек будет указывать иначе. – Andreas

ответ

1

Вашей задаче не из запроса на .../com, который вызывает метод handleCompare(). Этот запрос выполняется нормально и отправляет HTML-страницу в клиентский браузер.

Затем клиентский браузер попытается отобразить эту страницу и будет видеть тег <img width="300" height="300" src="sojghsirhsdfoh...bytes removed...daskfgdskfg=="></img>. Поэтому браузер отправит другой запрос на сервер по адресу .../sojghsirhsdfoh...bytes removed...daskfgdskfg==, чтобы получить данные для изображения, которое будет отображаться.

Это сообщение вызывает ошибку, поскольку URL-адрес слишком длинный. Это подтверждается вызовом, показывающим, что ошибка возникает во время вызова parseRequestLine().

Атрибут src тега <img> построен неправильно. Если вы планируете создавать URI данных, то data:image/jpeg;base64, должен быть префиксом для значения, но th:srcзаменяет атрибутом src. Также обратите внимание, что вам нужен ,.

Если возможно, вам следует избегать использования URI данных. Определите другой URL для получения изображения JPEG и измените атрибут src на этот URL. Особенно, если изображение статично, как показывает ваш код.

+0

Спасибо. Это имеет смысл! Согласно вашему предложению, должен ли я определить новый REST api, который извлекает массив байтов изображения и вызывает этот API из src? – seriousgeek

+0

Это правильно. – Andreas

1

какой сервер приложений вы используете это ?. Вам не хватает свойства maxPostSize под http-прослушивателем. в случае, если вы используете tomcat, это может быть достигнуто с помощью spmethign, например, например.

<Connector port="8080" protocol="HTTP/1.1" 
       connectionTimeout="20000" 
       redirectPort="8443" **maxHttpHeaderSize="65536" maxPostSize="4194304"** 
       URIEncoding="UTF-8"/> 

Попробуйте добавить их к своему application.properties

spring.http.multipart.max-file-size=1Mb # Max file size 
spring.http.multipart.max-request-size=10Mb # Max request size 
+0

Я использую Spring Boot с интегрированным Pivotal сервером, и поэтому считаю, что нам нужно изменить application.properties вместо server.xml – seriousgeek

+0

Обновлено мой ответ – mhasan

+0

попробовал это. К сожалению, это все равно дает мне такую ​​же ошибку. – seriousgeek

1

@mhasan Для тех, кто сталкивается ошибка java.lang.IllegalArgumentException: Request header is too large в приложении пружины загрузки, установив server.max-http-header-size свойство в вашем application.yml должен решить эту проблему:

server: 
    # increase max http header size to 128KB to allow large headers 
    # e.g. due to keycloak authentication tokens, cookies, etc. 
    maxHttpHeaderSize: 131072 

Это может быть особенно полезно, когда размер заголовка запроса превышает значение по умолчанию предел (8 КБ) от Tomcat/Coyote (см. https://github.com/apache/tomcat/blob/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java#L166), например из-за токенов аутентификации (Keycloak и т. д.) или любого файла cookie с большим содержимым, возможно, также установленного другим приложением в том же домене.