我希望通过name
和values
为DTO创建一个带有Json
或/和Jackson
注释的属性的JSON字符串
。
我的DTO:
class DTO {
@??? = "individual.lastName"
private List<String> lastName = ["LastName1","LastName2"];
@??? = "individual.firstName"
private List<String> firstName = ["FistName1"];
...
}
预期结果:
{
"fields": [
{
"name": "individual.lastName",
"values": [
"LastName1",
"LastName2"
]
},
{
"name": "individual.firstName",
"values": [
"FirstName1"
]
}
]
}
答案 0 :(得分:0)
您正在寻找为每个DTO属性创建一个具有两个属性的单独json对象。换句话说,您希望转换List
s Map
并序列化Map
。
这可以通过com.fasterxml.jackson.databind.util.Converter
类+ @JsonSerialize
注释来实现。问题是Jackson将转换器关联到Type,因此所有List
类型属性都将具有相同的转换器。另一个问题是转换器不知道DTO属性的名称。预计只会处理该值。
因此,我们为DTO类定制了一个自定义序列化程序,它针对特定的POJO进行了定制,可以访问所有属性并可以显式生成所需的任何内容。我添加了一个自定义注释,允许为每个dto属性指定“json name”:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) //can use in field only.
public @interface JsonName
{
String value();
}
@JsonSerialize(using = DTOSerializer.class)
public class DTO
{
@JsonName("individual.lastName")
public List<String> lastName = Arrays.asList("LastName1", "LastName2");
@JsonName("individual.firstName")
public List<String> firstName = Arrays.asList("firstName1");
}
自定义序列化程序获取dto的所有字段,查找@JsonName注释并从注释的值中分配json“name”属性:
public class DTOSerializer extends JsonSerializer<DTO>
{
@Override
public void serialize(DTO value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeStartObject();
gen.writeFieldName("fields");
gen.writeStartArray();
Field[] fields = dto.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(JsonName.class)) {
Object fieldValue = null;
try {
fieldValue = field.get(dto);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
if (fieldValue != null) {
String fieldName = ((JsonName)field.getAnnotation(JsonName.class)).value();
gen.writeStartObject();
gen.writeStringField("name", fieldName);
gen.writeObjectField("values", fieldValue);
gen.writeEndObject();
}
}
}
gen.writeEndArray();
gen.writeEndObject();
}
}
致电
new ObjectMapper().writeValue(System.out, new DTO());
产生完全符合预期的
{"fields":[{"name":"individual.lastName","values":["LastName1","LastName2"]},{"name":"individual.firstName","values":["firstName1"]}]}