jackson 은 null 회전 0 및 0 회전 null 의 예제 코드 를 실현 합 니 다.
최근 에 수치 형식의 필드 가 필요 하지 않 습 니 다.기본 값 은 비어 있 습 니 다.데이터베이스 바늘 은 이 필드 에 int 형식 으로 설계 되 었 습 니 다.dba 추천 규범 으로 인해 기본 값 은 not null 입 니 다.이때 문제 가 발생 했 습 니 다.데이터 베 이 스 는 기본적으로 0 이 저장 되 어 있 고 전단 전시 시 이 0 을 표시 할 수 없습니다.(필요 한 것 은 null)
해결 방안
이러한 처리 에 대해 일반적인 방안 은 다음 과 같은 두 가지 가 있다.
전단 을 처리 하고 0 과 null 을 통일 적 으로 처리 합 니 다.0 은 null 이 고 null 은 0 입 니 다.
백 엔 드 를 처리 합 니 다.처리 할 필드 에 대해 직렬 화 되 기 전이 나 그 후에 처리 하거나 하 드 인 코딩 방식 으로 처리 할 필드 에 대해 if else 를 씁 니 다.
방안 분석
첫 번 째,이 안 에는 비교적 난처 한 부분 이 있 습 니 다.전단 에 접 수 된 필드 중 일부 0 은 의미 가 있 습 니 다.예 를 들 어 효과 가 있 는 지,0 은 효과 가 있 는 지,만약 에 통일 적 으로 처리 하면 이것 은 null 로 바 뀌 면 문제 가 발생 합 니 다.만약 에 통일 적 으로 처리 하지 않 으 면 구별 해 야 한다.전단 에 대해 잘 모 르 기 때문에 주석 이나 표지 가 있 는 전체적인 방법 으로 비슷 한 문 제 를 처리 하 는 지 모 르 겠 고 전단 의 말 을 들 으 면 처리 가 비교적 번거롭다.so 는 백 엔 드 에서 만 처리 할 수 있다.
두 번 째,백 엔 드 처리 방식 이 더욱 유연 합 니 다.간단하게 확장 하려 면@Jason Serialize 와@Json Deserialize 주 해 를 사용 하여 사용자 정의 직렬 화 와 반 직렬 화 류 를 작성 하 십시오.빨리 완성 하려 면 하 드 인 코딩 을 하 세 요.처음에 잭 슨 의 직렬 화 반 직렬 화 체제 에 대해 잘 몰 랐 기 때문에 2 개의 serializer 와 deserializer 를 발표 한 후에 도 문제 가 끊 이지 않 았 기 때문에 프로젝트 의 진전 을 확보 하기 위해 비교적 역 겨 운 하 드 코딩 방식 으로 if else 를 많이 써 서 판단 했다.
테스트 직렬 화
maven 의존:jackson 버 전 2.9.7
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
직렬 화 클래스:
@JacksonStdImpl
public class ZeroToNullSerializer extends JsonSerializer implements ContextualSerializer {
private Class<?> type;
public ZeroToNullSerializer() {
}
public ZeroToNullSerializer(final JavaType type) {
this.type = type == null ? Object.class : type.getRawClass();
}
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (o instanceof Short) {
if (((Short) o).compareTo((short)0) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Short) o).shortValue());
}
}
if (o instanceof Integer) {
if (((Integer) o).intValue() == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Integer) o).intValue());
}
}
if (o instanceof Float) {
if (((Float) o).compareTo(0f) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Float) o).floatValue());
}
}
if (o instanceof Double) {
if (((Double) o).compareTo(0D) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Double) o).doubleValue());
}
}
if (o instanceof Long) {
if (((Long) o).compareTo(0L) == 0) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeNumber(((Long) o).longValue());
}
}
if (o instanceof BigDecimal) {
if (((BigDecimal) o).compareTo(BigDecimal.ZERO) == 0) {
jsonGenerator.writeNull();
}else {
jsonGenerator.writeNumber((BigDecimal) o);
}
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
return new ZeroToNullSerializer(property.getType());
}
}
테스트 서열 화 된 bean:
@Data
public class TestSerializerBean {
@JsonSerialize(using =ZeroToNullSerializer.class)
private Integer number;
private Integer age;
private BigDecimal money;
}
직렬 화 테스트:
@Test
public void testSerializer() throws JsonProcessingException {
TestSerializerBean serializerBean = new TestSerializerBean();
serializerBean.setNumber(0);
serializerBean.setAge(0);
serializerBean.setMoney(new BigDecimal(20));
String string = mapper.writeValueAsString(serializerBean);
System.out.println(string);
}
테스트 결과:1.테스트 대기 필드 테이프 0:
2.테스트 대기 필드 0 없 음
@Test
public void testSerializer() throws JsonProcessingException {
TestSerializerBean serializerBean = new TestSerializerBean();
serializerBean.setNumber(10);
serializerBean.setAge(0);
serializerBean.setMoney(new BigDecimal(20));
String string = mapper.writeValueAsString(serializerBean);
System.out.println(string);
}
테스트 역 직렬 화
역 직렬 화 클래스(핵심 코드 만 붙 이 고 전체 코드 는 github 에 업로드 합 니 다.주 소 는 뒷글 링크 참조):
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (this.type == Integer.class) {
return handleInteger(p, ctxt);
}
if (this.type == Long.class) {
return handleLong(p, ctxt);
}
if (this.type == BigDecimal.class) {
return handleBigDecimal(p, ctxt);
}
if (this.type == Double.class) {
return handleDouble(p, ctxt);
}
if (this.type == Float.class) {
return handleFloat(p, ctxt);
}
if (this.type == Short.class) {
return handleShort(p, ctxt);
}
throw new RuntimeException(" , " + type.toString() + "+ ");
}
private Object handleBigDecimal(JsonParser p, DeserializationContext ctxt) throws IOException {
switch (p.getCurrentTokenId()) {
case JsonTokenId.ID_NUMBER_INT:
case JsonTokenId.ID_NUMBER_FLOAT:
return p.getDecimalValue();
case JsonTokenId.ID_STRING:
String text = p.getText().trim();
// note: no need to call `coerce` as this is never primitive
if (text == null || text.length() == 0) {
return getNullValue(ctxt);
}
try {
return new BigDecimal(text);
} catch (IllegalArgumentException iae) {
}
return (BigDecimal) ctxt.handleWeirdStringValue(type, text,
"not a valid representation");
case JsonTokenId.ID_START_ARRAY:
throw new RuntimeException("NullToZeroDeserializer handleBigDecimal error, encounter token " + JsonTokenId.ID_START_ARRAY);
}
// Otherwise, no can do:
return (BigDecimal) ctxt.handleUnexpectedToken(type, p);
}
@Override
public Object getNullValue(DeserializationContext ctxt) throws JsonMappingException {
if (this.type == Integer.class) {
return 0;
}
if (this.type == BigDecimal.class) {
return BigDecimal.ZERO;
}
return 0;
}
역 정렬 을 기다 리 는 bean:
@Data
public class TestDeSerializerBean{
private Integer number;
@JsonDeserialize(using = NullToZeroDeserializer.class)
private BigDecimal money;
private BigDecimal balance;
}
역 직렬 화 테스트:
@Test
public void testDeSerializer() throws IOException {
TestDeSerializerBean serializerBean = new TestDeSerializerBean();
serializerBean.setNumber(5);
serializerBean.setMoney(new BigDecimal(20));
String string = mapper.writeValueAsString(serializerBean);
String testStr = "{
" +
" \"number\": 5,
" +
" \"money\": \"20.0\"
" +
"}";
TestDeSerializerBean deSerializerBean = mapper.readValue(testStr, TestDeSerializerBean.class);
System.out.println(deSerializerBean);
}
테스트 결과:null 형식:
@Test
public void testDeSerializer() throws IOException {
TestDeSerializerBean serializerBean = new TestDeSerializerBean();
serializerBean.setNumber(5);
serializerBean.setMoney(new BigDecimal(20));
String string = mapper.writeValueAsString(serializerBean);
String testStr = "{
" +
" \"number\": 5,
" +
" \"money\": \"\"
" +
"}";
TestDeSerializerBean deSerializerBean = mapper.readValue(testStr, TestDeSerializerBean.class);
System.out.println(deSerializerBean);
}
2.비 null 형식
역 직렬 화 된 클래스 직렬 화 null 값 을 사용 할 때 getNullValue 방법 을 다시 쓰 는 것 에 주의 하 십시오.
총결산
이상 은 null 에서 0 으로 전환 하고 0 으로 전환 하 는 null 에 대한 코드 일 뿐 사용자 정의 직렬 화가 필요 할 때 기 존의 serializer 와 deserializer 류 를 참고 할 수 있 습 니 다.예 를 들 어 DateDeserializer 와 DateSerializer,BigDecimal Deserializer 와 BigDecimal Serializer 등 입 니 다.이러한 이후 의 직렬 화 와 반 직렬 화 류 를 참고 하여 우 리 는 원 하 는 사용자 정의 직렬 화 와 반 직렬 화 효 과 를 쓸 수 있다.
코드 주소
이상 의 이 jackson 은 null 전 0 과 0 전 null 을 실현 하 는 예제 코드 는 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.참고 하 시기 바 랍 니 다.여러분 들 도 저 희 를 많이 사랑 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Spring Boot에서 json Date/LocalDateTime/LocalDate 형식 지정Spring Boot는 기본적으로 을 사용하여 json 데이터를 직렬화, 역직렬화합니다. 기본적으로 Jackson은 객체를 타임스탬프로 직렬화합니다Date. LocalDateTime , LocalDate 객체에 대해...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.