Как выставить метод с помощью GSon?
Используя Play Framework, я сериализую свои модели через GSON. Я указываю, какие поля выставлены, а какие нет.
Это отлично работает, но я также хотел бы использовать метод @expose. Конечно, это слишком просто.
Как я могу это сделать?
Спасибо за вашу помощь!
public class Account extends Model {
@Expose
public String username;
@Expose
public String email;
public String password;
@Expose // Of course, this don't work
public String getEncodedPassword() {
// ...
}
}
Ответы
Ответ 1
Лучшим решением, с которым я столкнулся с этой проблемой, было создание специализированного сериализатора:
public class AccountSerializer implements JsonSerializer<Account> {
@Override
public JsonElement serialize(Account account, Type type, JsonSerializationContext context) {
JsonObject root = new JsonObject();
root.addProperty("id", account.id);
root.addProperty("email", account.email);
root.addProperty("encodedPassword", account.getEncodedPassword());
return root;
}
}
И использовать его, как это, на мой взгляд:
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(Account.class, new AccountSerializer());
Gson parser = gson.create();
renderJSON(parser.toJson(json));
Но иметь @Expose
, работающий для метода, было бы замечательно: он бы избегал создания сериализатора только для показа методов!
Ответ 2
Посмотрите Gson on Fire: https://github.com/julman99/gson-fire
Это библиотека, которую я создал, которая расширяет Gson для обработки таких случаев, как метод экспонирования, результаты Post-serialization, Post-deserialization и многие другие вещи, которые мне нужны с течением времени с Gson.
Эта библиотека используется в нашей компании Contactive (http://goo.gl/yueXZ3), как на Android, так и на Java Backend
Ответ 3
Gson @Expose
, по-видимому, поддерживается только в полях. На этом зарегистрирована проблема: @Expose следует использовать с методами.
Ответ 4
Пара различных вариантов, основанных на ответе Кирилла:
Пользовательский сериализатор с ярлыком:
public static class Sample
{
String firstName = "John";
String lastName = "Doe";
public String getFullName()
{
return firstName + " " + lastName;
}
}
public static class SampleSerializer implements JsonSerializer<Sample>
{
public JsonElement serialize(Sample src, Type typeOfSrc, JsonSerializationContext context)
{
JsonObject tree = (JsonObject)new Gson().toJsonTree(src);
tree.addProperty("fullName", src.getFullName());
return tree;
}
}
public static void main(String[] args) throws Exception
{
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(Sample.class, new SampleSerializer());
Gson parser = gson.create();
System.out.println(parser.toJson(new Sample()));
}
-ИЛИ-
Сериализатор на основе аннотаций
public static class Sample
{
String firstName = "John";
String lastName = "Doe";
@ExposeMethod
public String getFullName()
{
return firstName + " " + lastName;
}
}
public static class MethodSerializer implements JsonSerializer<Object>
{
public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContext context)
{
Gson gson = new Gson();
JsonObject tree = (JsonObject)gson.toJsonTree(src);
try
{
PropertyDescriptor[] properties = Introspector.getBeanInfo(src.getClass()).getPropertyDescriptors();
for (PropertyDescriptor property : properties)
{
if (property.getReadMethod().getAnnotation(ExposeMethod.class) != null)
{
Object result = property.getReadMethod().invoke(src, (Object[])null);
tree.add(property.getName(), gson.toJsonTree(result));
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
return tree;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) //can use in method only.
public static @interface ExposeMethod {}
public static void main(String[] args) throws Exception
{
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(Sample.class, new MethodSerializer());
Gson parser = gson.create();
System.out.println(parser.toJson(new Sample()));
}
Ответ 5
http://camelcode.org/tutorial/[email protected]
package org.camelcode;
import com.google.gson.annotations.Expose;
public class Book {
@Expose
private String author;
@Expose
private String title;
private Integer year;
private Double price;
public Book() {
this("camelcode.org", "Exclude properties with Gson", 1989, 49.55);
}
public Book(String author, String title, Integer year, Double price) {
this.author = author;
this.title = title;
this.year = year;
this.price = price;
}
}
package org.camelcode;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class WriteGson {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
String json = gson.toJson(new Book());
System.out.println(json);
Gson gsonNonExcluded = new Gson();
String jsonNonExcluded = gsonNonExcluded.toJson(new Book());
System.out.println(jsonNonExcluded);
}
}
{"author":"camelcode.org","title":"Exclude properties with Gson"}
{"author":"camelcode.org","title":"Exclude properties with Gson","year":1989,"price":49.55}