我需要一些帮助。我必须得到下一个json:
{
"433434" : {
"type" : "MULTIPLE",
"value" : [ {
"type" : "NUMBER",
"value" : 322332
}, {
"type" : "NUMBER",
"value" : 322332
} ]
}
}
但我有这个:
{
"433434" : {
"value" : [ {
"type" : "NUMBER",
"value" : 322332
}, {
"type" : "NUMBER",
"value" : 322332
} ]
}
}
我正在使用杰克逊。它是我的主要班级
package com.un1acker;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.un1acker.characteristic.AbstractCharacteristic;
import com.un1acker.characteristic.MultipleCharacteristic;
import com.un1acker.characteristic.NumCharacteristic;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
NumCharacteristic numCharacteristic = new NumCharacteristic();
numCharacteristic.setValue(BigInteger.valueOf(322332L));
List<AbstractCharacteristic<?>> list = new ArrayList<>();
list.add(numCharacteristic);
list.add(numCharacteristic);
StringWriter sw = new StringWriter();
MultipleCharacteristic multipleCharacteristic = new MultipleCharacteristic();
multipleCharacteristic.setValue(list);
Map<String, AbstractCharacteristic<?>> map = new HashMap<>();
map.put("433434", multipleCharacteristic);
mapper.writeValue(sw, map);
System.out.println(sw.toString());
}
}
我有从AbstractCharacteristic扩展的类MultipleCharateristic和NumberCharacteristic。计划我们有地图&gt;,其中包含值MultipleCharacteristic。 在NumberCharacteristic值的MultipleCharacteristic集列表中。
package com.un1acker.characteristic;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes({ @JsonSubTypes.Type(
value = NumCharacteristic.class,
name = "NUMBER"
), @JsonSubTypes.Type(
value = MultipleCharacteristic.class,
name = "MULTIPLE")})
public abstract class AbstractCharacteristic<T>{
private static final long serialVersionUID = -6524899961842198462L;
private T value;
public AbstractCharacteristic() {
}
public T getValue() {
return this.value;
}
protected void setValue(T value) {
this.value = value;
}
}
NumCharacteristic Class
package com.un1acker.characteristic;
import java.math.BigInteger;
public class NumCharacteristic extends AbstractCharacteristic<BigInteger> {
private static final long serialVersionUID = 9220460768952701281L;
public NumCharacteristic() {
}
public void setValue(BigInteger value) {
super.setValue(value);
}
}
MultipleCharacteristic class
package com.un1acker.characteristic;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.un1acker.MyCustomSerializer;
import java.util.List;
public class MultipleCharacteristic extends AbstractCharacteristic<List<? extends AbstractCharacteristic<?>>> {
@Override
public void setValue(List<? extends AbstractCharacteristic<?>> value) {
super.setValue(value);
}
@Override
@JsonSerialize(using = MyCustomSerializer.class)
public List<? extends AbstractCharacteristic<?>> getValue() {
return super.getValue();
}
}
我尝试使用覆盖方法serializeWithType为MultipleClass创建自定义序列化,但这不起作用。
答案 0 :(得分:0)
这看起来可能是杰克逊的错误。你的MultipleCharacteristic类型序列化很好并且包含了它自己的类型,但是当它是一个地图值时却不是,我希望它的工作方式相同:
@Test // passes
public void serialize_multiple_characteristic() throws Exception {
MultipleCharacteristic chr = new MultipleCharacteristic();
chr.setValue(new ArrayList<>());
ObjectMapper mapper = new ObjectMapper();
assertThat(mapper.writeValueAsString(chr), equivalentTo("{ type: 'MULTIPLE', value: [] }"));
}
@Test // fails, got: {"xyzzy":{"value":[]}}
public void serialize_multiple_characteristic_in_map_value() throws Exception {
MultipleCharacteristic chr = new MultipleCharacteristic();
chr.setValue(new ArrayList<>());
ObjectMapper mapper = new ObjectMapper();
Map<String, MultipleCharacteristic> map = new HashMap<>();
map.put("xyzzy", chr);
assertThat(mapper.writeValueAsString(map), equivalentTo("{ 'xyzzy': { type: 'MULTIPLE', value: [] } }"));
}
(透过内部看,BeanSerializer永远不会被TypeWrappedSerializer包裹)
如果地图嵌入某个地方,这个可能可能不是问题,好像杰克逊知道地图的类型参数(例如它通常从包含的bean获取,例如)它似乎做对了:
@Test // passes
public void serialize_multiple_characteristic_in_map_value_using_writer() throws Exception {
MultipleCharacteristic chr = new MultipleCharacteristic();
chr.setValue(new ArrayList<>());
ObjectMapper mapper = new ObjectMapper();
Map<String, AbstractCharacteristic<?>> map = new HashMap<>();
map.put("xyzzy", chr);
// Hint to Jackson what types will be in the map
TypeReference<?> mapType = new TypeReference<Map<String, AbstractCharacteristic<?>>>(){};
assertThat(mapper.writerFor(mapType).writeValueAsString(map), equivalentTo("{ 'xyzzy': { type: 'MULTIPLE', value: [] } }"));
}
一种解决方法,如果您只需要生成JSON并且无法更改代码以使用ObjectWrite,则使用ObjectNode而不是Map:
@Test
public void serialize_multiple_characteristic_in_json_node() throws Exception {
MultipleCharacteristic chr = new MultipleCharacteristic();
chr.setValue(new ArrayList<>());
ObjectMapper mapper = new ObjectMapper();
ObjectNode node = mapper.getNodeFactory().objectNode();
node.putPOJO("xyzzy", chr);
assertThat(mapper.writeValueAsString(node), equivalentTo("{ 'xyzzy': { type: 'MULTIPLE', value: [] } }"));
}
答案 1 :(得分:0)
这对我有用:为MultipleCharacteristic
添加自定义序列化程序:
public class MultipleCharacteristicValueSerializer extends JsonSerializer<MultipleCharacteristic> {
@Override
public void serialize(MultipleCharacteristic multipleCharacteristicValue, JsonGenerator jsonGenerator,SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeFieldName("value");
jsonGenerator.writeStartArray();
for (AbstractCharacteristic<?> characteristicValue : multipleCharacteristicValue.getValue()) {
jsonGenerator.writeObject(characteristicValue);
}
jsonGenerator.writeEndArray();
}
@Override
public void serializeWithType(MultipleCharacteristic value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException {
typeSer.writeTypePrefixForObject(value, jgen);
serialize(value, jgen, provider);
typeSer.writeTypeSuffixForObject(value, jgen);
}
@Override
public Class<MultipleCharacteristic> handledType() {
return MultipleCharacteristic.class;
}
}