2013-02-27 70 views
4

以JSON格式返回澤西例外的最佳方式是什麼? 這裏我的示例代碼。JSON返回澤西例外

public static class CompoThngExceptionMapper implements ExceptionMapper<Exception> { 
    @Override 
    public Response toResponse(Exception exception) { 
     if (exception instanceof WebApplicationException) { 
      WebApplicationException e = (WebApplicationException) exception; 
      Response r = e.getResponse(); 
      return Response.status(r.getStatus()).entity(**HERE JSON**).build(); 
    } else { 
      return null; 

     } 
    } 

在此先感謝!

回答

7

取決於你想回到什麼,但我個人有一個ErrorInfo對象,看起來是這樣的:

public class ErrorInfo { 
    final transient String developerMessage; 
    final transient String userMessage; 

    // Getters/setters/initializer 
} 

我繞過我的Exception S的部分,然後我就用傑克遜的ObjectMapper到從ExceptionMapper中的ErrorInfo對象創建一個JSON字符串。這種方法的好處是你可以很容易地擴展它,所以添加狀態信息,錯誤時間等等,只是添加另一個字段的情況。

請記住,添加諸如響應狀態之類的內容有點浪費,因爲無論如何這將會返回到HTTP標頭中。

更新

如下(在這種情況下ERRORINFO中有更多的領域,但你的總體思路)一個完整的例子:

import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.core.Response.ResponseBuilder; 
import javax.ws.rs.core.Response.Status; 
import javax.ws.rs.ext.ExceptionMapper; 
import javax.ws.rs.ext.Provider; 

import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.ObjectMapper; 

@Provider 
public class UnexpectedExceptionMapper implements ExceptionMapper<Exception> 
{ 
    private static final transient ObjectMapper MAPPER = new ObjectMapper(); 

    @Override 
    public Response toResponse(final Exception exception) 
    { 
    ResponseBuilder builder = Response.status(Status.BAD_REQUEST) 
             .entity(defaultJSON(exception)) 
             .type(MediaType.APPLICATION_JSON); 
    return builder.build(); 
    } 

    private String defaultJSON(final Exception exception) 
    { 
    ErrorInfo errorInfo = new ErrorInfo(null, exception.getMessage(), exception.getMessage(), (String)null); 

    try 
    { 
     return MAPPER.writeValueAsString(errorInfo); 
    } 
    catch (JsonProcessingException e) 
    { 
     return "{\"message\":\"An internal error occurred\"}"; 
    } 
    } 
} 
+0

謝謝jgm。抱歉。你如何編碼Jacson的ObjectMapper來從'ExceptionMapper' ???中的'ErrorInfo'對象創建JSON字符串。在此先感謝 – 2013-02-28 08:31:33

+0

添加了一個完整的示例。 – jgm 2013-02-28 09:58:05

+0

只有最後一個問題jgm。我在Jetty - Jersey環境中,並且我總是在exception.getMessage()中獲取null。我只想返回狀態描述。提前致謝。 – 2013-02-28 11:12:00

3

避免進口傑克遜班,但只堅持純JAX-RS類我創建了像這樣的json異常包裝器。

創建ExceptionInfo包裝器和子類的各種異常狀態類型。

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) 
@XmlRootElement 
public class ExceptionInfo { 
    private int status; 
    private String msg, desc; 
    public ExceptionInfo(int status, String msg, String desc) { 
     this.status=status; 
     this.msg=msg; 
     this.desc=desc; 
    } 

    @XmlElement public int getStatus() { return status; } 
    @XmlElement public String getMessage() { return msg; } 
    @XmlElement public String getDescription() { return desc; } 
} 

- - - - 

import javax.ws.rs.core.Response; 
import javax.ws.rs.core.Response.Status; 
import javax.ws.rs.WebApplicationException; 

/** 
* Create 404 NOT FOUND exception 
*/ 
public class NotFoundException extends WebApplicationException { 
    private static final long serialVersionUID = 1L; 

    public NotFoundException() { 
     this("Resource not found", null); 
    } 

    /** 
    * Create a HTTP 404 (Not Found) exception. 
    * @param message the String that is the entity of the 404 response. 
    */ 
    public NotFoundException(String msg, String desc) { 
     super(Response.status(Status.NOT_FOUND).entity(
       new ExceptionInfo(Status.NOT_FOUND.getStatusCode(), msg, desc) 
     ).type("application/json").build()); 
    } 

} 

然後在資源實現中拋出異常,客戶端收到一個很好的json格式的http錯誤體。

@Path("/properties") 
public class PropertyService { 
    ... 
    @GET @Path("/{key}") 
    @Produces({"application/json;charset=UTF-8"}) 
    public Property getProperty(@PathParam("key") String key) { 
     // 200=OK(json obj), 404=NotFound 
     Property bean = DBUtil.getProperty(key); 
     if (bean==null) throw new NotFoundException(); 
     return bean; 
    } 
    ... 
} 

- - - - 
Content-Type: application/json 
{"status":404,"message":"Resource not found","description":null} 
+0

我不明白。這個'ExceptionInfo'用在哪裏?或者你們是否有人'NotFoundException'應該擴展'ExceptionInfo'? – sja 2015-10-16 09:22:16

+0

@sja:請參閱'NotFoundException(String msg,String desc)'構造函數。 – Whome 2015-10-16 11:12:24