Как я могу отменить решения, принятые во время согласования содержимого JAX-RS? - PullRequest
5 голосов
/ 20 ноября 2011

Я использую RESTEasy 2.2.1.GA в качестве своей реализации JAX-RS для создания клиента для подключения к стороннему поставщику услуг.(REST API Education.com, если это имеет значение)

Чтобы убедиться, что я не пропустил важную деталь реализации, вот примеры кода:

Сервисный интерфейс

@Path("/")
public interface SchoolSearch {

@GET
@Produces({MediaType.APPLICATION_XML})
Collection<SchoolType> getSchoolsByZipCode(@QueryParam("postalcode") int postalCode);
}

Класс вызова

public class SimpleSchoolSearch {

public static final String SITE_URL = "http://api.education.com/service/service.php?f=schoolSearch&key=****&sn=sf&v=4";

SchoolSearch service = ProxyFactory.create(SchoolSearch.class, SITE_URL);

public Collection<SchoolType> getSchools() throws Exception {
    Collection<SchoolType> schools = new ArrayList<SchoolType>();
    Collection<SchoolType> response = service.getSchoolsByZipCode(35803);
    schools.addAll(response);
    return schools;

}
}

После настройки тестов для выполнения этого вызова я выполняю и вижу следующее исключение:

org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException: Unable to find JAXBContext for media type: text/html;charset="UTF-8"

Из прочтения документации RESTEasy / JAX-RS, насколько я понимаю, когда ответ возвращается клиенту, до демаршалинга данных, делается определение (согласование содержимого ??) о том, какой механизм использовать для демаршаллинга,(Я думаю, что мы говорим о MessageBodyReader здесь, но я не уверен.) Посмотрев на тело ответа, я вижу, что возвращается правильно отформатированный XML, , но согласование содержимого (черезТип содержимого заголовка HTTP действительно text / html; charset = "UTF-8") не позволяет анализировать текст JAXB.

Я думаю, что реализация работает правильно, и это служба, которая находится в состоянии ошибки, однако я не контролирую службу, но все равно хотел бы использовать ее.

Итаксказанное:

Правильно ли я понимаю , почему выдается исключение?

Как мне обойти это?

Существует ли простая однострочная аннотация, которая может заставить JAXB разархивировать данные, или мне нужно будет реализовать собственный MessageBodyReader?(Если это даже правильный класс для реализации).

Спасибо!

Follow Up:

Я просто хотел опубликовать несколько изменений, которые ясделал ответ Эйдена.Я создал ClientExecutionInterceptor, используя его код и информацию, доступную по Документация Resteasy ClientExecutionInterceptor .Мой последний класс выглядит как

@Provider
@ClientInterceptor
public class SimpleInterceptor implements ClientExecutionInterceptor {

@Override
  public ClientResponse execute(ClientExecutionContext ctx) throws Exception {
      final ClientResponse response = ctx.proceed();
      response.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML);
      return response;
  }
}

Большая разница заключается в добавлении аннотаций @Provider и @ClientExecutionInterceptor.Это должно обеспечить правильную регистрацию перехватчика.

Кроме того, для полноты картины я перехватил перехватчик немного иначе для своих тестов.Я использовал:

        providerFactory.registerProvider(SimpleInterceptor.class);

Ответы [ 2 ]

2 голосов
/ 22 ноября 2011

Я уверен, что есть несколько решений этой проблемы, но я могу думать только об одном.

Попробуйте установить тип содержимого с помощью ClientExecutionInterceptor:

public class Interceptor implements ClientExecutionInterceptor {

    @Override
    public ClientResponse<?> execute(ClientExecutionContext ctx) throws Exception {
        final ClientResponse<?> response = ctx.proceed();

        response
            .getHeaders()
            .putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML);

        return response;
    }

}

public void getSchools() throws Exception {
    ResteasyProviderFactory.getInstance()
        .getClientExecutionInterceptorRegistry()
        .register( new Interceptor() );

    SchoolSearch service =
            ProxyFactory.create(SchoolSearch.class, SITE_URL);
}
0 голосов
/ 21 ноября 2011

Я не знаю ни о какой подобной аннотации, другие могли бы сделать, но обходной путь должен создать локальный прокси.Создайте контроллер, который передает все параметры для education.com с помощью java.Net.URL.get (), возвращает полученный ответ, но изменяет заголовок.Затем подключите ваш клиент к локальному прокси-контроллеру.

...