问题描述
我正在使用 microprofile 3.2 来调用在响应实体中返回 java bean 的休息 web 服务。当我尝试从响应中提取 bean 时,虽然我得到了一个
java.lang.classCastException: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream incompatible with <class>
错误。
例如
我的豆子:
public class MyBean {
private int id;
public int getId() { return id; }
public void setId(final int id) { this.id = id; }
}
REST WS api 接口:
@GET
@Path("/{id}")
Response getBean(@PathParam("id") Integer id);
REST 实现类:
public Response getBean(final Integer id) {
MyBean myBean = new Service().getBean(id);
return Response.ok(myBean).build();
}
RestClient:
IBeanResource beanResource =
RestClientBuilder.newBuilder().baseUri(apiURI).build(IBeanResource.class);
Response beanResponse = beanResource.getBean(100);
if (beanResponse.getStatus() == Response.Status.OK.getStatusCode()) {
MyBean bean = (MyBean) beanResponse.getEntity();
}
在线触发错误
MyBean bean = (MyBean) beanResponse.getEntity();
有人见过这个吗?文档不是很好。
解决方法
是的,这将是预期的行为。如果您在调试中检查 beanResponse
的值,您将看到 Response 的类型为 InboundJaxrsResonse
,而 entity 的类型仅为 HttpUrlConnector
。这就是为什么当您尝试将其强制转换为自定义 bean 类时,它会抛出 ClassCastException
。您可以尝试以下任何一种方法:
-
你可以改为如下
String jsonString = beanResponse.readEntity(String.class);
以上内容将以字符串形式为您提供 JSON 响应,然后您可以使用您选择的 gson 或 jackson 等库将其转换为您各自的类。
- 在您的 REST WS api 接口中,而不是返回
Response
返回您的模型MyBean
。根据 Microprofile rest Client 规范,Microprofile Rest 客户端的实现必须提供内置的 JSON-P 实体提供程序,如果它支持 JSON-B,则必须提供 JSON-B 实体提供程序。
microprofile-rest-client-spec-2.0
,谢谢回复。我将再次查看返回模型的规范。我喜欢捕获响应而不是模型的想法,所以我也有任何标题或状态信息,例如找不到资源怎么办404?
我能够通过读取 InputStream 并使用 jsonb 绑定到 bean 来解决这个问题
InputStream is = (InputStream) beanResponse.getEntity();
return jsonb.fromJson(is,MyBean.class);