java 如何使用 Jackson 和包装器对象反序列化/序列化字节数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40993617/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to deserialize / serialize byte array using Hymanson and wrapper object
提问by Lukasz Rozek
I have two following classes:
我有以下两个课程:
public class User {
private String name;
private Secret secret;
public User( @JsonProperty("name") String name, @JsonProperty("secret") Secret secret ) {
this.name = name;
this.secret = secret;
}
public String getName() {
return name;
}
public Secret getSecret() {
return secret;
}
}
and
和
public class Secret {
private byte[] secret;
public Secret( byte[] secret ) {
this.secret = secret;
}
@JsonValue
public byte[] getSecret() {
return secret;
}
}
I would like to use these classes to serialize / deserialize following json:
我想使用这些类来序列化/反序列化以下 json:
{
"name": "bdf",
"secret": "AQ=="
}
Java to json works properly. However when I try to deserialize json I get the following exception:
Java 到 json 工作正常。但是,当我尝试反序列化 json 时,出现以下异常:
com.fasterxml.Hymanson.databind.JsonMappingException: Can not instantiate value of type [simple type, class deserialization.Secret] from String value ('YQ=='); no single-String constructor/factory method
at [Source: [B@3b938003; line: 1, column: 25] (through reference chain: deserialization.User["secret"])
at com.fasterxml.Hymanson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.Hymanson.databind.DeserializationContext.mappingException(DeserializationContext.java:875)
at com.fasterxml.Hymanson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:281)
at com.fasterxml.Hymanson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:284)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1176)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:143)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:134)
at com.fasterxml.Hymanson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:461)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:376)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1099)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:294)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:131)
at com.fasterxml.Hymanson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3702)
at com.fasterxml.Hymanson.databind.ObjectMapper.readValue(ObjectMapper.java:2807)
at deserialization.SerializationTest.itShouldDeserialize(SerializationTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.accesspublic Secret( byte[] secret )
0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
How can I tell Hymanson to first decode base64 encoded value and then use this constructor?
如何告诉 Hymanson 首先解码 base64 编码的值,然后使用此构造函数?
public static class Holder {
private Bytes bytes;
private String otherStuff;
public Bytes getBytes() {
return bytes;
}
public void setBytes(Bytes bytes) {
this.bytes = bytes;
}
public String getOtherStuff() {
return otherStuff;
}
public void setOtherStuff(String otherStuff) {
this.otherStuff = otherStuff;
}
}
回答by BretC
This can be done by writing your own custom serializer and deserializer.
这可以通过编写您自己的自定义序列化器和反序列化器来完成。
http://www.baeldung.com/Hymanson-custom-serialization
http://www.baeldung.com/Hymanson-custom-serialization
http://www.baeldung.com/Hymanson-deserialization
http://www.baeldung.com/Hymanson-deserialization
Here's an example similar to what you are doing...
这是一个类似于你正在做的例子......
Holder class
持有人类
@JsonSerialize(using = BytesSerializer.class)
@JsonDeserialize(using = BytesDeserializer.class)
public static class Bytes {
private byte[] bytes;
public Bytes(byte[] bytes) {
this.bytes = bytes;
}
public byte[] getBytes() {
return bytes;
}
}
Bytes class
字节类
Notice the annotations for the custom serializer...
请注意自定义序列化程序的注释...
public static class BytesSerializer extends StdSerializer<Bytes> {
private static final long serialVersionUID = -5510353102817291511L;
public BytesSerializer() {
super(Bytes.class);
}
@Override
public void serialize(Bytes value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeString(Base64.encode(value.getBytes()));
}
}
Serializer
序列化器
This will serialize a "Bytes" object as a base64 string...
这会将“字节”对象序列化为 base64 字符串...
public static class BytesDeserializer extends StdDeserializer<Bytes> {
private static final long serialVersionUID = 1514703510863497028L;
public BytesDeserializer() {
super(Bytes.class);
}
@Override
public Bytes deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
String base64 = node.asText();
return new Bytes(Base64.decode(base64));
}
}
Deserializer
解串器
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Holder holder = new Holder();
holder.setOtherStuff("[OTHER STUFF]");
holder.setBytes(new Bytes(new byte[] { 1, 2, 3, 4, 5 }));
String json = mapper.writeValueAsString(holder);
System.out.println(json);
Holder deserialised = mapper.readValue(json, Holder.class);
System.out.println(Arrays.toString(deserialised.getBytes().getBytes()));
}
Main method
主要方法
A simple test method...
一个简单的测试方法...
{"bytes":"AQIDBAU=","otherStuff":"[OTHER STUFF]"}
[1, 2, 3, 4, 5]
Output
输出
##代码##Run it yourself
自己运行
All of the classes above are "static" because I'd wrapped them into one big class called "Stack".
上面的所有类都是“静态的”,因为我将它们包装到一个名为“Stack”的大类中。
If you want to run this, create a new class (called anything you want) and paste all the code here into it...
如果您想运行它,请创建一个新类(称为您想要的任何名称)并将此处的所有代码粘贴到其中...