web-dev-qa-db-ja.com

Jackson ObjectMapperはどのようにbyte []をStringに転送し、オブジェクトクラスなしでどのように変換できますか?

Restfulサービスを開発したいのですが、JSON文字列がクライアントに返されます。これで、オブジェクトにbyte []属性があります。

ObjectMapperを使用して、このオブジェクトをjsonに変換し、クライアントに応答します。しかし、受信した文字列を変換するためにString.getBytes()を使用すると、byte []が間違っていることがわかります。以下は例です。

Pojoクラス

public class Pojo {
    private byte[] pic;
    private String id;
    //getter, setter,...etc
}

データの準備:画像を使用してバイト配列を取得します

InputStream inputStream = FileUtils.openInputStream(new File("config/images.jpg"));
byte[] pic = IOUtils.toByteArray(inputStream);
Pojo pojo = new Pojo();
pojo.setId("1");
pojo.setPic(pic);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(pojo);

-状況1:オブジェクトにreadvalueを使用=> image2.jpgは正しい

Pojo tranPojo = mapper.readValue(json, Pojo.class);

byte[] tranPicPojo = tranPojo.getPic();
InputStream isPojo = new ByteArrayInputStream(tranPicPojo);
File tranFilePojo = new File("config/images2.png");
FileUtils.copyInputStreamToFile(isPojo, tranFilePojo);

-状況2:readvalueを使用してマップし、文字列を取得します=> image3.jpgが壊れています

Map<String, String> map = mapper.readValue(json, Map.class);

byte[] tranString = map.get("pic").getBytes();
InputStream isString = new ByteArrayInputStream(tranString);
File tranFileString = new File("config/images3.png");
FileUtils.copyInputStreamToFile(isString, tranFileString);

状況2を使用してJSON文字列を翻訳する必要がある場合、どうすればよいですか?クライアントはPojo.classを取得できないため、クライアントはJSON文字列自体のみを翻訳できます。

どうもありがとう!

5
Ringing.Wang

Jacksonは、 シリアライザーのドキュメント で説明されているように、byte[]をBase64文字列としてシリアル化しています。

デフォルトのbase64バリアントは 改行なしのMIME (1行のすべて)です。

ObjectMappersetBae64Varient を使用して、バリアントを変更できます。

4
Kazaag

ObjectMapperはこれを処理し、ユニットテストで表現されます。

@Test
public void byteArrayToAndFromJson() throws IOException {
    final byte[] bytes = { 1, 2, 3, 4, 5 };

    final ObjectMapper objectMapper = new ObjectMapper();

    final byte[] jsoned = objectMapper.readValue(objectMapper.writeValueAsString(bytes), byte[].class);

    assertArrayEquals(bytes, jsoned);
}

これはjackson2.xbtwです。

ジャージーを使用してブラウザにファイルを送信する方法は次のとおりです。

@GET
@Path("/documentFile")
@Produces("image/jpg")
public Response getFile() {
    final byte[] yourByteArray = ...;
    final String yourFileName = ...;
    return Response.ok(yourByteArray)
                   .header("Content-Disposition", "inline; filename=\"" + yourFilename + "\";")
                   .build();

Spring MVCを使用した別の例:

@RequestMapping(method = RequestMethod.GET)
public void getFile(final HttpServletResponse response) {
    final InputStream yourByteArrayAsStream = ...;
    final String yourFileName = ...;

    response.setContentType("image/jpg");
    try {
        output = response.getOutputStream();
        IOUtils.copy(yourByteArrayAsStream, output);
    } finally {
        IOUtils.closeQuietly(yourByteArrayAsStream);
        IOUtils.closeQuietly(output);
    }
}
3
Tobb