2016-09-26 176 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,也可能由同一域上的不同应用程序设置。

相关问题