最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Jackson Custom Mapper to convert Byte Array to String - Stack Overflow

programmeradmin1浏览0评论

I'm incredibly new to Jackson and I have a problem with understanding how I could acplish something.

I've got some data that is of type byte[] (the data is within classes generated from JAXB). Before the data is sent to the browser, Jackson then (I believe) turns it into JSON so that the webpage can consume it. At least that is my crude understanding, so far.

The JSON data shows my byte [] as strings, which don't match the display that we want. For instance, the actual data might be CAFEDEAD but the JSON string looks like 3q2+78r+. I'd like the JSON to contain the string CAFEDEAD

My question is, can I write something custom for Jackson that before it creates the final JSON, turn the byte[] data into a readable hex string? Or if not, what other options do I have?

I have access to the javascript so if there is a way to turn the JSON string back, i'm up for that as well.

I'm incredibly new to Jackson and I have a problem with understanding how I could acplish something.

I've got some data that is of type byte[] (the data is within classes generated from JAXB). Before the data is sent to the browser, Jackson then (I believe) turns it into JSON so that the webpage can consume it. At least that is my crude understanding, so far.

The JSON data shows my byte [] as strings, which don't match the display that we want. For instance, the actual data might be CAFEDEAD but the JSON string looks like 3q2+78r+. I'd like the JSON to contain the string CAFEDEAD

My question is, can I write something custom for Jackson that before it creates the final JSON, turn the byte[] data into a readable hex string? Or if not, what other options do I have?

I have access to the javascript so if there is a way to turn the JSON string back, i'm up for that as well.

Share Improve this question asked Mar 26, 2013 at 17:33 RobbRobb 2,6864 gold badges20 silver badges24 bronze badges 3
  • 1 Why is it important how the JSON propagates the binary data? That sounds like it's probably Base64 - so decode the base64 to get back the original binary data, and then you can display it however you want. – Jon Skeet Commented Mar 26, 2013 at 17:37
  • Will give this idea a shot, thanks Jon! – Robb Commented Mar 26, 2013 at 17:38
  • Please show us some code – Jason Commented Mar 27, 2013 at 5:35
Add a ment  | 

4 Answers 4

Reset to default 3

Jackson will convert byte[] into Base64-encoded binary data. This is the safe way to pass binary content. Otherwise there is no way to know which character encoding might be used by contained data, so trying to build a String out of it would be risky and error-prone.

So the simplest way would be to have receiver base64 decode contents back into binary data.

You could alternatively add custom serializer to turn into other representations (hex, base85), but it really depends on what the goal is.

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

Below is how you could support this use case with MOXy as your JSON-binding provider.

Java Model

By default a JAXB implementation will convert a byte[] to base64Binary. You can use the HexBinaryAdapter to have it represented as hexBinary.

package forum15643723;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    private byte[] foo;

    @XmlJavaTypeAdapter(HexBinaryAdapter.class)
    private byte[] bar;

}

Demo

In the demo code below we will read the JSON into objects and then write it back to JSON.

package forum15643723;

import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Root.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource json = new StreamSource("src/forum15643723/input.json");
        Root root = (Root) unmarshaller.unmarshal(json, Root.class).getValue();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

jaxb.properties

To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model (see: http://blog.bdoughan./2011/05/specifying-eclipselink-moxy-as-your.html).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

input.json/Output

The foo and bar properties represent the same data. foo is represented as base64Binary and bar is represented as hexBinary.

{
   "foo" : "3q2+78r+",
   "bar" : "DEADBEEFCAFE"
}

For More Information

  • http://blog.bdoughan./2011/08/json-binding-with-eclipselink-moxy.html

You can use @JsonSerialize and @JsonDeSerialize annotations over any property. javadoc is at

 http://jackson.codehaus/1.2.1/javadoc/org/codehaus/jackson/map/annotate/JsonSerialize.html

I would personally use the serialization/deserialization technique rather than conversion at client side as you probably end up doing it at multiple places.

Without any code, I had to guess what you are doing according to your question. This tutorial JSON parse to / from using Jackson shows you how to convert ObjectMapper to a Stringfiyed representation of JSON for example

"{"age":29,"messages":["msg 1","msg 2","msg 3"],"name":"mkyong"}"

Then when Javascript client receives this String, you are going to have to parse this using either built in JSON parse function or jQuery provided one. Like

    ... 
    var myJson = JSONString.parse() | jQuery.parseJSON(JSONString);
    ..

   myJson.age;  //29
   myJson.name; //"mkyong"

Reason for attempting to parse it using parse() first is to avoid using jQuery while there is already a built in function for this provided by browser. However, if this function is not detected, it will parse it through jQuery.

I hope this helps

For your interest

Your data example appears to be some kind of binary data and you are attempting to send it over the networks. This might cause routers to filter these data. If you are interested, you can have a look at encoding this data into Base64 before streaming it to the client. It is very easy to do because there are many libraries out there already.

Some resources regarding to this topic.

So it is going to be like

SERVER
  1) Jackson creates JSON String
  2) Server encodes into Base64
  3) Send

CLIENT
  1) Receive
  2) Decode base64
  3) parse JSON String
发布评论

评论列表(0)

  1. 暂无评论