Domanda

sto lavorando su un servizio web RESTful in Java. Ho bisogno di un buon modo per inviare i messaggi di errore al client, se qualcosa non va.

Secondo la Javadoc , HttpServletResponse.setStatus(int status, String message) è deprecato " a causa di significato ambiguo del parametro messaggio ".

C'è un modo preferito per impostare il messaggio di stato o " motivo frase " della risposta? Il metodo sendError(int, String) non lo fa.

EDIT: Per chiarire, voglio modificare la riga di stato HTTP, cioè "HTTP/1.1 404 Not Found", non il contenuto del corpo. In particolare, vorrei inviare le risposte come "HTTP/1.1 400 Missing customerNumber parameter".

È stato utile?

Soluzione

Non credo che qualsiasi client RESTful si aspetterebbe a guardare il motivo frase per capire cosa è andato storto; maggior parte dei servizi RESTful che ho visto / usato invierà informazioni di stato standard ed un messaggio espanso nel corpo della risposta. sendError(int, String) è l'ideale per quella situazione.

Altri suggerimenti

Se si utilizza Tomcat, vedere l'org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER impostazione:

http://tomcat.apache.org/tomcat-5.5 -doc / config / systemprops.html

  • Se questo è vero messaggi di stato HTTP personalizzati saranno utilizzati all'interno di intestazioni HTTP. Gli utenti devono assicurare che tale messaggio è ISO-8859-1 codificato, in particolare se l'utente fornito in ingresso è incluso nel messaggio, per evitare una possibile vulnerabilità XSS. Se non specificato verrà utilizzato il valore predefinito false.

Si veda questa pagina per alcuni dettagli sulla vulnerabilità originale:

http://www.securityfocus.com / archivio / 1 / filmati / 1/495021/100/0 / filettato

Dopo il chiarimento, ho provato questo in Tomcat. Esecuzione

response.sendError(HttpServletResponse.SC_BAD_REQUEST, "message goes here");

ritorna

HTTP/1.1 400 message goes here

come la prima linea nella risposta.

Ci deve essere un problema con il servlet container che si sta utilizzando.

Io non sono molto familiarità con le 'migliori pratiche' in giro per REST. Ma so che il concetto è basato su HTTP e come dovrebbe funzionare in modo naturale. Così come su utilizzando un tipo MIME e testo semplice all'interno del corpo per un errore di applicazione, come 'application / myapp-eccezione' e un po 'Bla bla'? È possibile fornire una libreria client per questo.

Non vorrei usare codici di risposta HTTP per errori di applicazione. Perché mi piace sapere cosa sta mancanza di:. Se è la mia applicazione o il mio server HTTP

(spero, ci vediamo alcuni consigli migliori pratiche anche qui.)

Non è proprio chiaro cosa si sta cercando di realizzare. Il mio primo pensiero è stato il sendError ma dire che non fa ciò che si vuole ... Hai guardato la creazione di una serie di "risposte di errore", che significa XML specifico o il contenuto JSON (o qualsiasi altra cosa che si sta utilizzando come lingua di trasferimento), che contiene il messaggio di errore o codice e ogni altra informazione utile?

Ho fatto qualcosa di simile per la primavera-MVC servizi RESTful basati un po 'indietro e ha funzionato bene, ma si deve praticamente cattura e gestire ogni eccezione per mantenere il cliente di ottenere un messaggio generico 500 o qualcosa del genere. I resolver Primavera eccezione funzionato bene per questo.

Spero che questo aiuti ... se non, forse un po 'più di chiarezza su ciò che si sta cercando di realizzare. Scusate se io sia denso e manca qualcosa di ovvio.

Credo che la sendError dovrebbe farlo, ma il server di applicazione può mancherei ... IBM WebSphere 3.5 fallito su di me molto tempo fa, mentre Tomcat avrebbe propagare il messaggio più che bene; vedi JavaServer Pages (JSP) e JSTL - Pagina di errore: preservare header "HTTP / 1.x 400 il mio messaggio "? sui forum sole.

Alla fine ho usato la seguente soluzione, ma questo è una specie di JSP specifici, e può in effetti essere antiche:

<%@ page isErrorPage="true" %>
<%
    // This attribute is NOT set when calling HttpResponse#setStatus and then
    // explicitely incuding this error page using RequestDispatcher#include()
    // So: only set by HttpResponse#sendError()
    Integer origStatus = 
        (Integer)request.getAttribute("javax.servlet.error.status_code");
    if(origStatus != null) {
        String origMessage = 
            (String)request.getAttribute("javax.servlet.error.message");
        if(origMessage != null) {
            response.reset();
            response.setContentType("text/html");
            // deprecated, but works:
            response.setStatus(origStatus.intValue(), origMessage); 
            // would yield recursive error:
            // response.sendError(origStatus, origMessage); 
        }
    }
%>

E se vi capita di testare con Internet Explorer: "Mostra i messaggi di errore HTTP" disabilitare. (Quando non è invalidante che, IE ha qualche requisito dispari di una certa lunghezza minima del contenuto HTML che, se non ha incontrato, avrebbe -o volontà- rendere IE mostrare il proprio messaggio di errore. Si veda anche la HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\ErrorThresholds chiave di registro di Microsoft di Descrizione di Hypertext Transport Protocol messaggi di errore .)

In applicazione web alimentato primavera, in esecuzione su Tomcat ho utilizzare i seguenti bean:

import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.springframework.beans.factory.InitializingBean;

public class SystemPropertiesInitializingBean implements InitializingBean {

    private Map<String, String> systemProperties;

    @Override
    public void afterPropertiesSet() throws Exception {
        if (null == systemProperties || systemProperties.isEmpty()) {
            return;
        }

        final Set<Entry<String, String>> entrySet = systemProperties.entrySet();
        for (final Entry<String, String> entry : entrySet) {

            final String key = entry.getKey();
            final String value = entry.getValue();

            System.setProperty(key, value);
        }

    }

    public void setSystemProperties(final Map<String, String> systemProperties) {
        this.systemProperties = systemProperties;
    }

}

E in applicationContext.xml:

<bean class="....SystemPropertiesInitializingBean">
    <property name="systemProperties">
        <map>
            <entry key="org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER" value="true"/>
        </map>
    </property>
</bean>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top