我从正文中包含HTTP
的外部服务器收到XML
响应。
但是,响应标题显示为Content-Type:plain/text
这是不正确的,应该是application/xml
。但是,正如我所说,它是一个我们无法改变的外部服务器。
以下代码给出错误:
ClientResponse response = Client.create().resource(url).get(ClientResponse.class);
return response.getEntity(XmlResponse.class);
例外:
com.sun.jersey.api.client.ClientHandlerException:邮件正文 reader for com class com.evs.ats.XmlResponse和Java type class com.evs.ats.XmlResponse,找不到MIME媒体类型text / plain
以下代码有效,但我不喜欢它:
String resultString = response.getEntity(String.class);
InputStream stream = new ByteArrayInputStream(
resultString.getBytes(StandardCharsets.UTF_8)
);
JAXBContext jc = JAXBContext.newInstance(XmlResponse.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
return (XmlResponse) unmarshaller.unmarshal(stream);
有没有办法强迫"强迫"无论如何,泽西岛将其视为XML
?或者是我唯一可以使用JAXB
手动解组它(如上所述)?或者还有其他选择吗?
答案 0 :(得分:0)
如果您连接的上游服务器在Content-Type
HTTP标头字段中返回错误的值,并且无法“推理”(以修复返回的值),则没有其他方法(AFAIK)除了提供您自己的MessageBodyReader
的自定义实现。
使用泽西2 进行此操作的一种方法是:
public class TextAsXmlMessageBodyReader implements MessageBodyReader<Object> {
@Override
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return mediaType.getType().equals("text")
&& mediaType.getSubtype().equals("plain");
}
@Override
public Object readFrom(Class<Object> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException, WebApplicationException {
try {
final JAXBContext jc = JAXBContext.newInstance(type);
final Unmarshaller unmarshaller = jc.createUnmarshaller();
return unmarshaller.unmarshal(entityStream);
} catch (JAXBException e) {
throw new WebApplicationException("Error while unmarshalling the response.", e);
}
}
}
然后只需在您正在使用的Jersey客户端注册此课程。如果您在整个应用程序中使用相同的客户端实例,则可以为每个目标注册自定义消息体读取器(因此,如果您碰巧有其他上游服务器,则不会将其用于其他“理智”服务器的响应)你正在与之交流)。注册目标的示例:
return ClientBuilder.newClient() // Get a client; does not have to be a *new* client
.target(url) // Target the client to the particular upstream URL
.register(TextAsXmlMessageBodyReader.class) // Register the reader as described
.request() // Start building a request
.get(XmlResponse.class); // Issue a GET request (can be any HTTP method actually)
拥有自定义阅读器实现的优势在于,可以编写精简的简化代码,专注于配置和发出请求,获取响应以及在需要时进行处理。此外,如果您需要针对目标服务器上的不同资源发出请求(并且所有资源都指定了错误的Content-Type
),则可以重用读者实现。