您正在尋找具有兩個屬性爲每個DTO的屬性創建一個單獨的JSON對象。換句話說,你要轉換的List
小號Map
S和序列化Map
秒。
這可以通過com.fasterxml.jackson.databind.util.Converter
類+ @JsonSerialize
註釋來實現。問題在於Jackson將轉換器與類型關聯,因此所有List
類型的屬性將具有相同的轉換器。另一個問題是轉換器不知道DTO屬性的名稱。預計僅處理該值。
所以我們只剩下了一個符合特定的POJO的DTO類的自定義序列化,可以訪問所有的屬性,可以明確地產生什麼是必需的。我補充說,允許每個DTO屬性指定「JSON名」自定義註釋:
@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「名」財產註釋值:
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"]}]}
你試過'@ javax.xml.bind.annotation.XmlElement(NAME = 「individual.lastName」)'? – Smutje
@JsonProperty(「name」)但不映射真實名稱(individual.lastname)或@JsonSerialize不起作用。 –