2009-09-27 10 views
1

Je viens de commencer à utiliser Jersey pour créer une API RESTful pour mon site. C'est un changement merveilleux d'avoir à rouler mon propre support pour les services RESTful en Java. Une chose que je n'arrive tout simplement pas à comprendre est comment "simuler" une méthode DELETE et PUT.Quelle est la meilleure façon de "fausser" les méthodes DELETE et PUT en utilisant JAX-RS?

Jersey prend en charge les annotations @PUT et @DELETE, mais de nombreux Load-Balancers ne permettent pas ces méthodes. Dans le passé, je me suis basé sur la possibilité de définir un en-tête HTTP personnalisé (par exemple x-method-override: DELETE) et "tunneling" dans une requête POST.

Est-ce que quelqu'un a trouvé un moyen de lier une méthode en utilisant les annotations Jersey/JAX-RS aux en-têtes personnalisés? Sinon, existe-t-il un meilleur moyen de contourner le manque de support pour PUT et DELETE?

Répondre

2

Eh bien voici comment j'ai décidé de gérer la situation au sein de mon API. C'est relativement simple et ne nécessite pas beaucoup de codage supplémentaire. Pour illustrer envisager une api RESTful pour Adresse:

@Path("/address") 
public class AddressService { 

    @GET 
    @Produces("application/xml") 
    public StreamingOutput findAll() { ... } 

    @POST 
    @Produces("application/xml") 
    @Consumes("application/x-www-form-urlencoded") 
    public StreamingOutput create(...) { ... } 

    // 
    // This is the alternative to a "PUT" method used to indicate an "Update" 
    // action. Notice that the @Path expects "/id/{id}" which allows 
    // us to bind to "POST" and not get confused with a "Create" 
    // action (see create() above). 
    // 
    @POST 
    @Produces("application/xml") 
    @Consumes("application/x-www-form-urlencoded") 
    @Path("/id/{id}") 
    public StreamingOutput update(@PathParam("id") Long id, ...) { ... } 

    // 
    // This is the typical "GET" method with the addition of a check 
    // for a custom header "x-method-override" which is designed to 
    // look for inbound requests that come in as a "GET" but are 
    // intended as "DELETE". If the methodOverride is set to "DELETE" 
    // then the *real* delete() method is called (See below) 
    // 
    @GET 
    @Produces("application/xml") 
    @Path("/id/{id}") 
    public StreamingOutput retrieve(
     @PathParam("id") Long id, 
     @HeaderParam("x-method-override") String methodOverride) 
    { 
     if (methodOverride != null && methodOverride.equalsIgnoreCase("DELETE")) { 
     this.delete(id); 
     } 

     ... 
    } 


    // 
    // This is the typical "DELETE" method. The onlything special about it is that 
    // it may get invoked by the @GET equivalent is the "x-method-override" header 
    // is configured for "DELETE" 
    // 
    @DELETE 
    @Produces("application/xml") 
    @Path("/id/{id}") 
    public StreamingOutput retrieve(@PathParam("id") Long id) { ... } 

}

+2

Salut. D'abord une petite chose: la méthode delete s'appelle 'retrieve'. Ne serait-il pas préférable d'utiliser POST au lieu de GET pour un faux DELETE puisque la requête GET doit toujours être sûre. Autre chose: est-il possible d'utiliser de fausses suppressions et mises à l'intérieur de formulaires HTML? Il n'y a aucun moyen d'ajouter l'en-tête x-method-override. La seule chose possible est un champ '_method' caché dans le formulaire. –

+0

Points forts. Je n'ai vraiment pas trouvé de meilleure solution à ce stade. Les éléments de formulaire masqués sont très limités, car de nombreux messages contiennent des paramètres de formulaire XML ou codés. Cela dit, la plupart de mes services RESTful sont invoqués via XMLHTTPRequest (ou indirectement via des frameworks comme JQuery). La configuration des en-têtes est donc très simple et toujours possible. Pour cette raison principalement je reste avec ma solution. – ra9r

1

Il est plus vraiment repos, mais dans une situation similaire, nous avons défini POST/collection/à insérer (comme d'habitude), POST/collection/{id} pour être mis à jour, POST/collection/{id} sans body à supprimer.

Questions connexes