Gson 문자열 null 필드 를 빈 문자열 로 변환 합 니 다.

4551 단어 기술 소 해
최근 에 백 엔 드 데 이 터 를 제 이 슨 방식 으로 전단 에 전달 해 야 하 는 항목 이 있 습 니 다.그러나 백 엔 드 에 null 필드 가 있 으 면 원본 new Gson () 을 사용 하면 null 필드 를 제외 하고 전단 에 전달 하지 않 습 니 다.필드 전단 이 부족 하면 오류 가 발생 합 니 다.그래서 인터넷 방법 에 따라 new Gson Builder (). serializeNulls () 를 사용 했다.좋 습 니 다. 이 제 는 모든 필드 가 전단 에 전 달 될 수 있 지만 잠재 적 으로 부족 한 것 이 있 습 니 다. 바로 null 필드 를 위해 실제 적 으로 'null' 문자열 이 전단 에 전 달 된 것 입 니 다.
    엄밀 한 프로그래머 에 게 는 참 을 수 없다.그래서 더 완벽 한 방법 을 찾 고 싶 었 다.
    먼저 인터넷 에 현재 존재 하 는 두 가지 방법 을 말 해 보 자.
    1. NullStringToEmpty Adapter Factory 를 쓰 고 new Gson Builder (). registerTypeAdapter Factory (new NullStringToEmpty Adapter Factory () 를 사용 합 니 다.
    2. new TypeAdapter 내부 클래스 를 사용 한 다음 new GsonBuilder (). registerTypeAdapter (String. class, STRING) 를 사용 합 니 다.
    
    그리고 나 서 나 는 모두 시험 해 보 았 지만 방법 하 나 는 전혀 효과 가 없 었 고 방법 하 나 는 잘못 을 갚 았 다.
    만약 당신 이 위의 두 가지 중 어느 한 가지 방법 이 모두 성공 했다 면, 축하합니다. 직접 소스 분석 단계 에 들 어 갈 수 있 습 니 다.
    만약 당신 이 불행 하 게 도 나 와 같다 면, 여전히 안 된다 면, 나 는 당신 이 나 와 마찬가지 로, gs on jar 가방 문 제 를 만 날 수 있 을 것 이 라 고 생각 합 니 다!문제 가 있 는 것 은 gson - 2.2.1. jar 버 전이 다.
    
    소스 코드 를 연구 해 보 니 위의 두 가지 방법 이 모두 안 되 는 원인 을 찾 았 다.
    
  public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter)
  {
    Gson.Preconditions.checkArgument(((typeAdapter instanceof JsonSerializer)) || ((typeAdapter instanceof JsonDeserializer)) || ((typeAdapter instanceof InstanceCreator)) || ((typeAdapter instanceof TypeAdapter)));

    if ((Primitives.isPrimitive(type)) || (Primitives.isWrapperType(type)) || (type == String.class)) {
      throw new IllegalArgumentException("Cannot register type adapters for " + type);
    }

    if ((typeAdapter instanceof InstanceCreator)) {
      this.instanceCreators.put(type, (InstanceCreator)typeAdapter);
    }
    if (((typeAdapter instanceof JsonSerializer)) || ((typeAdapter instanceof JsonDeserializer))) {
      TypeToken typeToken = TypeToken.get(type);
      this.factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
    }
    if ((typeAdapter instanceof TypeAdapter)) {
      this.factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
    }
    return this;
  }

방법 2 보 오 류 는 원본 코드 가 사용자 가 기본 형식 과 패 키 징 형식 을 사용자 정의 할 수 없 기 때 문 입 니 다.방법 1. adapter 공장 에 등 록 했 지만 구 글 은 사용자 정의 adapter 를 사용 하지 않 았 다.
if (!Primitives.isPrimitive(type) && !Primitives.isWrapperType(type) && type != String.class)
{
}
else
{
throw new IllegalArgumentException("Cannot register type adapters for " + type);
}

gson - 2.2.2 이후 버 전 에는 위의 코드 가 없어 서 사용자 정의 adapter 를 등록 할 수 있 습 니 다.
나 는 gson 버 전 을 업 그 레이 드 했 고 gson - 2.5 를 사 용 했 지만 빈 문자열 을 출력 하지 않 았 다. 그래서 나 는 다시 원본 코드 를 보 러 갔다.
처음에 나 는 어떤 글 을 참고 하여 publicvoidwrite (JSonWriterwriter, Stringvalue) 에 다음 과 같은 코드 를 썼 다.
if (value == null)
{
    writer.nullValue();
    return;
}

그게 문제 야.
직렬 화 는 adapter 의 write 방법 을 사용 하고 반 직렬 화 는 read 방법 을 사용 하기 때문에 write 방법 에 써 야 합 니 다.
if (value == null)
{
    writer.value("");
    return;
}

마침내 문 제 를 해결 했다.
    
    이제 null 필드 를 빈 문자열 로 출력 하 는 방법 을 완벽 하 게 해결 하 는 방법 을 정리 합 니 다.정적 adapter 상수 만 정의 하고 Gson Builder 에 등록 하면 됩 니 다.인터넷 에서 NullStringToEmpty Adapter Factory 와 StringNullAdapter 류 를 정의 하 는 것 은 필요 하지 않 습 니 다.
    왜?원본 코드 에 적 혀 있 습 니 다. 사용자 정의 adapter 를 사용 하면 gs on 은 adapter Factory 로 재 구성 하여 등록 합 니 다.
if(typeAdapter instanceof TypeAdapter)
{
     this.factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
}

마지막 으로 최종 코드 샘플 을 드 리 겠 습 니 다.
public class TestMain
{
    //   Strig   
	private static final TypeAdapter STRING = new TypeAdapter()
	{
		public String read(JsonReader reader) throws IOException
		{
			if (reader.peek() == JsonToken.NULL)
			{
				reader.nextNull();
				return "";
			}
			return reader.nextString();
		}
		
		public void write(JsonWriter writer, String value) throws IOException
		{
			if (value == null)
			{
				//      null      
				writer.value("");
				return;
			}
			writer.value(value);
		}
	};
	
	public static void main(String[] args)
	{
		GsonBuilder gsonBuilder = new GsonBuilder();
		
		//     String    
		gsonBuilder.registerTypeAdapter(String.class, STRING);
		
		Gson gson = gsonBuilder.create();
		UserBean userBean = new UserBean();
		userBean.setId("1");
		System.out.println(gson.toJson(userBean));
	}
}

좋은 웹페이지 즐겨찾기