为什么自定义@Exclude不能从序列化中排除字段

时间:2020-04-27 13:57:35

标签: java gson

在将对象序列化/反序列化为json时,我需要排除特定字段。

我创建了自定义注释:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Exclude {}

使用:

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.Set;

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Exclude
    private int id;
    @NotNull
    @Exclude
    private String name;

在这里,由Gson进行序列化:

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
JsonObject json = new JsonObject();
    json.addProperty("user_name", currentUserName);
    Product product = productEntry.getProduct();
    json.addProperty("product", GsonUtil.gson.toJson(product));
    json.addProperty("quantity", productEntry.getQuantity());
    logger.info("addProductToCart: json = " + json);

结果如下:

addProductToCart: json = {"user_name":"admin@admin.com","product":"{\"id\":0,\"name\":\"My product 1\",\"description\":\"\",\"created\":\"Apr 27, 2020, 4:53:34 PM\",\"price\":1.0,\"currency\":\"USD\",\"images\":[\"url_1\",\"url_2\"]}","quantity":1}

为什么字段 id,名称不从json中排除?

3 个答案:

答案 0 :(得分:0)

Gson理解@Expose(serialize = false)注释,

import com.google.gson.annotations.Expose;

    @Expose(serialize = false)
    private int id;
}

答案 1 :(得分:0)

您可能需要为此编写自定义json序列化程序,

class ExcludeFieldsSerializer extends JsonSerializer<Bean> {

@Override
public void serialize(final Bean value, final JsonGenerator gen, final SerializerProvider serializer) throws IOException, JsonProcessingException {
    gen.writeStartObject();
    try {
        for (final Field aField : Bean.class.getFields()) {
            if (f.isAnnotationPresent(Ignore.class)) {
                gen.writeStringField(aField.getName(), (String) aField.get(value));
            }
        }
    } catch (final Exception e) {

    }
    gen.writeEndObject();
}

}

使用对象映射器进行注册

但是,您也可以将现有注释用作

@Expose (serialize = false, deserialize = false)

如果序列化为true,则在序列化时会在JSON中写出标记字段。

如果反序列化为true,则从JSON反序列化标记的字段。 和

Gson gson = new GsonBuilder()
    .excludeFieldsWithoutExposeAnnotation()
    .create();

稍后您可以执行gson.toJson(product)

编辑:如果将Gson对象创建为新的Gson(),并且如果我们尝试执行toJson()和fromJson()方法,则@Expose对序列化和反序列化没有任何影响。

答案 2 :(得分:0)

我找到了解决方法:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Exclude {}

以及初始化gson时:

公共类GsonUtil {

  public static GsonBuilder gsonbuilder = new GsonBuilder();
    public static Gson gson;
    public static JsonParser parser = new JsonParser();

    static {
        // @Expose -> to exclude specific field when serialize/deserilaize
        gsonbuilder.addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes field) {
                return field.getAnnotation(Exclude.class) != null;
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        });
        gson = gsonbuilder.create();
    }
}

使用:

@Entity
    public class Product {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Exclude
        private int id;

现在成功排除了特定字段。

相关问题