Java 使用Spring发送错误';s HandlerInterceptor导致406(不可接受)响应

Java 使用Spring发送错误';s HandlerInterceptor导致406(不可接受)响应,java,spring,spring-mvc,spring-boot,Java,Spring,Spring Mvc,Spring Boot,我试图使用Spring的HandlerInterceptorAdapter来处理以下rest端点的应用程序计划维护时的情况:/api/authentication 因此,我通过扩展HandlerInterceptorAdapter创建了一个拦截器: public class MigrationStateInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpSe

我试图使用Spring的
HandlerInterceptorAdapter
来处理以下rest端点的应用程序计划维护时的情况:
/api/authentication

因此,我通过扩展HandlerInterceptorAdapter创建了一个拦截器:

public class MigrationStateInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(someLogic) {
            return true
        }

        response.reset();
        response.sendError(HttpStatus.SERVICE_UNAVAILABLE.value());
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}
然后我将它添加到我的
截取注册表中:

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new MigrationStateInterceptor()).addPathPatterns("/api/authentication");
}
问题是,我没有在客户端接收到
503(服务不可用)
错误,而是接收到
加载资源失败:服务器响应状态为406(不可接受)

正如代码片段中所示,我尝试重置响应,但没有结果。 我还尝试修改
接受
内容类型
标题,但没有成功:

response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.addHeader("Accept", "text/plain");
你知道为什么会发生这种情况以及如何避免吗

注意:我在客户端使用Angular。从我所看到的
HttpServletResponse#senderro
将内容类型设置为
text/html
,保留cookie和其他标题不变。这可能是个问题吗

编辑: 我甚至尝试抛出一个异常,而不是使用
HttpServletResponse#senderro
,并单独处理,但最终结果是一样的

例如:

@覆盖
公共布尔预处理(HttpServletRequest请求、HttpServletResponse响应、对象处理程序)引发异常{
如果(某些逻辑){
返回true;
}
抛出新的MigrationStateException(“迁移进程已禁用”);
}
@ExceptionHandler(MigrationStateException.class)
公共响应迁移状态错误(迁移状态异常e){
返回新的响应属性(例如getMessage(),HttpStatus.SERVICE\u不可用);
}

我认为问题在于您映射到
/api/authenticate
的请求不是预期的
text/html
,就是您发送了错误类型的请求(即
GET
而不是
POST
,等等)


您声明angular正在发送
text/html
,考虑到与身份验证端点相关联的通常默认值,它可能需要
application/x-www-form-urlencoded
数据。因此,Spring正在拦截一个
内容类型
它没有映射和406'ing。

你能让一个调试器在预处理中中断吗?是的,我能。你对什么感兴趣?你的客户真的期望
text/plain
?那是很不寻常的
sendError
不只是设置内容类型,它会发送一个错误页面。您想发送自己的回复。异常处理程序仅适用于控制器。@zeroflagL异常处理程序捕获了异常,即使它不在控制器中。从非控制器环境返回的响应是否存在问题?关于我对客户端的期望,我可以很容易地进行更改,但是在服务器端发生了一些事情,将503转换为406。至少,这是我观察到的。你对此有什么建议吗?谢谢406意味着客户端期望服务器不能提供的东西。了解客户期望的媒体类型很重要。我假设服务器将
ResponseEntity
视为
text/plain
,而客户端期望
application/json
。尝试返回
映射
。您好@dardo,Spring正在将内容类型设置为
text/html
,而不是角度。更确切地说是
HttpServletResponse#senderro
方法。我试图通过抛出异常来绕过它,并从异常处理程序发送响应,但没有成功。请求没有问题,问题在于Spring发送的响应。这是因为Spring接收到请求后您正在拦截它。本例中的
text/html
是错误页面本身,而不是您期望的响应。
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (some logic) {
        return true;
    }
    throw new MigrationStateException("Migration process is disabled");
}

 @ExceptionHandler(MigrationStateException.class)
public ResponseEntity<String> migrationStateError(MigrationStateException e) {
    return new ResponseEntity<>(e.getMessage(), HttpStatus.SERVICE_UNAVAILABLE);
}