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

如何绕过AEM默认错误处理?在AEM Servlet中返回自定义HTTP错误响应

问题

能否在AEM运行的Sling Servlet中直接返回带自定义内容的HTTP错误响应?

背景

现有一个处理POST表单请求的Sling Servlet,代码如下:

@SlingServlet(
    methods = HttpConstants.METHOD_POST,
    resourceTypes = NameConstants.NT_PAGE,
    selectors = SELECTOR)
public class MyServlet extends SlingAllMethodsServlet {
//...
    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) {
        //if something is wrong with the request
        Gson gson = new Gson();
        gson.toJson(errorResponse, response.getWriter());
        response.setContentType(MediaType.JSON_UTF_8.toString());
        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
        //...
    }
//...
}

当该Servlet返回HTTP 400 Bad Request时,期望获取Servlet中生成的JSON响应,但AEM会通过/apps/sling/servlet/errorhandler生成HTML页面,仅将JSON添加在内容开头:

{"errors":["The provided value is incorrect"]}



<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
    <head><title>400 Bad Request</title></head>
    <body> 
                    <h1>400 Bad Request</h1>
                    <p>Cannot serve request to on this server.</p>
(...)
    </body>
</html>

已知可创建自定义错误页,但需Servlet中的验证错误来生成有意义的响应。AEM版本:6.5

解决方案

可以通过以下两种方式实现直接返回自定义JSON错误响应:

方法一:使用setStatus替代sendError

sendError会触发Sling的错误处理机制,导致默认错误页被追加到响应中。改用setStatus设置错误状态码,同时直接写入自定义响应内容:

@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
    // 验证请求出错时
    ErrorResponse errorResponse = new ErrorResponse();
    errorResponse.setErrors(List.of("The provided value is incorrect"));

    Gson gson = new Gson();
    response.setContentType(MediaType.JSON_UTF_8.toString());
    // 设置400状态码但不触发错误处理
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    gson.toJson(errorResponse, response.getWriter());
    // 确保响应输出完成
    response.getWriter().flush();
}

这种方式不会触发Sling的错误处理器,响应内容就是你生成的纯JSON。

方法二:自定义错误处理器并传递错误信息

如果必须使用sendError(比如需要触发某些全局错误逻辑),可以通过请求属性传递错误信息,再创建对应JSON格式的错误处理器:

  1. 在Servlet中设置错误属性并调用sendError:
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
    ErrorResponse errorResponse = new ErrorResponse();
    errorResponse.setErrors(List.of("The provided value is incorrect"));

    // 将错误对象存入请求属性
    request.setAttribute("customError", errorResponse);
    response.setContentType(MediaType.JSON_UTF_8.toString());
    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
  1. 创建自定义Sling错误处理器Servlet,匹配JSON请求和400状态码:
@SlingServlet(
    methods = "*",
    resourceTypes = "sling/servlet/errorhandler",
    selectors = "400",
    extensions = "json",
    priority = 100) // 设置更高优先级覆盖默认处理器
public class Custom400JsonErrorHandler extends SlingAllMethodsServlet {
    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
        ErrorResponse errorResponse = (ErrorResponse) request.getAttribute("customError");
        if (errorResponse == null) {
            // 处理无自定义错误的情况
            errorResponse = new ErrorResponse();
            errorResponse.setErrors(List.of("Bad Request"));
        }

        Gson gson = new Gson();
        response.setContentType(MediaType.JSON_UTF_8.toString());
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        gson.toJson(errorResponse, response.getWriter());
    }

    // 覆盖doPost方法处理POST请求的错误
    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
        doGet(request, response);
    }
}

注意要确保请求的Accept头为application/json,或者请求URL带有.json后缀,这样才会匹配到这个自定义错误处理器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:12:53