2016-09-26 175 views
0

我有一個使用Spring Boot開發的REST服務,試圖將圖像數據發送回客戶端,然後將其顯示在瀏覽器中。然而,當我嘗試,我得到了以下錯誤:在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 

我想發送的文件大小隻有19KB,但我不確定它爲什麼會拋出大的請求頭錯誤。你能否幫助確定我做錯了什麼?圖像數據是否在請求標頭中傳遞?如果是這樣,我怎麼能發送它在響應體?

謝謝

+0

你爲什麼要給我們展示'resp.html'?在你的''handleCompare()'方法被調用之前,對'http:// server/context/com'的POST請求正在被拒絕。客戶端發送錯誤的數據,因此請檢查客戶端代碼,和/或登錄請求標頭。 – Andreas

+0

@Andreas請求沒有被拒絕。對比較的調用是成功的,因爲我已經驗證了這一點。響應發送到「resp.html」時遇到此錯誤 – seriousgeek

+0

真的嗎?因爲該堆棧跟蹤會指示其他情況。 – Andreas

回答

1

你的問題不是從請求到.../com調用該方法handleCompare()。該請求通常完成,並將HTML頁面發送到客戶端瀏覽器。

客戶端瀏覽器將嘗試呈現該頁面,並會看到<img width="300" height="300" src="sojghsirhsdfoh...bytes removed...daskfgdskfg=="></img>標記。因此瀏覽器會向服務器發送另一個請求到URL .../sojghsirhsdfoh...bytes removed...daskfgdskfg==以獲取要顯示圖像的數據。

請求正在導致錯誤,因爲URL太長。這由調用堆棧支持,顯示在致電parseRequestLine()期間發生錯誤。

<img>標記的src屬性構建不正確。如果您打算構建數據URI,則data:image/jpeg;base64,應該是該值的前綴,但th:src將替代src屬性。另請注意,您需要,

如果可能,您應該避免使用數據URI。定義另一個用於檢索JPEG圖像的URL,並將src屬性更改爲該URL。特別是如果圖像是靜態的,就像你的代碼顯示的那樣。

+0

謝謝。這很有道理!根據你的建議,我是否必須定義一個新的REST api來檢索圖像字節數組並從src調用這個API? – seriousgeek

+0

這是正確的。 – Andreas

1

哪個應用程序服務器在運行這個?您缺少http-listener下的maxPostSize屬性。 如果您使用的是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

我使用集成Pivotal服務器的Spring Boot,因此我相信我們需要修改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 

這可以是請求頭大小超過了默認特別有用限制(8KB)的Tomcat/Coyote(見https://github.com/apache/tomcat/blob/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java#L166),例如由於身份驗證令牌(Keycloak等)或任何具有較大內容的cookie,也可能由同一域上的不同應用程序設置。

相關問題