SpringBoot 异常处理方式及异常信息入库方便查询

  • SpringBoot 异常处理方式
    SpringBoot 中对于异常处理提供了五种处理方式:
  1. 自定义错误页面
    SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。
    一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个叫 BasicExceptionController 来处理/error 请求,然后跳转到默认显示异常的页面来展示异常
    信息.
    在这里插入图片描述
如 果 我 们 需 要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , 需 要 再 src/main/resources/templates 目录下创建 error.html 页面。注意:名称必须叫 error
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>错误提示页面</title>
	</head>
	<body>
		出错了,请与管理员联系。。。
		<span th:text="${exception}"></span>
	</body>
</html>

  1. @ExceptionHandle 注解处理异常
/**
 * SpringBoot处理异常方式一:自定义错误页面
 *
 *
 */
@Controller
public class DemoController {
	
	@RequestMapping("/show")
	public String showInfo(){
		String str = null;
		str.length();
		return "index";
	}
	
	@RequestMapping("/show2")
	public String showInfo2(){
		int a = 10/0;
		return "index";
	}
	
	/**
	 * java.lang.ArithmeticException
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@ExceptionHandler(value={java.lang.ArithmeticException.class})
	public ModelAndView arithmeticExceptionHandler(Exception e){
		ModelAndView mv = new ModelAndView();
		mv.addObject("error", e.toString());
		mv.setViewName("error1");
		return mv;
	}
	
	/**
	 * java.lang.NullPointerException
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@ExceptionHandler(value={java.lang.NullPointerException.class})
	public ModelAndView nullPointerExceptionHandler(Exception e){
		ModelAndView mv = new ModelAndView();
		mv.addObject("error", e.toString());
		mv.setViewName("error2");
		return mv;
	}
}

============================================

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>错误提示页面-NullPointerException</title>
	</head>
	<body>
		出错了,请与管理员联系。。。
		<span th:text="${error}"></span>
	</body>
</html>


  • 3.@ControllerAdvice+@ExceptionHandler 处理异常
    需要创建一个能够处理异常的全局异常类。 。 在该类上需要添加@ControllerAdvice 注解
/**
 * 全局异常处理类
 *
 *
 */
@ControllerAdvice
public class GlobalException {
	/**
	 * java.lang.ArithmeticException
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@ExceptionHandler(value={java.lang.ArithmeticException.class})
	public ModelAndView arithmeticExceptionHandler(Exception e){
		ModelAndView mv = new ModelAndView();
		mv.addObject("error", e.toString());
		mv.setViewName("error1");
		return mv;
	}
	
	/**
	 * java.lang.NullPointerException
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@ExceptionHandler(value={java.lang.NullPointerException.class})
	public ModelAndView nullPointerExceptionHandler(Exception e){
		ModelAndView mv = new ModelAndView();
		mv.addObject("error", e.toString());
		mv.setViewName("error2");
		return mv;
	}
	
}

  • 4.配置SimpleMappingExceptionResolver
    在全局异常类中添加一个方法完成异常的统一处理
/**
 * 通过SimpleMappingExceptionResolver做全局异常处理
 *
 *
 */
@Configuration
public class GlobalException {
	
	/**
	 * 该方法必须要有返回值。返回值类型必须是:SimpleMappingExceptionResolver
	 */
	@Bean
	public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
		
		Properties mappings = new Properties();
		
		/**
		 * 参数一:异常的类型,注意必须是异常类型的全名
		 * 参数二:视图名称
		 */
		mappings.put("java.lang.ArithmeticException", "error1");
		mappings.put("java.lang.NullPointerException","error2");
		
		//设置异常与视图映射信息的
		resolver.setExceptionMappings(mappings);
		
		return resolver;
	}
	
}

  • 4.配置SimpleMappingExceptionResolver
    在全局异常类中添加一个方法完成异常的统一处理
/**
 * 通过SimpleMappingExceptionResolver做全局异常处理
 *
 *
 */
@Configuration
public class GlobalException {
	
	/**
	 * 该方法必须要有返回值。返回值类型必须是:SimpleMappingExceptionResolver
	 */
	@Bean
	public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
		
		Properties mappings = new Properties();
		
		/**
		 * 参数一:异常的类型,注意必须是异常类型的全名
		 * 参数二:视图名称
		 */
		mappings.put("java.lang.ArithmeticException", "error1");
		mappings.put("java.lang.NullPointerException","error2");
		
		//设置异常与视图映射信息的
		resolver.setExceptionMappings(mappings);
		
		return resolver;
	}
	
}

  • 5.自定义 HandlerExceptionResolver 类处理异常
    需要在全局异常处理类中实现 HandlerExceptionResolver
/**
 * 通过实现HandlerExceptionResolver接口做全局异常处理
 *
 *
 */
@Configuration
public class GlobalException implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		ModelAndView mv = new ModelAndView();
		//判断不同异常类型,做不同视图跳转
		if(ex instanceof ArithmeticException){
			mv.setViewName("error1");
		}
		
		if(ex instanceof NullPointerException){
			mv.setViewName("error2");
		}
		mv.addObject("error", ex.toString());
		
		return mv;
	}
}

异常信息入库:

@Slf4j
@Aspect
@Component
public class ExceptionLogAspect {

    @Autowired
    private ExceMapper exceMapper;

    @Pointcut("execution(* cc.mrbird.febs.common.handler.GlobalExceptionHandler.*(..) )")
    public void pointcut(){}

    @Before("pointcut()")
    public void addInfo(JoinPoint joinPoint )
    {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        Object[] args = joinPoint.getArgs();
        Exception ex = (Exception) args[0];
        // 将异常信息写入数据库
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw, true));
        ExcetionMessage excetionMessage = new ExcetionMessage();
        excetionMessage.setOperTime(new Date());
        excetionMessage.setMessage(ex.getMessage());
        excetionMessage.setExecption(sw.toString());
        exceMapper.insert(excetionMessage);
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于 Spring Boot 和 Akka 的代码示例,演示了如何利用 Actor 模型实现数据并发处理入库。 ### 1. 引入依赖 在 `pom.xml` 文件中添加以下依赖: ```xml <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-actor_2.12</artifactId> <version>2.6.10</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` ### 2. 定义 Actor 定义一个 Actor,用于并行处理接收到的数据并将其保存到数据库中。 ```java import akka.actor.AbstractActor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceUnit; @Component public class DataWriterActor extends AbstractActor { @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Autowired public DataWriterActor(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } @Override public Receive createReceive() { return receiveBuilder() .match(DataMessage.class, data -> { saveData(data); }) .build(); } private void saveData(DataMessage data) { EntityManager entityManager = entityManagerFactory.createEntityManager(); try { entityManager.getTransaction().begin(); entityManager.persist(data.getData()); entityManager.getTransaction().commit(); } catch (Exception e) { entityManager.getTransaction().rollback(); e.printStackTrace(); } finally { entityManager.close(); } } } ``` ### 3. 定义消息 定义一个消息类,用于传递需要处理数据。 ```java public class DataMessage { private Object data; public DataMessage(Object data) { this.data = data; } public Object getData() { return data; } } ``` ### 4. 配置 ActorSystem 在 Spring Boot 的配置类中创建一个 ActorSystem,并将 DataWriterActor 注册到该 ActorSystem 中。 ```java import akka.actor.ActorRef; import akka.actor.ActorSystem; import akka.actor.Props; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ActorSystemConfig { @Autowired private EntityManagerFactory entityManagerFactory; @Bean public ActorSystem actorSystem() { ActorSystem actorSystem = ActorSystem.create("DataWriterActorSystem"); ActorRef dataWriterActor = actorSystem.actorOf(Props.create(DataWriterActor.class, entityManagerFactory)); return actorSystem; } } ``` ### 5. 发送消息 在需要处理数据的地方,通过 ActorSystem 发送消息给 DataWriterActor 处理。 ```java import akka.actor.ActorRef; import akka.actor.ActorSystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class DataProcessor { @Autowired private ActorSystem actorSystem; public void processData(Object data) { ActorRef dataWriterActor = actorSystem.actorSelection("/user/dataWriterActor").resolveOne().value().get(); dataWriterActor.tell(new DataMessage(data), ActorRef.noSender()); } } ``` 以上就是利用 Spring Boot 和 Akka 实现数据并发处理入库的示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值