Web services Jersey客户端请求中的多个返回类型
我以以下方式使用Jersey客户端API:-Web services Jersey客户端请求中的多个返回类型,web-services,rest,client,jersey,Web Services,Rest,Client,Jersey,我以以下方式使用Jersey客户端API:- User user = webRsrc.accept(MediaType.APPLICATION_XML).post(User.class, usr); 因此,我期望用户类的对象中出现响应,这是一个JAXB注释类。 然而,有时我也会得到一个错误xml,为此我创建了一个JAXB类ErrorResponse 现在的问题是,如果我的请求返回一个ErrorResponse对象而不是User,我该如何处理 我试过这样- ClientResponse resp
User user = webRsrc.accept(MediaType.APPLICATION_XML).post(User.class, usr);
因此,我期望用户类的对象中出现响应,这是一个JAXB注释类。
然而,有时我也会得到一个错误xml,为此我创建了一个JAXB类ErrorResponse
现在的问题是,如果我的请求返回一个ErrorResponse对象而不是User,我该如何处理
我试过这样-
ClientResponse response=null;
try {
response = webRsrc.accept(MediaType.APPLICATION_XML).post(ClientResponse.class,usr);
User usr = response.getEntity(User.class);
}catch(Exception exp)
{
ErrorResponse err = response.getEntity(ErrorResponse.class);
}
但当我尝试在catch块中使用getEntity()时,它会引发以下异常
[org.xml.sax.SAXParseException: Premature end of file.]
at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.readFrom(AbstractRootElementProvider.java:107)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:532)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:491) .....
似乎在调用getEntity()一次之后,inputstream就耗尽了。我认为您在整个“休息思维方式”中遗漏了一点。
简短回答:是的,您只能调用getEntity一次。您需要检查返回的HTTP状态,以了解应该获得哪个实体 在服务器端:
ClientResponse response=null;
response = webRsrc.accept(MediaType.APPLICATION_XML).post(ClientResponse.class,usr);
int status = response.getStatus();
if (Response.Status.OK.getStatusCode() == status) {
// normal case, you receive your User object
User usr = response.getEntity(User.class);
} else {
ErrorResponse err = response.getEntity(ErrorResponse.class);
}
注意:根据返回的状态代码,此错误可能非常不同(因此需要非常不同的行为):
- 客户端错误40X:您的客户端请求错误
- 服务器错误500:服务器端发生意外错误
protected <T> T call(String uri, Class<T> c) throws BusinessException {
WebResource res = new Client().create().resource(url);
ClientResponse cresp = res.get(ClientResponse.class);
InputStream respIS = cresp.getEntityInputStream();
try {
// Managing business or error response
JAXBContext jCtx = JAXBContext.newInstance(c, BeanError.class);
Object entity = jCtx.createUnmarshaller().unmarshal(respIS);
// If the response is an error, throw an exception
if(entity instanceof BeanError) {
BeanError error = (BeanError) entity;
throw new BusinessException(error);
// If this not an error, this is the business response
} else {
return (T) entity;
}
} catch (JAXBException e) {
throw(new BusinessException(e));
}
}
protectedt调用(字符串uri,类c)引发BusinessException{
WebResource res=new Client().create().resource(url);
ClientResponse cresp=res.get(ClientResponse.class);
InputStream respIS=cresp.getEntityInputStream();
试一试{
//管理业务或错误响应
JAXBContext jCtx=JAXBContext.newInstance(c,BeanError.class);
对象实体=jCtx.createUnmarshaller().unmarshal(respIS);
//如果响应是错误,则引发异常
if(实体实例的BeanError){
BeanError=(BeanError)实体;
抛出新的BusinessException(错误);
//如果这不是错误,则这是业务响应
}否则{
返回(T)实体;
}
}捕获(JAXBEException e){
抛出(新业务异常(e));
}
}
如果无法更改服务器代码,可以使用ReaderInterceptor
。这确实有一些限制,但至少可以获取错误响应对象的内容
我使用的是JSON,但同样的原则也适用:
public class MyException extends RuntimeException {
private final ErrorResponse content;
public MyException(ErrorResponse content) {
this.content = content;
}
public ErrorResponse getContent() {
return content;
}
}
public class ErrorResultInterceptor implements ReaderInterceptor {
private static final ObjectReader JSON = new ObjectMapper().readerFor(ErrorResponse.class);
@Override
public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
byte[] buffer = context.getInputStream().readAllBytes();
context.setInputStream(new ByteArrayInputStream(buffer));
try {
return context.proceed();
} catch (UnrecognizedPropertyException ex) {
try {
throw new MyException(JSON.readValue(buffer));
} catch (IOException errorProcessingEx) {
// Log errorProcessingEx using your preferred framework
throw ex;
}
}
}
}
然后将其用作调用的一部分:
client.register(ErrorResultInterceptor.class);
// Oher client setup
try {
// Make the client call
// Handle OK case
} catch (ResponseProcessingException ex) {
if (ex.getCause() instanceof MyException) {
ErrorResponse respone = ((MyException)ex.getCause()).getContent();
// Handle error response
} else {
throw ex;
}
}
限制是:
- 必须缓冲响应,这可能是内存开销
- 获取错误结果的客户端调用非常笨拙