5

我对杰克逊非常陌生,我很难理解如何完成某件事。

我有一些类型byte[]的数据(数据在从 JAXB 生成的类中)。在将数据发送到浏览器之前,杰克逊(我相信)将其转换为 JSON,以便网页可以使用它。到目前为止,至少这是我粗略的理解。

JSON 数据将 my 显示byte []为字符串,这与我们想要的显示不匹配。例如,实际数据可能是CAFEDEAD,但 JSON 字符串看起来像3q2+78r+. 我希望 JSON 包含字符串CAFEDEAD

我的问题是,我可以为 Jackson 编写一些自定义的东西,在它创建最终 JSON 之前,将byte[]数据转换为可读的十六进制字符串吗?或者如果没有,我还有什么其他选择?

我可以访问 javascript,所以如果有办法将 JSON 字符串转回,我也愿意。

4

4 回答 4

3

Jackson 会将 byte[] 转换为 Base64 编码的二进制数据。这是传递二进制内容的安全方式。否则,无法知道包含的数据可能使用哪种字符编码,因此尝试从中构建字符串将是冒险且容易出错的。

因此,最简单的方法是让接收器 base64 将内容解码回二进制数据。

您也可以添加自定义序列化程序以转换为其他表示形式(十六进制,base85),但这实际上取决于目标是什么。

于 2013-03-27T16:59:16.193 回答
1

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.com/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

于 2013-03-27T10:59:23.397 回答
-1

您可以在任何属性上使用 @JsonSerialize 和 @JsonDeSerialize 注释。javadoc 在

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

我个人会使用序列化/反序列化技术,而不是在客户端进行转换,因为您可能最终会在多个地方进行转换。

于 2013-03-26T17:41:31.803 回答
-1

没有任何代码,我不得不根据你的问题猜测你在做什么。本教程JSON 解析到/从使用 Jackson向您展示如何将 ObjectMapper 转换为 JSON 的 Stringfiyed 表示,例如

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

然后,当 Javascript 客户端收到这个字符串时,您将不得不使用内置的 JSON 解析函数或 jQuery 提供的函数来解析它。喜欢

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

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

尝试首先使用 parse() 解析它的原因是避免使用 jQuery,而浏览器已经为此提供了一个内置函数。但是,如果没有检测到这个函数,它会通过 jQuery 对其进行解析。

我希望这有帮助

为了您的利益

您的数据示例似乎是某种二进制数据,您正试图通过网络发送它。这可能会导致路由器过滤这些数据。如果您有兴趣,可以先看一下将此数据编码为 Base64,然后再将其流式传输到客户端。这很容易做到,因为那里已经有很多库了。

有关此主题的一些资源。

所以它会像

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

CLIENT
  1) Receive
  2) Decode base64
  3) parse JSON String
于 2013-03-27T05:44:35.467 回答