Gson : 주석없이 직렬화에서 특정 필드를 제외하는 방법


413

나는 Gson을 배우려고 노력하고 있으며 필드 배제로 고심하고 있습니다. 여기 내 수업이 있습니다

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;
}

GsonBuilder를 사용하고 firstName또는 같은 필드 이름에 ExclusionStrategy를 추가 할 수는 있지만와 같은 country특정 필드의 속성을 제외시키는 것은 관리 할 수 ​​없습니다 country.name.

이 메소드를 사용하면 public boolean shouldSkipField(FieldAttributes fa)FieldAttributes에 필터와 같은 필드를 일치시키기에 충분한 정보가 없습니다 country.name.

추신 : 나는 이것을 개선하고 RegEx를 사용하여 필드를 필터링하기 때문에 주석을 피하고 싶습니다.

편집 : Struts2 JSON 플러그인 의 동작을 에뮬레이트 할 수 있는지 확인하려고합니다.

Gson 사용

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

편집 : 다음을 추가하여 질문을 다시 열었습니다.

이 문제를 더 명확히하기 위해 동일한 유형의 두 번째 필드를 추가했습니다. 기본적으로 제외하고 싶지는 country.name않습니다 countrOfBirth.name. 또한 국가를 유형으로 제외하고 싶지 않습니다. 따라서 유형은 객체 그래프에서 정확히 지적하고 제외하려는 실제 위치와 동일합니다.


1
여전히 2.2 버전부터는 제외 할 필드의 경로를 지정할 수 없습니다. flexjson.sourceforge.net 은 좋은 대안처럼 느껴집니다.
Liviu T.

비슷한 질문에 대한 대답 을 살펴보십시오 . 직렬화 할 필드를 결정하는 적용되는 JsonSerializer일부 유형에 대한 사용자 정의 작성을 기반으로 Country합니다 ExclusionStrategy.
pirho

답변:


625

일반적으로 직렬화하지 않으려는 모든 필드는 "일시적"수정자를 사용해야하며 이는 json 직렬화 기에도 적용됩니다 (적어도 gson을 포함하여 내가 사용한 몇 가지에 해당).

직렬화 된 json에 이름을 표시하지 않으려면 임시 키워드를 지정하십시오 (예 :

private transient String name;

Gson 문서에 대한 자세한 내용


6
해당 클래스의 모든 인스턴스에 적용되는 제외 주석과 거의 동일합니다. 런타임 동적 제외를 원했습니다. 더 가벼운 / 제한된 응답을 제공하기 위해 일부 필드를 제외하고 싶은 경우도 있고 전체 개체를 직렬화하려는 경우도 있습니다.
Liviu T.

34
한 가지 주목할 점은 일시적이 직렬화와 직렬화 해제에 영향을 미친다는 것입니다. JSON에 존재하더라도 값이 객체에 직렬화 된 값을 방출합니다.
Kong

3
transient대신에 사용 하는 문제 @Expose는 들어오는 모든 필드를 사용하여 클라이언트에서 POJO를 여전히 조롱해야한다는 것입니다. 프로젝트간에 공유 될 수있는 백엔드 API의 경우 문제가 될 수 있습니다. 추가 필드가 추가됩니다. 기본적으로 필드의 허용 목록과 차단 목록입니다.
theblang

11
이 방법은 gson 직렬화에서 필드를 제외했을뿐만 아니라 내부 응용 프로그램 직렬화 (Serializable 인터페이스 사용)에서 필드를 제외했기 때문에 저에게 효과적이지 않았습니다.
pkk

8
transient는 필드의 직렬화 및 직렬화를 방지합니다. 이것은 내 요구와 일치하지 않습니다.
Loenix

318

Nishant는 좋은 솔루션을 제공했지만 더 쉬운 방법이 있습니다. 다음과 같이 @Expose 주석으로 원하는 필드를 표시하십시오.

@Expose private Long id;

직렬화하지 않으려는 필드는 제외하십시오. 그런 다음 Gson 객체를 다음과 같이 만듭니다.

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

95
"notExpose"와 같은 것을 가질 수 있고 하나의 필드를 제외한 모든 필드를 직렬화해야하고 모든 필드에 주석을 추가하는 것이 중복되는 경우에만 무시할 수 있습니까?
Daniil Shevelev

2
@DaSh 최근에 그러한 시나리오가있었습니다. 정확히 그렇게 한 맞춤형 ExclusionStrategy를 작성하는 것은 매우 쉬웠습니다. Nishant의 답변을 참조하십시오. 유일한 문제는 컨테이너 클래스와 스킵 클래스 대 스킵 필드를 가진 바이올린을 포함하는 것이 었습니다 (필드는 클래스가 될 수 있습니다 ...)
keyser

1
@DaSh 아래의 대답 은 정확히 그렇게합니다.
Derek Shockey

정말 좋은 해결책입니다. 디스크로 직렬화 된 필드를 원하지만 gson을 통해 서버로 보낼 때 무시되는 시나리오가 발생했습니다. 고마워요!
Slynk

1
@Danlil @Expose (serialize = false, deserialize = false)를 사용할 수 있어야합니다
Hrk

237

따라서 및 을 제외 firstName 하고 싶습니다 country.name. 당신의 ExclusionStrategy모습은 다음과 같습니다.

    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"));
        }

    }

당신이 자세히 볼 경우 반환 true을 위해 Student.firstNameCountry.name제외 할 무엇이다.

이런 ExclusionStrategy식 으로 적용해야합니다

    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);

이것은 다음을 반환합니다.

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

국가 객체가 id = 91L학생 클래스에서 초기화되었다고 가정합니다 .


당신은 공상을 얻을 수 있습니다. 예를 들어, 이름에 "name"문자열이 포함 된 필드를 직렬화하지 않으려 고합니다. 이 작업을 수행:

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

이것은 다음을 반환합니다 :

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

편집 : 요청에 따라 더 많은 정보가 추가되었습니다.

이 작업 ExclusionStrategy이 수행되지만 "완전한 필드 이름"을 전달해야합니다. 아래를보십시오 :

    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));
        }

    }

일반적인 사용법은 다음과 같습니다.

    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); 

다음을 반환합니다.

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

답변 주셔서 감사합니다. 내가 원하는 것은 country.name필드 name를 직렬화 할 때 필드를 제외하고 문자열을 취할 수있는 ExclusionStrategy를 만드는 것입니다 country. Country 클래스의 country라는 속성이있는 모든 클래스에 적용 할 수있을 정도로 일반적이어야합니다. 모든 수업에 대해 ExclusionStrategy를 만들고 싶지 않습니다
Liviu T.

@ Liviu T. 답변을 업데이트했습니다. 그것은 일반적인 접근 방식을 취합니다. 당신은 더 창조적이 될 수 있지만, 나는 그것을 정직하게 유지했습니다.
Nishant

업데이트를 위해 타이. 내가; 객체 그래프에서 어디에서 메소드를 호출했는지 알 수 있는지 확인하기 위해 국가의 일부 필드를 제외 할 수 있지만 countryOfBirth (예 :)와 같은 클래스는 아니지만 속성이 다릅니다. 내가 달성하려는 것을 명확히하기 위해 내 질문을 편집했습니다
Liviu T.

빈 값을 가진 필드를 제외하는 방법이 있습니까?
Yusuf K.

12
이 답변은 기본 답변으로 표시해야합니다. 현재 더 많은 투표가있는 다른 답변과 달리이 솔루션에서는 Bean 클래스를 수정할 필요가 없습니다. 이것은 큰 장점입니다. 다른 사람이 같은 Bean 클래스를 사용하고 있고 "transient"로 유지하려는 필드를 표시 한 경우 어떻게합니까?
user64141

221

사용 가능한 모든 답변을 읽은 후 가장 유연한 것은 사용자 정의 @Exclude주석 을 사용하는 것 입니다. 그래서 나는 이것을 위해 간단한 전략을 구현했다 (나는 모든 필드를 사용하여 표시하고 싶지 않았고 앱 직렬화 에서 충돌하는 @Expose것을 사용 하고 싶지 않았다 ).transientSerializable

주석:

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

전략:

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;
    }
}

용법:

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

16
추가로, 직렬화 또는 역 직렬화에만 제외 전략을 사용하려면 다음을 사용하십시오. 대신addSerializationExclusionStrategyaddDeserializationExclusionStrategysetExclusionStrategies
GLee

9
완전한! DB 용 Realm을 사용하고 있고 Gson에서만 필드를 제외하고 있지만 Realm이 아닌 필드를 제외하고 싶기 때문에 임시 솔루션이 작동하지 않습니다.
Marcio Granzotto

3
이것이 정답입니다. null 필드를 무시하려면 다음과 같이 변경하십시오 f.getAnnotation(Exclude.class) != null.f.getAnnotation(Exclude.class) == null
Sharp Edge

3
transient다른 도서관의 요구 때문에 사용할 수 없을 때 좋습니다 . 감사!
Martin D

1
안드로이드가 액티비티간에 클래스를 직렬화하기 때문에 나에게도 좋지만 GSON을 사용할 때만 제외하고 싶습니다. 이것은 내 앱이 다른 사람에게 보내기 위해 랩을 만들고 싶을 때까지 동일한 방식으로 계속 작동하게합시다.
ThePartyTurtle

81

나는이 문제에 부딪쳤다.이 필드에는 직렬화에서만 제외하고 싶었던 소수의 필드가 있었으므로 @Expose맞춤형 제외 전략과 함께 Gson의 주석 을 사용하는 상당히 간단한 솔루션을 개발했다 .

사용하는 기본 제공 방법 @Expose은을 설정하는 GsonBuilder.excludeFieldsWithoutExposeAnnotation()것이지만 이름에서 알 수 있듯이 명시 적 필드가없는 필드 @Expose는 무시됩니다. 제외 할 필드가 몇 개 밖에 없었기 때문에 모든 필드에 주석을 추가 할 가능성이 매우 성가신 것으로 나타났습니다.

나는 @Expose그것을 배제하기 위해 명시 적으로 사용하지 않는 한 모든 것이 포함 된 역수를 효과적으로 원 했습니다. 이를 달성하기 위해 다음 제외 전략을 사용했습니다.

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();

이제 몇 개의 필드 @Expose(serialize = false)또는 @Expose(deserialize = false)주석을 쉽게 제외 할 수 있습니다 (두 @Expose속성 의 기본값 은입니다 true). 물론 사용할 수 @Expose(serialize = false, deserialize = false)있지만 필드를 transient대신 선언하여 더 간결하게 수행 할 수 있습니다 (이러한 사용자 지정 제외 전략에는 여전히 적용됨).


효율성을 위해 일시적이지 않고 @Expose (serialize = false, deserialize = false)를 사용하는 경우를 볼 수 있습니다.
paiego

1
@paiego 당신은 그것을 확장 할 수 있습니까? 나는 Gson 사용에서 수년이 지났으며 왜 주석이 일시적인 것으로 표시하는 것보다 효율적인지 이해할 수 없습니다.
Derek Shockey

아, 실수를 저지른 점에 감사드립니다. 나는 일시적으로 휘발성을 취했다. (예를 들어, 캐싱이 없으므로 휘발성에 대한 캐시 일관성 문제는 없지만 성능이 떨어집니다) 어쨌든 코드는 훌륭하게 작동했습니다!
paiego

18

gson으로 json 트리를 탐색 할 수 있습니다.

다음과 같이 해보십시오.

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

당신은 또한 몇 가지 속성을 추가 할 수 있습니다 :

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

gson으로 테스트 2.2.4.


3
제거하기 전에 구문 분석 해야하는 복잡한 속성을 제거하려는 경우 이것이 너무 많은 성능 저하인지 궁금합니다. 생각?
Ben

확실히 확장 가능한 솔루션은 아닙니다. 객체의 구조를 변경하거나 물건을 추가 / 제거 할 때 겪어야 할 모든 두통을 상상해보십시오.
codenamezero

16

이 기능을 지원하기 위해 클래스 팩토리를 고안했습니다. 제외하려는 필드 또는 클래스의 조합을 전달하십시오.

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();

    }
}

사용하려면 두 개의 목록을 만들고 (각각 선택 사항 임) GSON 객체를 만듭니다.

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);
}

물론 이것은 속성의 정규화 된 이름을보고 일치하는 경우 제외하도록 수정할 수 있습니다.
Domenic D.

아래 예제를하고 있습니다. 작동하지 않습니다. Pls는 개인 정적 최종 Gson GSON을 제안합니다. static {List <String> fieldExclusions = 새로운 ArrayList <String> (); fieldExclusions.add ( "id"); GSON = GsonFactory.build (fieldExclusions, null); } private static String getSomeJson () {String jsonStr = "[{\"id \ ": 111, \"name \ ": \"praveen \ ", \"age \ ": 16}, {\"id \ ": 222, \ "이름 \": \ "취약 제 \", \ "나이 \": 20}] "; jsonStr을 리턴; } public static void main (String [] args) {문자열 jsonStr = getSomeJson (); System.out.println (GSON.toJson (jsonStr)); }
Praveen Hiremath

13

사용자 지정 주석 으로이 문제를 해결했습니다. 이것은 나의 "SkipSerialisation"주석 클래스입니다 :

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

}

그리고 이것은 내 GsonBuilder입니다.

gsonBuilder.addSerializationExclusionStrategy(new ExclusionStrategy() {

  @Override public boolean shouldSkipField (FieldAttributes f) {

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

  }

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

    return false;
  }
});

예 :

public class User implements Serializable {

  public String firstName;

  public String lastName;

  @SkipSerialisation
  public String email;
}

5
Gson : 주석없이
Ben

3
@Retention(RetentionPolicy.RUNTIME)주석에 추가 해야합니다.
David Novák

9

또는 어떤 필드에 노출되지 않을 것인지 말할 수 있습니다.

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

속성에 대한 클래스 :

private **transient** boolean nameAttribute;

17
임시 및 정적 필드는 기본적으로 제외됩니다. 그럴 필요가 없습니다 excludeFieldsWithModifiers().
Derek Shockey

9

이 전략을 사용했습니다. @SerializedName 주석으로 표시 되지 않은 모든 필드를 제외했습니다 .

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);

반환

{ "VisibleValue": "이것을 볼 것입니다"}


6

또 다른 방법은 (런타임에 필드를 제외하기로 결정한 경우 특히 유용합니다) gson 인스턴스에 TypeAdapter를 등록하는 것입니다. 아래 예 :

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

아래의 경우 서버는 두 값 중 하나를 기대하지만 둘 다 정수이므로 gson은 두 값을 직렬화합니다. 내 목표는 서버에 게시 된 json에서 0 이하의 값을 생략하는 것이 었습니다.

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의 @Transient주석은 분명히 트릭을 수행합니다.

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

산출:

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

1

나는 @Expose주석 을 넣는 것만으로 노력하고 있습니다.

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

에서 Model클래스 :

@Expose
int number;

public class AdapterRestApi {

에서 Adapter클래스 :

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 버전이 있습니다

@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
    }
}

Retrofit GSONConverterFactory에 추가하는 방법 :

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

내가 항상 사용하는 것 :

Gson에서 구현 된 기본 동작은 null 개체 필드가 ​​무시되는 것입니다.

Gson 객체가 null 값을 가진 필드를 JSON으로 직렬화하지 않음을 의미합니다. Java 객체의 필드가 null이면 Gson에서 제외합니다.

이 함수를 사용하여 일부 객체를 null로 변환하거나 자체적으로 잘 설정할 수 있습니다

     /**
   * 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);
  }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.