How does Jackson ObjectMapper transfer byte[] to String and how can I translate it without object class?

Ringing.Wang picture Ringing.Wang · Oct 13, 2016 · Viewed 23.5k times · Source

I would like to develop restful service and it will return JSON String to client. Now there is byte[] attribute in my object.

I use ObjectMapper to translate this object to json and response to client. But I find the byte[] is wrong if I use String.getBytes() to translate the received string. Following is example.

Pojo class

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

Prepare data: use image to get byte array

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);

--Situation 1: use readvalue to object => the image2.jpg is correct

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);

--Situation 2: use readvalue to Map and get String => the image3.jpg is broken

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);

If I have to use situation 2 to translate the JSON String, how can I do it? Because clients can not get the Pojo.class, so clients only can translate the JSON string themselves.

Thanks a lot!

Answer

Kazaag picture Kazaag · Oct 13, 2016

Jackson is serializing byte[] as a Base64 string as describe in the documentation of the serializer.

The default base64 variant is the MIME without line feed (everything in one line).

You can change the variant by using the setBase64Variant on the ObjectMapper.