欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot 错误处理小结

程序员文章站 2022-06-29 12:55:47
在 java web开发过程中,难免会有一些系统异常或人为产生一些异常。在 restful springboot 项目中如何优雅的处理? 分析:在restful 风格的s...

在 java web开发过程中,难免会有一些系统异常或人为产生一些异常。在 restful springboot 项目中如何优雅的处理?

分析:在restful 风格的springboot 项目中,返回的都是 body 对象,所以定义一个结果基类,其中包含 status,message,data(请求方法的返回结果),是比较合适的。

如果定义多个异常类进行处理,会比较麻烦。比如studentnotexistsexception、studentexistsexception。。。等,并且不能指定错误码,不方便前端根据错误码进行处理。

说明:一般的spring mvc模型处理流程如下

一般controller层 -> service层 -> dao层。

1.controller层,接受请求,进行分页,dto对象封装操作。

2.service层,执行逻辑,控制并发,事务。

3.dao层,与数据库交互。

使用一个学生表的处理进行说明:

1、定义常见的错误枚举 studentexceptionenum

public enum studentexceptionenum {
  student_not_exist(1004,"学生不存在,请确认后再查"),
  student_exist(1005,"学生已存在");
  private integer status;
  private string comment;
  studentexceptionenum(integer status, string comment) {
    this.status = status;
    this.comment = comment;
  }
  public integer getstatus() {
    return status;
  }
  public void setstatus(integer status) {
    this.status = status;
  }
  public string getcomment() {
    return comment;
  }
  public void setcomment(string comment) {
    this.comment = comment;
  }
}

2 定义一个基本的处理结果类 requestresult

@data
public class requestresult {
  private string message;
  private integer status;
  private object data;
  public requestresult(string message, integer status, object data) {
    this.message = message;
    this.status = status;
    this.data = data;
  }
  public requestresult(string message, integer status) {
    this.message = message;
    this.status = status;
  }
  public requestresult(string message, studentexceptionenum requestexceptionenum) {
    this.message = message;
    this.status = requestexceptionenum.getstatus();
  }
  public requestresult() {
    status = 200;
    message = "ok";
  }
  public static requestresult ok(object data) {
    requestresult result = new requestresult();
    result.setdata(data);
    return result;
  }
  public static requestresult exception(string message, integer status) {
    return new requestresult(message, status);
  }
  public static requestresult exception(string message, studentexceptionenum requestexceptionenum) {
    return new requestresult(message, requestexceptionenum);
  }
}

3 实体类 student

@data
public class student implements serializable{
  private string id;
  private string nickname;
  private string name;
  private int age;
  private string sex;
  private string address;
  @override
  public string tostring() {
    return tostringbuilder.reflectiontostring(this);
  }
}

4 处理请求,添加学生,nickname 必填项。此处只显示 service 片段代码

@override
  public requestresult addstudent(student student) {
    if (studentdao.queryidbynickname(student.getnickname()) == null) {
      studentdao.addstudent(student);
      system.out.println("添加成功");
      student = studentdao.querybynickname(student.getnickname());
      return requestresult.ok(student);
    } else {
      return requestresult.exception("用户" + student.getnickname() + "已存在", studentexceptionenum.student_exist);
    }
  }

5 此时,已经完成了基本的处理情况。下面就进行基本的测试了

5.1 添加一个新同学信息

5.2 再次添加让其出现异常测试

二、到此基本已大功告成,但是,对于基本的运行时异常没有处理,直接返回给前端会很不友好。所以要定义一个全局的 runtimeexception 异常处理类。

此处需要使用的关键标注: @exceptionhandler

用法有两种 1)在处理请求的 controller 中添加 @exceptionhandler,此时该方法只会处理该 controller 抛出的异常。

2)将其用在全局的异常处理类中,全局异常处理类需要使用  @restcontrolleradvice 或 @controlleradvice 标记

我们需要处理全局的 runtimeexception,所以我们使用第二种方法。当然,这样处理是为了客户友好型,我们还是要处理这种错误,怎么办?就需要将错误的信息记录下来,方便以后分析处理。此处使用 logger 进行记录。代码如下

@restcontrolleradvice
public class baseexceptionhandler {
  private static logger logger = loggerfactory.getlogger(baseexceptionhandler.class);
  @exceptionhandler(value = runtimeexception.class)
  public requestresult exceptionhandler(httpservletrequest request,exception e) {
    logerror(request,e);
    return requestresult.exception("内部处理异常,工程师正在抓紧抢修,请稍后再来...",500);
  }
  public static void logerror(httpservletrequest request, exception e) {
    logger.error("请求地址:" + request.getrequesturl());
    logger.error("请求方法:" + request.getmethod());
    logger.error("请求ip:" + getremoteip(request));
    logger.error("错误详情:");
    stacktraceelement[] error = e.getstacktrace();
    for (stacktraceelement stacktraceelement : error) {
      logger.error(stacktraceelement.tostring());
    }
  }
  public static string getremoteip(httpservletrequest request) {
    string ip = request.getheader("x-forwarded-for");
    if (ip == null || ip.length() == 0 || "unknown".equalsignorecase(ip)) {
      if (ip == null || ip.length() == 0 || "unknown".equalsignorecase(ip)) {
        ip = request.getheader("proxy-client-ip");
      }
      if (ip == null || ip.length() == 0 || "unknown".equalsignorecase(ip)) {
        ip = request.getheader("wl-proxy-client-ip");
      }
      if (ip == null || ip.length() == 0 || "unknown".equalsignorecase(ip)) {
        ip = request.getheader("http_client_ip");
      }
      if (ip == null || ip.length() == 0 || "unknown".equalsignorecase(ip)) {
        ip = request.getheader("http_x_forwarded_for");
      }
      if (ip == null || ip.length() == 0 || "unknown".equalsignorecase(ip)) {
        ip = request.getremoteaddr();
      }
    } else if (ip.length() > 15) {
      string[] ips = ip.split(",");
      for (int index = 0; index < ips.length; index++) {
        string strip = (string) ips[index];
        if (!("unknown".equalsignorecase(strip))) {
          ip = strip;
          break;
        }
      }
    }
    return ip;
  }
}

进行测试看是否生效:

修改添加学生信息代码如下:

public requestresult addstudent(student student) {
    int a = 1/0;
    
    if (studentdao.queryidbynickname(student.getnickname()) == null) {
      studentdao.addstudent(student);
      system.out.println("添加成功");
      student = studentdao.querybynickname(student.getnickname());
      return requestresult.ok(student);
    } else {
      return requestresult.exception("用户'" + student.getnickname() + "'已存在", studentexceptionenum.student_exist);
    }
  }

进行测试

后台打印错误信息

2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : 请求地址:http://localhost:8080/demo1/student
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : 请求方法:post
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : 请求ip:0:0:0:0:0:0:0:1
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : 错误详情:
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : com.huitong.demo.service.studentservice.addstudent(studentservice.java:71)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : com.huitong.demo.controller.studentcontroller.addstudent(studentcontroller.java:38)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : sun.reflect.nativemethodaccessorimpl.invoke0(native method)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : java.lang.reflect.method.invoke(method.java:498)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.method.support.invocablehandlermethod.doinvoke(invocablehandlermethod.java:209)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.method.support.invocablehandlermethod.invokeforrequest(invocablehandlermethod.java:136)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.mvc.method.annotation.servletinvocablehandlermethod.invokeandhandle(servletinvocablehandlermethod.java:102)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter.invokehandlermethod(requestmappinghandleradapter.java:870)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter.handleinternal(requestmappinghandleradapter.java:776)
2018-03-26 17:01:19.125 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.mvc.method.abstracthandlermethodadapter.handle(abstracthandlermethodadapter.java:87)
2018-03-26 17:01:19.129 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.dispatcherservlet.dodispatch(dispatcherservlet.java:991)
2018-03-26 17:01:19.129 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.dispatcherservlet.doservice(dispatcherservlet.java:925)
2018-03-26 17:01:19.129 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.frameworkservlet.processrequest(frameworkservlet.java:978)
2018-03-26 17:01:19.129 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.frameworkservlet.dopost(frameworkservlet.java:881)
2018-03-26 17:01:19.129 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : javax.servlet.http.httpservlet.service(httpservlet.java:661)
2018-03-26 17:01:19.129 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.servlet.frameworkservlet.service(frameworkservlet.java:855)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : javax.servlet.http.httpservlet.service(httpservlet.java:742)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:231)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:166)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.tomcat.websocket.server.wsfilter.dofilter(wsfilter.java:52)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:193)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:166)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : com.alibaba.druid.support.http.webstatfilter.dofilter(webstatfilter.java:123)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:193)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:166)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.requestcontextfilter.dofilterinternal(requestcontextfilter.java:99)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.onceperrequestfilter.dofilter(onceperrequestfilter.java:107)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:193)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:166)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.httpputformcontentfilter.dofilterinternal(httpputformcontentfilter.java:109)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.onceperrequestfilter.dofilter(onceperrequestfilter.java:107)
2018-03-26 17:01:19.130 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:193)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:166)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.hiddenhttpmethodfilter.dofilterinternal(hiddenhttpmethodfilter.java:81)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.onceperrequestfilter.dofilter(onceperrequestfilter.java:107)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:193)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:166)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.characterencodingfilter.dofilterinternal(characterencodingfilter.java:200)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.springframework.web.filter.onceperrequestfilter.dofilter(onceperrequestfilter.java:107)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.internaldofilter(applicationfilterchain.java:193)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.applicationfilterchain.dofilter(applicationfilterchain.java:166)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.standardwrappervalve.invoke(standardwrappervalve.java:199)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.standardcontextvalve.invoke(standardcontextvalve.java:96)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.authenticator.authenticatorbase.invoke(authenticatorbase.java:496)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.standardhostvalve.invoke(standardhostvalve.java:140)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.valves.errorreportvalve.invoke(errorreportvalve.java:81)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.core.standardenginevalve.invoke(standardenginevalve.java:87)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.catalina.connector.coyoteadapter.service(coyoteadapter.java:342)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.coyote.http11.http11processor.service(http11processor.java:803)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.coyote.abstractprocessorlight.process(abstractprocessorlight.java:66)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.coyote.abstractprotocol$connectionhandler.process(abstractprotocol.java:790)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.tomcat.util.net.nioendpoint$socketprocessor.dorun(nioendpoint.java:1459)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.tomcat.util.net.socketprocessorbase.run(socketprocessorbase.java:49)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1142)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:617)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : org.apache.tomcat.util.threads.taskthread$wrappingrunnable.run(taskthread.java:61)
2018-03-26 17:01:19.131 error 9136 --- [nio-8080-exec-2] c.h.d.controller.baseexceptionhandler  : java.lang.thread.run(thread.java:745)
2018-03-26 17:01:19.133 warn 9136 --- [nio-8080-exec-2] .m.m.a.exceptionhandlerexceptionresolver : resolved exception caused by handler execution: java.lang.arithmeticexception: / by zero

总结

以上所述是小编给大家介绍的springboot 错误处理小结,希望对大家有所帮助