我有Athlete和Injury两个类,最后一个包含Athlete对象,当发生序列化时,我得到以下JSON表示形式:
{"id":X,"kindOfInjury":"...","muscle":"...","side":"...","outOfTrainig":Y,"injuryDate":"2018-Jun-02","athlete":{"id":X,"firstName":"...","lastName":"...","age":X,"email":"..."}}
我不想获取有关运动员的所有信息-仅获取"athleteId":1
之类的id值,而不是获取整个对象的表示形式。
因此,我发现我需要应用我的自定义序列化程序,该序列化程序在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)是否有任何机制为我提供了仅更改我真正需要的ONE属性的序列化的功能,而不是编写所有繁琐的代码(实际更改仅在此行中)? :
jgen.writeNumberField("athleteId", value.getAthlete().getId());
2)您能推荐我一些有关杰克逊的文章,因为在这一点上我对此有些困惑吗?
感谢您的耐心配合,我们期待您的答复:)
答案 0 :(得分:1)
您可能会发现使用@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);
}
答案 1 :(得分:1)
您可以为此目的使用数据传输对象(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。
答案 2 :(得分:0)
您可以尝试使用基本的字符串替换方法来处理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'
如果您可以用正则表达式替换,它将更加整洁。