2014-12-26 12 views
10
@Provider 
public class JerseyExceptionMapper implements ExceptionMapper<JerseyException> { 


    @Override 
    public Response toResponse(JerseyException jerseyException) { 
     return Response.status(jerseyException.getErrorCode()). 
       entity(jerseyException.getJsonResponseObj()). 
       type(MediaType.APPLICATION_JSON). 
       build(); 
    } 

} 

Il codice ha sopra i risultati indesiderati quando si utilizza un componente <error-page> nel web.xml. Ad esempio, se il mio Response.status è impostato su 400 e il mio componente error-page definisce un <error-code> di 400, il server Web reindirizzerà la richiesta alla posizione definita nello web.xml.Ignorando web.xml errore-page con Jersey ExceptionMapper

Questo ovviamente non è quello che voglio per le richieste REST. Ho letto un altro post su StackOverflow che diceva che la ragione per cui una richiesta viene trasferita allo error-page è perché è impostato HttpServletResponse.sendError(400). Quel post diceva che se si imposta HttpServletResponse.setStatus(400) invece, lo error-page verrà ignorato.

Se ciò è vero, non vedo come sia utile poiché non ho implementato il codice Jersey. L'opzione che sto vedendo è di investigare il codice sorgente della classe Response e possibilmente re-implementare il metodo dello status o forse altro codice di Jersey. C'è una semplice opzione qui o qualcosa che mi manca?

In sostanza, la mia domanda è: Dato che sto usando Jersey per il riposo e sto usando error-page nel mio web.xml, come posso utilizzare il codice di cui sopra, mentre ignorando l'error-page solo per il codice Jersey? Qualsiasi altro codice che causa errori HTTP dovrebbe andare a error-page. O c'è un'altra soluzione che non coinvolge error-page ma funzionerà esattamente come voglio?

+0

Quali servlet container sono voi usando? questo potrebbe essere correlato a https://java.net/jira/browse/JERSEY-2673 –

+0

I Impossibile riprodurre questo problema (glassfish 4 jersey 2.13). 1) Che cosa è 'JerseyException'? 2) Hai controllato se il mapper è stato chiamato? 3) Per fare questo, ho semplicemente fatto una classe 'JerseyException' estendere' WebApplicationException' e l'ho lanciata da un metodo di risorsa. 4) Se il 3. non funziona per te, puoi fornire ulteriori informazioni per riprodurre questo, come l'ambiente, la versione di Jersey, Server, dove viene lanciata l'eccezione. –

risposta

3

Posso riprodurre il problema, ma solo se passo uno null come contenuto di entità.

Esempio:

return Response.status(400) 
     .entity(null) 
     .type(MediaType.APPLICATION_JSON) 
     .build(); 

o anche

return Response.status(400) 
     .type(MediaType.APPLICATION_JSON) 
     .build(); 

Entrambi si tradurrà in un reindirizzamento all'errore-pagina che è impostato per il codice di stato HTTP 400 perché il contenitore utilizzerà il Metodo sendError() se non viene specificato il contenuto del messaggio.

Ma se lo si fa in questo modo:

return Response.status(400) 
     .entity("An error occured.") 
     .type(MediaType.APPLICATION_JSON) 
     .build(); 

o questo:

return Response.status(400) 
     .entity("") 
     .type(MediaType.APPLICATION_JSON) 
     .build(); 

contenitore/Maglia userà solo il metodo setStatus() e non reindirizzerà l'errore-pagina. Come indicato nei documenti:

Questo metodo viene utilizzato per impostare il codice di stato restituito in assenza errore (ad esempio, per lo stato SC_OK o SC_MOVED_TEMPORARILY codici).

Se questo metodo viene utilizzato per impostare un codice di errore, il meccanismo della pagina di errore del contenitore non verrà attivato. Se c'è un errore e il chiamante desidera richiamare una pagina di errore definita nell'applicazione web , quindi sendError (int, java.lang.String) deve essere utilizzato .

Quindi nel tuo caso il problema sembra essere il fatto che i rendimenti jerseyException.getJsonResponseObj()null. È necessario implementare un controllo null per evitare questo.

C'è il bug JERSEY-1557 per Jersey 1.x che descrive il problema, è stato chiuso senza una correzione ma con il consiglio di utilizzare una stringa di entità vuota come soluzione alternativa.
C'è anche un simile bug aperto per Jersey 2.x: JERSEY-2673

Vedi anche:

+0

Ho intenzione di darti la taglia perché hai dato buone informazioni. Tuttavia, penso che ciò che è accaduto nel mio caso (che non avevi modo di sapere) è un'eccezione generata dal metodo entity() perché non è stato trovato alcun MessageBodyWriter. Questa eccezione deve aver causato il richiamo del metodo errorCode. Una volta che ho incluso genson JAR nel mio progetto, non ho più questi errori. – KyleM