Java 使用Spring发送错误';s HandlerInterceptor导致406(不可接受)响应
我试图使用Spring的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
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);
}