반응형
Gson용 커스텀 JSON 디시리얼라이저를 작성하려면 어떻게 해야 하나요?
Java 클래스가 있습니다.사용자:
public class User
{
int id;
String name;
Timestamp updateDate;
}
웹 서비스에서 사용자 개체가 포함된 JSON 목록을 받았습니다.
[{"id":1,"name":"Jonas","update_date":"1300962900226"},
{"id":5,"name":"Test","date_date":"1304782298024"}]
커스텀 디시리얼라이저를 작성하려고 했습니다.
@Override
public User deserialize(JsonElement json, Type type,
JsonDeserializationContext context) throws JsonParseException {
return new User(
json.getAsJsonPrimitive().getAsInt(),
json.getAsString(),
json.getAsInt(),
(Timestamp)context.deserialize(json.getAsJsonPrimitive(),
Timestamp.class));
}
하지만 탈시리얼라이저가 작동하지 않아요.Gson용 커스텀 JSON 디시리얼라이저를 작성하려면 어떻게 해야 하나요?
코드의 "수동" 파싱을 최소화하기 위해 다음과 같이 조금 다른 방법을 사용하겠습니다.그렇지 않으면 불필요하게 Gson과 같은 API를 사용하는 목적이 다소 어긋나기 때문입니다.
// output:
// [User: id=1, name=Jonas, updateDate=2011-03-24 03:35:00.226]
// [User: id=5, name=Test, updateDate=2011-05-07 08:31:38.024]
// using java.sql.Timestamp
public class Foo
{
static String jsonInput =
"[" +
"{\"id\":1,\"name\":\"Jonas\",\"update_date\":\"1300962900226\"}," +
"{\"id\":5,\"name\":\"Test\",\"update_date\":\"1304782298024\"}" +
"]";
public static void main(String[] args)
{
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
gsonBuilder.registerTypeAdapter(Timestamp.class, new TimestampDeserializer());
Gson gson = gsonBuilder.create();
User[] users = gson.fromJson(jsonInput, User[].class);
for (User user : users)
{
System.out.println(user);
}
}
}
class User
{
int id;
String name;
Timestamp updateDate;
@Override
public String toString()
{
return String.format(
"[User: id=%1$d, name=%2$s, updateDate=%3$s]",
id, name, updateDate);
}
}
class TimestampDeserializer implements JsonDeserializer<Timestamp>
{
@Override
public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
long time = Long.parseLong(json.getAsString());
return new Timestamp(time);
}
}
(원래 질문에서는 "date_date"를 "update_date"로 가정합니다).
@Override
public User deserialize(JsonElement json, Type type,
JsonDeserializationContext context) throws JsonParseException {
JsonObject jobject = json.getAsJsonObject();
return new User(
jobject.get("id").getAsInt(),
jobject.get("name").getAsString(),
new Timestamp(jobject.get("update_date").getAsLong()));
}
사용자 클래스에는 적절한 생성자가 있을 것입니다.
오늘 나는 우리 반에서 했던 것처럼 이것을 찾고 있었다.java.time.Instant
디폴트 gson은 그것을 역직렬화 할 수 없었습니다.내 POJO는 다음과 같습니다.
open class RewardResult(
@SerializedName("id")
var id: Int,
@SerializedName("title")
var title: String?,
@SerializedName("details")
var details: String?,
@SerializedName("image")
var image: String?,
@SerializedName("start_time")
var startTimeUtcZulu: Instant?, // Unit: Utc / Zulu. Unit is very important
@SerializedName("end_time")
var endTimeUtcZulu: Instant?,
@SerializedName("unlock_expiry")
var unlockExpiryTimeUtcZulu: Instant?,
@SerializedName("target")
var target: Int,
@SerializedName("reward")
var rewardItem: RewardItem
);
data class RewardItem(
@SerializedName("type")
var type: String?,
@SerializedName("item_id")
var itemId: Int,
@SerializedName("amount")
var amount: Int
)
그럼 다음에Instant
변수, json의 시간 변수를 해석하고 문자열을 Instant로 변환합니다.integer, string 등에 사용하는jsonObject.get("id").asInt
기타 pojo에서는 다음과 같이 디폴트 디시리얼라이저를 사용합니다.
val rewardItem: RewardItem = context!!.deserialize(rewardJsonElement,
RewardItem::class.java);
따라서 대응하는 커스텀디시리얼라이저는 다음과 같습니다.
val customDeserializer: JsonDeserializer<RewardResult> = object : JsonDeserializer<RewardResult> {
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): RewardResult {
val jsonObject: JsonObject = json!!.asJsonObject;
val startTimeString: String? = jsonObject.get("start_time")?.asString;
var startTimeUtcZulu: Instant? = createTimeInstant(startTimeString);
val endTimeString: String? = jsonObject.get("end_time")?.asString;
var endTimeUtcZulu: Instant? = createTimeInstant(endTimeString);
val unlockExpiryStr: String? = jsonObject.get("unlock_expiry")?.asString;
var unlockExpiryUtcZulu: Instant? = createTimeInstant(unlockExpiryStr);
val rewardJsonElement: JsonElement = jsonObject.get("reward");
val rewardItem: ridmik.one.modal.reward.RewardItem = context!!.deserialize(rewardJsonElement,
ridmik.one.modal.reward.RewardItem::class.java); // I suppose this line means use the default jsonDeserializer
var output: ridmik.one.modal.reward.RewardResult = ridmik.one.modal.reward.RewardResult(
id = jsonObject.get("id").asInt,
title = jsonObject.get("title")?.asString,
details = jsonObject.get("details")?.asString,
image = jsonObject.get("image")?.asString,
startTimeUtcZulu = startTimeUtcZulu,
endTimeUtcZulu = endTimeUtcZulu,
unlockExpiryTimeUtcZulu = unlockExpiryUtcZulu,
target = jsonObject.get("target").asInt,
rewardItem = rewardItem
);
Timber.tag(TAG).e("output = "+output);
return output;
}
}
마지막으로 다음과 같이 커스텀 gson을 만듭니다.
val gsonBuilder = GsonBuilder();
gsonBuilder.registerTypeAdapter(RewardResult::class.javaObjectType,
this.customJsonDeserializer);
val customGson: Gson = gsonBuilder.create();
언급URL : https://stackoverflow.com/questions/6096940/how-do-i-write-a-custom-json-deserializer-for-gson
반응형
'IT' 카테고리의 다른 글
ASP.NET MVC 2 - jquery ajax 응답으로 실패했습니다. (0) | 2023.03.29 |
---|---|
PHP에서 json을 xml로 변환하는 방법이 있습니까? (0) | 2023.03.29 |
스프링 부트 @autowired가 작동하지 않습니다.클래스는 다른 패키지로 되어 있습니다. (0) | 2023.03.29 |
Greasemonkey 스크립트에서 XMLHttpRequests를 대행 수신하려면 어떻게 해야 합니까? (0) | 2023.03.29 |
oneOf 개체에 대한 Json 스키마 예제 (0) | 2023.03.29 |