2013-03-02 9 views
5

Ho un endpoint generato come segue:Restituzione di errori con Google Cloud Endpoint

public Book insertBook(Book book) { 
    PersistenceManager mgr = getPersistenceManager(); 
    try { 
     if (containsShout(book)) { 
      throw new EntityExistsException("Object already exists"); 
     } 
     mgr.makePersistent(book); 
    } finally { 
     mgr.close(); 
    } 
    return book; 
} 

Mi chiedo come avrei dovuto restituire gli errori al client. E.g. il libro contiene alcuni campi obbligatori, un controllo ISNM, ecc.

Quindi suppongo di lanciare un'eccezione, ma come fa questa mappa alla risposta json restituita. La risposta di JSON dovrebbe contenere tutti gli errori di campo per evidenziare questi campi nel client.

+0

siete riusciti a risolvere questo problema? Se come l'hai fatto? – dynamokaj

+0

No, ma non sono più interessato –

risposta

5

In generale, le eccezioni sono mappate su un codice di stato http 500 nella risposta. Con le seguenti eccezioni si possono ottenere i codici diversi: com.google.api.server.spi.response.BadRequestException -> 400 com.google.api.server.spi.response.UnauthorizedException -> 401 com.google.api.server.spi.response.ForbiddenException -> 403 com.google.api.server.spi.response.NotFoundException -> 404

Se si consumano il tuo punto finale in Android il codice di errore sarà nella IOException gettato lì e tu puoi reagire di conseguenza nella cattura.

+0

Sì, ho capito di aver restituito i codici di errore HTTP. Quello che mi chiedo è come gestire i messaggi di errore dettagliati come i vincoli violati delle proprietà del dominio. –

+0

Questo non è il comportamento che vedo in 1.7.5. Sto lanciando una BadRequestException e il client ottiene un 200 con il mio messaggio String nel corpo come un po 'di JSON. – Eliot

+0

Lasciami qualificare che: questo non funziona sul server dev locahost, ma * sembra * funziona sul server App Engine, anche in 1.7.5. Quindi questo è un bug nel server di localhost dev davvero. – Eliot

0

In questo modo ho una entità di classe astratta.

Ha un ResponseCode, che è un enum e un ErrorMessage stringa.

Quindi "Libro" potrebbe ereditare dall'entità. E la tua risposta potrebbe essere la seguente:

public Book insertBook(Book book) { 
    PersistenceManager mgr = getPersistenceManager(); 
    try { 
     if (containsShout(book)) { 
      book.setResponseCode(ResponseCode.ERROR); 
      book.setError("Object already exists"); 
     } else { 
      mgr.makePersistent(book); 
     } 
    } finally { 
     mgr.close(); 
    } 
    return book; 
} 
+0

Grazie per la risposta @davibq, ma questo non inquina le classi entità imo. Forse dovrei creare un SingleEntitiyResponse contenente il modello, lo stato della risposta e gli errori.Tieni presente che posso fare lo stesso per com.google.api.server.spi.response.CollectionResponse estendendolo e includendo lo stato e gli errori di risposta simili. –

3

Ho provato qualcosa del genere e sembrava funzionare bene per me.

class Response<T> { 
    Status status; 
    String userFriendlyMessage; 
    T object; //your bean or entity object 

    RestResponse toRestResponse() { 
     RestResponse r = new RestResponse(); 
     r.status = status; 
     r.userFriendlyMessage = userFriendlyMessage; 
     r.object = object; 
    } 
} 

Non è possibile restituire un oggetto generico dall'endpoint. Quindi creare una classe RestResponse equivalente che possa essere creata da Response.

class RestResponse { 
    Status status; 
    String userFriendlyMessage; 
    Object object; 
} 

Lo stato può essere così.

public enum Status { 
    SUCCESS, RESOURCE_NOT_FOUND, RESOURCE_ALREADY_EXISTS; //etc 
} 

Tutti i vostri metodi endpoint sarebbero tornati RestResponse che a sua volta essere costruito da una risposta (T può essere il bean o oggetto entità).

Quando si deserializza la risposta JSON (RestResponse), è possibile procedere alla deserializzazione come Risposta.

Spero che questo aiuti.

saluti, Sathya

+0

Questo non funziona per me, ottengo: "Errore: tipo di oggetto T non supportato." Esempio: public Response.RestResponse getBeer() { Risposta genericResponse = new Response (); \t genericResponse.status = Status.SUCCESS; genericResponse.object = new Beer ("Carlsberg"); return genericResponse.toRestResponse(); } – dynamokaj

+0

@dynamokaj: puoi inserire alcuni frammenti di codice? Puoi collegarti a github o qualche altro documento. – Sathya

+0

Sì, eccolo: https://gist.github.com/dynamokaj/cb0c0569311d9d15ee40 dovrebbe essere come il tuo. Tuttavia ho reso privati ​​i campi e l'ho inserito in un file (ResponseDto.java) invece di tre file. – dynamokaj