簡體   English   中英

Dropwizard解壓縮請求過濾器

[英]Dropwizard decompress request filter

我有一個dropwizard應用程序,客戶端請求正文內容是gzip壓縮內容。 我需要解壓縮dropwizard應用程序中的內容。 我有以下代碼,但是我在GZIPInputStream is = new GZIPInputStream(new ByteArrayInputStream(gzipBody))行獲取異常java.io.EOFException GZIPInputStream is = new GZIPInputStream(new ByteArrayInputStream(gzipBody))

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.util.zip.GZIPInputStream;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;

@Path("/")
public class UserEventResource {
    @POST
    @Path("/save")
    @Produces("application/json;charset=utf-8")
    public Response save(byte[] gzipBody) {
        try {
            try (GZIPInputStream is = new GZIPInputStream(new ByteArrayInputStream(gzipBody))) {
                try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
                    byte[] buffer = new byte[4096];
                    int length;
                    while ((length = is.read(buffer)) > 0) {
                        os.write(buffer, 0, length);
                    }
                    String body = new String(os.toByteArray(), Charset.forName("UTF-8"));
                }
            }
            return Response.status(OK).build();
        } catch (Exception exception) {
            return Response.status(INTERNAL_SERVER_ERROR).build();
        }
    }
}

客戶端發送以下請求,

curl -XPOST -d @test.gz http://localhost:8080/save

test.gz是通過以下步驟創建的,

echo "hello world" > test
gzip test

代碼本身有效。 這個問題的問題是cURL請求。 如果添加-v (詳細)標志,您將看到問題。

$ curl -XPOST -v -d @test.gz http://localhost:8080/api/gzip/save
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /api/gzip/save HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 8
> Content-Type: application/x-www-form-urlencoded

問題出在最后一行: Content-Typeapplication/x-www-form-urlencoded 不僅僅是這個,但文件中的數據也沒有發送。 我不知道具體細節,但它與-d標志有關。 cURL的默認設置是在使用-d標志時發送application/x-www-form-urlencoded數據。

我們應該做的是使用--data-binary選項而不是-d ,並將Content-Type設置為application/octet-stream 這也將導致在服務器端調用正確的提供程序。

curl -XPOST -v \
     -H 'Content-Type:application/octet-stream' \
     --data-binary @test.gz \
     http://localhost:8080/api/gzip/save

為了確保我們的端點只接受application/octet-stream ,我們應該添加@Consumes注釋。 這很重要,因為我們不希望調用隨機提供程序,這可能會導致奇怪的錯誤消息。

@POST
@Path("/save")
@Produces("application/json;charset=utf-8")
@Consumes("application/octet-stream")
public Response save(byte[] gzipBody) {

}

旁白

  • 我不會在方法中使用byte[]參數。 您並不希望將整個文件讀入內存。 當然,示例已經讀取它以獲取String。 但最有可能在實際應用程序中,您將在某處保存文件。 因此,只需使用InputStream而不是byte[]參數。 您可以將該InputStream傳遞給GZIPInputStream構造函數。

  • 要上傳文件,請考慮使用multipart。 使用multipart,您不能一次只發送多個文件,但您也可以將元數據添加到文件中。 請參閱Jersey支持Dropwizard支持 (這不僅僅是Jersey功能的捆綁包裝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM