2013-04-30 10 views
33

Sto lavorando alla creazione di una API REST. La mia domanda è, quando si usa Jersey, quali sono le differenze tra i miei servizi di costruzione e la restituzione di un oggetto Response o la restituzione del bean o della raccolta. Mi interessano solo le chiamate riuscite, sto lanciando le opportune eccezioni per errori e situazioni eccezionali.In JAX RS, differenze tra risposta di risposta e bean o raccolta di fagioli (DTO)

Ecco un esempio:

@Produces(MediaType.APPLICATION_JSON) 
public Response search(FooBean foo){ 
    List<FooBean> results = bar.search(foo); 
    return Response.ok(results).build(); 
} 

vs.

@Produces(MediaType.APPLICATION_JSON) 
public List<FooBean> search(FooBean foo){ 
    List<FooBean> results = bar.search(foo); 
    return results; 
} 

Ho visto entrambi gli esempi utilizzati, e preferirei il secondo scenario, solo per rendere più facile riconoscere il metodo di servizio. Ho esaminato le risposte a entrambi questi metodi e sembrano identici.

Pensieri?

+1

Essi sono identici, se si considera che non ritorni un po 'di classe 'Exception' come hai detto. 'Response' fornisce l'opzione per restituire qualsiasi tipo di oggetto, e anche impostare un' HttpStatus'. In questo caso, risulterà '200 OK'. Ma non puoi passare a un altro stato come preferisci usando 'Risposta'. È la mia opinione, ovviamente, ma mi piace il modo di "Risposta". –

+0

Significa che è possibile passare a uno stato di risposta diverso utilizzando l'oggetto Risposta? Se si restituisce la Lista , lo stato della risposta è anche 200 OK. –

+2

Sì, puoi cambiare se vuoi. Di default 'Response.ok(). Entity (entity) .build();' restituirà '200 OK' se l'entità non è nulla, altrimenti restituirà' 204 NO CONTENT'. È possibile forzare la restituzione di uno stato '200 OK' con' Response.ok(). Entity (entity) .status (Status.OK) .build(); 'anche l'entità è null; –

risposta

31

Le differenze sono spiegate nelle specifiche JAX-RS:

3.3.3 Tipo restituito

metodi risorsa può tornare vuoto, di risposta, GenericEntity, o un altro tipo Java, questi tipi di ritorno sono mappati ad un corpo di entità risposta come segue:

nulli
risultati in un corpo dell'entità vuoto con 204 codice di stato.

risposta
Risultati in un corpo dell'entità mappati dalla proprietà dell'entità della risposta con il codice di stato specificato dalla proprietà dello stato della risposta. Un valore di ritorno nullo risulta in un codice di stato 204. Se la proprietà status della Response non è impostata: viene utilizzato un codice di stato 200 per una proprietà di entità non nulla e viene utilizzato un codice di stato 204 se la proprietà dell'entità è null.
GenericEntity
Risultati in un corpo entità mappato dalla proprietà Entity di GenericEntity. Se il valore restituito non è nullo, viene utilizzato un codice di stato 200, un valore di ritorno nullo risulta in un codice di stato 204.

Altro
Risultati in un corpo dell'entità mappato dalla classe dell'istanza restituita. Se il valore restituito non è nullo, viene utilizzato un codice di stato 200, un valore di ritorno nullo risulta in un codice di stato 204.

I metodi che devono fornire metadati aggiuntivi con una risposta dovrebbe restituire un'istanza di risposta, la classe ResponseBuilder fornisce un modo conveniente per creare un'istanza di risposta utilizzando un builder.

fagioli 'regolare' sono mappati su più o meno nello stesso modo in cui è Response, con l'eccezione che un Response consente di impostare i metadati aggiuntivi (intestazioni di risposta, lo stato specializzato, tipo di contenuti specializzati, ecc). Per quanto riguarda il sistema da utilizzare, tutto dipende anche da te: Response ti offre maggiore flessibilità, ma i bean regolari sono più "auto-documentanti".

+1

ecco il link alle specifiche: http://download.oracle.com/otndocs/jcp/jaxrs-2_0-fr-spec/index.html –

8

Non esiste alcuna differenza se si desidera restituire sempre la risposta 200 - OK, catturando e manipolando tutte le eccezioni che potrebbero verificarsi prima del ritorno del metodo, con intercettazioni o WebApplicationException. Quindi, entrambi questi metodi risulteranno le stesse risposte.

L'unica diference è a scenari specifici, come tornare oggetti nulli, o creando oggetto, come in questo esempio:

@POST 
@Consumes("application/json") 
public Response post(String content) { 
    URI createdUri = ... 
    Object createdContent = create(content); 
    return Response.created(createdUri).entity(createdContent).build(); 
} 

In questo caso il rendimento sarà 201 - CREATED (Con l'URI per accedere all'oggetto creato)

Così, il seguente metodo:

@POST 
@Consumes("application/json") 
public Object post(String content) { 
    URI createdUri = ... 
    Object createdContent = create(content); 
    return createdContent; 
} 

... restituirà una risposta 200 - OK

Se non si cura di quale stato di risposta riceverà il client, è possibile utilizzare qualsiasi dichiarazione senza problemi.

Fonte: Jersey.

+0

Buona soluzione, perché per lo più operiamo con gli Oggetti, non solo con le stringhe. Quindi, ho una domanda: come recuperare l'oggetto da Response e ottenere una rappresentazione xml o json di esso? – Nikolas

0

Il mio personale di vista, se la risposta contiene DTO (Bean/Raccolta di fagioli), quindi il servizio di riposo deve sempre restituire DTO, ma non oggetto di risposta.

La motivazione: presto o tardi, vi verrà chiesto di fare un uso del servizio di riposo facile per i clienti, fornendo resto client API. Di solito, devi estrapolare le interfacce per il resto e implementarle con i tuoi servizi di riposo . Queste interfacce di resto sono utilizzate dai client del tuo rest client.

E dal punto di vista del cliente c'è un'enorme differenza tra l'elaborazione di DTO e la risposta semplice. In caso di risposta viene utilizzato, il vostro cliente è costretto:

  1. controllare codice di risposta esplicitamente al processo di risposta di successo
  2. errori maniglia, per il codice di verifica esplicitamente
  3. corpo Converti della vostra risposta in DTO da lui stesso.

Il che significa che la gestione della risposta è molto simile ai codici di errore restituiti nei metodi, che è considerata una pratica molto negativa. Per gestire gli errori in un unico punto, vengono utilizzate eccezioni (non sto parlando di modi FP di gestire gli errori, che è il migliore).

Così che cosa può fare:

  1. Nel caso in cui una richiesta viene elaborata con successo, di convertire i dati di servizio resto in DTO/Bean e restituirlo.
  2. Nel caso in cui la convalida non sia andata a buon fine o qualcosa sia andato storto, genera un'eccezione nel servizio di assistenza. Forse un mappatore di eccezioni predefinito non è adatto a te, quindi dovrai implementare il tuo mappatore di eccezioni.

Quindi, se si pensa in anticipo, è necessario restituire DTO.

Un caso d'uso, quando è necessario restituire una risposta semplice, ad es. Quando si esporta un file. Sembra che JAX RS non permetta di restituire l'oggetto InputStream. Non sono sicuro, deve essere controllato.

L'altro caso d'uso, è stato ricordato da @Perception, ma è più un'eccezione, di una regola:

I metodi che devono fornire metadati aggiuntivi con una risposta dovrebbe restituire un'istanza di risposta, la classe ResponseBuilder fornisce un modo conveniente per creare un'istanza di risposta utilizzando un modello di build .

Nota: si tratta di una questione generale per JAX RS, non dipende dalla realizzazione precisa, come Resteasy o Jersey

Problemi correlati