9

その holdを含むPOSTリクエストを受け入れるRESTサービスがあります。REST サービス内では、提供されたデータに基づいてファイルが作成される場合があります。MultiPart BodyPartsInputStream

仕事

入力に基づいてファイル操作を行うクラスを単体テストしたいと考えていMultiPartます。: Jersey-Test を使用したくない! Grizzly は、DAO および fileHandler サービスを REST サービス クラスに挿入するために必要な Spring アプリケーション コンテキストをロードしません。fileHandler サービスが multiPart データを処理する方法を明示的にテストしたいと考えています。

ただし、問題は、 REST クライアントMultiPartから送信されたものが、 REST サーバーによって受信されたものと同じではないことです。これは、おそらく jersey がデータをストリーミングするために何かを行うためです。次のセットアップをテストしようとすると (以下を参照)、

IllegalArgumentException [B cannot be cast to com.sun.jersey.multipart.BodyPartEntity

REST クライアント - MultiPart の送信

(ほんの一部です。明らかなことは省略しました):

    byte[] bytes = FileManager.readImageFileToArray(completePath, fileType);

    MultiPart multiPart = new MultiPart().
            bodyPart(new BodyPart(bytes, MediaType.APPLICATION_OCTET_STREAM_TYPE)).
            bodyPart(new BodyPart(fileName, MediaType.APPLICATION_XML_TYPE)).
            bodyPart(new BodyPart(senderId, MediaType.APPLICATION_XML_TYPE));

    ClientConfig cc = new DefaultClientConfig();
    cc.getClasses().add(MultiPartWriter.class);
    Client client = Client.create(cc);
    WebResource webResource = client.resource(requestUrl);
    Builder builder = webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE);
    builder = addHeaderParams(builder, headerParams);

    ClientResponse response = builder.post(ClientResponse.class, multiPart);

サーバー側 - マルチパートの受信

休み:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Response create(MultiPart multiPart) {

    try {
            multiPartReader.saveFile(multiPart);

マルチパートからファイルを保存するためのサーバー側 MultiPartReader

public class MultiPartReader {

    public void saveFile(MultiPart multiPart) throws IOException {

        BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(0).getEntity();
        InputStream inputStream = bpe.getInputStream();

        // ...

        BufferedImage bi = ImageIO.read(inputStream);
        String fileName = getFileNameFromMultiPart(multiPart);

        File file = new File(filename);

        if (file.isDirectory()) {
            ImageIO.write(bi, formatName, file);
        } else {
            file.mkdirs();
            ImageIO.write(bi, formatName, file);
        }

        bpe.close();
    }

テスト - 着信マルチパートを分離して処理する

次に、MultiPartReader をテストします。

@Test
public void saveFile_should_Create_file() throws IOException {
    byte[] bytes = IOUtils.toByteArray(this.getClass().getResourceAsStream(fileResource));

    MultiPart multiPart = new MultiPart().
            bodyPart(new BodyPart(bytes, MediaType.APPLICATION_OCTET_STREAM_TYPE)).
            bodyPart(new BodyPart(fileName, MediaType.APPLICATION_XML_TYPE)).
            bodyPart(new BodyPart(senderId, MediaType.APPLICATION_XML_TYPE));
     
    multiPartReader.saveFile(multiPart);

    file = new File(fileName);
    Assert.assertNotNull(file);
    Assert.assertTrue(file.getTotalSpace() > 0);
    file.delete();
}

しかし、私が言ったように、私は

IllegalArgumentException [B cannot be cast to com.sun.jersey.multipart.BodyPartEntity

    BodyPartEntity bpe = (BodyPartEntity) multiPart.getBodyParts().get(0).getEntity();

では、Jersey によって処理される送受信をエミュレートして、REST サービスがサーバーにデプロイされ、REST クライアントによって要求されるのと同じデータをテストが取得するにはどうすればよいでしょうか?

編集

使用する

BodyPartEntity bpe = multiPart.getBodyParts().get(0).getEntityAs(BodyPartEntity.class);

を投げます

IllegalStateException: Entity instance does not contain the unconverted content

MultiPartReader を呼び出す前に、テストで生成された MultiPart を何らかの方法で変換する必要があると思います

jersey にはいくつかのメソッドが必要です。配置されたシステムで MultiPart リクエストを送信するとき、または HTTP リクエストを受信するときに解析を行うのは受信側である場合と同じように、この変換を実行するメソッドを呼び出すことができます。 ..?

4

1 に答える 1

0

jersey-multipart docs を見ると、次のように表示されます。

「現在、アプリケーションが個々のボディ パーツにどの Java クラスを使用することを好むかを事前に知ることはできないため、適切なプロバイダーを選択することはできません。現在、各ボディ パーツの解析されていないコンテンツが (バイト配列として) 返されます。 ) in the entity property of the returned BodyPart} instance, and the application can determine what more steps are needed by the header based on the body part in that body part. 最も簡単な方法は、受信した BodyPart を調べてから、getEntityAs() メソッドを呼び出すことです。どの実装クラスを好むかがわかったら。」

その提案に従う必要があるようです。サーバー側の MultiPartReader コードで返されたバイト配列を調べます。

multiPart.getBodyParts().get(0).getEntity();

...そして、BodyPart で getEntityAs() を呼び出します。

于 2013-01-22T16:36:17.430 に答える