Qual é a melhor maneira de “falsos” métodos excluem e colocar usando JAX-RS?
-
18-09-2019 - |
Pergunta
Eu apenas comecei a usar Jersey para criar uma API RESTful para o meu site. É uma mudança maravilhosa de ter que fazer a minha própria suporte para serviços RESTful em Java. Uma coisa que eu simplesmente não consigo descobrir é como "fake" um método de exclusão e PUT.
Jersey suporta as anotações @PUT e @Delete, no entanto muitos balanceadores de carga não vai permitir que esses métodos através. No passado, eu tenho contado com a capacidade de definir um costume cabeçalho HTTP (por exemplo, x-método-override: delete). E "tunneling" dentro de um pedido POST
Alguém já encontrou uma maneira de vincular um método utilizando Jersey / JAX-RS anotações para cabeçalhos personalizados? Como alternativa, há uma maneira melhor em torno falta de suporte para PUT e DELETE?
Solução
Bem, aqui é como eu decidi lidar com a situação dentro do meu API. faz o seu relativamente simples e não exigem muito codificação adicional. Para ilustrar considerar uma API RESTful para Endereço:
@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) { ... }
}
Outras dicas
Não é realmente DESCANSAR mais, mas em uma situação semelhante definimos POST / coleção / ser inserção (como normal), POST / coleta / {id} para ser atualização, POST / coleta / {id} sem corpo para ser excluir.