【问题标题】:Return a pretty error json for rest api为rest api返回一个漂亮的错误json
【发布时间】:2015-10-23 03:18:08
【问题描述】:

当我的基于 Java 的 REST Web 服务发生错误时 我像这样将异常发送给客户端

 type Exception report

message Invalid Token

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.security.authentication.AuthenticationServiceException: Invalid Token
    com.resource.security.TokenAuthenticationFilter.doFilter(TokenAuthenticationFilter.java:220)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:208)
    com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:271)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.23 logs.

但我想返回这样的响应

{
"code" : 500,
"message" : "invalid token"
}

如何做到这一点?

更新

@Provider
   public class MyApplicationExceptionHandler implements
    ExceptionMapper<WebApplicationException> {

@Override
public Response toResponse(WebApplicationException weException) {

    // get initial response
    Response response = weException.getResponse();
    // create custom error
    ErrorDTO error = new ErrorDTO();
    error.setCode(response.getStatus());
    error.setMessage(weException.getMessage());
    // return the custom error
    return Response.status(response.getStatus()).entity(error).build();
}

}

Web.xml

  <context-param>
       <param-name>resteasy.providers</param-name>
       <param-value>com.madzz.common.exception.MadzzApplicationExceptionHandler</param-value>
 </context-param>

应用代码:

public String getTrackingDetailById(long orderItemId) throws Exception {
 throw new NotFoundException("not found"); }

我正在使用 java.ws.rs.NotFoundException 。但这似乎不起作用。 任何指针为什么?

【问题讨论】:

  • 只捕获异常并返回您自己的代码...

标签: java json rest exception error-handling


【解决方案1】:

您正在寻找的是 @ControllerAdvice 。逻辑如下:

您创建一个带有注释的类,其中该类中的每个方法都响应一个或多个异常。此处示例:

        @ControllerAdvice
    public class MyExceptionHandler {

        private static final Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class);
        @ExceptionHandler(MyCustomException.class)
@ResponseBody
        public ExcObject handleSQLException(HttpServletRequest request, Exception ex){
            logger.info("SQLException Occured:: URL="+request.getRequestURL());
            return "database_error";
        }

        @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="IOException occured")
        @ExceptionHandler(IOException.class)
        public void handleIOException(){
            logger.error("IOException handler executed");
            //returning 404 error code
        }
    }

在handleSQLException 中构造新创建的ExcObject 类的新创建对象并返回它。

在您的控制器中,您需要抛出特定的异常。

还要注意你需要创建 MyCustomException 来扩展异常。

【解决方案2】:

使用您自己的异常处理程序:

try {
   ...you code that throws AuthenticationServiceException
} catch (AuthenticationServiceException ex) {
   ... return you custom JSONObject
}

【讨论】:

    【解决方案3】:

    在基础级别捕获所有异常,并转换为 JSON,然后返回异常的 JSON 表示形式,返回码为 400。以下是以标准化方式将异常转换为 JSON 的例程:

    public static JSONObject convertToJSON(Throwable e, String context) throws Exception {
        JSONObject responseBody = new JSONObject();
        JSONObject errorTag = new JSONObject();
        responseBody.put("error", errorTag);
    
        errorTag.put("code", 400);
        errorTag.put("context", context);
    
        JSONArray detailList = new JSONArray();
        errorTag.put("details", detailList);
    
        Throwable nextRunner = e;
        List<ExceptionTracer> traceHolder = new ArrayList<ExceptionTracer>();
        while (nextRunner!=null) {
            Throwable runner = nextRunner;
            nextRunner = runner.getCause();
    
            detailObj.put("code", runner.getClass().getName());
            String msg =  runner.toString();
            detailObj.put("message",msg);
    
            detailList.put(detailObj);
        }
    
        JSONArray stackList = new JSONArray();
        for (StackTraceElement ste : e.getStackTrace()) {
            ja.put(ste.getFileName() + ": " + ste.getMethodName()
                   + ": " + ste.getLineNumber());
        }
        errorTag.put("stack", stackList);
    
        return responseBody;
    }
    

    您可以在以下位置找到实现此功能的完整开源库:Mendocino JSON Utilities。该库支持 JSON 对象以及异常。

    这会产生这种形式的 JSON 结构:

    {
       "error": {
          "code": "400",
          "message": "main error message here",
          "target": "approx what the error came from",
          "details": [
             {
                "code": "23-098a",
                "message": "Disk drive has frozen up again.  It needs to be replaced",
                "target": "not sure what the target is"
             }
          ],
          "innererror": {
             "trace": [ ... ],
             "context": [ ... ]
          }
       }
    }
    

    这是 OASIS 数据标准 OASIS OData 提出的格式,似乎是目前最标准的选项,但目前似乎没有任何标准的高采用率。

    详情在我Error Handling in JSON REST API的博文中讨论

    【讨论】:

      猜你喜欢
      • 2016-05-03
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      相关资源
      最近更新 更多