Java Quarkus中如何抛出带消息体的NotFoundException
问题分析
直接抛出javax.ws.rs.NotFoundException时,Quarkus默认的异常处理器仅返回404状态码,不会将异常消息写入响应体;同时OpenAPI配置中指定的404响应JSON结构,无法通过默认的NotFoundException正确序列化输出。
解决方案
以下两种方法均可实现带自定义消息的404响应,按需选择:
方法一:自定义异常映射器(推荐,全局生效)
创建一个全局异常处理器,自动将NotFoundException转换为包含自定义消息的JSON响应:
import javax.ws.rs.NotFoundException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; @Provider public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> { @Override public Response toResponse(NotFoundException exception) { ErrorResponse errorResponse = new ErrorResponse(404, exception.getMessage()); return Response.status(Response.Status.NOT_FOUND) .entity(errorResponse) .type(MediaType.APPLICATION_JSON) .build(); } // 自定义错误响应实体类,用于JSON序列化 public static class ErrorResponse { private int status; private String message; public ErrorResponse(int status, String message) { this.status = status; this.message = message; } // Getter & Setter public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } }
使用说明:无需修改原有端点代码,抛出NotFoundException后,该映射器会自动处理并返回包含消息的404 JSON响应。
方法二:端点内手动捕获异常(局部生效)
修改端点方法,直接捕获异常并构建自定义响应:
@GET @Path(API_RESOURCE_IMAGE_REPORT) @Consumes(MediaType.APPLICATION_JSON) @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON}) // 新增JSON媒体类型支持 @Operation(summary = "", description = "") @APIResponses( value = { @APIResponse( responseCode = "200", description = "Request successful", content = @Content(mediaType = MediaType.TEXT_HTML)), @APIResponse( responseCode = "404", description = "Resource not found ", content = @Content( mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ErrorResponse.class))), }) public Response getReport(@Parameter(description = "", required = true) @PathParam("imageName") final String imageName, @Parameter(description = "", required = true) @PathParam("tag") final String tag, @Parameter(description = "") @PathParam("type") String type ) { try { InputStream report = jenkinsClient.getReport(imageName, tag, type); return Response.ok(report, MediaType.TEXT_HTML).build(); // 修正为200 OK状态码 } catch (NotFoundException e) { ErrorResponse errorResponse = new ErrorResponse(404, e.getMessage()); return Response.status(Response.Status.NOT_FOUND) .entity(errorResponse) .type(MediaType.APPLICATION_JSON) .build(); } } // 自定义错误响应实体类 public static class ErrorResponse { private int status; private String message; public ErrorResponse(int status, String message) { this.status = status; this.message = message; } // Getter & Setter public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
注意事项:
- 修正原端点返回的状态码:将
HttpURLConnection.HTTP_ACCEPTED(202)改为200 OK,符合请求成功的语义。 - 更新
@Produces注解,添加MediaType.APPLICATION_JSON,避免媒体类型不匹配问题。 - 调整OpenAPI的
@APIResponseschema为自定义的ErrorResponse类,确保文档与实际响应结构一致。
内容的提问来源于stack exchange,提问作者Karlito Brigante
相关产品推荐
相关产品推荐

