繁体   English   中英

使用WebServices时如何捕获原始异常?

[英]How to catch the original Exception, when using WebServices?

经过数天的搜索并阅读了与之相关的所有内容之后,我终于在这里发布了我的问题,因为我找不到适合自己特定问题的解决方案。

我希望我的REST WebServices返回已抛出的原始Exception,或者至少返回正确的StackTrace。 为了测试这一点,我使用JUnit集成测试和Wildfly 13作为应用程序服务器。 经过研究,我发现了2种可能的解决方案。

1,使用异常映射器

虽然这神奇的事情捕获了我所有的异常并允许我返回一个Response,但我注意到,如果像示例中那样使用它,我的StackTrace也会更改。 例如,“ com.test.TestClass”变成“ null.thread”或“ null.interceptor”。 似乎在某种程度上,异常在途中发生了变化,并且类的路径丢失或受到了检查,但我无法理解。 我也找不到对Response.entity的任何限制,无论是大小,数据类型还是安全性。

据我了解,您可以捕获ExceptionMapper响应或包含响应的WebApplicationException。 就我而言,WebApplicationException中的响应包含(正确的)StackTrace之外的所有相关数据。

2.使用WebApplicationException

另一个解决方案是简单地抛出WebApplicationException而不是ECEException而不使用映射器。 如果我这样做并捕获了它,则异常为空。 它不包含任何数据集,始终为500-InternalServerError(我想,Wildfly无法处理它,并且本身引发了异常)。

还是不应该那样被捕获/抛掷? 我需要将其转换为JSon还是可以期望它通过WebServiceInterface和Response MediaType中的注释直接使用即可使用? 将完整的Response放入WebApplicationException甚至有意义吗? 我的意思是,这两个字段都包含ErrorCode的字段,即使存在该方法的构造函数,该字段似乎也是多余的。

长话短说:捕获所有可能的异常并检索完整堆栈跟踪的最佳方法是什么? 阅读这篇文章 ,我想捕获所有“异常”都很好,并且它们总是作为WebApplicationExceptions返回,但是堆栈跟踪仍然不存在/格式不正确...您的想法是什么?

    **JUnitTest** 
    @Test
    public void testCreateTask_ClusterInvalid() throws IOException {

        final RPETask taskToCreate = new RPETask();;

        try 
        {
            final long tid = taskManagerWebService.createTask(taskToCreate);
        } 
        catch (WebApplicationException e) //Responses are ALWAYS catched as WebApplicationException
        {

            Response response = e.getResponse();  
            String emString = response.readEntity(String.class);

            Gson gson = new Gson(); 

            ECEWebErrorMessage errorMessage = gson.fromJson(emString, ECEWebErrorMessage.class);       
            errorMessage.displayErrorInformationOnConsole();
        }
    }




    **WebServiceInterface**
    @POST
    @Path(URI_CREATE_TASK)
    @Consumes(WebServiceNames.JSON)
    @Produces(WebServiceNames.JSON)
    long createTask(final RPETask task) throws ECEException;




    **WebService**
    @Override
    public long createTask(final RPETask task) throws ECEException {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("createTask(" + task + ")");
        }
        return taskManager.createTask(task);
    }




    **ManagerBeanInterface**
    long createTask(RPETask task) throws ECEException;




    **ManagerBean**
    @Override
    public long createTask(final RPETask task) throws ECEException {
        final ClusterEngineBean cluster = find(ClusterEngineBean.class, task.getCluster());
        if (cluster == null) {
            throw new ECEObjectNotFoundException(ClusterEngineBean.class, task.getCluster());
        }
    }




    **ExceptionMapper**
    @Provider
    public class GenericWebExceptionMapper implements ExceptionMapper<Exception> {
    final Log logger = LogFactory.getLog(getClass());

    @Override
    public Response toResponse(Exception ex) {

        //At this point, the Exception is fully available -> Sending it as Response breaks it!
        logger.error("GenericWebExceptionMapper -> toResponse(Throwable ex)", ex);

        ECEWebErrorMessage errorMessage = new ECEWebErrorMessage(500, 
                                                                 ex.getMessage(), 
                                                                 ex.getClass().getCanonicalName(),
                                                                 ex.getStackTrace());
        return Response.status(Status.INTERNAL_SERVER_ERROR)
                .entity(errorMessage)
                .type(MediaType.APPLICATION_JSON)
                .build();
        }
    }

经过更多的研究,我终于找到了适合自己的解决方案。

为什么StackTrace消失/格式错误?

出于安全原因。 Wildfly使用拦截器自动检测传出的StackTrace并对其进行审查。 我不确定您是否可以对此做任何事情,但是我想您还是不应该这样做。

最好的方法是什么?

使用异常映射器对我有用。 不必总是将它们捕获为WebApplicationException,而是始终可以期待带有适当错误代码的响应并以这种方式进行处理。 例如,错误代码200 = OK,执行此操作...错误代码404 = NOTFOUND,执行该操作...在这种情况下,您的Web服务应始终返回Responses并在Response的实体字段中包含要检索的对象。

随时向该解决方案添加其他信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM