我正在做一个使用Sping Boot 的REST API项目。每个REST API调用都应该以空字符串的形式返回NULL值,以便UI开发人员可以按原样显示这些值。
我找不到Jackson注解在序列化过程中将NULL转换为空字符串。因此,我编写了一个自定义序列化器,但它没有按预期工作。如果你看下面的代码,自定义序列化器中的sysout stmt,即“in date serializer”没有被打印。所以看起来自定义序列化器甚至没有被调用。
我用的是Jackson2.13.3.
@Entity
@Table(name="hlr_vw")
@Immutable
public class Healer_Flattened implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "hlr_id")
private Integer healerId;
@JsonSerialize(using = CustomSerializer.class)
@com.fasterxml.jackson.annotation.JsonFormat(pattern="YYYY-MM-dd")
@Column(name = "hlr_brth_dt")
private Date dob;
@JsonSerialize(using = CustomStringSerializer.class)
@Column(name = "hlr_rsdnc_city")
private String city;
// getters & setters
}
字符串
REST控制器方法:
@GetMapping("/healers/search")
public List<Healer_Flattened> searchHealers(@Param("fname") String fname, @Param("city") String city, @Param("lngId") String lngId) throws JsonProcessingException {
System.out.println("fname=" + fname);
List<Healer_Flattened> hf = healerFlattenedRepo.findByFirstName(fname);
System.out.println(hf.get(0).getFirstName());
System.out.println("dob before serialization=" + hf.get(0).getDob());
String serialized = new ObjectMapper().writeValueAsString(hf.get(0));
System.out.println("After serialization=" + serialized);
// ...
}
型
这是我的自定义序列化器:
public class CustomSerializer extends StdSerializer<Date> {
private static final long serialVersionUID = 1L;
public CustomSerializer() {
this(null);
}
public CustomSerializer(Class<Date> t) {
super(t);
}
@Override
public void serialize(Date value, JsonGenerator generator, SerializerProvider arg2) throws IOException {
System.out.println("in date serializer"); // doesn't print
generator.writeStartObject();
generator.writeString(value==null?"":value.toString());
generator.writeEndObject();
}
}
型CustomStringSerializer
类似。
日志输出:
2023-09-11 22:41:13.494 TRACE 17616 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [admin]
型
序列化后,我有:
{“healerId”:0,“dob”:null,“city”:null,“firstName”:“admin”,“lastName”:“admin”,“emailId”:“email protected(https://stackoverflow.com/cdn-cgi/l/email-protection)“,“acceptNewCaseFlag”:null,“maxNumberOfCases”:null,“languagesSpoken”:null}
如果你们中的任何人能帮助我,告诉我下面的代码有什么问题,我将不胜感激。
1条答案
按热度按时间ttp71kqs1#
回答
对于自定义
null
-序列化,您应该使用nullsUsing
属性:字符串
根据文档,这是你需要的:
序列化器类,用于序列化带注解的属性的空值,而不是默认的空值序列化器。请注意,在注解类型(类)时使用此属性目前没有效果(将来可能会改进)。自定义:2.3
定制序列化器
请注意,您不能在序列化程序中使用方法
writeStartObject()
和writeEndObject()
。这些方法用于编写{
和}
来描述JSON对象。关于另一种方法的几句话
使用应用程序逻辑实体作为域转移对象并不是一种常见的方法。我认为您应该将这些对象分开。
什么意思?
您的
Healer_Flattened
类是应用程序的私有实体。并且您希望通过REST API提供该类。这不是一个好主意,因为它会使您的应用程序变得不灵活,并且对REST API的消费者来说是危险的。例如,如果您更改
Healer_Flattened
,REST API提供的数据将自动更改,而这些更改不会被预期到,或者您将不得不付出额外的努力,以避免使用@JsonIgnore
或其他东西将您的内部更改提供给API消费者。为了避免这些恼人的问题,通常使用DTO。
型
与使用
Healer_Flattened
不同,您可以使用HealerFlattenedDto
向API消费者提供数据。您可以根据需要更改此类。