Как Jersey / Jax-RS выбирает правильный метод в ресурсе
Я использую последнюю версию Jersey для сервера API. Я определил следующий ресурс:
@javax.ws.rs.Path("/myPath")
public class MyResource {
@GET
@Consumes({MediaType.WILDCARD, MediaType.TEXT_PLAIN, MediaType.TEXT_HTML})
@Produces(MediaType.TEXT_PLAIN)
public Response method1(@Context Request request) {
}
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public MyObject method2() {}
}
Теперь предположим, что я вызываю этот ресурс со следующим заголовком:
<header>
<name>Accept</name>
<value>text/html, application/xhtml+xml, */*</value>
</header>
Как Джерси знает, какой из них соответствует в этом случае, когда ни один метод Producer
аннотации не соответствует?
Я спрашиваю, потому что один раз сервер ответил на method2 и после перезагрузки он ответил на method1.
2 ответа:
<header> <name>Accept</name> <value>text/html, application/xhtml+xml, */*</value> </header>
Я не знаю, что это такое; заголовки не отправляются в XML, но если предположить, что вы отправили заголовок правильно, вот как он разбивается.
@Produces
обрабатывает ЗаголовокAccept
, а@Consumes
обрабатывает заголовок клиентаContent-Type
, когда клиент отправляет данные. Итак, давайте посмотрим на ваши две аннотации@Produces
против заголовкаAccept
Так что ни один из них не имеет@Produces(MediaType.TEXT_PLAIN) public Response method1() {} @Produces(MediaType.APPLICATION_JSON) public MyObject method2() {} text/html, application/xhtml+xml, */*
text/html
, так что вычеркните это. Ни один из них не имеетapplication/xhtml+xml
, так что вычеркните это. Остается только*/*
, что означает " пошли меня что угодно". Так что Джерси волен выбирать, какой именно. Результаты непредсказуемы. Вы не можете делать никаких предположений по этому поводу.И это вина клиента. Не наша. Клиент должен отправить правильный заголовок. Или, может быть, нам следует лучше документировать наш API, чтобы клиент знал, какие типы мы можем производить : -)
Я столкнулся с тем же вопросом, где я должен методы с конкретными
@Produces()
аннотациями. Этот трюк работает:@Produces(MediaType.APPLICATION_JSON) public Response method1() {} @Produces({MediaType.TEXT_PLAIN, "*/*;q=0"}) public Response method2() {}
При использовании типов MIME можно добавить свойство
Это своего рода Хак, поэтому я не знаю, останется ли он работать, но он помог мне.q
, которое указывает приоритет (от 0 до 1). Отсутствие свойстваq
подразумевает 1, но, по-видимому, Хитростьq=0
заключается в использовании другой функции.