2013-06-29 15 views
8

Ho un'applicazione Web AngularJS con un'applicazione di backend in Jersey.AngularJS e Jersey REST DELETE operazione non riuscita con 415 Codice di stato

Ora tutto funziona correttamente utilizzando ngResource per accedere alla risorsa REST da AngularJS. L'unico problema è con l'opzione DELETE.

Ho il seguente codice per eliminare un corso usando il mio ngResource:

Course.deleteCourse = function(course) { 
    course.$remove({ 
     courseId:course.id 
    }); 
    return course; 
}; 

Nel backend (Jersey) ho il seguente codice:

@DELETE 
@Path("{id}") 
public final void remove(@PathParam("id") final String id) { 
    System.out.println("DELETE ID = " + id); 
} 

Se cerco di eliminare un elemento il seguente url viene chiamato da Angular:

DELETE http://localhost:8080/manager-api/courses/5 

Questo va bene (dopo di me). Se chiamo questo URL da CURL, ottengo ssystem.out dal backend pubblicato sulla console.

Nel client-app (AngularJS) ottengo la seguente eccezione sulla console del browser:

DELETE http://localhost:8080/manager-api/courses/5 415 (Unsupported Media Type) 

Chiunque un'idea di cosa il problema potrebbe essere? POST + GET funzionano bene.

Ho il seguente consumano/producono annotazioni:

@Consumes({ MediaType.APPLICATION_JSON }) 

@Produces ({} MediaType.APPLICATION_JSON)

Grazie in anticipo per il vostro aiuto.

saluta Marc


EDIT:

ho cercato di sostituire il modo di accedere ai servizi REST di AngularJS con $ http.

Ora il mio servizio appare come di seguito:

MyApp.factory("Course", ["$http", function ($http) { 
var courseBaseUrl = "/api/courses/"; 

return { 
    show: function show(courseId) { 
     return $http.get(courseBaseUrl + courseId); 
    }, 
    list: function list() { 
     return $http.get(courseBaseUrl, {}); 
    }, 
    remove: function remove(courseId) { 
     return $http.delete(courseBaseUrl + courseId, {}); 
    }, 
    save: function save(course) { 
     return $http.post(courseBaseUrl, course, {}); 
    } 
}; 

}]);

Il risultato è sempre lo stesso. L'applicazione chiama per esempio

DELETE http://localhost:8080/manager-api/courses/1 

e riceve un

DELETE http://localhost:8080/manager-api/courses/1 415 (Unsupported Media Type) 

Se io chiamo la stessa chiamata CANC sulla Curl, tutto funziona bene.

Grazie per il vostro aiuto Marc

risposta

0

ho avuto lo stesso problema, prova a tornare nuova istanza dell'oggetto Corso nel metodo di eliminazione.

@DELETE 
@Path("{id}") 
public final Course remove(@PathParam("id") final String id) { 
    System.out.println("DELETE ID = " + id); 
    return new Course(); 
} 
11

mi sono imbattuto in questo pure, il problema è angolare sempre imposta l'intestazione Content-Type di xml sulle richieste DELETE e jersey sarà buttare un errore, come è stato specificato che il vostro api consuma/produce JSON con le annotazioni .

Quindi per risolvere il problema (dal lato client), impostare l'intestazione del tipo di contenuto, ad esempio:

.config(function($httpProvider) { 
    /** 
    * make delete type json 
    */ 
    $httpProvider.defaults.headers["delete"] = { 
    'Content-Type': 'application/json;charset=utf-8' 
    }; 
}) 

Tuttavia, per ragioni che non capisco/non so di, angolare metterà a nudo via il Content digita l'intestazione dalla richiesta se non ha dati. Questo avrebbe senso se non fosse per il fatto che i browser (almeno Chrome) invieranno sempre un tipo di contenuto ... Comunque dovrai andare a cercare di trovarlo nella fonte angolare:

// strip content-type if data is undefined 
    if (isUndefined(config.data)) { 
    delete reqHeaders['Content-Type']; 
    } 

e liberarsene. Non conosco un modo per farlo senza modificare la fonte. Forse qualcuno con un miglior know-how JS, ehm, sa come.


In alternativa, dal lato server, si può fare come Rob ha suggerito e modificare la configurazione Jersey per consentire consumare MediaType.APPLICATION_XML

@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) 
public final void remove(@PathParam("id") final String id) { 
    System.out.println("DELETE ID = " + id); 
} 
+1

Un'altra opzione è quella di cambiare il lato JAX-RS Jersey per consentire consumare MediaType.APPLICATION_XML ... @Consumi ({MediaType.APPLICATION_JSON,, MediaType.APPLICATION_XML}). –

+0

buon punto, aggiunto alla risposta – paullth

+0

Dove mettere ".config (funzione ($ httpProvider) ..."? –

0

Utilizzando angularjs $ risorse (invece di $ http), senza "payload" nella richiesta, il tipo di contenuto viene impostato come text/plain.

Quindi IMHO è meglio un supporto lato server. "Postel's Law afferma che si dovrebbe essere liberale in ciò che accetti e conservatore in ciò che si invia -. source"

@DELETE 
@Path("{id}") 
@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN }) 
public void remove(@PathParam("id") Long id) { ... 
Problemi correlati