【发布时间】:2011-11-19 22:51:12
【问题描述】:
我使用 RESTEasy 2.2.1.GA 作为我的 JAX-RS 实现来创建客户端以连接到第三方服务提供商。 (如果重要,Education.com 的 REST API)
为了确保我没有错过重要的实现细节,这里提供了代码示例:
服务接口
@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? (如果这甚至是要实现的正确类)。
谢谢!
跟进:
我只是想发布我对 Eiden 的回答所做的一些更改。我使用他的代码和Resteasy ClientExecutionInterceptor documentation 提供的信息创建了一个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);
【问题讨论】: