![](/img/trans.png)
[英]How can I control which instance variables are serialized when using Jackson JSON
[英]How can I specify certain field to be serialized into JSON using Jackson?
我有Athlete和Injury兩個類,最后一個包含Athlete對象,當序列化發生時,我得到以下JSON表示形式: {"id":X,"kindOfInjury":"...","muscle":"...","side":"...","outOfTrainig":Y,"injuryDate":"2018-Jun-02","athlete":{"id":X,"firstName":"...","lastName":"...","age":X,"email":"..."}}
我不想獲取有關運動員的所有信息-只是一個id值,例如"athleteId":1
,而不是獲取整個對象的表示形式。
因此,我發現我需要應用我的自定義序列化程序,該序列化程序在Injury類上實現StdSerializer。 所以這就是我到目前為止所得到的:
class InjurySerializer extends StdSerializer<Injury> {
public InjurySerializer() {
this(null);
}
public InjurySerializer(Class<Injury> i) {
super(i);
}
@Override
public void serialize(
Injury value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("id", value.getId());
jgen.writeStringField("kindOfInjury", value.getKindOfInjury());
jgen.writeStringField("muscle", value.getMuscle());
jgen.writeStringField("side", value.getSide());
jgen.writeNumberField("outOfTraining", value.getOutOfTraining());
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MMM-dd");
Date date = new Date();
String ourformat = formatter.format(date.getTime());
jgen.writeStringField("injuryDate", ourformat);
jgen.writeNumberField("athleteId", value.getAthlete().getId());
jgen.writeEndObject();
}
}
以及實際的傷害類別:
@Entity
@Table(name = "INJURY")
@JsonSerialize(using = InjurySerializer.class)
public class Injury {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "INJURY_ID")
private Long id;
@Column(name = "KIND_OF_INJURY")
private String kindOfInjury;
@Column(name = "MUSCLE")
private String muscle;
@Column(name = "SIDE")
private String side;
@Column(name = "OUT_OF_TRAINING")
private Integer outOfTraining;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MMM-dd")
@Column(name = "INJURY_DATE")
private Date injuryDate;
@ManyToOne
@JoinColumn(name = "ATHLETE_ID")
private Athlete athlete;
因此,此解決方案有效,但看起來很糟糕...
問題如下: 1)是否有任何機制可以為我提供僅更改我真正需要的一個屬性的序列化功能,而不是編寫所有僅此行的繁瑣代碼,而無需編寫所有繁瑣的代碼? :
jgen.writeNumberField("athleteId", value.getAthlete().getId());
2)您能推薦我一些有關傑克遜的文章,因為在這一點上我對此有些困惑嗎?
感謝您的耐心配合,我們期待您的答復:)
您可能會發現使用@JsonIgnore
批注而不是編寫自定義序列化程序會比較@JsonIgnore
。 舉個例子
public class Person {
private int id;
@JsonIgnore
private String first;
@JsonIgnore
private String last;
@JsonIgnore
private int age;
// getters and setters omitted
}
當Jackson序列化此類時,它僅在結果JSON中包含“ id”屬性。
@Test
void serialize_only_includes_id() throws JsonProcessingException {
final var person = new Person();
person.setId(1);
person.setFirst("John");
person.setLast("Smith");
person.setAge(22);
final var mapper = new ObjectMapper();
final var json = mapper.writeValueAsString(person);
assertEquals("{\"id\":1}", json);
}
為此,可以使用數據傳輸對象(DTO)。
像這樣創建一個簡單的POJO:
public class InjuryDTO {
//all other required fields from Injury model...
@JsonProperty("athlete_id")
private Long athleteId;
}
並為其轉換:
@Component
public class InjuryToDTOConverter{
public InjuryDTO convert(Injury source){
InjuryDTO target = new InjuryDTO();
BeanUtils.copyProperties(source, target); //it will copy fields with the same names
target.setAthleteId(source.getAthlete().getId());
return target;
}
}
您可以這樣使用它:
@RestController("/injuries")
public class InjuryController {
@Autowired
private InjuryToDTOConverter converter;
@Autowired
private InjuryService injuryService;
@GetMapping
public InjuryDTO getInjury(){
Injury injury = injuryService.getInjury();
return converter.convert(injury);
}
}
這種方法的好處是,您可以具有多個用於不同用途的DTO。
您可以嘗試使用基本的字符串替換方法來處理json字符串。 我運行了您的json並將其轉換為所需的格式:
public static void main(String args[]) {
String json = "{\"id\":123,\"kindOfInjury\":\"...\",\"muscle\":\"...\",\"side\":\"...\",\"outOfTrainig\":Y,\"injuryDate\":\"2018-Jun-02\",\"athlete\":{\"id\":456,\"firstName\":\"...\",\"lastName\":\"...\",\"age\":14,\"email\":\"...\"}}";
JsonObject injury = new JsonParser().parse(json).getAsJsonObject();
JsonObject athelete = new JsonParser().parse(injury.get("athlete").toString()).getAsJsonObject();
String updateJson = injury.toString().replace(injury.get("athlete").toString(), athelete.get("id").toString());
updateJson = updateJson.replace("athlete", "athleteId");
System.out.println(updateJson);
}
輸出:
{"id":123,"kindOfInjury":"...","muscle":"...","side":"...","outOfTrainig":"Y","injuryDate":"2018-Jun-02","athleteId":456}
依賴關系:
implementation 'com.google.code.gson:gson:2.8.5'
如果可以用正則表達式替換,它將更加干凈。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.