2016-06-29 13 views
8

Uso Spring Data REST e Hateoas in combinazione con il browser HAL. Funziona perfettamente, ma ora vorrei fare un dump JSON di una specifica entità con (un insieme di) i suoi oggetti associati. Ho usato @Projection ma poi mi sono bloccato di nuovo.Spring REST Dati Come aggiungere risorse incorporate in linea

FYI: Il comportamento normale (con incorporato e collegamenti, ecc.) Dovrebbe rimanere accanto al nuovo endpoint (senza incorporato e collegamenti).

Per illustrare ulteriormente il mio problema/domanda:

class Person { 
    String name; 
    List<Company> companies; 
} 

class Company { 
    String name; 
    Address address; 
} 

class Address { 
    String street; 
} 

Ora vorrei vedere qualcosa di simile:

{ 
    "name": "John", 
    "companies": [ 
     { 
      "name": "Stackoverflow", 
      "address": {"street": "Highway blvd."} 
     }, 
     { 
      "name": "Oracle", 
      "address": {"street": "Main rd."} 
     } 
    ] 
} 

Mentre sto ottenendo questo:

{ 
    "name": "John", 
    "_links": { 
     "self": {"href": "http...."}, 
     "companies": {"href": "http ..."} 
    }, 
} 

Vedi anche: http://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts

Nel mio esempio ho introdotto due difficoltà che ho: elenchi (aziende) e più livelli: persona-> azienda-> indirizzo. Entrambi sono tenuti a lavorare (probabilmente 5 livelli, alcuni dei quali hanno "molte" relazioni).

+0

È possibile non utilizzando primavera dati REST.Spring Data Rest prende una visione d'opinione su come fare riposare, e questo include i collegamenti per le relazioni invece che l'intera entità. –

+0

Grazie, Deinum. Spring Data Rest è sul classpath e deve rimanere lì. Il tuo commento è ancora applicabile allora? – codesmith

risposta

0

Nella seconda finale, se non si desidera che i collegamenti, è necessario disporre di un controller e una risorsa, in cui mappare i dati alla risorsa e restituire la raccolta di risorse dal controller

+0

Grazie Fahad, ma puoi per favore illustrare cosa intendi? Intendi un '@ Controller' e un' @ Resource' o più in generale? Come funziona questa mappatura dei dati nella tua vista? – codesmith

+0

Per risorsa intendo, una classe che è simile all'entità con le informazioni desiderate. È possibile eseguire il mapping del bean dozer per mappare i dati sulla risorsa. –

+0

Potrebbe quindi diventare problematico quando le relazioni puntano anche nell'altro senso (da Indirizzo a Società e da Azienda a Persona. L'approccio non-spring-data-rest mostrerà tutto (loop ricorsivo infinito). '@ JsonIgnore' non è un'opzione in questo caso, perché quindi la vista di hatoas verrà visualizzata in modo errato. Non l'ho ancora testato, ma a me sembra logico. – codesmith

10

Il accettati il metodo di allineare le entità è proiezioni, come hai identificato. Le proiezioni sono sempre inline, quindi una possibilità è quella di creare le proiezioni per ciascuno dei tuoi soggetti e combinarle in questo modo:

@Projection(name = "personProjection", types = Person.class) 
public interface PersonProjection { 

    String getFirstName(); 
    List<CompanyProjection> getCompanies(); 

} 

@Projection(name = "companyProjection", types = Company.class) 
public interface CompanyProjection { 

    String getName(); 
    AddressProjection getAddress(); 

} 

@Projection(name = "addressProjection", types = Address.class) 
public interface AddressProjection { 

    String getStreet(); 

} 

Un GET people/1?projection=personProjection sarà ancora rendere _links elementi, ma si otterrà il si nidificazione desidera:

{ 
    "companies" : [ { 
    "address" : { 
     "street" : "123 Fake st", 
     "_links" : { 
     "self" : { 
      "href" : "http://localhost:8080/addresses/1{?projection}", 
      "templated" : true 
     } 
     } 
    }, 
    "name" : "ACME inc.", 
    "_links" : { 
     "self" : { 
     "href" : "http://localhost:8080/companies/1{?projection}", 
     "templated" : true 
     }, 
     "address" : { 
     "href" : "http://localhost:8080/companies/1/address" 
     } 
    } 
    } ], 
    "firstName" : "Will", 
    "_links" : { 
    "self" : { 
     "href" : "http://localhost:8080/people/1" 
    }, 
    "person" : { 
     "href" : "http://localhost:8080/people/1{?projection}", 
     "templated" : true 
    }, 
    "companies" : { 
     "href" : "http://localhost:8080/people/1/companies" 
    } 
    } 
} 

in alternativa, se non è necessario per esporre le Company e Address entità come le risorse di riposo, è possibile contrassegnare i loro depositi con @RepositoryRestResource(exported=false), e saranno inline ovunque essi si fa riferimento, senza alcuna necessità di proiezioni.

Un ultimo avvertimento, tuttavia, questa richiesta è in qualche modo in conflitto con l'ethos di Spring Data REST e Spring HATEOAS, e invitando query grandi e ingombranti che soffrono il problema n + 1. Ricorda che Spring Data REST non è una soluzione chiavi in ​​mano per trasformare un modello di dominio in un'API e il rendering di grafici di oggetti profondi (se questa è la tua intenzione) è potenzialmente qualcosa che potresti esporre come endpoint del controller personalizzato su una base ad-hoc in cui può controllare a fondo le condizioni.

-1

Credo che il modo migliore per incorporare una lista o un HashMap è via convertirlo in una stringa JSON e di nuovo a oggetto Java quando lo si legge ....

questo può essere facilmente essere fatto utilizzando

@Convert(converter = PluginAnalyzerConfigConverter.class) 
    private PluginAnalyzerConfig configuration; 
//in Entity Class 

// declare a converter class like this 
public class PluginAnalyzerConfigConverter implements 
    AttributeConverter<PluginAnalyzerConfig, String> { 

    @Override public String convertToDatabaseColumn(PluginAnalyzerConfig config) { 
    Gson parser = new Gson(); 
    return parser.toJson(config, PluginAnalyzerConfig.class); 
    } 

    @Override public PluginAnalyzerConfig convertToEntityAttribute(String source) { 
    Gson parser = new Gson(); 
    return parser.fromJson(source, PluginAnalyzerConfig.class); 
    } 
} 

come mostrato Spring Data with Mysql JSON type

Abbiamo cosa simile nella primavera dati DynamoDB - per AWS DynamoDB

Problemi correlati