Как 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 3

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 заключается в использовании другой функции.

Это своего рода Хак, поэтому я не знаю, останется ли он работать, но он помог мне.