2013-02-27 4 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 개체가 : 다음 난 그냥 잭슨의 ObjectMapper에를 사용하여 내 Exception의의 일환으로 주변에 통과

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

    // Getters/setters/initializer 
} 

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 문자열을 생성하기 위해 어떻게 인코딩합니까? 미리 감사드립니다 –

+0

전체 예제를 추가했습니다. – jgm

+0

마지막 질문 만 jgm. 저는 Jetty - Jersey 환경에 있으며, 예외에서 항상 null을 얻습니다 .getMessage(). 상태 설명 만 반환하고 싶습니다. 미리 감사드립니다. –

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

+0

@sja :'NotFoundException (String msg, String desc)'생성자를 참조하십시오. – Whome

관련 문제