我对杰克逊来说是一个非常新的人,我在理解如何完成某些事情时遇到了问题。
我有一些byte[]
类型的数据(数据在JAXB生成的类中)。在将数据发送到浏览器之前,Jackson然后(我相信)将其转换为JSON,以便网页可以使用它。到目前为止,至少这是我粗略的理解。
JSON数据显示我的byte []
为字符串,与我们想要的显示不匹配。例如,实际数据可能是CAFEDEAD
,但JSON字符串看起来像3q2+78r+
。我希望JSON包含字符串CAFEDEAD
我的问题是,我可以在创建最终JSON之前为Jackson编写一些自定义内容,将byte[]
数据转换为可读的十六进制字符串吗?或者如果没有,我还有其他选择吗?
我可以访问javascript,所以如果有办法将JSON字符串重新打开,我也会这样做。
答案 0 :(得分:4)
Jackson将byte []转换为Base64编码的二进制数据。这是传递二进制内容的安全方法。否则无法知道包含的数据可能使用哪个字符编码,因此尝试从中构建一个String会有风险且容易出错。
所以最简单的方法是让接收器base64将内容解码回二进制数据。
您也可以添加自定义序列化器以转换为其他表示形式(hex,base85),但这实际上取决于目标是什么。
答案 1 :(得分:1)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
以下是如何使用MOXy作为JSON绑定提供程序来支持此用例。
Java模型
默认情况下,JAXB实现会将byte[]
转换为base64Binary。您可以使用HexBinaryAdapter
将其表示为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;
}
<强>演示强>
在下面的演示代码中,我们将JSON读入对象,然后将其写回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 强>
要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含名为jaxb.properties
的文件(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
<强> input.json /输出强>
foo
和bar
属性表示相同的数据。 foo
表示为base64Binary,bar
表示为hexBinary。
{
"foo" : "3q2+78r+",
"bar" : "DEADBEEFCAFE"
}
了解更多信息
答案 2 :(得分:0)
没有任何代码,我不得不根据你的问题猜测你在做什么。本教程JSON parse to / from using Jackson向您展示了如何将ObjectMapper转换为JSON的Stringfiyed表示形式,例如
"{"age":29,"messages":["msg 1","msg 2","msg 3"],"name":"mkyong"}"
然后,当Javascript客户端收到此String时,您将不得不使用内置的JSON解析函数或jQuery提供的解析它。像
...
var myJson = JSONString.parse() | jQuery.parseJSON(JSONString);
..
myJson.age; //29
myJson.name; //"mkyong"
首先尝试使用parse()解析它的原因是避免使用jQuery,而浏览器已经提供了内置函数。但是,如果未检测到此函数,它将通过jQuery解析它。
我希望这会有所帮助
为了您的兴趣
您的数据示例似乎是某种二进制数据,您尝试通过网络发送它。这可能会导致路由器过滤这些数据。如果您有兴趣,可以先将这些数据编码到Base64中,然后再将其传输到客户端。这很容易做到,因为那里已经有很多库了。
Some resources regarding to this topic.
所以它会像
SERVER
1) Jackson creates JSON String
2) Server encodes into Base64
3) Send
CLIENT
1) Receive
2) Decode base64
3) parse JSON String
答案 3 :(得分:-1)
您可以在任何属性上使用@JsonSerialize和@JsonDeSerialize注释。 我个人会使用序列化/反序列化技术而不是客户端的转换,因为你最终可能会在多个地方进行转换。 http://jackson.codehaus.org/1.2.1/javadoc/org/codehaus/jackson/map/annotate/JsonSerialize.html