在REST响应中发送图像时请求标头太大

时间:2016-09-26 16:12:45

标签: java spring rest spring-boot

我有一个使用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

我尝试发送的文件大小只有19KB,但我不确定为什么会抛出大量的请求标头错误。你能帮忙找出我做错了什么吗?图像数据是否在请求标头中传递?如果是这样,我如何将其发送到响应正文中?

由于

3 个答案:

答案 0 :(得分:2)

你在运行这个应用服务器吗?您缺少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

答案 1 :(得分:2)

问题不在于调用.../com方法的handleCompare()请求。该请求正常完成,并将HTML页面发送到客户端浏览器。

然后,客户端浏览器将尝试呈现该页面,并会看到<img width="300" height="300" src="sojghsirhsdfoh...bytes removed...daskfgdskfg=="></img>标记。因此,浏览器将向服务器发送另一个请求到URL .../sojghsirhsdfoh...bytes removed...daskfgdskfg==以获取要显示的图像的数据。

请求导致错误,因为该URL太长。这由callstack支持,显示在调用parseRequestLine()期间发生错误。

src标记的<img>属性构建错误。如果您打算构建数据URI,data:image/jpeg;base64,应该是该值的前缀,但th:src 将替换 src属性。另请注意,您需要,

如果可能,您应该避免使用数据URI。定义另一个用于检索JPEG图像的URL,并将src属性更改为该URL。特别是如果图像是静态的,就像你的代码一样。

答案 2 :(得分:2)

@mhasan对于在Spring启动应用程序中遇到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

当请求标头大小超过Tomcat / Coyote(参见https://github.com/apache/tomcat/blob/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java#L166)的默认限制(8KB)时,这可能特别有用。由于身份验证令牌(Keycloak等)或任何内容较大的cookie,可能也由同一域中的其他应用程序设置。