当前位置: 首页 > 知识库问答 >
问题:

当使用web服务时,如何捕捉最初的异常?

潘嘉颖
2023-03-14

经过几天的搜索,阅读了几乎所有与之相关的内容,我终于在这里发布了我的问题,因为我找不到解决我的具体问题的方法。

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

1.Using异常映射

虽然这个神奇的东西捕获了我的所有异常并允许我返回响应,但我注意到,如果我像在示例中那样使用它,我的 StackTrace 就会被更改。例如,“测试类”将转换为“空线程”或“空拦截器”。似乎不知何故,例外在途中发生了变化,通往班级的路径丢失或被审查,但我无法理解它。此外,我找不到响应实体的任何限制,无论是大小,数据类型还是安全性。

据我所知,您可以捕获ExceptionMapper响应或包含响应的WebApplicationException。在我的例子中,WebApplicationException中的响应包含除(正确的)StackTrace之外的所有相关数据。

2.使用WebApplicationException

另一种解决方案是简单地抛出 Web 应用程序异常而不是 ECE 异常,而不使用映射器。如果我这样做并捕获它,则异常是空的。它不包含任何数据集,它总是500 - 内部服务器错误(我猜,Wildfly当时无法处理它,并且自己抛出了一个异常)。

或者它不应该像那样被接住/扔出去?我需要将它转换成JSon吗?或者我可以期望它在WebServiceInterface和Response MediaType中使用我的注释就能开箱即用吗?将完整的响应放在WebApplicationException中有意义吗?我的意思是,两者都包含ErrorCode的字段,这看起来是多余的,尽管该方法有一个构造函数。

长话短说:捕获所有可能的异常并检索完整堆栈跟踪的最佳方法是什么?阅读这篇文章,我想捕获所有“异常”是可以的,它们总是作为Web应用程序异常返回,但是堆栈跟踪仍然消失/格式不正确...你的想法?

    **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();
        }
    }

共有1个答案

田兴怀
2023-03-14

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

为什么StackTrace没有了/畸形了?

这是出于安全原因。Wildfly会自动检测传出的StackTraces并使用拦截器对其进行审查。我不确定你是否能对此做些什么,但我想你无论如何都不应该这样做。

最佳方法是什么?

使用异常映射器对我很有效。除了将它们捕获为WebApplicationException之外,您总是可以期待带有适当错误代码的响应,并以这种方式处理它们。例如,错误代码200 =好,这样做...错误代码404 =未找到,请执行此操作...在这种情况下,您的web服务应该总是返回响应,并在响应的实体字段中包含您想要检索的对象。

请随意向此解决方案添加其他信息。

 类似资料:
  • 问题内容: 我一直在使用Apache CXF wsdl2java生成的代码来调用Web服务的方法已有一段时间了,到目前为止,它一直运行良好。.我遇到的问题是,当Web服务(在我身旁实现)时合法地引发肥皂异常,CXF出现以下错误消息: 无法初始化com.sun.xml.internal.ws.fault.SOAPFaultBuilder类 我正在使用Ubuntu 9.04,OpenJDK(IcedT

  • 我正在尝试用kotlin做一个Spring MVC RestController,但是我很难用LocalDatetime使用RequestParams。 如果我不指定参数< code>localhost:8080/,它会给出一个可在ControllerAdvice中捕获的错误,但如果我指定一个空值< code > localhost:8080/end date = ,它会给出< code > Ja

  • 我正在尝试为一些网站检索超文本标记语言。我正在使用PHPfile_get_contents它运行得非常好,但是很慢,而且有点有限,所以我决定试试Guzzes。不幸的是,我发现很难阻止Guzzes抛出异常,即使使用他们记录的异常处理。我的代码非常简单: 我不断得到以下错误: GuzzleHttp\Exception\ConnectException cURL错误28:无法连接到acme.biz端口8

  • 我在用滑翔4。当URL返回404时,获取FileNotFoundException。我尝试使用RequestListener捕捉异常。但它并没有缓存这个异常。 记录如下: 2019-03-20 17:48:07.134 32233-32233/com。zyta。zflikz带滑翔:装载失败https://lh4.googleusercontent.com/-UxjwFuQRjXA/AAAAAAAA

  • 问题内容: 据我所知,netty通过重写方法exceptionCaught()处理异常。但是我想要的是一个可以处理所有异常的处理程序。因此,管道应类似于: InboundExceptionHandler- inboundHandler1-inboundHandler2-outboundHandler1-outboundHandler2-OutboundExceptionHandler 这意味着我应