Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从Spring MVC REST服务引发的Jersey REST客户端捕获异常_Java_Spring_Jakarta Ee_Exception_Jersey - Fatal编程技术网

Java 从Spring MVC REST服务引发的Jersey REST客户端捕获异常

Java 从Spring MVC REST服务引发的Jersey REST客户端捕获异常,java,spring,jakarta-ee,exception,jersey,Java,Spring,Jakarta Ee,Exception,Jersey,我使用SpringMVC、Jersey和JAXB实现了一个REST应用程序 客户端发送一个包含请求信息的ServiceRequest对象,并接收一个包含响应信息的serviceressponse对象 服务请求 @XmlRootElement(name = "servicerequest") public class ServiceRequest{ String serviceName = "AddUser" public String getServiceName() {

我使用SpringMVC、Jersey和JAXB实现了一个REST应用程序

客户端发送一个包含请求信息的
ServiceRequest
对象,并接收一个包含响应信息的
serviceressponse
对象

服务请求

@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);
在服务器端,服务获取请求,处理它并返回一个
servicesponse
对象

@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
    ,因此发生异常时将返回的对象类型是什么
  • 客户机希望获得
    servicesponse
    类型的对象。如果响应是异常类型,它是如何工作的
最后,我注意到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处理程序中返回
serviceressponse
类型,则这是不可能的

编辑 我尝试使用一个通用异常类使用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();
    }
    
  • 在您的例子中,它将是
    字符串
    ,因为您使用
    @ResponseBody
    对它进行了注释,但是您可能希望将返回的http代码更改为一些错误代码。您可以通过添加

    @ResponseStatus(value = HttpStatus.WHATEVER_CODE_YOU_WANT, reason = "Your message")` 
    
    异常处理程序的注释

  • 如果调用返回的http代码大于或等于
    300
    ,jersey客户端将抛出
    UniformInterfaceException
    。你可以抓住它并处理它。在这种情况下,响应类型无关紧要,因为异常是在转换之前抛出的

  • 更新

    一旦您获得了
    UniformInterfaceException
    并更改了服务器上的异常处理程序,使其返回
    serviceressponse
    作为响应主体,则可以使用以下方法获取响应:

    ServiceResponse response = uniformInterfaceException.getResponse().getEntity(ServiceResponse.class);
    

    我确实尝试过,但响应返回为错误响应,这意味着ServiceResponse对象为null。有没有办法读取ServiceResponse对象?(参见文章中的编辑)@ziggy在spring端,您可以将其作为异常处理程序的
    @ResponseBody
    返回。我不知道如何在jersey端恢复它。@ziggy是客户端抛出的
    UniformInterfaceException
    。@ziggy您的客户端代码也不正确,因为
    WebResource.post()
    将响应的类作为参数。