2012-03-12 12 views
7

Sto lavorando su un frontend JavaScript abilitato per AJAX che effettua chiamate a un backend Java scritto con Struts. Il mio problema è che quando il backend lancia un'eccezione, il client vede ancora un codice di risposta HTTP "200 OK" invece di "500 Internal Server Error" come ci si aspetterebbe.Making Struts invia 500 Internal Server Error quando vengono lanciate eccezioni

Questo mi è inciampare ripetutamente perché il mio cliente 3rd-party libreria JavaScript dipende codici di stato HTTP per determinare se qualcosa non va con una chiamata AJAX, come la maggior parte delle biblioteche moderne normalmente. Gli errori passano inosservati fino a quando il mio codice esplode quando tenta di analizzare quello che normalmente sarebbe JSON.

Voglio davvero evitare di hackerare la libreria JS del mio client per gestire con grazia questi errori. Allora, come posso far sì che Struts mi dia un codice di stato di 500 quando c'è un'eccezione non gestita nel back-end? Non dovrebbe questo essere il comportamento predefinito di Struts?

Modifica: In questo caso il codice lato client è irrilevante. Ho bisogno di riparare il server in modo che invii il codice di stato appropriato quando si verificano eccezioni non gestite. Grazie!

risposta

3

ho capito un modo per farlo. Non sono sicuro che sia il migliore o il più semplice, ma funziona. Ho trovato i Struts Exception Configuration guide e ha aggiunto il seguente al mio <package> all'interno struts.xml:

<global-results> 
    <result name="exception">/exception.jsp</result> 
</global-results> 

<global-exception-mappings> 
    <exception-mapping exception="java.lang.Exception" result="exception" /> 
</global-exception-mappings> 

Questo fa sì che tutte le eccezioni non gestite per essere reindirizzati al /exception.jsp. E qui ci sono i contenuti del JSP:

<%@ taglib prefix="s" uri="/struts-tags" %> 
<%@ page contentType="application/json; charset=UTF-8" %> 
<% response.setStatus(500); %> 
{"success": false,"errors": "<s:property value="%{exception.message}"/>"} 

noterete al 3 ° linea che ho impostato manualmente il codice di risposta a 500.

Questo mi ha dato un nuovo problema: le eccezioni non venivano registrati più . Come suggerito nella guida Struts suddetto, ho risolto questo aggiungendo questo al <package> in struts.xml così:

<interceptors> 
    <interceptor-stack name="appDefaultStack"> 
     <interceptor-ref name="defaultStack"> 
      <param name="exception.logEnabled">true</param> 
      <param name="exception.logLevel">ERROR</param> 
     </interceptor-ref> 
    </interceptor-stack> 
</interceptors> 

<default-interceptor-ref name="appDefaultStack" /> 

Puntoni: -1 per fare un NOT caratteristica così semplice ed evidente difetto, e un altro -1 per aver reso la soluzione così ottusa.

-1

Non hai menzionato quale libreria JS stai usando. Suggerirei di leggere attentamente la documentazione. Se ha qualche tipo di metodo di callback, deve avere un numero responseText diverso da responseCode. Ogni volta che accade qualche eccezione di validazione sul lato server, passa anche un messaggio di errore. Basta non fare affidamento su alcune eccezioni, perché stai usando AJAX. Puoi tenere traccia di quello responseText per mostrare alcuni messaggi come "convalida fallita per questo motivo, per favore riprova". Essere d'accordo ?

Altrimenti gettare WebApplicationException prima che la risposta è impegnata:

throw new javax.ws.rs.WebApplicationException(); // or by any other constructor 

Ecco la jar

+0

La libreria sul lato client è ExtJS ma non importa. Il server è ciò che sta avendo il problema. Struts invia un report di errore HTML e un codice di stato "200 OK" quando c'è un'eccezione non gestita sul lato server, ed è quello che sto cercando di risolvere. L'HTML che posso gestire, ma Struts deve essere in grado di inviare il codice 500 quando si verificano errori, non il codice 200. Grazie! – curtisdf

+0

'WebApplicationException()' provoca un codice di errore HTTP 500. hai provato a lanciare questo? – tusar

+0

Sul lato server, voglio evitare di dover inserire try/catch blocchi ovunque. Ho solo bisogno di un qualche tipo di configurazione che indichi a Struts, "fai la cosa giusta (tm) e dammi un codice di risposta 500 ogni volta che invii questi stupidi rapporti sui problemi". – curtisdf

0

L'errore del server interno 500 è un errore lato server, il che significa che il problema probabilmente non è con il computer o la connessione Internet, ma è invece un problema con il server del sito web.

Si noti che è necessario gestirlo dal lato client. Si trova sul server Web (server HTTP) configurato nella gestione delle richieste.

+0

-1. Penso che dal modo in cui ho scritto la mia domanda, è chiaro che ho già capito cosa sia un errore di 500 server interno, così come la natura delle interazioni client-server. Stavo cercando informazioni su come far funzionare Struts (sul mio server) come volevo. – curtisdf

2

Aggiornamento: ho messo a posto la sezione <global-results> (che mancava il tag httpheader)

mi piace your solution meglio, ma qui è un altro modo si potrebbe farlo se non si vuole pasticciare w/impostazione dell'intestazione della risposta nel jsp.

  1. In struts.xml, creare una mappatura globale delle eccezioni da "java.lang.Exception" ad un risultato di nome "eccezione"
  2. In struts.xml, creare un risultato globale che mappa "eccezione" ad un httpheader risultato con un valore di 500.
  3. In web.xml, creare una voce di errore che associa il codice di errore 500 alla posizione della pagina di errore.

Così, per struts.xml:

<global-exception-mappings> 
    <exception-mapping exception="java.lang.Exception" result="exception" /> 
</global-exception-mappings> 

<global-results> 
    <result name="exception" type="httpheader"> 
     <param name="error">500</param> 
    </result> 
</global-results> 

E per web.xml

<error-page> 
    <error-code>500</error-code> 
    <location>/exception.jsp</location> 
</error-page> 

Questo funziona, ma ha alcuni grossi svantaggi. Il contenitore servlet sta visualizzando la tua pagina di errore (non struts) in modo che tu non abbia accesso al messaggio di errore originale o allo stack valueStack. Tuttavia, la registrazione delle eccezioni funzionerà comunque (se è stata abilitata).

Per inciso, anch'io trovo sconcertante che i montanti lo rendano così difficile. In ogni altro framework mi sono occupato del concetto di restituire una pagina di errore e un codice di errore è piuttosto semplice da implementare.

Problemi correlati