, Немного отстой, ты спрашиваешь меня;)

public class UserAction {
    private final UUID uuid;
    private String userId;
    /* more fields, setters and getters here */

    public UserAction(){
        this.uuid = UUID.fromString(new com.eaio.uuid.UUID().toString());
    }

    public UserAction(UUID uuid){
        this.uuid = uuid;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final UserAction other = (UserAction) obj;
        if (this.uuid != other.uuid && (this.uuid == null || !this.uuid.equals(other.uuid))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 53 * hash + (this.uuid != null ? this.uuid.hashCode() : 0);
        return hash;
    }
}

ользую Gson для сериализации и десериализации этого класса. Как и сегодня, мне пришлось добавить окончательный UUID в этот объект. У меня нет проблем с сериализацией. Мне нужно заставить gson использоватьpublic UserAction(UUID uuid) конструктор при десериализации. Как я могу этого достичь?

Ответы на вопрос(3)

gson.registerTypeAdapter(DateTime.class, new DateTimeDeserializer());

private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
  public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new DateTime(json.getAsJsonPrimitive().getAsString());
  }
}
 Tomasz Błachowicz31 мая 2011 г., 15:00
Копировать вставить, Немного отстой, ты спрашиваешь меня;)
Решение Вопроса

Вы могли бы реализовать кастомJsonDeserializer и зарегистрируйте его в GSON.

class UserActionDeserializer implements JsonDeserializer<UserAction> {
    public UserAction deserialize(JsonElement json, Type typeOfT,
        JsonDeserializationContext context) throws JsonParseException {
        return new UserAction(UUID.fromString(json.getAsString());
}

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(UserAction.class, new UserActionDeserializer());

Имейте в виду, что этот код не был проверен.

 frail31 мая 2011 г., 14:53
Я проверяю это сейчас, спасибо за совет.

чтобы воспользоваться тем фактом, что во время десериализации Gson закроет любые значения, заданные конструкторами, новыми значениями, найденными в JSON, и поэтому просто используетInstanceCreator, который существует специально для «создания экземпляров класса, который не определяет конструктор без аргументов». Этот подход особенно эффективен, когда используемый конструктор просто присваивает значения параметров полям и не выполняет никаких проверок достоверности или иным образом не выполняет какой-либо значимой обработки на основе состояния.

Кроме того, этот подход не требует дальнейшей пользовательской десериализации - никакой пользовательской реализацииJsonDeserializer это необходимо. Это может быть выгодно в ситуациях, когда введение пользовательского десериализатора для решения одной небольшой проблемы затем требует «ручной» обработки других элементов JSON в непосредственной близости, что может быть нетривиальным.

С учетом сказанного, вот такое рабочее решение, которое использует предпочтительныйUserAction конструктор, но передает ему только нулевую ссылку. Фактическое значение из JSON устанавливается позже. (Гсону все равно, чтоuuid поле должно быть окончательным.)

import java.lang.reflect.Type;
import java.util.UUID;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;

public class Foo
{
  public static void main(String[] args)
  {
    UserAction action = new UserAction(UUID.randomUUID());
    action.setUserId("user1");

    String json = new Gson().toJson(action);
    System.out.println(json);

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(UserAction.class, new UserActionInstanceCreator());
    Gson gson = gsonBuilder.create();
    UserAction actionCopy = gson.fromJson(json, UserAction.class);
    System.out.println(gson.toJson(actionCopy));
  }
}

class UserActionInstanceCreator implements InstanceCreator<UserAction>
{
  @Override
  public UserAction createInstance(Type type)
  {
    return new UserAction(null);
  }
}

class UserAction
{
  private final UUID uuid;
  private String userId;

  public UserAction()
  {
    throw new RuntimeException("this constructor is not used");
  }

  public UserAction(UUID uuid)
  {
    this.uuid = uuid;
  }

  void setUserId(String userId)
  {
    this.userId = userId;
  }
}
 frail18 июн. 2011 г., 01:44
хороший способ, спасибо

Ваш ответ на вопрос