SpringBoot启动遇到的异常问题及解决方案
目录
- SpringBoot启动遇到异常
- 1、问题
- 2、异常
- 3、异常
- 4、异常
- 5、异常
- 6、异常
- 7、异常
- SpringBoot优雅的处理异常
- 使用异常
- 创建统一异常类
- 测试
SpringBoot启动遇到异常
1、 问题
SpringBoot本身需要引入自身的一个parent,但是pom里面一般都已经存在了一个parent,这时就不能在引入springBoot的parent
解决方案:
org.springframework.boot spring-boot-starter-web1.3.3.RELEASE org.springframework.boot spring-boot-dependencies1.5.6.RELEASE pom import
2、异常
Exception in thread "main" java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationListener : org.springframework.boot.logging.ClasspathLoggingApplicationListener解决方案:
。。。。。。
Caused by: java.lang.NoClassDefFoundError: org/springframework/context/event/GenericApplicationListener
这个问题可能是由于Spring的版本低导致,升级spring版本。亲测到4.2.5.RELEASE可以
4.2.5.RELEASE
3、异常
Exception in thread "main" java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.Log4jLoggerFactory loaded from file:/D:/maven/repository/org/slf4j/slf4j-log4j12/1.7.5/slf4j-log4j12-1.7.5.jar). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml Object of class [org.slf4j.impl.Log4jLoggerFactory] must be an instance of class ch.qos.logback.classic.LoggerContext解决方案:
at org.springframework.util.Assert.isInstanceOf(Assert.java:346)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:221)
这个异常是由于打印日志的jar冲突导致,SpringBoot本身有打印日志的功能,如果跟本地的冲突,就需要去掉,如下
org.springframework.boot spring-boot-starter-web1.3.3.RELEASE org.springframework.boot spring-boot-starter-logging
4、异常
Cannot instantiate factory class: org.springframework.boot.autoconfigure.AutoConfigurationImportFilter解决方案:
Caused by: java.lang.IllegalAccessException: Class org.springframework.core.io.support.SpringFactoriesLoader can not access a member of class org.springframework.boot.autoconfigure.condition.OnClassCondition with modifiers ""
这种可以检查org.springframework.boot的版本,可能是版本不兼容,我这里一开始设置的1.5.6.RELEASE,一直出异常,后来SpringBoot的版本改成全部改成1.3.3.RELEASE把Spring的版本改成4.2.5.RELEASE,通过
5、 异常
SpringBoot启动
xport.annotation.AnnotationMBeanExporter -Unregistering JMX-exposed beans on shutdown ,tomcat也没有运行
可能原因1:
看看是否屏蔽了,检查 spring-boot-starter-web 这个下面是否屏蔽了spring-boot-starter-tomcat,
如果有,请去掉
org.springframework.boot spring-boot-starter-tomcat
可能原因2:
org.springframework.boot spring-boot-starter-tomcatprovided
将provided注释掉
6、异常
Caused by: java.lang.NoClassDefFoundError: org/springframework/beans/factory/ObjectProvider解决方案:
Caused by: java.lang.ClassNotFoundException: org.springframework.beans.factory.ObjectProvider
这个异常最蛋疼,搞了半天是SpringBoot的版本不兼容,切换了一个版本到1.3.3.RELEASE 这里就好了
org.springframework.boot spring-boot-starter-web1.3.3.RELEASE org.springframework.boot spring-boot-starter-logging
建议把
7、异常
java.lang.NoSuchMethodError: org.springframework.expression.spel.SpelParserConfiguration.解决方案:(Lorg/springframework/expression/spel/SpelCompilerMode; Ljava/lang/ClassLoader
缺少jar
org.springframework spring-expression4.2.5.RELEASE
SpringBoot优雅的处理异常 SpringBoot 统一异常处理
像这种统一异常的文章博客有许多,但是每个人使用都有自己的心得,我来总结一下自己使用的心得
统一异常,顾名思义,就是统一管理项目中会方法的异常,然后进行一个处理,Spring发生错误后,底层会去请求一个/error的地址,抛出对应的异常到页面上,对客户或者开发来说都不是特别的友好
使用统一异常处理的话,可以返回自定义的异常数据,阅读性提高,优雅的处理异常
使用异常
使用异常的方式很简单,Spring提供了两个注解:@ControllerAdvice和@ExceptionHandler
@ControllerAdvice
:控制器增强,使@ExceptionHandler、@InitBinder、@ModelAttribute注解的方法应用到所有的 @RequestMapping注解的方法@ExceptionHandler
:异常处理器,此注解的作用是当出现其定义的异常时进行处理的方法
创建统一异常类
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.TypeMismatchException; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.web.AbstractErrorController; import org.springframework.boot.autoconfigure.web.ErrorAttributes; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartException; import org.springframework.web.servlet.NoHandlerFoundException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.sql.SQLException; import java.util.Map; /** * 全局异常处理 * 一般情况下,方法都有异常处理机制,但不能排除有个别异常没有处理,导致返回到前台,因此在这里做一个异常拦截,统一处理那些未被处理过的异常 * * @author ${author} on ${date} */@ControllerAdvice@Controller@RequestMappingpublic class GlobalExceptionHandler extends AbstractErrorController {private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class); public GlobalExceptionHandler(ErrorAttributes errorAttributes) {super(errorAttributes); }@Value("${server.error.path:${error.path:/error}}")private static String errorPath = "/error"; /*** sql异常** @param req* @param rsp* @param ex* @return* @throws Exception*/@ResponseBody@ExceptionHandler(SQLException.class)public Result sqlException(HttpServletRequest req, HttpServletResponse rsp, Exception ex) {LOGGER.error("!!! request uri:{} from {} server exception:{}", req.getRequestURI(), RequestUtil.getIpAddress(req), ex == null ? null : ex); return ResponseMsgUtil.builderResponse(1002, ex == null ? null : ex.getMessage(), null); }/*** 500错误.** @param req* @param rsp* @param ex* @return* @throws Exception*/@ResponseBody@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)@ExceptionHandler(Exception.class)public Result serverError(HttpServletRequest req, HttpServletResponse rsp, Exception ex) throws Exception {LOGGER.error("!!! request uri:{} from {} server exception:{}", req.getRequestURI(), RequestUtil.getIpAddress(req), ex == null ? null : ex); return ResponseMsgUtil.builderResponse(1002, ex == null ? null : ex.getMessage(), null); }/*** 404的拦截.** @param request* @param response* @param ex* @return* @throws Exception*/@ResponseBody@ResponseStatus(code = HttpStatus.NOT_FOUND)@ExceptionHandler(NoHandlerFoundException.class)public Result notFound(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {LOGGER.error("!!! request uri:{} from {} not found exception:{}", request.getRequestURI(), RequestUtil.getIpAddress(request), ex); return ResponseMsgUtil.builderResponse(404, ex == null ? null : ex.getMessage(), null); }@ExceptionHandler(MissingServletRequestParameterException.class)@ResponseBodypublic Result paramException(MissingServletRequestParameterException ex) {LOGGER.error("缺少请求参数:{}", ex.getMessage()); return ResponseMsgUtil.builderResponse(99999, "缺少参数:" + ex.getParameterName(), null); }//参数类型不匹配//getPropertyName()获取数据类型不匹配参数名称//getRequiredType()实际要求客户端传递的数据类型@ExceptionHandler(TypeMismatchException.class)@ResponseBodypublic Result requestTypeMismatch(TypeMismatchException ex) {LOGGER.error("参数类型有误:{}", ex.getMessage()); return ResponseMsgUtil.builderResponse(99999, "参数类型不匹配,参数" + ex.getPropertyName() + "类型应该为" + ex.getRequiredType(), null); }@ExceptionHandler(HttpRequestMethodNotSupportedException.class)@ResponseBodypublic Result requestMethod(HttpRequestMethodNotSupportedException ex) {LOGGER.error("请求方式有误:{}", ex.getMethod()); return ResponseMsgUtil.builderResponse(99999, "请求方式有误:" + ex.getMethod(), null); }@ExceptionHandler(MultipartException.class)@ResponseBodypublic Result fileSizeLimit(MultipartException m) {LOGGER.error("超过文件上传大小限制"); return ResponseMsgUtil.builderResponse(99999, "超过文件大小限制,最大10MB", null); }/*** 重写/error请求, ${server.error.path:${error.path:/error}} IDEA报红无需处理,作用是获取spring底层错误拦截** @param request* @param response* @return* @throws Exception*/@ResponseBody@RequestMapping(value = "https://www.it610.com/article/${server.error.path:${error.path:/error}}")public Result handleErrors(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpStatus status = getStatus(request); if (status == HttpStatus.NOT_FOUND) {throw new NoHandlerFoundException(request.getMethod(), request.getRequestURL().toString(), new HttpHeaders()); }Map body = getErrorAttributes(request, true); return ResponseMsgUtil.builderResponse(Integer.parseInt(body.get("status").toString()), body.get("message").toString(), null); }@Overridepublic String getErrorPath() {return errorPath; }}
从上面可以看出来,我定义了sql异常,500异常,404异常该做的事情,通过@ExceptionHandler注解来拦截程序中的异常,比如执行SQL时,抛出了异常,就会被统一异常给拦截,然后返回我们想要返回的数据
@ResponseStatus注解可加可不加,就是对响应码进行拦截,如代码上,对404响应码进行了拦截
最下面的handleErrors方法,是对Spring底层访问/error的时候进行了一次拦截,获取当前请求码,如果是404.抛出404的异常
优化处理异常怎么能没有自定义返回数据呢
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; /** * 返回数据结果集合 */public class Result{private Integer code; private String resMsg; private T data; public Result() {}public Integer getCode() {return this.code; }public void setCode(Integer resCode) {this.code = resCode; }public String getResMsg() {return this.resMsg; }public void setResMsg(String resMsg) {this.resMsg = resMsg; }public T getData() {return this.data; }public void setData(T data) {this.data = https://www.it610.com/article/data; }public String toJson() {return this.data == null ? JSON.toJSONString(this) : this.toJson(SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue); }public String toJson(SerializerFeature... features) {return features == null ? this.toJson() : JSON.toJSONString(this, features); }public String toString() {return"Result{code=" + this.code + ", resMsg='" + this.resMsg + '\'' + ", data="https://www.it610.com/article/+ this.data +'}'; }}
/** * 返回数据结果集合 * @author RuXuanWo on 2019/02/21 */public class ResponseMsgUtil {public ResponseMsgUtil() {}public staticResult builderResponse(int code, String msg, T data) {Result res = new Result(); res.setCode(code); res.setResMsg(msg); res.setData(data); return res; }public static Result success(String msg) {return builderResponse(0, msg, null); }public static Result success(String msg, T data) {return builderResponse(0, msg, data); }public static Result success(T data) {return builderResponse(0, "Success", data); }public static Result success() {return builderResponse(0, "Success", null); }public static Result failure() {return builderResponse(1, "Failure", null); }public static Result failure(String msg) {return builderResponse(1, msg, null); }public static Result failure(T date) {return builderResponse(-1, "Failure", date); }public static Result illegalRequest() {return builderResponse(1008, "Illegal request", (T) null); }public static Result exception() {return builderResponse(1002, "request exception", (T) null); }public static Result paramsEmpty() {return builderResponse(1009, "the input parameter is null", (T) null); }}
测试
将这些准备都做好以后,项目跑起来,访问一个接口,故意不传某个必填项,就会被统一异常拦截,如下
{code: 1002,data: null,msg: "Required String parameter 'id' is not present"}
【SpringBoot启动遇到的异常问题及解决方案】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- Springboot-Shiro基本使用详情介绍
- springboot|springboot 如何添加webapp文件夹
- springboot新建项目pom.xml文件第一行报错的解决
- springboot-curd基于mybatis项目搭建
- 华为新系统|华为新系统 鸿蒙,华为鸿蒙遇到竞争对手,谷歌推出新系统,暴露出更大的野心...
- springboot|SpringBoot集成Minio搭建自己的分布式文件服务器(Minio集成篇)
- 基于SpringBoot框架和VUE的求职招聘系统
- 个人笔记|SpringBoot Admin 系统监控
- 前端|React踩坑日记React启动后报错TypeError Cannot read properties of undefined (reading ‘forEach‘)
- 免费硬件、专属导师、豪华大礼|AI达人创造营第二期项目征集启动啦!