GSON serialize Date를 json 문자열에서 java.util.date로 수정
REST 콜에 Retrofit 라이브러리를 사용하고 있습니다.지금까지의 대부분의 작업은 순조로웠지만, 어떤 이유로 인해 JSON 타임스탬프 문자열을 로 변환하는 데 문제가 있습니다.java.util.Date
물건들.들어오는 JSON은 이렇게 생겼어요.
{
"date": "2013-07-16",
"created_at": "2013-07-16T22:52:36Z",
}
어떻게 하면 Retrofit 또는 Gson에게 이 스트링을 변환하도록 지시할 수 있습니까?java.util.Date objects
?
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.create();
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(API_BASE_URL)
.setConverter(new GsonConverter.create(gson))
.build();
또는 Kotlin 등가:
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create()
RestAdapter restAdapter = Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(T::class.java)
커스터마이즈된 Gson 파서를 retrofit으로 설정할 수 있습니다.자세한 사항은 이쪽: Retrofit Web 사이트
Ondreju의 답변을 보고 이것을 어떻게 리트로피트2로 구현하는지 확인해 주세요.
@gderaco의 답변이 2.0으로 업데이트되었습니다.
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.create();
Retrofit retrofitAdapter = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
방법은 다음과 같습니다.
날짜 확장 DateTime 클래스를 만든 다음 사용자 지정 역직렬화기를 작성합니다.
public class DateTime extends java.util.Date {
public DateTime(long readLong) {
super(readLong);
}
public DateTime(Date date) {
super(date.getTime());
}
}
다음으로 Date 및 DateTime 변환기를 모두 등록하는 디시리얼라이저 파트의 경우:
public static Gson gsonWithDate(){
final GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
return df.parse(json.getAsString());
} catch (final java.text.ParseException e) {
e.printStackTrace();
return null;
}
}
});
builder.registerTypeAdapter(DateTime.class, new JsonDeserializer<DateTime>() {
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
return new DateTime(df.parse(json.getAsString()));
} catch (final java.text.ParseException e) {
e.printStackTrace();
return null;
}
}
});
return builder.create();
}
또한 RestAdapter를 작성할 때 다음을 수행합니다.
new RestAdapter.Builder().setConverter(gsonWithDate());
Foo는 다음과 같습니다.
class Foo {
Date date;
DateTime created_at;
}
Gson은 하나의 datetime 형식(빌더에 지정된 형식)과 커스텀 형식을 사용하여 구문 분석할 수 없는 경우 iso8601만 처리할 수 있습니다.그 때문에, 커스텀 디시리얼라이저를 쓰는 것이 해결책이 될 수 있습니다.문제를 해결하기 위해 내가 정의한 사항:
package stackoverflow.questions.q18473011;
import java.util.Date;
public class Foo {
Date date;
Date created_at;
public Foo(Date date, Date created_at){
this.date = date;
this.created_at = created_at;
}
@Override
public String toString() {
return "Foo [date=" + date + ", created_at=" + created_at + "]";
}
}
다음 디시리얼라이저를 사용합니다.
package stackoverflow.questions.q18473011;
import java.lang.reflect.Type;
import java.text.*;
import java.util.Date;
import com.google.gson.*;
public class FooDeserializer implements JsonDeserializer<Foo> {
public Foo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String a = json.getAsJsonObject().get("date").getAsString();
String b = json.getAsJsonObject().get("created_at").getAsString();
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdfDateWithTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
Date date, created;
try {
date = sdfDate.parse(a);
created = sdfDateWithTime.parse(b);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return new Foo(date, created);
}
}
마지막 순서는 다음 명령어를 작성하는 것입니다.Gson
올바른 어댑터가 있는 인스턴스:
package stackoverflow.questions.q18473011;
import com.google.gson.*;
public class Question {
/**
* @param args
*/
public static void main(String[] args) {
String s = "{ \"date\": \"2013-07-16\", \"created_at\": \"2013-07-16T22:52:36Z\"}";
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Foo.class, new FooDeserializer());
Gson gson = builder.create();
Foo myObject = gson.fromJson(s, Foo.class);
System.out.println("Result: "+myObject);
}
}
결과:
Result: Foo [date=Tue Jul 16 00:00:00 CEST 2013, created_at=Tue Jul 16 22:52:36 CEST 2013]
말 그대로 작성 중인 클래스에 "created_at" 이름의 Date 개체가 이미 있는 경우 다음과 같이 간단합니다.
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").create();
YourObject parsedObject1 = gson.fromJson(JsonStringYouGotSomehow, YourObject.class);
그리고 넌 끝났어.복잡한 덮어쓸 필요가 없습니다.
다음과 같은 두 가지 새 클래스를 정의할 수 있습니다.
import java.util.Date;
public class MyDate extends Date {
}
그리고.
import java.util.Date;
public class CreatedAtDate extends Date {
}
POJO는 다음과 같습니다.
import MyDate;
import CreatedAtDate;
public class Foo {
MyDate date;
CreatedAtDate created_at;
}
마지막으로 사용자 지정 역직렬화기를 설정합니다.
public class MyDateDeserializer implements JsonDeserializer<Date> {
public static final SimpleDateFormat sServerDateDateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public MyDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json != null) {
final String jsonString = json.getAsString();
try {
return (MyDate) sServerDateDateFormat.parse(jsonString);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
}
그리고.
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(MyDate.class, new MyDateDeserializer());
이것은 질문에 직접적으로 대답하는 것은 아니지만, 만약 코더가 문제를 해결하는 방법에 대한 완전한 선택의 자유를 갖는다면, 제 생각에는 "최신 기술"입니다.
먼저 java.util을 사용하는 것은 최선의 솔루션이 아닙니다.날짜. 그 이유는 이러한 클래스가 일부 코너 케이스에서 이상적인 동작이 없었기 때문에 Java Instant 클래스 등에 의해 관리되기 때문입니다.이 S.O. 질문에서 Basil Bourque의 답변을 확인합니다: Kotlin에서 API 레벨이 16 이하인 날짜 개체를 만듭니다.
그래서 Android에서 ThreeTenABP의 Instant 클래스를 사용하고 Kotlin을 사용하고 있습니다.
val gson = GsonBuilder().registerTypeAdapter(Instant::class.java,
JsonDeserializer<Instant> { json: JsonElement, _: Type?, _: JsonDeserializationContext? ->
ZonedDateTime.parse(
json.asJsonPrimitive.asString
).toInstant()
}
).create()
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
언급URL : https://stackoverflow.com/questions/18473011/retrofit-gson-serialize-date-from-json-string-into-java-util-date
'programing' 카테고리의 다른 글
jar 실행 시 정적 콘텐츠를 포함하는 Spring Boot 프로젝트가 404 생성 (0) | 2023.03.01 |
---|---|
휴지 상태 쌍방향 매핑에 의해 발생하는 json 시리얼라이저의 순환 참조를 해결하는 방법 (0) | 2023.03.01 |
'string' 형식의 표현식을 인덱싱에 사용할 수 없으므로 요소에 '임의' 형식이 암시적으로 있습니다. (0) | 2023.03.01 |
TypeScript를 사용하여 window.location을 설정합니다. (0) | 2023.03.01 |
UI 라우터 URL에서 문자열 매개 변수를 쿼리하시겠습니까? (0) | 2023.03.01 |