2016-02-23 4 views
3

При преобразовании объекта Java в строку Json с использованием API GSON, я также хочу, чтобы это преобразование Json было неудачным, если любой из аннотированных атрибутов равен NULL.Проверка Java на Json с использованием GSON

Например

public class Order{ 

@SerializedName("orderId") 
@Expose 
@Required 
private Integer id; 

//getter & setter available for id 
} 

Теперь, когда я делаю

Order order = new Order(); 

JSONObject jsonobj = new JSONObject(gson.toJson(order)); 

Я хочу потерпеть неудачу выше Java для преобразования Json, если какой-либо из @Required атрибута является нулевым Является ли это возможно с помощью GSON ?

+0

Похожие: https://stackoverflow.com/questions/21626690/gson-optional-and-required-fields – Vadzim

ответ

5

Я хотел пропустить преобразование Java в Json, если какой-либо атрибут Java имеет значение null, которое аннотируется как @Required, Я могу добиться этого, используя следующий подход. Пожалуйста, дайте мне знать, если вы видите какие-либо вопросы:

class RequiredKeyAdapterFactory implements TypeAdapterFactory { 

    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { 

     final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); 

     return new TypeAdapter<T>() { 
      @Override 
      public void write(JsonWriter out, T value) throws IOException { 
       if (value != null) { 

        Field[] fields = value.getClass().getDeclaredFields(); 

        for (int i = 0; i < fields.length; i++) { 
         if (fields[i] 
           .isAnnotationPresent(Required.class)) { 
          validateNullValue(value, fields[i]); 
         } 

        } 
       } 
       delegate.write(out, value); 
      } 

      private <T> void validateNullValue(T value, Field field) { 
       field.setAccessible(true); 
       Class t = field.getType(); 
       Object v = null; 
       try { 
        v = field.get(value); 
       } catch (IllegalArgumentException | IllegalAccessException e) { 
        throw new IllegalArgumentException(e); 
       } 
       if (t == boolean.class && Boolean.FALSE.equals(v)) { 
        throw new IllegalArgumentException(field + " is null"); 
       } else if (t.isPrimitive() 
         && ((Number) v).doubleValue() == 0) { 

        throw new IllegalArgumentException(field + " is null"); 
       } else if (!t.isPrimitive() && v == null) { 
        throw new IllegalArgumentException(field + " is null"); 

       } 
      } 

      @Override 
      public T read(JsonReader in) throws IOException { 
       return delegate.read(in); 
      } 

     }; 
    } 
} 

RequiredKeyAdapterFactory requiredKeyAdapterFactory = new RequiredKeyAdapterFactory(); 
Gson gson = new GsonBuilder().registerTypeAdapterFactory(requiredKeyAdapterFactory) 
     .create(); 

Это работает

+0

привет @Preetam : можете ли вы предоставить нам определение требуемого интерфейса. –

+0

Это должно быть похоже на простую аннотацию, которая может использоваться для всех атрибутов, которые являются обязательными. @Retention (RetentionPolicy.RUNTIME) @Target (ElementType.FIELD) общественного @interface Обязательный { // ничего } –

+0

Обратите внимание, что это не сработает, если десериализованный JSON содержит примитивный число равным 0 (из-за 'если (t.isPrimitive() && ((Number) v) .doubleValue() == 0) 'line), но я не думаю, что есть хороший способ обойти это, если вы не сделаете каждое сериализованное значение объектом. –

Смежные вопросы