Koh*_*aki 7 java json jackson lombok
我计划使用 Lombok 创建数百个基于“值对象”模式的类,如下所示:
@Data
public final class SomeId implements Serializable {
private final long value;
}
Run Code Online (Sandbox Code Playgroud)
我想将这些类用于由 Jackson 提供支持的 JSON 序列化。例如,考虑一个 DTO 类,如下所示:
public class SomeDTO {
SomeId id;
public SomeId getId() {
return id;
}
}
Run Code Online (Sandbox Code Playgroud)
我想这DTO类序列化为类似{"id":123}
,但杰克逊会产生类似{"id":{"value":123}}
,它配备了不必要的嵌套对象有一个名为场value
。即一个测试用例表达了我的要求:
public class SomeDTOTest {
@Test
public void serializationTest() throws Exception {
SomeDTO dto = new SomeDTO();
dto.id = new SomeId(123);
String serialized = new ObjectMapper().writeValueAsString(dto);
System.out.println(serialized); // {"id":{"value":123}}
assertThat(serialized, is("{\"id\":123}")); // I want {"id":123} instead!
}
}
Run Code Online (Sandbox Code Playgroud)
我知道@JsonValue
为类中的每个getValue()
方法添加注释SomeId
是一个解决方案,但我不能这样做,因为没有@Data
类的实际定义,因为 Lombok 会自动创建它。
手动创建为每个类getValue()
注释的实际方法@JsonValue
可能是另一种解决方案,但这意味着创建大量样板代码。
如何在没有样板代码的情况下实现此要求?
我创建了一个接口,其getValue()
注释为@JsonValue
:
public interface LongValue {
@JsonValue
long getValue();
}
Run Code Online (Sandbox Code Playgroud)
然后在每个班级中实施@Data
。getValue()
请注意, Lombok 将自动生成实际的实现:
@Data
public final class SomeId implements LongValue, Serializable {
private final long value;
}
Run Code Online (Sandbox Code Playgroud)
这样我就SomeDTOTest
通过了测试 -按我的预期SomeDTO
序列化{"id":123}
。
您可以为此类编写自定义序列化器。
例如:
class CustomSerializer extends StdSerializer<SomeId>{
protected CustomSerializer(Class<SomeId> t) {
super(t);
}
@Override
public void serialize(SomeId someId, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException {
gen.writeNumber(someId.getValue());
}
}
Run Code Online (Sandbox Code Playgroud)
现在使用这个序列化器来序列化SomeId
类:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(new CustomSerializer(SomeId.class));
mapper.registerModule(module);
SomeDTO dto = new SomeDTO();
dto.id = new SomeId(123);
String serialized = mapper.writeValueAsString(dto);
System.out.println(serialized); // output : {"id":123}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8535 次 |
最近记录: |