Custom Jersey Error Handling, how to catch response at client side?

Per*_*eel 3 java rest error-handling web-services jersey

I'm trying out some custom error handling on my webservice. In my webservice, I created a custom Exception class extending WebApplicationException as described in 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

For testing, I have a simple Country service that gives a list of countries. I made sure that an error will occur to test the throwing of the 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

At my client I have a CountryClient with following method:

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>>(){});
}
Run Code Online (Sandbox Code Playgroud)

And in my controller I use it like this:

    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());
    }
Run Code Online (Sandbox Code Playgroud)

So everytime I use the findAll() method in my client, I see following info in my output windows: Info: I want this message to show at client side at server side, and HTTP 500 Internal Server Error at client side.

Is there a way to get the errorMessage on the client side (in the catch block) without using Response as a return type?

我想要实现的是以下内容:当客户端发生错误时,用户可以向我的 JIRA 实例发送调试报告,其中包含大量信息,例如客户端的堆栈跟踪、有关系统的额外信息、谁是已登录,... 将服务器的堆栈跟踪也附加在那里会很好。或者有没有更好的方法来实现这一目标?

Pau*_*tha 5

有没有办法在不使用Response返回类型的情况下在客户端(在 catch 块中)获取 errorMessage ?

您可以使用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>>(){});
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然不是在标题中,我只是将消息作为响应正文发送出去。这就是我

super(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
        .entity( message).type(MediaType.TEXT_PLAIN).build());
Run Code Online (Sandbox Code Playgroud)

客户端

if (response.getStatus() != 200) {
    System.out.println(response.readEntity(String.class));
    return null;
}
Run Code Online (Sandbox Code Playgroud)