Java REST服务:返回异常的正确方法

Java REST服务:返回异常的正确方法,java,rest,exception,Java,Rest,Exception,我使用Jersey API进行REST服务。我的问题是:是否有一种更优雅的方式以JSON形式返回异常?自己创建一个json对象并将其直接附加到响应中是否更好 这是服务中方法之一的简化示例。如您所见,我使用HashMap只是因为该方法可能会引发异常,在这种情况下,我需要返回有关该异常的信息 @Path("/admin") public class AdminService { @Context HttpServletRequest request; @POST

我使用Jersey API进行REST服务。我的问题是:是否有一种更优雅的方式以JSON形式返回异常?自己创建一个json对象并将其直接附加到响应中是否更好

这是服务中方法之一的简化示例。如您所见,我使用HashMap只是因为该方法可能会引发异常,在这种情况下,我需要返回有关该异常的信息

@Path("/admin")
public class AdminService {

    @Context
    HttpServletRequest request;

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public Map<Integer, String> createCompany(Company company){

        Map<Integer, String> map = new HashMap<>();
        try{
            AdminFacade adminFacade = (AdminFacade)Utility.getFacade(request);
            adminFacade.createCompany(company);
            map.put(1,"success");
        } catch (ExceptionREST e) {
            map.put(e.getErrorNumber(), e.getMessage());
        } finally {
            return map;
        }
    }
}
@Path(“/admin”)
公共类管理服务{
@上下文
HttpServletRequest请求;
@职位
@产生(MediaType.APPLICATION_JSON)
公共地图创建公司(公司){
Map Map=newhashmap();
试一试{
AdminFacade AdminFacade=(AdminFacade)实用程序.getFacade(请求);
adminFacade.createCompany(公司);
地图放置(1,“成功”);
}捕获(例外休息e){
put(e.getErrorNumber(),e.getMessage());
}最后{
返回图;
}
}
}

我相信人们使用http响应状态代码来处理错误是非常流行的。例如,找不到404状态5xx是服务器内部错误E.t.c。 您可以使用Response对象轻松设置错误代码。 返回响应对象,而不是返回映射

@Path("/admin")public class AdminService {

@Context
HttpServletRequest request;

@POST
@Produces(MediaType.APPLICATION_JSON)
public Response createCompany(Company company){

    Map<Integer, String> map = new HashMap<>();
    try{
        AdminFacade adminFacade = (AdminFacade)Utility.getFacade(request);
        Company commpany=adminFacade.createCompany(company);//this entity annotated by XmlRootElement
        Response response=Response.ok().entity(company).build();
    } catch (ExceptionREST e) {
        response=Response.status(404).build();
    } return response;
}}
@Path(“/admin”)公共类AdminService{
@上下文
HttpServletRequest请求;
@职位
@产生(MediaType.APPLICATION_JSON)
公众反应公司(公司){
Map Map=newhashmap();
试一试{
AdminFacade AdminFacade=(AdminFacade)实用程序.getFacade(请求);
Company commpany=adminFacade.createCompany(Company);//此实体由XmlRootElement注释
Response=Response.ok().entity(company.build();
}捕获(例外休息e){
response=response.status(404.build();
}返回响应;
}}
为了使Restful api更加健壮,一些api将返回OK响应以防止服务器“智能重定向”,并输出一些奇怪的html。 您可以参考http状态代码列表及其含义。
对于JavaEE响应类,您可以参考

,您可以将错误包装到一个类中,比如我有一个ErrorData类,它具有status、message和stacktrace。每次发生异常时,我都会抛出带有errordata对象的GeneralAppException

public class GeneralAppException  extends WebApplicationException {
 public GeneralAppException(ErrorData er) {

            super(Response.status(er.getStatusCode()).
            entity(er).type(MediaType.APPLICATION_JSON).build());
          }
}
我有另一个类,它有所有已知的错误,例如

public static final ErrorData NODATAFOUND = new ErrorData(Response.Status.NOT_FOUND.getStatusCode(),"No data was found for given query");

public static final ErrorData CODEERROR = new ErrorData(502,"CodeError");
你的渔获量看起来像

catch (ExceptionREST e) {
        throw new GeneralAppException(ErrorData.NODATAFOUND);
    } 

使用的参考:

您可以创建一个类似下面的类来表示错误

@JsonPropertyOrder({ "code", "field", "message" })
public class ErrorInfo {

    private String code;

    private String field;

    private String message;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}
您可以创建一个类来扩展这样的异常

public class InvalidInputException extends RuntimeException {

    private static final long serialVersionUID = -5027121014723838738L;

    private List<ErrorInfo> errors;

    public List<ErrorInfo> getErrors() {
        return this.errors;
    }

    public InvalidInputException(List<ErrorInfo> errors) {
        super();
        this.errors = errors;
    }

    public InvalidInputException(String message, List<ErrorInfo> errors) {
        super(message);
        this.errors = errors;
    }

}

}

您现在的设备有什么问题?另外,请查看以下链接:,没有问题。我问有关写作惯例的问题。这是我发明的东西,但我确信它有一些惯例,因为我不是第一个这样做的人。你应该以HTTP状态码的形式返回你的错误,在正文中有一个(可选的)清除。正如@arsham所说,阅读并理解REST-apisThanks的概念!我最终就是这么做的。
@Provider
public class InvalidInputExceptionMapper implements ExceptionMapper<InvalidInputException> {

    @Override
    @Produces(MediaType.APPLICATION_JSON)
    public Response toResponse(InvalidInputException e) {

        ResponseBuilder rb = Response.status(Status.BAD_REQUEST);

        rb.entity(e.getErrors());
        return rb.build();   
    }
}
HTTP/1.1 400 BAD REQUEST
{
"errors": [{
    "error": {
        "code": "100",
        "field": null,
        "message": "Name is required"
    },
    "error": {
        "code": "100",
        "field": null,
        "message": "Age is required"
    }
}]