본문 바로가기
IT/JAVA

Gson LocalDateTime 처리(BEGIN_OBJECT but was STRING)

by 최고영회 2019. 9. 18.
728x90
반응형
SMALL

Date 와 관련된 값들은 Java8 부터 지원하는 LocalDateTime 을 주로 사용한다. 

API 를 통해 객체 정보를 요청하고 수신할때 serialize, deserialize 하게 되는데 

이때 google의 Gson을 많이 사용한다. 

그런데 Gson 은 LocalDateTime 을 알지 못하기 때문에 LocalDateTime 에 대한 구문 분석을 하지 못한다.

Expected BEGIN_OBJECT but was STRING ....

18:05 ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/decide7] threw exception [Request processing failed; nested exception is com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 231 path $.createDate] with root cause
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 231 path $.createDate
	at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
	at com.google.gson.Gson.fromJson(Gson.java:927)
	at com.google.gson.Gson.fromJson(Gson.java:892)
	at com.google.gson.Gson.fromJson(Gson.java:841)
	at com.google.gson.Gson.fromJson(Gson.java:813)
	at com.yhkim.study.common.component.UserRestRunner.findByNo(UserRestRunner.java:63)
	at com.yhkim.study.doclayout.DocLayoutService.findMyDocLayout(DocLayoutService.java:71)
	at com.yhkim.study.doclayout.DocLayoutService$$FastClassBySpringCGLIB$$6f08b4d3.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

 

Gson 이 LocalDateTime 을 이해할 수 있도록 Adapter 에 등록하면 해결 된다.

Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
	@Override
	public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
			throws JsonParseException {
		return LocalDateTime.parse(json.getAsString(), DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"));
	}
}).create();

return gson.fromJson(resultStr, User.class);

잘 된다...

참고로 Gson을 사용하지 않고 webclient 의 bodyToMono를 이용하면 굳이 위와 같이 하지 않아도 된다..

return getWebClient().get().exchange().block().bodyToMono(User.class).block();

 

 

728x90
반응형
LIST