>  기사  >  Java  >  SpringBoot에서 Json의 직렬화 및 역직렬화 문제를 해결하는 방법

SpringBoot에서 Json의 직렬화 및 역직렬화 문제를 해결하는 방법

WBOY
WBOY앞으로
2023-05-12 16:07:06786검색

json 직렬화/역직렬화 제어

1. @JsonIgnoreProperties

@JsonIgnoreProperties(value = { "prop1","prop2" })

사용은 Pojo 클래스를 수정하고 직렬화 및 역직렬화 중에 지정된 속성을 무시하는 데 사용됩니다.

@JsonIgnoreProperties(ignoreUnknown = true)

Pojo를 수정하는 데 사용됩니다. 클래스, 생성자에서 설정할 수 없고 해당 setter 메서드가 없는 속성을 포함하여 역직렬화 중에 설정할 수 없는 속성을 무시합니다.

2. @JsonProperty 주석

json 필드의 이름이 Pojo와 동일한 경우 속성 이름이 일관되지 않으면 @JsonProperty를 사용하여 getter() 또는 setter() 메서드에 주석을 달 수 있습니다. 이 주석은 json에 해당하는 속성 이름을 설정합니다. 또한 @JsonProperty는 생성자의 형식 매개변수에 주석을 달기 위해 자주 사용됩니다. 이 경우 생성자 @JsonCreator 주석을 추가해야 합니다.

3. @JsonCreator 주석

Pojo 클래스가 매개변수가 있는 생성자를 정의하지만 매개변수 없는 생성자를 제공하지 않으면 역직렬화 중에 오류가 보고됩니다. 두 가지 방법:

  • 방법 1: 매개변수 없는 생성자 추가

  • 방법 2: 이 매개변수화된 생성자에 @JsonCreator 주석을 추가하고 매개변수에 @JsonProperty.

4로 주석을 달아야 합니다. @JsonGetter를 사용한 주석

json 필드의 이름이 Pojo의 속성 이름과 일치하지 않는 경우 @JsonGetter를 사용하여 getter()에 주석을 달고 @JsonSetter를 사용하여 setter() 메서드에 주석을 달 수 있습니다. 속성 이름을 지정합니다. 이 두 주석은 모두 @JsonProperty.

5로 대체될 수 있습니다. @JsonAnySetter 주석

브랜드/가격과 같은 속성이 있는 Car 객체와 같은 일반 객체 속성 이름은 결정됩니다. 때로는 Car 객체가 일부 확장 속성을 설정해야 합니다. 이러한 확장 속성의 이름은 일반적으로 이러한 확장 속성의 K/V를 json 데이터에 저장하는 데 사용됩니다. Map에서는 K/V setter 메서드를 클래스에 추가해야 하며 이 setter 메서드에는 @JsonAnySetter라는 주석을 달아야 합니다.

public class Car {
    public String brand;
    private Map<String, String> properties;
 
    @JsonAnySetter
    public void add(String key, String value) {
        properties.put(key, value);
    }
}

클래스에 @JsonAnySetter가 추가되면 다음 json이 생성됩니다. 데이터는 Map으로 역직렬화될 수 있습니다:

{
"brand":"Benz",
"attr2":"val2",
"attr1":"val1"
}

6. @JsonAnyGetter 주석

은 @JsonAnySetter 주석에 해당합니다. 클래스의 Map K/V 속성을 json으로 직렬화하려면 @JsonAnyGetter를 추가해야 합니다.

public class Car {
    public String brand;
    private Map<String, String> properties;
 
    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }
}

직렬화된 json은

{
"brand":"Benz",
"attr2":"val2",
"attr1":"val1"
}

7입니다. @JsonFormat 주석

일반적으로 날짜/시간 속성의 직렬화에 사용되는 시간 형식을 지웁니다.

public class Event {
    public String name;
 
    @JsonFormat(
      shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
    public Date eventDate;
}

8. @JsonSerialize 및 @JsonDeserialize 주석

@ JsonSerialize 주석은 클래스 속성에 대한 특수 직렬화 기능을 설정할 수 있으며 @JsonDeserialize 주석은 json 속성에 대한 역직렬화 기능을 사용자 정의하는 데 사용됩니다

SpringBoot 직렬화 규칙

  • 포함 .Include.ALWAYS 기본 Include.Include.ALWAYS 默认

  • Include.NON_DEFAULT 属性为默认值不序列化

  • Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化

  • Include.NON_NULL

Include.NON_DEFAULT 속성은 기본값이며 직렬화되지 않습니다.

Include.NON_EMPTY 속성은 다음과 같습니다. 비어 있음("") 또는 NULL이고 직렬화되지 않았습니다.

Include.NON_NULL 속성이 NULL이고 직렬화되지 않았습니다

1. 전역 설정

/**
 * 〈返回json空值去掉null和""〉 〈功能详细描述〉
 * 
 * @author gogym
 * @version 2017年10月13日
 * @see JacksonConfig
 * @since
 */
@Configuration
public class JacksonConfig
{
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
    {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        // 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
        // Include.Include.ALWAYS 默认
        // Include.NON_DEFAULT 属性为默认值不序列化
        // Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
        // Include.NON_NULL 属性为NULL 不序列化,就是为null的字段不参加序列化
        //objectMapper.setSerializationInclusion(Include.NON_EMPTY);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        return objectMapper;
    }
}

또는

spring.jackson.default-property-inclusion=non_null
spring:
  jackson:
    default-property-inclusion: non_null

2 . 설정해야 하는 엔터티 클래스 또는 필드에 대한 로컬 설정

@JsonInclude(Include.NON_NULL)

3. 로컬 직렬화 사용자 정의

(1) StdSerializer8742468051c85b06f0a0af9e3e506b5c를 구현해야 하는 직렬화 도구 클래스를 사용자 정의합니다. ;

public class ClientObjectSerialize extends JsonSerializer<CreditBorrowerRepaymentRequestDto>{
 @Override
 public void serialize(CreditBorrowerRepaymentRequestDto dto, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
 
  jsonGenerator.writeStartObject();
  try {
   Field[] fields = dto.getClass().getDeclaredFields();
   for (Field field : fields) {
    field.setAccessible(true);
    if(null == field.get(dto)){
     continue; 
    }
    jsonGenerator.writeFieldName(field.getName());
    jsonGenerator.writeObject(field.get(dto));
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  jsonGenerator.writeEndObject();
 }
}
(2) 주석을 사용하여 엔터티 클래스에 대해 작업 위의
@JsonSerialize(using = ClientObjectSerialize.class)
public class CreditBorrowerRepaymentRequestDto{
}

(3)을 엔터티 개체 필드에 사용하여 NULL 값을 처리하거나

@JsonSerialize(using = ClientStringSerialize.class)
private String name;
 
@JsonSerialize(using = ClientDtaeSerialize.class)
private Date date;
public class ClientStringSerialize extends JsonSerializer<String> {
 
 @Override
 public void serialize(String string, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
 
  if(string == null){
   jsonGenerator.writeString(string + "[NULL]");
  }else{
   jsonGenerator.writeString(string);
  }
 }
}
 
public class ClientDtaeSerialize extends JsonSerializer<Date> {
 @Override
 public void serialize(Date createDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
  jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createDate));
 }
}
4 전역 Null 변환 직렬화

SpringBoot 반환을 사용자 정의할 수 있습니다. Json 데이터에서 null 값을 처리하고 문자열 유형을 변환합니다. null 값을 ""로 변환하고, 컬렉션 배열 유형 null 값을 []로 변환하고, 기본 데이터 유형 null 값을 0으로 변환하고, Boolean 유형 null 값을 변환합니다. false로 변경되고 엔터티 객체 null 값은 {}로 변환됩니다.

(1)사용자 정의 null 값 직렬 변환기

🎜
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
/**
 * 自定义null值序列化处理器
 */
public class CustomizeNullJsonSerializer {
 
 /**
  * 处理数组集合类型的null值
  */
 public static class NullArrayJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
    SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeStartArray();
   jsonGenerator.writeEndArray();
  }
 }
 
 /**
  * 处理字符串类型的null值
  */
 public static class NullStringJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
    SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeString("");
  }
 }
 
 /**
  * 处理数值类型的null值
  */
 public static class NullNumberJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeNumber(0);
  }
 }
 
 /**
  * 处理boolean类型的null值
  */
 public static class NullBooleanJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeBoolean(false);
  }
 }
 
 /**
  * 处理实体对象类型的null值
  */
 public static class NullObjectJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeStartObject();
   jsonGenerator.writeEndObject();
  }
 }
}
🎜(2)🎜Serializer modifier🎜🎜
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.util.Collection;
import java.util.List;
 
/**
 * <pre class="brush:php;toolbar:false">
 * 此modifier主要做的事情为:
 * 1.当序列化类型为数组集合时,当值为null时,序列化成[]
 * 2.String类型值序列化为""
 *
 * 
*/ public class MyBeanSerializerModifier extends BeanSerializerModifier { @Override public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List beanProperties) { // 循环所有的beanPropertyWriter for (int i = 0; i < beanProperties.size(); i++) { BeanPropertyWriter writer = beanProperties.get(i); // 判断字段的类型,如果是数组或集合则注册nullSerializer if (isArrayType(writer)) { // 给writer注册一个自己的nullSerializer writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullArrayJsonSerializer()); } if (isStringType(writer)) { writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullStringJsonSerializer()); } } return beanProperties; } /** * 是否是数组 */ private boolean isArrayType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return clazz.isArray() || Collection.class.isAssignableFrom(clazz); } /** * 是否是String */ private boolean isStringType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz); } /** * 是否是数值类型 */ private boolean isNumberType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return Number.class.isAssignableFrom(clazz); } /** * 是否是boolean */ private boolean isBooleanType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return clazz.equals(Boolean.class); } }🎜(3)🎜Jackson 엔터티 구성🎜🎜
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 
/**
 * 配置Jackson实体
 */
@Configuration
public class JacksonConfig {
 @Bean
 @Primary
 @ConditionalOnMissingBean(ObjectMapper.class)
 public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
  ObjectMapper objectMapper = builder.createXmlMapper(false).build();
  /** 为objectMapper注册一个带有SerializerModifier的Factory */
  objectMapper.setSerializerFactory(objectMapper.getSerializerFactory()
    .withSerializerModifier(new MyBeanSerializerModifier()));
 
  SerializerProvider serializerProvider = objectMapper.getSerializerProvider();
  serializerProvider.setNullValueSerializer(new CustomizeNullJsonSerializer
 .NullObjectJsonSerializer());
  return objectMapper;
 }
}

위 내용은 SpringBoot에서 Json의 직렬화 및 역직렬화 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제