Java Spring@ExceptionHandler返回错误的HttpStatus代码

Java Spring@ExceptionHandler返回错误的HttpStatus代码,java,spring,http,spring-boot,exception-handling,Java,Spring,Http,Spring Boot,Exception Handling,TL;DR:@ExceptionHandler函数在调用HttpServletResponse.getStatus时返回200ok而不是400错误请求以请求MissingServletParameterExceptionMissingServletParameterException仅用作示例,其他异常也会发生 你好, 我遇到的问题是,我正在尝试将Raygun(一个崩溃报告系统)与我们的Java/Spring启动应用程序集成。我发现的最简单的方法是创建一个自定义异常处理程序,它将向用户显示错误消

TL;DR:
@ExceptionHandler
函数在调用
HttpServletResponse.getStatus
时返回
200ok
而不是
400错误请求
以请求
MissingServletParameterException
MissingServletParameterException
仅用作示例,其他异常也会发生

你好,

我遇到的问题是,我正在尝试将Raygun(一个崩溃报告系统)与我们的Java/Spring启动应用程序集成。我发现的最简单的方法是创建一个自定义异常处理程序,它将向用户显示错误消息,并将异常传递给Raygun

最初,我尝试了这里建议的实现,并添加了我自己的Raygun实现

这就是它没有被注释掉的原因(将异常发送给Raygun):


任何关于我做错了什么的帮助或建议都将不胜感激。谢谢您的时间。

在控制器建议中,尝试以下方法将异常类型映射到Http状态
Http,如下所示:

if (ex instanceof MyException)
{//just an example.
    return new ResponseEntity<>(e, HttpStatus.BAD_REQUEST);
}
else
{//all other unhandled exceptions
    return new ResponseEntity<>(e, HttpStatus.INTERNAL_SERVER_ERROR);
}
if(例如MyException的实例)
{//只是一个例子。
返回新的响应属性(e,HttpStatus.BAD_请求);
}
其他的
{//所有其他未处理的异常
返回新的响应属性(e,HttpStatus.INTERNAL_SERVER_ERROR);
}

这里MyException是您在运行时抛出的异常类型。假设我正在处理错误的请求。

在控制器建议中,尝试以这种方式将异常类型映射到
Http状态,如下所示:

if (ex instanceof MyException)
{//just an example.
    return new ResponseEntity<>(e, HttpStatus.BAD_REQUEST);
}
else
{//all other unhandled exceptions
    return new ResponseEntity<>(e, HttpStatus.INTERNAL_SERVER_ERROR);
}
if(例如MyException的实例)
{//只是一个例子。
返回新的响应属性(e,HttpStatus.BAD_请求);
}
其他的
{//所有其他未处理的异常
返回新的响应属性(e,HttpStatus.INTERNAL_SERVER_ERROR);
}

这里MyException是您在运行时抛出的异常类型。假设我正在处理错误的请求。

我仍然不确定当抛出异常时,它为什么返回
200 OK
状态。但我已经意识到,我试图创建一个模仿Spring默认json错误消息的字符串的做法过于复杂,根本没有必要

一旦我将异常发送给Raygun,我就可以重新显示异常,并让框架像任何用
@ResponseStatus
注释的异常一样处理它

@ExceptionHandler(value = Exception.class)
public void defaultErrorHandler(Exception e) throws Exception {

    RaygunClient client = new RaygunClient("<MyRaygunAPIKey>");

    // If the exception is annotated with @ResponseStatus rethrow it and let
    // the framework handle it
    if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
        throw e;
    }

    // Otherwise send the exception Raygun and then rethrow it and let the framework handle it
    if (accessToken.getUsername() != null && accessToken.getDatabaseName() != null) {
        ArrayList tags = new ArrayList<String>();
        tags.add("username: " + accessToken.getUsername());
        tags.add("database: " + accessToken.getDatabaseName());
        client.Send(e, tags);
        accessToken = null;
        throw e;

    } else if (databaseName != null) {
        ArrayList tags = new ArrayList<String>();
        tags.add("database: " + databaseName);
        client.Send(e, tags);
        databaseName = null;
        throw e;

    } else {
        client.Send(e);
        throw e;
    }
}
@ExceptionHandler(值=Exception.class)
public void defaultErrorHandler(异常e)引发异常{
RaygunClient=新的RaygunClient(“”);
//如果用@ResponseStatus注释异常,则重新引用它并让
//框架可以处理它
if(AnnotationUtils.findAnnotation(e.getClass(),ResponseStatus.class)!=null){
投掷e;
}
//否则,发送异常Raygun,然后重新播放它,并让框架处理它
if(accessToken.getUsername()!=null&&accessToken.getDatabaseName()!=null){
ArrayList标记=新的ArrayList();
添加(“用户名:+accessToken.getUsername());
tags.add(“数据库:+accessToken.getDatabaseName());
发送(e,标签);
accessToken=null;
投掷e;
}else if(databaseName!=null){
ArrayList标记=新的ArrayList();
添加(“数据库:“+databaseName”);
发送(e,标签);
databaseName=null;
投掷e;
}否则{
客户发送(e);
投掷e;
}
}
裸骨植入将如下所示:

@ExceptionHandler(value = Exception.class)
public void defaultErrorHandler(Exception e) throws Exception {

    RaygunClient client = new RaygunClient("<MyRaygunAPIKey>");

    // If the exception is annotated with @ResponseStatus rethrow it and let the framework handle it
    if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
        throw e;
    }
    // Otherwise send the exception Raygun and then rethrow it and let the framework handle it
    else {
        client.Send(e);
        throw e;
    }
}
@ExceptionHandler(值=Exception.class)
public void defaultErrorHandler(异常e)引发异常{
RaygunClient=新的RaygunClient(“”);
//如果用@ResponseStatus注释异常,则重新引用它并让框架处理它
if(AnnotationUtils.findAnnotation(e.getClass(),ResponseStatus.class)!=null){
投掷e;
}
//否则,发送异常Raygun,然后重新播放它,并让框架处理它
否则{
客户发送(e);
投掷e;
}
}

我仍然不确定,当抛出异常时,它为什么会返回
200 OK
状态。但我已经意识到,我试图创建一个模仿Spring默认json错误消息的字符串的做法过于复杂,根本没有必要

一旦我将异常发送给Raygun,我就可以重新显示异常,并让框架像任何用
@ResponseStatus
注释的异常一样处理它

@ExceptionHandler(value = Exception.class)
public void defaultErrorHandler(Exception e) throws Exception {

    RaygunClient client = new RaygunClient("<MyRaygunAPIKey>");

    // If the exception is annotated with @ResponseStatus rethrow it and let
    // the framework handle it
    if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
        throw e;
    }

    // Otherwise send the exception Raygun and then rethrow it and let the framework handle it
    if (accessToken.getUsername() != null && accessToken.getDatabaseName() != null) {
        ArrayList tags = new ArrayList<String>();
        tags.add("username: " + accessToken.getUsername());
        tags.add("database: " + accessToken.getDatabaseName());
        client.Send(e, tags);
        accessToken = null;
        throw e;

    } else if (databaseName != null) {
        ArrayList tags = new ArrayList<String>();
        tags.add("database: " + databaseName);
        client.Send(e, tags);
        databaseName = null;
        throw e;

    } else {
        client.Send(e);
        throw e;
    }
}
@ExceptionHandler(值=Exception.class)
public void defaultErrorHandler(异常e)引发异常{
RaygunClient=新的RaygunClient(“”);
//如果用@ResponseStatus注释异常,则重新引用它并让
//框架可以处理它
if(AnnotationUtils.findAnnotation(e.getClass(),ResponseStatus.class)!=null){
投掷e;
}
//否则,发送异常Raygun,然后重新播放它,并让框架处理它
if(accessToken.getUsername()!=null&&accessToken.getDatabaseName()!=null){
ArrayList标记=新的ArrayList();
添加(“用户名:+accessToken.getUsername());
tags.add(“数据库:+accessToken.getDatabaseName());
发送(e,标签);
accessToken=null;
投掷e;
}else if(databaseName!=null){
ArrayList标记=新的ArrayList();
添加(“数据库:“+databaseName”);
发送(e,标签);
databaseName=null;
投掷e;
}否则{
客户发送(e);
投掷e;
}
}
裸骨植入将如下所示:

@ExceptionHandler(value = Exception.class)
public void defaultErrorHandler(Exception e) throws Exception {

    RaygunClient client = new RaygunClient("<MyRaygunAPIKey>");

    // If the exception is annotated with @ResponseStatus rethrow it and let the framework handle it
    if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
        throw e;
    }
    // Otherwise send the exception Raygun and then rethrow it and let the framework handle it
    else {
        client.Send(e);
        throw e;
    }
}
@ExceptionHandler(值=Exception.class)
public void defaultErrorHandler(异常e)引发异常{
RaygunClient=新的RaygunClient(“”);
//如果用@ResponseStatus注释异常,则重新引用它并让框架处理它
if(AnnotationUtils.findAnnotation(e.getClass(),response
@ExceptionHandler(value = Exception.class)
public void defaultErrorHandler(Exception e) throws Exception {

    RaygunClient client = new RaygunClient("<MyRaygunAPIKey>");

    // If the exception is annotated with @ResponseStatus rethrow it and let the framework handle it
    if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
        throw e;
    }
    // Otherwise send the exception Raygun and then rethrow it and let the framework handle it
    else {
        client.Send(e);
        throw e;
    }
}