Gson: Ek açıklama olmadan belirli alanları Seri Hale Getirme'den hariç tutma


413

Gson öğrenmeye çalışıyorum ve alan dışlanmasıyla mücadele ediyorum. İşte sınıflarım

public class Student {    
  private Long                id;
  private String              firstName        = "Philip";
  private String              middleName       = "J.";
  private String              initials         = "P.F";
  private String              lastName         = "Fry";
  private Country             country;
  private Country             countryOfBirth;
}

public class Country {    
  private Long                id;
  private String              name;
  private Object              other;
}

Ben GsonBuilder kullanmak ve böyle bir alan adı için bir ExclusionStrategy ekleyebilir firstNameveya countryama gibi bazı alanların özelliklerini dışlamak yönetmek gibi olamaz country.name.

public boolean shouldSkipField(FieldAttributes fa)FieldAttributes yöntemi kullanarak alanı benzer bir filtreyle eşleştirmek için yeterli bilgi içermiyor country.name.

Not: Bu konuda iyileştirmek ve alanları filtrelemek için RegEx kullanmak istediğimden ek açıklamalardan kaçınmak istiyorum.

Düzenleme : Struts2 JSON eklentisi davranışını taklit mümkün olup olmadığını görmek için çalışıyorum

Gson kullanarak

<interceptor-ref name="json">
  <param name="enableSMD">true</param>
  <param name="excludeProperties">
    login.password,
    studentList.*\.sin
  </param>
</interceptor-ref>

Düzenleme: Aşağıdaki ekleme ile soruyu yeniden açtım:

Bu sorunu açıklığa kavuşturmak için aynı türde ikinci bir alan ekledim. Temelde hariç tutmak istiyorum country.nameama değil countrOfBirth.name. Ayrıca Ülke'yi tür olarak hariç tutmak istemiyorum. Türler aynıdır, nesne grafiğinde tam olarak saptamak ve hariç tutmak istediğim gerçek yerdir.


1
Yine de 2.2 sürümünden itibaren hariç tutulacak alana bir yol belirleyemiyorum. flexjson.sourceforge.net iyi bir alternatif gibi geliyor.
Liviu T.

Benzer bir soruya verdiğim cevaba bir göz atın . Belirli bir JsonSerializertür için özel bir durum oluşturmaya dayanır - Countrysizin ExclusionStrategydurumunuzda - daha sonra uygulanır ve hangi alanların serileştirileceğine karar verir.
pirho

Yanıtlar:


625

Genel olarak serileştirilmesini istemediğiniz tüm alanlar "geçici" değiştiriciyi kullanmalısınız ve bu aynı zamanda json serileştiricileri için de geçerlidir (en azından gson dahil kullandığım birkaç tane için de geçerlidir).

Serileştirilmiş json'da adın görünmesini istemiyorsanız, buna geçici bir anahtar kelime verin, örneğin:

private transient String name;

Gson belgelerinde daha fazla ayrıntı


6
bu sınıfın tüm örnekleri için geçerli olan bir hariç tutma ek açıklamasıyla neredeyse aynı şeydir. Çalışma zamanı dinamik hariç tutma istedim. Bazı durumlarda daha açık / kısıtlı bir yanıt sağlamak için bazı alanların hariç tutulmasını istiyorum ve diğerlerinde tam nesnenin serileştirilmesini istiyorum
Liviu T.

34
Dikkat edilmesi gereken bir şey, geçici ve hem serileştirmeyi hem de serileştirmeyi etkiler. JSON'da mevcut olsa bile, nesneye serileştirilmiş olan değeri de yayacaktır.
Kong

3
Bunun transientyerine kullanmayla ilgili sorun @Expose, müşterinizde gelebilecek tüm alanlarla bir POJO'yu alay etmeniz gerektiğidir. Projeler arasında paylaşılabilecek bir arka uç API durumunda, bu sorunlu olabilir ek alanlar eklendi. Esasen alanların kara listeye eklenmesi ve beyaz listeye alınmasıdır.
theblang

11
Bu yaklaşım benim için işe yaramadı, çünkü sadece alanı gson serileştirmesinden değil, aynı zamanda dahili uygulama serileştirmesinden (Serializable arabirimini kullanarak) hariç tuttu.
pkk

8
geçici, bir alanın SERİLEŞTİRİLMESİNİ VE ÇALIŞTIRILMASINI önler. Bu benim ihtiyaçlarımla uyuşmuyor.
Loenix

318

Nishant iyi bir çözüm sağladı, ancak daha kolay bir yol var. İstediğiniz alanları @Expose ek açıklamasıyla işaretleyin, örneğin:

@Expose private Long id;

Serileştirmek istemediğiniz alanları dışarıda bırakın. Ardından Gson nesnenizi şu şekilde oluşturun:

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

95
"NotExpose" gibi bir şeye sahip olmak ve yalnızca bir alan dışındaki tüm alanların serileştirilmesi ve hepsine ek açıklama eklemenin gereksiz olduğu durumları göz ardı etmek mümkün mü?
Daniil Shevelev

2
@DaSh Son zamanlarda böyle bir senaryo yaşadım. Tam olarak bunu yapan özel bir ExclusionStrategy yazmak çok kolaydı. Nishant'ın cevabına bakın. Tek sorun kapsayıcı sınıfları bir grup dahil ve skipclass vs skipfield (alanlar sınıf olabilir ...)
keyser

1
@DaSh Aşağıdaki cevabım tam olarak bunu yapıyor.
Derek Shockey

Ne harika bir çözüm. Bir alana diske serileştirildiğini ancak gson aracılığıyla bir sunucuya gönderirken göz ardı edileceğim bir senaryoya koşuyordum. Mükemmel teşekkürler!
Slynk

1
@Danlil @Expose (serialize = false, deserialize = false)
Hrk

237

Yani, istediğiniz dışlamak firstName ve country.name. İşte ExclusionStrategyböyle görünmelisin

    public class TestExclStrat implements ExclusionStrategy {

        public boolean shouldSkipClass(Class<?> arg0) {
            return false;
        }

        public boolean shouldSkipField(FieldAttributes f) {

            return (f.getDeclaringClass() == Student.class && f.getName().equals("firstName"))||
            (f.getDeclaringClass() == Country.class && f.getName().equals("name"));
        }

    }

Eğer yakından görürseniz döndürür trueiçin Student.firstNameve Country.namedışlamak istediğiniz budur.

Bunu ExclusionStrategyböyle uygulamanız gerekir ,

    Gson gson = new GsonBuilder()
        .setExclusionStrategies(new TestExclStrat())
        //.serializeNulls() <-- uncomment to serialize NULL fields as well
        .create();
    Student src = new Student();
    String json = gson.toJson(src);
    System.out.println(json);

Bu döndürür:

{ "middleName": "J.", "initials": "P.F", "lastName": "Fry", "country": { "id": 91}}

Ülke nesnesinin id = 91Löğrenci sınıfında başlatıldığını düşünüyorum .


Fantezi olabilirsiniz. Örneğin, adında "ad" dizesi içeren hiçbir alanı serileştirmek istemezsiniz. Bunu yap:

public boolean shouldSkipField(FieldAttributes f) {
    return f.getName().toLowerCase().contains("name"); 
}

Bu geri dönecektir:

{ "initials": "P.F", "country": { "id": 91 }}

EDIT: İstendiği gibi daha fazla bilgi eklendi.

Bu bir ExclusionStrategyşey yapacak, ancak "Tam Nitelikli Alan Adı" nı geçmeniz gerekiyor. Aşağıya bakınız:

    public class TestExclStrat implements ExclusionStrategy {

        private Class<?> c;
        private String fieldName;
        public TestExclStrat(String fqfn) throws SecurityException, NoSuchFieldException, ClassNotFoundException
        {
            this.c = Class.forName(fqfn.substring(0, fqfn.lastIndexOf(".")));
            this.fieldName = fqfn.substring(fqfn.lastIndexOf(".")+1);
        }
        public boolean shouldSkipClass(Class<?> arg0) {
            return false;
        }

        public boolean shouldSkipField(FieldAttributes f) {

            return (f.getDeclaringClass() == c && f.getName().equals(fieldName));
        }

    }

İşte jenerik olarak nasıl kullanabiliriz.

    Gson gson = new GsonBuilder()
        .setExclusionStrategies(new TestExclStrat("in.naishe.test.Country.name"))
        //.serializeNulls()
        .create();
    Student src = new Student();
    String json = gson.toJson(src);
    System.out.println(json); 

Döndürür:

{ "firstName": "Philip" , "middleName": "J.", "initials": "P.F", "lastName": "Fry", "country": { "id": 91 }}

Cevabınız için teşekkür ederim. Ne istiyorum gibi bir dize alabilir country.nameve sadece alan nameseri hale getirirken alan hariç bir ExclusionStrategy oluşturmaktır country. Country sınıfının country adlı bir özelliğe sahip her sınıfa uygulanacak kadar genel olmalıdır. Her sınıf için bir ExclusionStrategy oluşturmak istemiyorum
Liviu T.

@Liviu T. Cevabı güncelledim. Bu genel bir yaklaşım gerektirir. Daha da yaratıcı olabilirsiniz, ama onu temel olarak sakladım.
Nishant

Güncelleme için ty. Ne ben; denilen yöntem zaman nesne grafiğinde nerede olduğunu bilmek mümkün olup olmadığını görmek için çalışıyorum böylece ülkenin bazı alanları hariç ancak ülkeOfBirth (örneğin) aynı sınıf ama farklı özellikleri hariç olabilir. Ben başarmak için çalışıyorum netleştirmek için sorumu kaydetmiştiniz
Liviu T.

Boş değerleri olan alanları hariç tutmanın bir yolu var mı?
Yusuf K.

12
Bu cevap tercih edilen cevap olarak işaretlenmelidir. Şu anda daha fazla oy alan diğer cevapların aksine, bu çözüm fasulye sınıfını değiştirmenizi gerektirmez. Bu büyük bir artı. Ya başka biri aynı fasulye sınıfını kullanıyorsa ve istedikleri bir alanı "geçici" olarak işaretlediyseniz?
user64141

221

Mevcut tüm cevapları okuduktan sonra, benim durumumda en esnek @Excludeolanın özel açıklama kullanmak olduğunu öğrendim . Bu nedenle, bunun için basit bir strateji uyguladım (tüm alanları kullanarak işaretlemek istemedim @Exposeveya transientuygulama Serializableserileştirmesinde çakışan kullanmak istemedim ):

Ek Açıklama:

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

Strateji:

public class AnnotationExclusionStrategy implements ExclusionStrategy {

    @Override
    public boolean shouldSkipField(FieldAttributes f) {
        return f.getAnnotation(Exclude.class) != null;
    }

    @Override
    public boolean shouldSkipClass(Class<?> clazz) {
        return false;
    }
}

Kullanımı:

new GsonBuilder().setExclusionStrategies(new AnnotationExclusionStrategy()).create();

16
Ek bir not olarak, hariç tutma stratejinizi yalnızca serileştirme veya yalnızca serileştirme için kullanmak istiyorsanız, şunu kullanın: addSerializationExclusionStrategyveya addDeserializationExclusionStrategyyerinesetExclusionStrategies
GLee

9
Mükemmel! Geçici çözüm benim için çalışmıyor çünkü DB için Realm kullanıyorum ve bir alanı sadece Gson'dan hariç tutmak istiyorum, ancak Realm'den (geçici olan) değil
Marcio Granzotto 15:16

3
Bu kabul edilen cevap olmalı. Boş alanları yok saymak için şu şekilde değiştirin f.getAnnotation(Exclude.class) != null:f.getAnnotation(Exclude.class) == null
Sharp Edge

3
transientDiğer kütüphanelerin ihtiyaçları nedeniyle kullanamadığınızda mükemmeldir . Teşekkürler!
Martin D

1
Benim için de harika çünkü Android, derslerimi etkinlikler arasında seri hale getiriyor, ancak sadece GSON kullandığımda bunların hariç tutulmasını istiyorum. Bu benim app başkalarına göndermek için onları sarmak istiyorum kadar aynı şekilde çalışmaya devam edelim.
ThePartyTurtle

81

Sadece serileştirmeden hariç tutmak istediğim az sayıda alanımın olduğu bu sorunla karşılaştım, bu nedenle Gson'un @Exposeek açıklamalarını özel hariç tutma stratejileriyle kullanan oldukça basit bir çözüm geliştirdim.

Kullanmanın tek yerleşik yolu @Exposeayarlamaktır GsonBuilder.excludeFieldsWithoutExposeAnnotation(), ancak adından da anlaşılacağı gibi, açık olmayan alanlar @Exposeyok sayılır. Dışlamak istediğim sadece birkaç alanım olduğu için, ek açıklamaları her alana çok hantalca ekleme olasılığını buldum.

Açıkça @Exposedışlamak için kullanmadıkça , her şeyin dahil edildiği tersi etkili bir şekilde istedim . Bunu gerçekleştirmek için aşağıdaki hariç tutma stratejilerini kullandım:

new GsonBuilder()
        .addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes fieldAttributes) {
                final Expose expose = fieldAttributes.getAnnotation(Expose.class);
                return expose != null && !expose.serialize();
            }

            @Override
            public boolean shouldSkipClass(Class<?> aClass) {
                return false;
            }
        })
        .addDeserializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes fieldAttributes) {
                final Expose expose = fieldAttributes.getAnnotation(Expose.class);
                return expose != null && !expose.deserialize();
            }

            @Override
            public boolean shouldSkipClass(Class<?> aClass) {
                return false;
            }
        })
        .create();

Şimdi birkaç alanı @Expose(serialize = false)veya @Expose(deserialize = false)ek açıklamaları kolayca hariç tutabilirim (her iki @Exposeözellik için varsayılan değerin olduğunu unutmayın true). Tabii ki kullanabilirsiniz @Expose(serialize = false, deserialize = false), ancak bunun transientyerine alanı ilan ederek (bu özel hariç tutma stratejileri ile hala geçerli olan) daha kısaca yapılır .


Verimlilik için geçici olmak yerine @Expose (serialize = false, deserialize = false) kullanmak için bir durum görebilirim.
paiego

1
@paiego Bunu genişletebilir misiniz? Şimdi yıllarca Gson kullanmaktan çıkarıldım ve ek açıklamanın neden geçici olarak işaretlemekten daha etkili olduğunu anlamıyorum.
Derek Shockey

Ahh, bir hata yaptım, bunu yakaladığınız için teşekkürler. Geçici olarak geçici olarak yanlış anladım. (örneğin, geçici bir önbellek ve dolayısıyla önbellek tutarlılığı sorunu yoktur, ancak daha az performans gösterir) Her neyse, kodunuz harika çalıştı!
paiego

18

Json ağacını gson ile keşfedebilirsiniz.

Bunun gibi bir şey deneyin:

gson.toJsonTree(student).getAsJsonObject()
.get("country").getAsJsonObject().remove("name");

Bazı özellikler de ekleyebilirsiniz:

gson.toJsonTree(student).getAsJsonObject().addProperty("isGoodStudent", false);

Gson 2.2.4 ile test edilmiştir.


3
Kaldırmadan önce ayrıştırılması gereken karmaşık bir mülkten kurtulmak istiyorsanız, bunun çok fazla bir performans isabeti olup olmadığını merak ediyorum. Düşünceler?
Ben

Kesinlikle ölçeklenebilir bir çözüm değil, nesnenizin yapısını değiştirirseniz veya bir şeyler ekler / kaldırırsanız geçmeniz gereken tüm baş ağrısını hayal edin.
codenamezero

16

Bu işlevselliği desteklemek için bir sınıf fabrikası buldum. Hariç tutmak istediğiniz alanların veya sınıfların herhangi bir kombinasyonunu iletin.

public class GsonFactory {

    public static Gson build(final List<String> fieldExclusions, final List<Class<?>> classExclusions) {
        GsonBuilder b = new GsonBuilder();
        b.addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return fieldExclusions == null ? false : fieldExclusions.contains(f.getName());
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return classExclusions == null ? false : classExclusions.contains(clazz);
            }
        });
        return b.create();

    }
}

Kullanmak için iki liste oluşturun (her biri isteğe bağlıdır) ve GSON nesnenizi oluşturun:

static {
 List<String> fieldExclusions = new ArrayList<String>();
 fieldExclusions.add("id");
 fieldExclusions.add("provider");
 fieldExclusions.add("products");

 List<Class<?>> classExclusions = new ArrayList<Class<?>>();
 classExclusions.add(Product.class);
 GSON = GsonFactory.build(null, classExclusions);
}

private static final Gson GSON;

public String getSomeJson(){
    List<Provider> list = getEntitiesFromDatabase();
    return GSON.toJson(list);
}

Tabii ki, bu, özelliğin tam adına bakmak ve bir maçta hariç tutmak için değiştirilebilir ...
Domenic D.

Aşağıdaki örneği yapıyorum. Bu çalışmıyor. Pls özel statik nihai Gson GSON önerir; static {List <String> fieldExclusions = new ArrayList <String> (); fieldExclusions.add ( "kimlik"); GSON = GsonFactory.build (fieldExclusions, null); } private static Dize getSomeJson () {String jsonStr = "[{\" id \ ": 111, \" name \ ": \" praveen \ ", \" age \ ": 16}, {\" id \ ": 222, \ "ismi \": \ "prashant \", \ "yaş \": 20}] "; dönüş jsonStr; } public static void main (Dize [] args) {Dize jsonStr = getSomeJson (); System.out.println (GSON.toJson (jsonStr)); }
Praveen Hiremath

13

Bu sorunu özel ek açıklamalarla çözdüm. Bu benim "SkipSerialisation" Detaylandırma sınıfım:

@Target (ElementType.FIELD)
public @interface SkipSerialisation {

}

ve bu benim GsonBuilder'ım:

gsonBuilder.addSerializationExclusionStrategy(new ExclusionStrategy() {

  @Override public boolean shouldSkipField (FieldAttributes f) {

    return f.getAnnotation(SkipSerialisation.class) != null;

  }

  @Override public boolean shouldSkipClass (Class<?> clazz) {

    return false;
  }
});

Misal :

public class User implements Serializable {

  public String firstName;

  public String lastName;

  @SkipSerialisation
  public String email;
}

5
Gson: Ek açıklama olmadan
Ben

3
Ayrıca @Retention(RetentionPolicy.RUNTIME)ek açıklamanıza eklemeniz gerekir .
David Novák

9

Veya hangi alanların gösterilmeyeceğini söyleyebiliriz:

Gson gson = gsonBuilder.excludeFieldsWithModifiers(Modifier.TRANSIENT).create();

öznitelik konusunda sınıfınızda:

private **transient** boolean nameAttribute;

17
Geçici ve statik alanlar varsayılan olarak hariç tutulur; buna gerek yok excludeFieldsWithModifiers().
Derek Shockey

9

Bu stratejiyi kullandık: i her alanını hariç değil işaretli @SerializedName açıklama, yani:

public class Dummy {

    @SerializedName("VisibleValue")
    final String visibleValue;
    final String hiddenValue;

    public Dummy(String visibleValue, String hiddenValue) {
        this.visibleValue = visibleValue;
        this.hiddenValue = hiddenValue;
    }
}


public class SerializedNameOnlyStrategy implements ExclusionStrategy {

    @Override
    public boolean shouldSkipField(FieldAttributes f) {
        return f.getAnnotation(SerializedName.class) == null;
    }

    @Override
    public boolean shouldSkipClass(Class<?> clazz) {
        return false;
    }
}


Gson gson = new GsonBuilder()
                .setExclusionStrategies(new SerializedNameOnlyStrategy())
                .create();

Dummy dummy = new Dummy("I will see this","I will not see this");
String json = gson.toJson(dummy);

Geri döner

{"VisibleValue": "Bunu göreceğim"}


6

Başka bir yaklaşım (özellikle çalışma zamanında bir alanı hariç tutmak için bir karar vermeniz gerekiyorsa yararlıdır) gson örneğinizle bir TypeAdapter kaydetmektir. Aşağıdaki örnek:

Gson gson = new GsonBuilder()
.registerTypeAdapter(BloodPressurePost.class, new BloodPressurePostSerializer())

Aşağıdaki durumda, sunucu iki değerden birini beklerdi ama ikisi de ints olduklarından gson her ikisini de serileştirirdi. Amacım sunucuya gönderilen json sıfır (veya daha az) herhangi bir değeri atlamak oldu.

public class BloodPressurePostSerializer implements JsonSerializer<BloodPressurePost> {

    @Override
    public JsonElement serialize(BloodPressurePost src, Type typeOfSrc, JsonSerializationContext context) {
        final JsonObject jsonObject = new JsonObject();

        if (src.systolic > 0) {
            jsonObject.addProperty("systolic", src.systolic);
        }

        if (src.diastolic > 0) {
            jsonObject.addProperty("diastolic", src.diastolic);
        }

        jsonObject.addProperty("units", src.units);

        return jsonObject;
    }
}

6

Kotlin'in @Transientek açıklaması da hile yapıyor.

data class Json(
    @field:SerializedName("serialized_field_1") val field1: String,
    @field:SerializedName("serialized_field_2") val field2: String,
    @Transient val field3: String
)

Çıktı:

{"serialized_field_1":"VALUE1","serialized_field_2":"VALUE2"}

1

Sadece @Exposeek açıklama koyarak çalışıyorum , burada kullandığım versiyonum

compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

In Modelsınıfında:

@Expose
int number;

public class AdapterRestApi {

In Adaptersınıfında:

public EndPointsApi connectRestApi() {
    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(90000, TimeUnit.SECONDS)
            .readTimeout(90000,TimeUnit.SECONDS).build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(ConstantRestApi.ROOT_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

    return retrofit.create  (EndPointsApi.class);
}

1

Kotlin versiyonum var

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
internal annotation class JsonSkip

class SkipFieldsStrategy : ExclusionStrategy {

    override fun shouldSkipClass(clazz: Class<*>): Boolean {
        return false
    }

    override fun shouldSkipField(f: FieldAttributes): Boolean {
        return f.getAnnotation(JsonSkip::class.java) != null
    }
}

ve bunu Retrofit GSONConverterFactory'e nasıl ekleyebilirsiniz:

val gson = GsonBuilder()
                .setExclusionStrategies(SkipFieldsStrategy())
                //.serializeNulls()
                //.setDateFormat(DateFormat.LONG)
                //.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                //.setPrettyPrinting()
                //.registerTypeAdapter(Id.class, IdTypeAdapter())
                .create()
        return GsonConverterFactory.create(gson)

0

Her zaman kullandığım bu:

Gson'da uygulanan varsayılan davranış, null nesne alanlarının yok sayılmasıdır.

Gson nesnesinin boş değerli değerleri JSON'a serileştirmediği anlamına gelir. Java nesnesindeki bir alan null olursa, Gson bunu hariç tutar.

Bu işlevi, bazı nesneleri kendi başınıza boş veya iyi ayarlanmış bir biçime dönüştürmek için kullanabilirsiniz.

     /**
   * convert object to json
   */
  public String toJson(Object obj) {
    // Convert emtpy string and objects to null so we don't serialze them
    setEmtpyStringsAndObjectsToNull(obj);
    return gson.toJson(obj);
  }

  /**
   * Sets all empty strings and objects (all fields null) including sets to null.
   *
   * @param obj any object
   */
  public void setEmtpyStringsAndObjectsToNull(Object obj) {
    for (Field field : obj.getClass().getDeclaredFields()) {
      field.setAccessible(true);
      try {
        Object fieldObj = field.get(obj);
        if (fieldObj != null) {
          Class fieldType = field.getType();
          if (fieldType.isAssignableFrom(String.class)) {
            if(fieldObj.equals("")) {
              field.set(obj, null);
            }
          } else if (fieldType.isAssignableFrom(Set.class)) {
            for (Object item : (Set) fieldObj) {
              setEmtpyStringsAndObjectsToNull(item);
            }
            boolean setFielToNull = true;
            for (Object item : (Set) field.get(obj)) {
              if(item != null) {
                setFielToNull = false;
                break;
              }
            }
            if(setFielToNull) {
              setFieldToNull(obj, field);
            }
          } else if (!isPrimitiveOrWrapper(fieldType)) {
            setEmtpyStringsAndObjectsToNull(fieldObj);
            boolean setFielToNull = true;
            for (Field f : fieldObj.getClass().getDeclaredFields()) {
              f.setAccessible(true);
              if(f.get(fieldObj) != null) {
                setFielToNull = false;
                break;
              }
            }
            if(setFielToNull) {
              setFieldToNull(obj, field);
            }
          }
        }
      } catch (IllegalAccessException e) {
        System.err.println("Error while setting empty string or object to null: " + e.getMessage());
      }
    }
  }

  private void setFieldToNull(Object obj, Field field) throws IllegalAccessException {
    if(!Modifier.isFinal(field.getModifiers())) {
      field.set(obj, null);
    }
  }

  private boolean isPrimitiveOrWrapper(Class fieldType)  {
    return fieldType.isPrimitive()
        || fieldType.isAssignableFrom(Integer.class)
        || fieldType.isAssignableFrom(Boolean.class)
        || fieldType.isAssignableFrom(Byte.class)
        || fieldType.isAssignableFrom(Character.class)
        || fieldType.isAssignableFrom(Float.class)
        || fieldType.isAssignableFrom(Long.class)
        || fieldType.isAssignableFrom(Double.class)
        || fieldType.isAssignableFrom(Short.class);
  }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.