Каков наилучший способ “подделать” методы УДАЛЕНИЯ и размещения с использованием JAX-RS?
-
18-09-2019 - |
Вопрос
Я только начал использовать Джерси чтобы создать RESTful API для моего сайта.Это замечательное отличие от необходимости внедрять собственную поддержку RESTful services на Java.Одна вещь, которую я просто не могу понять, - это как "подделать" метод УДАЛЕНИЯ и помещения.
Джерси поддерживает аннотации @PUT и @DELETE, однако многие балансировщики нагрузки не пропускают эти методы.В прошлом я полагался на возможность определения пользовательского HTTP-заголовка (напримерx-метод-переопределение:УДАЛИТЬ) и "туннелирование" внутри POST-запроса.
Кто-нибудь нашел способ привязать метод, использующий аннотации Jersey / JAX-RS, к пользовательским заголовкам?В качестве альтернативы, есть ли лучший способ обойти отсутствие поддержки PUT и DELETE?
Решение
Что ж, вот как я решил справиться с ситуацией в моем API.Это относительно просто и не требует большого дополнительного кодирования.Чтобы проиллюстрировать это, рассмотрим RESTful api для Address:
@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) { ... }
}
Другие советы
На самом деле это больше не REST, но в аналогичной ситуации мы определили POST / collection / для вставки (как обычно), POST / collection /{id} для обновления, POST / collection /{id} без тела для удаления.