java - 如何在 JAX-RS 客户端获取直接异常堆栈跟踪

标签 java jboss jax-rs resteasy

我在项目中使用 REST 服务,并且创建了一个过滤器来在服务调用不成功时记录错误,但如何使用 Resteasy 客户端捕获错误堆栈跟踪。

public class MyLogResponseFilter implements ClientResponseFilter {
    ...
    @Override
    public void filter(ClientRequestContext requestContext,
            ClientResponseContext responseContext) throws IOException {
        if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
            if (responseContext.hasEntity()) {
                String body = IOUtils.toString(responseContext.getEntityStream(), "UTF-8");
                log.error("Error with status={}, statusInfo={}, message={}", 
                        responseContext.getStatus(),
                        responseContext.getStatusInfo(),
                        body);
            }
        }
    }
}

这段代码可以工作,但是resteasy将错误堆栈包装到html正文中,例如从responseContext.getEntityStream()中读出的内容是这样的:

Error with status=500, statusInfo=Internal Server Error, message=<html><head><title>ERROR</title><style>body {
    font-family: "Lucida Grande", "Lucida Sans Unicode", "Trebuchet MS", Helvetica, Arial, Verdana, sans-serif;
    margin: 5px;
}

.header {
    background-image: linear-gradient(bottom, rgb(153,151,153) 8%, rgb(199,199,199) 54%);
    background-image: -o-linear-gradient(bottom, rgb(153,151,153) 8%, rgb(199,199,199) 54%);
    background-image: -moz-linear-gradient(bottom, rgb(153,151,153) 8%, rgb(199,199,199) 54%);
    background-image: -webkit-linear-gradient(bottom, rgb(153,151,153) 8%, rgb(199,199,199) 54%);
    background-image: -ms-linear-gradient(bottom, rgb(153,151,153) 8%, rgb(199,199,199) 54%);

    background-image: -webkit-gradient(
        linear,
        left bottom,
        left top,
        color-stop(0.08, rgb(153,151,153)),
        color-stop(0.54, rgb(199,199,199))
    );
    color: black;
    padding: 2px;
    font-weight: normal;
    border: solid 1px;
    font-size: 170%;
    text-align: left;
    vertical-align: middle; 
    height: 32px; 
}
.error-div {
   display: inline-block;   width: 32px;   height: 32px;    background: url('data:image/png;base64,longEncryptedPath') left center no-repeat;
}.error-text-div {
   display: inline-block;   vertical-align: top;   height: 32px;}.label {   font-weight:bold;   display: inline-block;}.value {   display: inline-block;}</style></head><body><div class="header"><div class="error-div"></div><div class="error-text-div">Error processing request</div></div><div class="label">Context Path:</div><div class="value">/my-webservice</div><br/><div class="label">Servlet Path:</div><div class="value">/services</div><br/><div class="label">Path Info:</div><div class="value">/mypath</div><br/><div class="label">Query String:</div><div class="value">usridNbr=1000001</div><br/><b>Stack Trace</b><br/>org.jboss.resteasy.spi.UnhandledException: javax.ejb.EJBException: java.lang.RuntimeException: ====test it<br/>org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76)...Long stack trace</body></html>

我只需要捕获错误消息和错误堆栈跟踪,任何建议都可以轻松实现这一点,而无需解析 html 正文。提前致谢。

最佳答案

注册 ExceptionMapper它将您的异常映射到可以轻松解析的实体。下面是一个将 RuntimeException 映射到 JSON 的快速示例:

@Provider
public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> {

    @Override
    public Response toResponse(RuntimeException exception) {
        Map<String, String> map = new HashMap<>();
        map.put("exception", exception.getClass().getName());
        map.put("message", exception.getMessage());
        return Response.status(500).entity(map).type(MediaType.APPLICATION_JSON_TYPE).build();
    }

}

在客户端,您可以像这样过滤它:

@Override
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
    if (responseContext.getStatus() == 500 && responseContext.hasEntity()) {
        Map error = new ObjectMapper().readValue(responseContext.getEntityStream(), Map.class);
        LOG.error("Status: {}, Exception: {}, Message: {}", 
            responseContext.getStatus(), error.get("exception"), error.get("message"));
    }
}

关于java - 如何在 JAX-RS 客户端获取直接异常堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36854779/

相关文章:

java - 正确使用 JavaFX setUserData?

java - 我怎样才能制作一个JSON对象,输出会像这样?

java - 如何解决 MessageBodyWriter not found for media type=multipart/form-data 错误

java - Jboss eap7.0 支持 JDK 7 或 8

java - JBoss MBean : How to have an array attribute?

java - 自定义对象在 Jax-RS 中反序列化很好,但如果它在另一个对象中使用,则它不起作用

java - Jax-rs -jersey 跨源请求启用

java - Spring Boot MVC Post Responseentity 返回 null

java - 使用 Spring JavaMailSender 将文件作为附件或内联发送

java - 使用InternalEntryFactory类将Infinispan 4.2迁移到5.1