struts2异常处理和log4j日志记录怎么弄?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了struts2异常处理和log4j日志记录怎么弄?相关的知识,希望对你有一定的参考价值。

用的struts2 spring hibernate,打算在manager和dao层中都抛出异常,然后在action中捕获这些异常,并记录到日志中,然后再抛出此异常,通过struts2的拦截器拦截异常,转到有友好的错误提示页面。
这么做符合正常开发的做法吗?
还有一个问题就是做日志记录是不是只记录异常信息就行了?其它插入删除查询更新等操作还用做日志记录吗

其实在action中捕获异常并记录到日志中后,就可以直接转到提示也了,不用再抛出给拦截器。
对于其他操作是否需要做日志记录,不知道你是说只是通过log4j记录一下,还是说要存到数据库中,看软件需求吧,有就做,没有就无所谓了,主要为了debug。
参考技术A 找本书,下点教材,一点一点就看懂了。追问

您看过书和教材吗?
您能告诉我哪本书能讲这些东西?

参考技术B 看struts2权威指南吧,这本书写得很不错的,
struts2提供了addActionError(“异常提示信息”)方法,在页面上获取就可以了,不需要用拦截器去做!

无聊系列 - 教你怎么正确处理异常

在工作中,常遇见乱处理Exception的情况:

  1. 要么吞掉异常,不打印任何日志;
  2. 要么记录日志时,日志级别不对、或者把重要的出错堆栈信息干掉,在做生产问题排查时,简直让人抓狂。

我这篇博文,也是对记录的一个开源组件,对异常自行K掉,造成我排查耗费了好久的时间--。https://www.cnblogs.com/chongsha/p/11931109.html

下面我们用一段代码对1进行举例,该代码是网上随便搜的,原作者请勿见怪。

 1  /*
 2    * 加密
 3    * 1.构造密钥生成器
 4    * 2.根据ecnodeRules规则初始化密钥生成器
 5    * 3.产生密钥
 6    * 4.创建和初始化密码器
 7    * 5.内容加密
 8    * 6.返回字符串
 9    */
10     public static String AESEncode(String encodeRules,String content){
11         try {
12             //1.构造密钥生成器,指定为AES算法,不区分大小写
13             KeyGenerator keygen=KeyGenerator.getInstance("AES");
14             //2.根据ecnodeRules规则初始化密钥生成器
15             //生成一个128位的随机源,根据传入的字节数组
16             keygen.init(128, new SecureRandom(encodeRules.getBytes()));
17               //3.产生原始对称密钥
18             SecretKey original_key=keygen.generateKey();
19               //4.获得原始对称密钥的字节数组
20             byte [] raw=original_key.getEncoded();
21             //5.根据字节数组生成AES密钥
22             SecretKey key=new SecretKeySpec(raw, "AES");
23               //6.根据指定算法AES自成密码器
24             Cipher cipher=Cipher.getInstance("AES");
25               //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
26             cipher.init(Cipher.ENCRYPT_MODE, key);
27             //8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
28             byte [] byte_encode=content.getBytes("utf-8");
29             //9.根据密码器的初始化方式--加密:将数据加密
30             byte [] byte_AES=cipher.doFinal(byte_encode);
31           //10.将加密后的数据转换为字符串
32             //这里用Base64Encoder中会找不到包
33             //解决办法:
34             //在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
35             String AES_encode=new String(new BASE64Encoder().encode(byte_AES));
36           //11.将字符串返回
37             return AES_encode;
38         } catch (NoSuchAlgorithmException e) {
39             e.printStackTrace();
40         } catch (NoSuchPaddingException e) {
41             e.printStackTrace();
42         } catch (InvalidKeyException e) {
43             e.printStackTrace();
44         } catch (IllegalBlockSizeException e) {
45             e.printStackTrace();
46         } catch (BadPaddingException e) {
47             e.printStackTrace();
48         } catch (UnsupportedEncodingException e) {
49             e.printStackTrace();
50         }
51         
52         //如果有错就返加nulll
53         return null;         
54     }

该段代码主要的问题是:

  1. 吃掉了异常,因为是公共类,连日志记录都没有
  2. 出现异常后,仍然返回了一个null值。

这个方法在我们平时使用时,如果不读源码,直接使用,第一直觉是,返回正确结果,如果不正确,那就会抛出异常。但是这段代码却返回了null,使用者遇到时,会抓狂,这是什么情况啊,为啥不对,明明没有报错,万般无奈,进代码一看。。。原来是把异常给干掉了。

对此代码做出的改进建议是:

  1. 在方法上声明throws是
  2. 如果你觉得1方案不爽,可以直接一个大的catch Exception,然后throw new RuntimeException(e.getMessage(), e);
  3. 出错了就是出错了,不能把错误自己干掉,然后返回一个null。

要么记录日志时,日志级别不对、或者把重要的出错堆栈信息干掉,在做生产问题排查时,简直让人抓狂。

在用log4j记录日志时,请正确使用logger.error()来记录日志,请注意该方法的重载,不要使用 Exception的getMessage()方法只记录异常的消息,而把异常的错误堆栈给抛弃,异常的错误堆栈是很有用的信息,会告诉你在哪行代码出错了,这样你可以快速的定位错误。

 1 package com.demo;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         try {
 7             int a = 0;
 8             int b = 1;
 9 
10             System.out.println(b / a);
11         } catch (Exception e) {
12             e.printStackTrace();
13         }
14     }
15 
16 }

 

这段代码的错误堆栈信息:

java.lang.ArithmeticException: / by zero
at com.demo.Test.main(Test.java:10)

这行错误信息at com.demo.Test.main(Test.java:10)标明了出错位置,可以快速定位是在什么地方。所以在记录日志的时候,请不要把错误堆栈信息干掉了。

 

以上是关于struts2异常处理和log4j日志记录怎么弄?的主要内容,如果未能解决你的问题,请参考以下文章

logback运行时异常怎么记录

Java基础学习补充 -- 异常处理和log4j日志

JAVA中的异常处理及日志(log4j为例)的使用

使用 log4j 在 Java 中记录运行时异常

log4j并发打印日志导致线程Block问题排查记录

java 中怎么将程序出现的异常信息保存到日志文件中