java捕获Spring MVC REST服务抛出的Jersey REST客户端的异常
我使用SpringMVC、Jersey和JAXB实现了一个REST应用程序
客户机发送一个ServiceRequest
对象,该对象包含有关请求的信息,并接收一个带有有关响应信息的ServiceResponse
对象
服务请求
@XmlRootElement(name = "servicerequest")
public class ServiceRequest{
String serviceName = "AddUser"
public String getServiceName() {
return serviceName;
}
@XmlElement
public void setServiceName(String serviceName) {
this.serviceName = name;
}
}
服务响应
@XmlRootElement(name = "serviceresponse")
public class ServiceResponse {
String responseCode;
public String getResponseCode() {
return responseCode;
}
@XmlElement
public void setResponseCode(String code) {
this.responseCode = name;
}
}
客户端使用Jersey调用服务
服务客户端
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(RESOURCE_URL);
ServiceRequest request = new ServiceRequest();
ServiceResponse response = service.path("addUser").type(MediaType.APPLICATION_XML)
.accept(MediaType.APPLICATION_XML).entity(request).post(ServiceRequest.class);
在服务器端,服务获取请求,处理它并返回一个ServiceResponse
对象
@RequestMapping(method = RequestMethod.POST,
value = "/addUser",headers="Accept=application/xml")
@ResponseStatus(HttpStatus.OK)
public @ResponseBody ServiceResponse addUser(@RequestBody ServiceRequest request) {
ServiceResponse response = new ServiceResponse();
//Handle request
//service.addUser();
response.setCode("200");
return response;
}
上面显示的控制器类调用另一个服务类来处理请求(service.addUser()
)。此服务类可能引发许多异常
我不确定的是如何最好地处理它们。在搜索之后,我发现我可以使用ExceptionHandler,如下所示:
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public String handleException1(NullPointerException ex)
{
return ex.getMessage();
}
我可以让控制器扩展具有异常处理程序的基类
关于上述方法的几个问题:
- 我是否必须为每个异常类型创建一个处理程序?我需要处理的异常太多了,所以不可能对所有异常都使用通用处理程序吗李>
- 当我的控制器返回类型为
ServiceResponse
的对象时,发生异常时将返回的对象类型是什么李> - 客户端希望获得
ServiceResponse
类型的对象。如果响应是异常类型,它是如何工作的李>
最后,我注意到ExceptionHanlder只能具有以下返回类型之一:
ModelAndView
Model
Map
View
String – interpreted as a view name
void, but only if the method writes directly to the response object
我想我可以在ExceptionHandler
中创建ServiceResponse
对象,设置适当的代码并返回ServiceResponse
对象。但是,如果我不能在expetion处理程序中返回ServiceResponse
类型,则这是不可能的
编辑
我尝试使用一个通用异常类使用ExceptionHandler,如下所示
@ExceptionHandler(ServiceException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public @ResponseBody resolveServiceValidationException(ServiceException ex) {
System.out.println("In resolveServiceError");
ServiceResponse = new ServiceResponse();
response.setResponseException(ex.getMessage());
return response;
}
正在捕获异常,但ServiceResponse对象始终为null。我得到的只是以下信息:
GET http://localhost:8080/myService/services/pingError returned a response status of 400 Bad Request
当返回异常时,如何访问响应对象
谢谢
# 1 楼答案
@ExceptionHandler
注释可以将类数组作为参数,因此您只能为多个异常创建一个(或多个)处理程序。更改方法签名以将所有已处理异常类的公共祖先作为参数。大致如下:在您的例子中,它将是
String
,因为您用@ResponseBody
注释了它,但是您可能希望将返回的http代码更改为一些错误代码。您可以通过添加异常处理程序的注释
当调用返回的http代码大于或等于
300
时,jersey客户端抛出UniformInterfaceException
。你可以抓住它并处理它。在这种情况下,响应类型无关紧要,因为异常是在转换之前抛出的更新
一旦获得
UniformInterfaceException
并更改服务器上的异常处理程序,使其返回ServiceResponse
作为响应主体,则可以使用以下方法获取响应: