版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第5章 日志及异常处理我们学习过Java异常处理和JSP的相关课程。本章,我们将对Web应用程序中得异常集中处理。对于情况严重的系统异常我们需要将其写入日志文件,对于用于操作不规范的异常我们应该给出客户友好的提示信息。在本章中我们将讲解如何使用lor4j框架来实现日志文件的记录,以及如何设计web应用程序的结构来实现相应异常的处理。5.1 日志概述5.1.1 日志简介软件的运行过程离不开日志。日志的主要作用是记录一些重要的操作信息,比如应用权限的修改、程序运行的系统异常、导致致命错误的异常,日志文件记录的信息一般包括错误类型、时间、错误点。日志文件能够帮助用户提前发现和避免灾难,并且找到系统发
2、生的根本原因。位程序的升级、维护提供有力保障。比如当你开发完一个项目、并交互给客户使用后发现在客户的环境中不能运行。由于是以window服务的防是启动的web服务器,所有不能使用控制台的方式查看异常信息,这时将给维护人员或实施人员将无从下手。但如果将系统的异常信息记录到日志文件中,维护人员或实施人员就可以根据日志文件中记录的运行信息解决问题。也就是说在我们开发的系统中需要将运行的一些信息、状态、过程使用文件流的方式将其写在硬盘的某一个文件或多个文件中,这就是我们所说的日志记录。5.1.2 log4j简介log4j是Apache的一个开放源代码项目,log4j框架是用Java语言编写的标准日志记
3、录框架。作为Jakarta项目的一部分,它在Apache软件许可证(Apache Software License)下分发,以速度和灵活性为中心概念:log4j环境是完全可配置的,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。此外,通过Log4j其他语言接口,您可以在C、C+、.Net、PL/SQL程序
4、中使用Log4j,其语法和用法与在Java程序中一样,使得多语言分布式系统得到一个统一一致的日志组件模块。而且,通过使用各种第三方扩展,您可以很方便地将Log4j集成到J2EE、JINI甚至是SNMP应用中。log4j的好处在于:l 通过修改配置文件,就可以决定log信息的目的地控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等。l 通过修改配置文件,可以定义每一条日志信息的级别,从而控制是否输出。在系统开发阶段可以打印详细的log信息以跟踪系统运行情况,而在系统稳定后可以关闭log输出,从而在能跟踪系统运行情况的同时,又减少了垃圾代码(Syste
5、m.out.println(.)等)。l 使用log4j,需要整个系统有一个统一的log机制,有利于系统的规划。5.2 log4j的使用log4j是apache提供的开源的第三方框剪,也就是在在j2ee开发包中并没有对log4j的支持,当我们需要使用log4j时必须添加相应的jar包。根据前面对于log4j的介绍我们知道它是通过配置文件来设置输入的内容、格式、目标,所以我们也必须掌握log4j配置文件的编写。最后还需在代码中添加log4j的调用。由此可知log4j日志系统的使用步骤有:添加log4j支持、配置log4j配置文件、在java代码中调用log4j记录日志。5.2.1 添加log4j
6、首先需要获取log4j的jar包,可以在apache的官方网站中下载、其下载页面路径是/,该页面中包含log4j的所有版本下载,如:1.2、1.3、2.0。下载后将其保存在指定目录中。然后就可以将log4j的jar包添加到web应用程序中。选择web应用程序项目点击右键à【Properties】à【Java Build Path】出现如图5-1所示的界面。图5-1 添加jar包选择【Libraries】à【Add External JARs】出现如图5-2所示的文件选择对话框。图5-2 选择log4j支持包选择log
7、4j支持包完成添加。5.2.2 创建log4j配置文件log4j配置文件必须保存在源代码跟目录中、及src下,并且文件名是perties(也可以使用log4j.xml文件配置)。选择src目录点击右键,选择【New】à【File】选项,弹出“新建文件”对话框,输入文件名“perties”,点击“完成”按钮,创建工作结束,如图5-3所示。图5-3 创建配置文件src中的perties配置文件是专门用来配置日志信息的输出内容、格式等。该配置文件的内容如下:# 配置到控制台的日志信息输出源 #log4j.appender.stdout
8、= org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target = System.outlog4j.appender.stdout.layout = org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern = %d %m %n# 配置到文件的日志信息输出源 #log4j.appender.f = org.apache.log4j.FileAppenderlog4j.appender.f.File = i:/test.loglog4j.a
9、ppender.f.layout = org.apache.log4j.PatternLayoutlog4j.appender.f.layout.ConversionPattern = %dyyyy-MM-dd HH:mm:ss %l %m %n# 设置日志信息的输出级别和启动的输出源 #log4j.rootLogger=warn,stdoutMyEclipse中属性文件默认的编码格式为ISO-8859-1,该编码不支持中文。当属性文件中包含中文内容时将无法保存,此时可以修改文件的编码格式,选择菜单【Window】à【Preferences】à【Genernal】à
10、;【Content Types】出现如图5-4所示的文档格式设置界面。图5-4 修改编码格式选择图5-4中的ContentTypes中的【Text】à【Java Properties File】,修改Default encoding的值为“UTF-8”,即将属性文件的默认编码格式修改为“UTF-8”字符集。如图5-5所示。图5-5 修改编码格式点击【Update】à【OK】完成编码格式修改。在perties文件中所配置的内容包含如下几点:1、输出源配置输出源配置是指将日志信息以指定格式输出到指定的目标,一般目标分为两种、即控制台和文件。如果输出目标类是时控
11、制台则使用org.apache.log4j.ConsoleAppder类实现输出管理、目标属性为System.out(系统标准输出流);如果输出目标是日志文件则使用org.apache. log4j.FileAppender类实现输出管理、目标属性File登录日志文件路径和文件名。当然日志文件输出目标除了控制台、文件外还有HTML页面等形式。2、输出源布局配置输出源都需要使用org.apache.log4j.PatternLayout类实现输出日志内容格式和布局管理,在配置文件中通过log4j.appender.f.layout.ConversionPattern配置PatternLayout
12、类的日志信息格式。%d表示在日志信息中出当前系统时间、时间的格式通过后面的一个日期格式的字符串表达式控制(字符串表达式的格式和SimpleDateFormat)相同;%l表示在日志信息中输出事件发生的文字,包括雷鸣、发生的线程、以及代码中的行数。例如:输出日志信息为:com.sanlian.javaWeb.ch5.Test.main(Test.java:16)说明日志事件发生在Test类中的main线程中,在代码中的行数为第16行;%p表示输出日志信息的级别;%m用来输出调用log4j代码中的指定信息;%n用于输出一个回车换行符。3、优先级配置在log4j中的日志信息是有优先级别的,通过log
13、4j.rootLogger配置。在log4j中的优先级有:off、fatal、error、warn、info、debug、all或者您定义的级别。log4j建议只使用四个级别,优先级从高到低分别是error、warn、info、debug。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。假如在一个级别为q的Logger中发生一个级别为p的日志请求,如果p>=q,那么请求将被启用。比如在配置文件定义的输出级别是info,则应用程序中所有debug级别的日志信息将不被打印出来。因为debug的优先级别小于info,所以不会输出。4、启动输出源在配置文件中配置的输出目标不
14、会都起作用,只是使用到的输出源才会起效,这需要在配置优先级的log4j.rootLogger后添加相应的输出源,如配置文件中的:log4j.rootLogger=warn,stdout表示在设置输出级别为warn的同时启动stdout输出源,及日志信息将会输出到控制台,但是不会输出到e盘的test.log文件中。当然在配置文件中也可以启动多个输出源,如:log4j.rootLogger=warn,stdout,f表示将日志信息同时输出在控制台和e:/test.log文件中。5、注释在属性文件中(即后缀名为.properties的文件)使用“#”编写注释。5.2.3 使用log4j输出日志当完成
15、支持添加和配置文件添加之后就可以在程序中使用log4j了。在例5-1中我们通过测试类来实现不同级别的日志信息输出。例5-1:记录日志信息package com.sanlian.javaWebAd.ch5;import org.apache.log4j.Logger;public class Test public static void main(String args) /获得日志记录器,这个记录器将负责控制日志信息Logger log = Logger.getLogger(Test.class);/调用log对象的相应方法输出不同级别的日志信息/输出fatal级别的日志信息log.fata
16、l("-fatal-");/输出error级别的日志信息log.error("-error-");/输出warn级别的日志信息log.warn("-warn-");/输出info级别的日志信息("-info-");/输出debug级别的日志信息("-debug-");在上例中,我们使用日志记录器的相应方法输出了每种级别的日志信息。其输出内容如图5-6所示。图5-6 log4j输出结果因为在配置文件中设置了输出级别为warn,所以比warn级别低的info、debu
17、g信息没有被输出。又因为没有在配置文件中启动文件输出源,所示在i盘中不能找到test.log文件和日志信息。如果修改配置文件的级别和输出源如下:log4j.rootLogger=debug,stdout,f运行时将看到空台的内容如图5-7所示。图5-7 输出所有级别的日志信息在i盘中生成的test.log内容如图5-8所示。图5-8 日志文件对比5-7和5-8我们可以看出在日志文件中记录的每个日志信息所发生的位置,这是因为我们在文件输出源的布局方式中使用%l的缘故。5.3 web应用程序架构设计在web应用程序中有很多的异常,如果不进行相应的处理在页面将不能得到友好的提示信息,并且也不能为维护
18、人员提供技术保障。在web应用程序中的异常通常分为两种类型,即系统异常及业务异常。系统异常通常需要记录到日志文件中,方便维护人员解决问题;业务异常需要返回给客户端作出友好的提示。结合MVC设计模式和log4j日志系统可以对系统进行如图5-9所示的架构,以便将系统异常记录日志、将业务异常提示给客户端。图5-9 web应用程序架构图图5-9中的黑色实体线条表示请求走向和模块调用走向。当请求进入web应用程序是首先都必须经过BaseServlet,然后才是执行相应的控制处理servlet,通过servlet调用业务方法,业务方法调用DAO访问数据库。图5-9中的红色虚线表示异常处理的流程。在程序中异
19、常可能会在每一个阶段发生,但是所有的异常都向外抛出,一直抛到BaseServlet集中处理。为了能够在BaseServlet中方便集中处理异常,我们在程序中创建两个自定义异常类,分别是BizException、SysException。其实现代码如下:BizSysException类package com.sanlian.javaWebAd.ch5.util;/* * 自定义业务异常 */public class BizException extends RuntimeException public BizException(String message)super(message);Sys
20、Exception类package com.sanlian.javaWebAd.ch5.util;/* * 自定义系统异常 */public class SysException extends RuntimeException public SysException(String message)super(message);BizException、SysException通过继承RuntimeException可以降低代码中异常手动抛出的痛苦,因为运行时异常不需要在方法中使用trycatch处理、也不需要在方法手使用throws显示的声明。在BaseServlet中通过判断异常的类型来实
21、现不同的处理,其实现代码如下:BaseServlet类package com.sanlian.javaWebAd.ch5.web.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.log4j.Logger;im
22、port com.sanlian.javaWebAd.ch5.util.BizException;public class BaseServlet extends HttpServlet Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException trysuper.service(request, response);catch(Exception e)/判断异常的内容if(e instanceof Bi
23、zException)/自定义异常,将异常信息保存到request中request.setAttribute("errorMessage", e.getMessage();elseString message = "系统正在升级维护,请于管理员联系!"request.setAttribute("errorMessage",message);/记录日志 log4jLogger log = Logger.getLogger(BaseServlet.class);log.warn(e.getMessage();/跳转到错误页面String
24、url = "/common/error.jsp"request.getRequestDispatcher(url).forward(request, response);在该BaseServlet中通过判断异常类型进行操作。如果是业务类型则直接将业务信息保存在request中,并跳转错误页面显示业务信息;如果是系统异常则将异常信息记录到日志文件中,并保存一个友好的提示信息在request中,并跳转到错误页面提示。普通的控制Servlet通过继承至BaseServlet来实现异常的总处理。错误页面的实现代码如下所示:error.jsp<% page language=
25、"java" pageEncoding="UTF-8"%><html><head> <title>错误信息</title></head> <body> $requestScope.errorMessage </body></html>如例5-2通过该架构完成用户登录操作。例5-2:用户登录通过如上的系统架构可知登录功能的流程如图5-10所示。图5-10 登录流程图数据库名为DB,其中有一表个内容如下:create table user_info ( us
26、er_id int identity(1,1) primary key, user_no varchar(15) not null, user_account varchar(30) not null, user_pass varchar(30) not null, user_name varchar(20) not null, user_pid varchar(18) not null, user_sex bit default(1) not null, user_birthday datetime not null, user_address varchar(100) null, user
27、_email varchar(50) null)创建和表相对应的实体类UserInfo。1、DataUtil类DataUtil用于创建数据库连接对象和关闭数据库连接对象,实现代码如下:package com.sanlian.javaWebAd.ch5.pers;import java.sql.Statement;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;/* * 数据功能类 * 得到数据库连接、关闭数据库连接 */
28、public class DataUtil /* * 得到数据库连接对象 */public static Connection getConn() throws ExceptionConnection conn = null;Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");String url = "jdbc:sqlserver:/localhost:1433;databaseName=DB"conn = DriverManager.getConnection(url,"
29、;sa","123456");return conn;/* * 关闭查询 * param rs 结果集 * param st 上下文 * param conn 连接 */public static void closeConn(ResultSet rs,Statement st,Connection conn)try rs.close(); catch (Exception e) try st.close(); catch (Exception e) try conn.close(); catch (Exception e) /* * 关闭增、删、该 * para
30、m st 上下文 * param conn 连接 */public static void closeConn(Statement st,Connection conn)try st.close(); catch (Exception e) try conn.close(); catch (Exception e) 2、UserDAO类该类称为数据访问类。在web应用程序中将所有的数据访问类统称为数据访问层,主要用于对数据的数据进行访问,执行增、删、改、查sql语句。UserDAO类的实现代码如下所示:package com.sanlian.javaWebAd.ch5.pers.dao;imp
31、ort java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import com.sanlian.javaWebAd.ch5.entity.UserInfo;import com.sanlian.javaWebAd.ch5.pers.DataUtil;import com.sanlian.javaWebAd.ch5.util.SysException;public class UserDAO public UserInfo queryByAccount(String account)Us
32、erInfo user = null;/定义数据库访问对象Connection conn = null;PreparedStatement q = null;ResultSet rs = null;try conn = DataUtil.getConn(); /得到连接/创建sql语句预编译对象String sql = "select * from user_info where user_account=?"q = conn.prepareStatement(sql);/设置参数q.setString(1, account);/执行rs = q.executeQuery(
33、);if (rs.next() user = new UserInfo();user.setUserAccount(rs.getString("user_account");user.setUserPass(rs.getString("user_pass");user.setUserName(rs.getString("user_name"); catch (Exception e) /将系统异常转换为自定义系统异常throw new SysException(e.getMessage();finallyDataUtil.closeC
34、onn(rs, q, conn);return user;3、UserBiz类用户信息业务类。在web应用程序中所有的业务类组成了业务逻辑成,主要用于完成业务逻辑处理。比如登录判断,订单处理等。UserBiz类的实现代码如下:package com.sanlian.javaWebA;import com.sanlian.javaWebAd.ch5.entity.UserInfo;import com.sanlian.javaWebAd.ch5.pers.dao.UserDAO;import com.sanlian.javaWebAd.ch5.util.BizException
35、;public class UserBiz private UserDAO udao = new UserDAO();/* * 登录业务方法 * param account 帐号 * param pwd 密码 * return */public UserInfo login(String account,String pwd)UserInfo emp = null;UserInfo temp = this.udao.queryByAccount(account);if(temp != null)if(pwd!=null && pwd.equals(temp.getUserPas
36、s()/登录成功emp = temp;elsethrow new BizException("密码错误");elsethrow new BizException("账号错误");return emp;在登录的业务方法中,根据客户端输入的帐号、密码进行验证,并使用业务异常的方式将业务信息返回到上一层(即控制层、Servlet中)。4、LoginServletpackage com.sanlian.javaWebAd.ch5.web.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.sanlian.javaWebA.UserBiz;import com.sanlian.javaWebAd.ch5.entity.UserInfo;public class LoginSer
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 境外项目并购合同范本
- 公交轮胎租赁合同范本
- 工艺品展出合同范本
- 2026年养老机构管理业务培训考试试卷
- 应急物资储备、更新管理细则
- 线上借款合同范本
- 民房钢筋加工合同范本
- 专用车生产项目可行性研究报告
- 商品房现房合同范本
- 公司清凉饮品采购合同范本
- 3.2.1 分数除以整数 教学课件2026-2027学年人教版数学六年级上册
- 译林版七年级英语上册知识清单
- 2026秋冀少版新教材七年级上册生物学每课知识点清单
- 中国重症患者液体管理专家共识(2026版)
- 2026国睿防务公司反无人机雷达总体工程师岗位招聘笔试历年参考题库附带答案详解
- 雨课堂学堂在线学堂云《声纳技术(中国人民解放军海军航空)》单元测试考核答案
- 重症医学临床路径标准化
- 稻盛和夫心法课件
- 雨课堂学堂在线学堂云《临床伦理与科研道德(山东大学)》单元测试考核答案
- 2025年住院医师规范化师资培训考试题附答案
- 保险公司医生健康知识讲座
评论
0/150
提交评论