自定义 Jersey 错误处理,如何在客户端捕获响应?
Custom Jersey Error Handling, how to catch response at client side?
我正在我的网络服务上尝试一些自定义错误处理。在我的网络服务中,我创建了一个自定义异常 class 扩展 WebApplicationException ,如 JAX-RS / Jersey how to customize error handling? 中所述:
public class InternalServerErrorException extends WebApplicationException {
public InternalServerErrorException(String message) {
super(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.header("errorMessage", message).type(MediaType.TEXT_PLAIN).build());
System.out.println(message);
}
}
为了测试,我有一个简单的国家/地区服务,它提供了国家/地区列表。我确保会发生错误以测试 InternalServerErrorException:
的抛出
@GET
@Override
@Path("countries")
@Produces({"application/xml"})
public List<Country> findAll() {
try {
int i = Integer.parseInt("moo"); //<-- generate error
List<Country> countries = super.findAll();
return countries;
} catch (Exception ex) {
throw new InternalServerErrorException("I want this message to show at client side");
}
}
在我的客户端,我有一个 CountryClient,方法如下:
public List<Country> findAll() throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path("countries");
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(new GenericType<List<Country>>(){});
}
在我的控制器中,我是这样使用它的:
try {
CountryClientSSL cc = new CountryClientSSL();
cc.setUsernamePassword(USERNAME, PASSWORD);
ObservableList<Country> olCountries = FXCollections.observableArrayList(cc.findAll());
tblCountries.setItems(olCountries);
tcCountry.setSortType(SortType.ASCENDING);
tblCountries.getSortOrder().add(tcCountry);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
因此,每次我在客户端使用 findAll() 方法时,我都会在输出 windows 中看到以下信息:服务器端为 Info: I want this message to show at client side
,客户端为 HTTP 500 Internal Server Error
。
有没有办法在不使用 Response
作为 return 类型的情况下在客户端(在 catch 块中)获取错误消息?
我想要实现的是:当客户端发生错误时,用户可以向我的 JIRA 实例发送调试报告,其中包含大量信息,如客户端的堆栈跟踪、额外信息关于系统,谁登录了,...也可以在其中附加服务器的堆栈跟踪。或者有更好的方法来实现吗?
Is there a way to get the errorMessage on the client side (in the catch block) without using Response
as a return type?
您可以使用 response.readEntity(new GenericType<List<Country>>(){})
。这样您仍然可以访问 Response
。尽管在这种情况下不会有堆栈跟踪。只有当您尝试使用 get(ParsedType)
时,客户端才会出现异常。原因是使用 get(ParsedType)
,没有其他方法可以处理错误状态。但是使用 Response
,开发人员应该根据状态进行检查。所以这个方法看起来更像
public List<Country> findAll() throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path("countries");
Response response = resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get();
if (response.getStatus() != 200) {
System.out.println(response.getHeaderString("errorResponse"));
return null;
} else {
return response.readEntity(new GenericType<List<Country>>(){});
}
}
虽然我不会在 header 中发送消息作为响应 body。这就是我
super(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity( message).type(MediaType.TEXT_PLAIN).build());
客户端
if (response.getStatus() != 200) {
System.out.println(response.readEntity(String.class));
return null;
}
我不认为您可以 return 在除 HTTP 200 (Response.ok().build
) 之外的任何响应类型中自定义内容(即 errorMessage
)。
但是,您可以在服务器代码中抛出异常,然后捕获它们并将它们转换为具有 ExceptionMapper
的有效响应。有关详细信息,请参阅 this question。
我正在我的网络服务上尝试一些自定义错误处理。在我的网络服务中,我创建了一个自定义异常 class 扩展 WebApplicationException ,如 JAX-RS / Jersey how to customize error handling? 中所述:
public class InternalServerErrorException extends WebApplicationException {
public InternalServerErrorException(String message) {
super(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.header("errorMessage", message).type(MediaType.TEXT_PLAIN).build());
System.out.println(message);
}
}
为了测试,我有一个简单的国家/地区服务,它提供了国家/地区列表。我确保会发生错误以测试 InternalServerErrorException:
的抛出@GET
@Override
@Path("countries")
@Produces({"application/xml"})
public List<Country> findAll() {
try {
int i = Integer.parseInt("moo"); //<-- generate error
List<Country> countries = super.findAll();
return countries;
} catch (Exception ex) {
throw new InternalServerErrorException("I want this message to show at client side");
}
}
在我的客户端,我有一个 CountryClient,方法如下:
public List<Country> findAll() throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path("countries");
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(new GenericType<List<Country>>(){});
}
在我的控制器中,我是这样使用它的:
try {
CountryClientSSL cc = new CountryClientSSL();
cc.setUsernamePassword(USERNAME, PASSWORD);
ObservableList<Country> olCountries = FXCollections.observableArrayList(cc.findAll());
tblCountries.setItems(olCountries);
tcCountry.setSortType(SortType.ASCENDING);
tblCountries.getSortOrder().add(tcCountry);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
因此,每次我在客户端使用 findAll() 方法时,我都会在输出 windows 中看到以下信息:服务器端为 Info: I want this message to show at client side
,客户端为 HTTP 500 Internal Server Error
。
有没有办法在不使用 Response
作为 return 类型的情况下在客户端(在 catch 块中)获取错误消息?
我想要实现的是:当客户端发生错误时,用户可以向我的 JIRA 实例发送调试报告,其中包含大量信息,如客户端的堆栈跟踪、额外信息关于系统,谁登录了,...也可以在其中附加服务器的堆栈跟踪。或者有更好的方法来实现吗?
Is there a way to get the errorMessage on the client side (in the catch block) without using
Response
as a return type?
您可以使用 response.readEntity(new GenericType<List<Country>>(){})
。这样您仍然可以访问 Response
。尽管在这种情况下不会有堆栈跟踪。只有当您尝试使用 get(ParsedType)
时,客户端才会出现异常。原因是使用 get(ParsedType)
,没有其他方法可以处理错误状态。但是使用 Response
,开发人员应该根据状态进行检查。所以这个方法看起来更像
public List<Country> findAll() throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path("countries");
Response response = resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get();
if (response.getStatus() != 200) {
System.out.println(response.getHeaderString("errorResponse"));
return null;
} else {
return response.readEntity(new GenericType<List<Country>>(){});
}
}
虽然我不会在 header 中发送消息作为响应 body。这就是我
super(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity( message).type(MediaType.TEXT_PLAIN).build());
客户端
if (response.getStatus() != 200) {
System.out.println(response.readEntity(String.class));
return null;
}
我不认为您可以 return 在除 HTTP 200 (Response.ok().build
) 之外的任何响应类型中自定义内容(即 errorMessage
)。
但是,您可以在服务器代码中抛出异常,然后捕获它们并将它们转换为具有 ExceptionMapper
的有效响应。有关详细信息,请参阅 this question。