Come convalidare molti campi JSON senza ingombrare il codice con if-checks su ogni campo?

1

Ho una classe che contiene vari campi e potrebbero essere accessibili con l'aiuto di getter e setter come il seguente

public class Student {

    private String name;
    private int age;
    private int sibblingsCount;
    private String elderSibblingName;
    private String youngerSibblingName;

    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return this.name;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public void setSibblingsCount(int count) {
        this.sibblingsCount = count;
    }
    public int getSibblingsCount() {
        return this.sibblingsCount;
    }

    public void setElderSibblingName(String name) {
        this.elderSibblingName = name;
    }
    public String getElderSibblingName() {
        return this.elderSibblingName;
    }

    public void setYoungerSibblingName(String name) {
        this.youngerSibblingName = name;
    }
    public void getYoungerSibblingName() {
        return this.youngerSibblingName;
    }

    public String getStudentDetails() {    
        JSONObject json = new JSONObject();
        if(name != null && !name.isEmpty()) {
            json.put("name", this.name);
        }

        if(this.age != 0) {
            json.put("age", this.age);
        }

        if(this.sibblingsCount != 0) {
            json.put("sibblingsCount", this.sibblingsCount);
        }

        if(this.elderSibblingName != null && !this.elderSibblingName.isEmpty()) {
            json.put("elderSibblingName", this.elderSibblingName);
        }

        if(this.youngerSibblingName != null && !this.youngerSibblingName.isEmpty() {
            json.put("youngerSibblingName", this.youngerSibblingName);
        }
        return json.toString();
    }
}

Tutto ciò di cui ho bisogno è di comprimere i campi validi nella classe Student . Si dice che il campo sia valido quando contiene qualche valore in esso. Dire age non dovrebbe essere 0 e deve essere un numero valido. Dire elderSibblingName non deve essere nullo o vuoto. Come verificare i campi validi mentre si impacchetta il JSON risultante?

È davvero doloroso verificare la validità di ogni singolo file della classe che rende il codice sgradevole quando ci sono troppi campi nella classe.

    
posta rm -rf star 02.07.2017 - 11:02
fonte

1 risposta

2

Se sei infastidito dai tuoi controlli ripetitivi, estraili in una funzione per renderli meno ripetitivi. Ad esempio:

private static <T> void putIf(JsonObject json, String name, T value, Predicate<T> isValid) {
  if (isValid.test(value)) json.put(name, value);
}

private boolean isNonEmpty(String s) {
  return s != null && !s.isEmpty();
}

private boolean isNonZero(int i) {
  return i != 0;
}

public String getStudentDetails() {    
    JSONObject json = new JSONObject();

    putIf(json, "name", name, x -> isNonEmpty(x));
    putIf(json, "age", age, x -> isNonZero(x));
    putIf(json, "siblingsCount", siblingsCount, x -> isNonZero(x));
    putIf(json, "elderSiblingName", elderSiblingName, x -> isNonEmpty(x));
    putIf(json, "youngerSiblingName", youngerSiblingName, x -> isNonEmpty(x));

    return json.toString();
}

Tuttavia, ciò non risolve un problema fondamentale della tua classe: i campi possono contenere valori non validi! In molti casi, ciò può essere evitato inizializzando completamente l'oggetto in un costruttore ed evitando setter a meno che non convalidino completamente i loro valori.

Se i vincoli di convalida sono più complicati, puoi anche creare i tuoi tipi che rappresentano un particolare vincolo di convalida, ad esempio:

final class Name {
  private final String name;

  public Name(String name) {
    if (name == null || name.isEmpty())
      throw ...;
    this.name = name;
  }

  public String get() { return name; }
}

Se un valore ha un significato particolare nel tuo modello di dominio, dovresti preferire una classe semplice come questa su tipi built-in o primitivi.

Ora puoi usare quella classe per tutto il codice, anche se devi ancora controllare che l'oggetto non sia nullo:

public class Student {

    private Name name;
    ...
    private Name elderSibblingName;
    private Name youngerSibblingName;

    public Name getName() {
        return this.name;
    }
    public void setName(Name name) {
        this.name = name;  // assuming null is valid
    }

    ...

    public String getStudentDetails() {    
        JSONObject json = new JSONObject();

        if(name != null) {
            json.put("name", name.get());
        }
        ...
    }
}
    
risposta data 03.07.2017 - 09:41
fonte

Leggi altre domande sui tag