You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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; }
}

注意事项:

  1. 修正原端点返回的状态码:将HttpURLConnection.HTTP_ACCEPTED(202)改为200 OK,符合请求成功的语义。
  2. 更新@Produces注解,添加MediaType.APPLICATION_JSON,避免媒体类型不匹配问题。
  3. 调整OpenAPI的@APIResponse schema为自定义的ErrorResponse类,确保文档与实际响应结构一致。

内容的提问来源于stack exchange,提问作者Karlito Brigante

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:55:19