6

ジャージー例外を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;

        }
    }

前もって感謝します!!!

4

2 に答える 2

9

何を返したいかにもよりますが、個人的には次のErrorInfoようなオブジェクトがあります。

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

    // Getters/setters/initializer
}

これをsの一部として渡し、ExceptionJacksonを使用してのオブジェクトObjectMapperからJSON文字列を作成します 。このアプローチの良いところは、非常に簡単に拡張できることです。したがって、ステータス情報、エラーの時間などを追加することは、別のフィールドを追加する場合にすぎません。ErrorInfoExceptionMapper

とにかく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\"}";
    }
  }
}
于 2013-02-27T16:11:54.500 に答える
9

インポート Jackson クラスを回避し、純粋な 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}
于 2014-12-09T13:05:36.127 に答える