java-从Spring MVC Rest服务抛出的Jersey REST客户端捕获异常

我使用Spring MVC,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对象.但是,如果我无法在执行处理程序中返回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

返回异常后,如何访问响应对象?

谢谢

解决方法:

> @ExceptionHandler批注可以将一类类作为参数,因此您只能为多个异常创建一个(或多个)处理程序.更改方法签名,以将所有已处理异常类的公共祖先作为参数.大致情况:

@ExceptionHandler(value = {NullPointerException.class, AnotherException.class})
@ResponseBody
public String handleException1(Exception ex) {
    return ex.getMessage();
}

>在您的情况下,它将是String,因为您已使用@ResponseBody对其进行了注释,但是您可能希望将返回的http代码更改为某些错误代码.您可以通过添加

@ResponseStatus(value = HttpStatus.WHATEVER_CODE_YOU_WANT, reason = "Your message")` 

注释到您的异常处理程序.
>如果调用返回的http代码大于或等于300,则球衣客户端抛出UniformInterfaceException.您可以抓住并处理它.在这种情况下,响应类型无关紧要,因为转换之前会引发异常.

更新

一旦获得UniformInterfaceException的保留权并更改服务器上的异常处理程序,使其返回ServiceResponse作为响应主体,则可以使用以下命令获取响应:

ServiceResponse response = uniformInterfaceException.getResponse().getEntity(ServiceResponse.class);
上一篇:java-jersey-spring和jenkins-读取zip文件/jersey-core-1.8.jar时发生奇怪的错误


下一篇:java-为什么球衣中的方法被调用两次?