- 浏览: 2880263 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (1173)
- 名言警句 (5)
- 心情随笔 (50)
- 数据库 (57)
- Java基础 (241)
- J2EE框架 (91)
- 数据结构 (12)
- 程序设计 (21)
- WEB技术 (128)
- 网络日志 (12)
- IT资讯 (247)
- linux (64)
- solaris (2)
- 其它 (143)
- WebService (4)
- 日语学习 (2)
- 机器人 (5)
- Android (5)
- cgywin (3)
- Game (1)
- DWR (1)
- spring (8)
- canvas (1)
- Guava (3)
- Modbus (5)
- 测试 (6)
- mongodb (9)
- Quartz (2)
- Cron (1)
- windows (2)
- 持续集成 (1)
- bootstrap (3)
- 结对编程 (1)
- nodejs (1)
- Netty (1)
- 安全 (3)
- webstorm (2)
- sparkline (1)
- Job (1)
- git (3)
- Maven (3)
- knockout (5)
- jquery (1)
- bower (1)
- docker (1)
- confluence (4)
- wiki (1)
- GoogleMap (1)
- jekyll (10)
- ruby (2)
- npm (3)
- browserify (1)
- gulp (3)
- openwrt (1)
- discuz (3)
- 输入法 (1)
- JPA (1)
- eclipse (2)
- IntelliJ (1)
- css (1)
- 虚拟机 (1)
- 操作系统 (1)
- azkaban (2)
- scrum (1)
最新评论
-
pangxiea_:
你好, 想请问一下 Linux下 这么使用rxtxcomm 在 ...
使用Java进行串口通信 -
abababudei:
请教一下,这个您是怎么解决的:/dev/ttyS2enteri ...
Java应用程序的MODBUS通讯 -
xuniverse:
hannibal005 写道楼主,我问下 request.se ...
用javascript与java进行RSA加密与解密 -
atxkm:
找了一下午,终于找到了
gulp 拷贝文件时如何移除文件目录结构 -
kalogen:
gtczr 写道非常感谢,经过我自己的修改,已经完美实现。发出 ...
用javascript与java进行RSA加密与解密
在设计一个新的异常类时,首先看看是否真正的需要这个异常类。一般情况下尽量不要去设计新的异常类,而是尽量使用Java中已经存在的异常类。
如IllegalArgumentException, UnsupportedOperationException
不管是新的异常是chekced异常还是unChecked异常。我们都必须考虑异常的嵌套问题。
public void methodA()throws ExceptionA...{
…..
throw new ExceptionA();
}
方法methodA声明会抛出ExceptionA.
public void methodB()throws ExceptionB
methodB声明会抛出ExceptionB,当在methodB方法中调用methodA时,ExceptionA是无法处理的,所以ExceptionA应该继续往上抛出。一个办法是把methodB声明会抛出ExceptionA.但这样已经改变了MethodB的方法签名。一旦改变,则所有调用methodB的方法都要进行改变。
另一个办法是把ExceptionA封装成ExceptionB,然后再抛出。如果我们不把ExceptionA封装在ExceptionB中,就丢失了根异常信息,使得无法跟踪异常的原始出处。
public void methodB()throws ExceptionB...{
try...{
methodA();
……
}catch(ExceptionA ex)...{
throw new ExceptionB(ex);
}
}
如上面的代码中,ExceptionB嵌套一个ExceptionA.我们暂且把ExceptionA称为“起因异常”,因为ExceptionA导致了ExceptionB的产生。这样才不使异常信息丢失。
所以我们在定义一个新的异常类时,必须提供这样一个可以包含嵌套异常的构造函数。并有一个私有成员来保存这个“起因异常”。
public Class ExceptionB extends Exception...{
private Throwable cause;
public ExceptionB(String msg, Throwable ex)...{
super(msg);
this.cause = ex;
}
public ExceptionB(String msg)...{
super(msg);
}
public ExceptionB(Throwable ex)...{
this.cause = ex;
}
}
当然,我们在调用printStackTrace方法时,需要把所有的“起因异常”的信息也同时打印出来。所以我们需要覆写 printStackTrace方法来显示全部的异常栈跟踪。包括嵌套异常的栈跟踪。
public void printStackTrace(PrintStrean ps)...{
if(cause == null)...{
super.printStackTrace(ps);
}else...{
ps.println(this);
cause.printStackTrace(ps);
}
}
一个完整的支持嵌套的checked异常类源码如下。我们在这里暂且把它叫做NestedException
public NestedException extends Exception...{
private Throwable cause;
public NestedException (String msg)...{
super(msg);
}
public NestedException(String msg, Throwable ex)...{
super(msg);
This.cause = ex;
}
public Throwable getCause()...{
return (this.cause == null ? this :this.cause);
}
public getMessage()...{
String message = super.getMessage();
Throwable cause = getCause();
if(cause != null)...{
message = message + “;nested Exception is ” + cause;
}
return message;
}
public void printStackTrace(PrintStream ps)...{
if(getCause == null)...{
super.printStackTrace(ps);
}else...{
ps.println(this);
getCause().printStackTrace(ps);
}
}
public void printStackTrace(PrintWrite pw)...{
if(getCause() == null)...{
super.printStackTrace(pw);
}
else...{
pw.println(this);
getCause().printStackTrace(pw);
}
}
public void printStackTrace()...{
printStackTrace(System.error);
}
}
同样要设计一个unChecked异常类也与上面一样。只是需要继承RuntimeException。
4. 如何记录异常
作为一个大型的应用系统都需要用日志文件来记录系统的运行,以便于跟踪和记录系统的运行情况。系统发生的异常理所当然的需要记录在日志系统中。
public String getPassword(String userId)throws NoSuchUserException...{
UserInfo user = userDao.queryUserById(userId);
If(user == null)...{
Logger.info(“找不到该用户信息,userId=”+userId);
throw new NoSuchUserException(“找不到该用户信息,userId=”+userId);
}
else...{
return user.getPassword();
}
}
public void sendUserPassword(String userId)throws Exception ...{
UserInfo user = null;
try...{
user = getPassword(userId);
//……..
sendMail();
//
}catch(NoSuchUserException ex)(
logger.error(“找不到该用户信息:”+userId+ex);
throw new Exception(ex);
}
我们注意到,一个错误被记录了两次.在错误的起源位置我们仅是以info级别进行记录。而在sendUserPassword方法中,我们还把整个异常信息都记录了。
笔者曾看到很多项目是这样记录异常的,不管三七二一,只有遇到异常就把整个异常全部记录下。如果一个异常被不断的封装抛出多次,那么就被记录了多次。那么异常倒底该在什么地方被记录?
异常应该在最初产生的位置记录!
如果必须捕获一个无法正确处理的异常,仅仅是把它封装成另外一种异常往上抛出。不必再次把已经被记录过的异常再次记录。
如果捕获到一个异常,但是这个异常是可以处理的。则无需要记录异常
public Date getDate(String str)...{
Date applyDate = null;
SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);
try...{
applyDate = format.parse(applyDateStr);
}
catch(ParseException ex)...{
//乎略,当格式错误时,返回null
}
return applyDate;
}
捕获到一个未记录过的异常或外部系统异常时,应该记录异常的详细信息
try...{
……
String sql=”select * from userinfo”;
Statement s = con.createStatement();
……
Catch(SQLException sqlEx)...{
Logger.error(“sql执行错误”+sql+sqlEx);
}
究竟在哪里记录异常信息,及怎么记录异常信息,可能是见仁见智的问题了。甚至有些系统让异常类一记录异常。当产生一个新异常对象时,异常信息就被自动记录。
public class BusinessException extends Exception ...{
private void logTrace() ...{
StringBuffer buffer=new StringBuffer();
buffer.append("Business Error in Class: ");
buffer.append(getClassName());
buffer.append(",method: ");
buffer.append(getMethodName());
buffer.append(",messsage: ");
buffer.append(this.getMessage());
logger.error(buffer.toString());
}
public BusinessException(String s) ...{
super(s);
logTrace();
}
}
这似乎看起来是十分美妙的,其实必然导致了异常被重复记录。同时违反了“类的职责分配原则”,是一种不好的设计。记录异常不属于异常类的行为,记录异常应该由专门的日志系统去做。并且异常的记录信息是不断变化的。我们在记录异常同应该给更丰富些的信息。以利于我们能够根据异常信息找到问题的根源,以解决问题。
虽然我们对记录异常讨论了很多,过多的强调这些反而使开发人员更为疑惑,一种好的方式是为系统提供一个异常处理框架。由框架来决定是否记录异常和怎么记录异常。而不是由普通程序员去决定。但是了解些还是有益的。
5.J2EE项目中的异常处理
目前,J2EE项目一般都会从逻辑上分为多层。比较经典的分为三层:表示层,业务层,集成层(包括数据库访问和外部系统的访问)。
J2EE项目有着其复杂性,J2EE项目的异常处理需要特别注意几个问题。
在分布式应用时,我们会遇到许多checked异常。所有RMI调用(包括EJB远程接口调用)都会抛出Java.rmi.RemoteException;同时RemoteException是checked异常,当我们在业务系统中进行远程调用时,我们都需要编写大量的代码来处理这些checked异常。而一旦发生RemoteException这些checked异常对系统是非常严重的,几乎没有任何进行重试的可能。也就是说,当出现RemoteException这些可怕的checked异常,我们没有任何重试的必要性,却必须要编写大量的try…catch代码去处理它。一般我们都是在最底层进行RMI调用,只要有一个RMI调用,所有上层的接口都会要求抛出RemoteException异常。因为我们处理RemoteException的方式就是把它继续往上抛。这样一来就破坏了我们业务接口。RemoteException这些J2EE系统级的异常严重的影响了我们的业务接口。我们对系统进行分层的目的就是减少系统之间的依赖,每一层的技术改变不至于影响到其它层。,
public class UserSoaImpl implements UserSoa...{
public UserInfo getUserInfo(String userId)throws RemoteException...{
//……
远程方法调用.
//……
}
}
public interface UserManager...{
public UserInfo getUserInfo(Stirng userId)throws RemoteException;
}
同样JDBC访问都会抛出SQLException的checked异常。
为了避免系统级的checked异常对业务系统的深度侵入,我们可以为业务方法定义一个业务系统自己的异常。针对像SQLException,RemoteException这些非常严重的异常,我们可以新定义一个unChecked的异常,然后把SQLException,RemoteException封装成unChecked异常后抛出。
如果这个系统级的异常是要交由上一级调用者处理的,可以新定义一个checked的业务异常,然后把系统级的异常封存装成业务级的异常后再抛出。
一般地,我们需要定义一个unChecked异常,让集成层接口的所有方法都声明抛出这unChecked异常。
定义一个checked的业务异常,让业务层的接口的所有方法都声明抛出unChecked异常.
public DataAccessException extends RuntimeException...{
……
}
public interface UserDao...{
public String getPassword(String userId)throws DataAccessException;
}
public class UserDaoImpl implements UserDAO...{
public String getPassword(String userId)throws DataAccessException...{
String sql = “select password from userInfo where userId= ‘”+userId+”’”;
try...{
…
//JDBC调用
s.executeQuery(sql);
…
}catch(SQLException ex)...{
throw new DataAccessException(“数据库查询失败”+sql,ex);
}
}
}
public class BusinessException extends Exception...{
…..
}
public interface UserManager...{
public Userinfo copyUserInfo(Userinfo user)throws BusinessException...{
Userinfo newUser = null;
try...{
newUser = (Userinfo)user.clone();
}catch(CloneNotSupportedException ex)...{
throw new BusinessException(“不支持clone方法:”+Userinfo.class.getName(),ex);
}
}
}
J2EE表示层应该是一个很薄的层,主要的功能为:获得页面请求,把页面的参数组装成POJO对象,调用相应的业务方法,然后进行页面转发,把相应的业务数据呈现给页面。表示层需要注意一个问题,表示层需要对数据的合法性进行校验,比如某些录入域不能为空,字符长度校验等。
J2EE从页面所有传给后台的参数都是字符型的,如果要求输入数值或日期类型的参数时,必须把字符值转换为相应的数值或日期值。
如果表示层代码校验参数不合法时,应该返回到原始页面,让用户重新录入数据,并提示相关的错误信息。
通常把一个从页面传来的参数转换为数值,我们可以看到这样的代码
ModeAndView handleRequest(HttpServletRequest request,HttpServletResponse response)throws Exception...{
String ageStr = request.getParameter(“age”);
int age = Integer.parse(ageStr);
…………
String birthDayStr = request.getParameter(“birthDay”);
SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);
Date birthDay = format.parse(birthDayStr);
}
上面的代码应该经常见到,但是当用户从页面录入一个不能转换为整型的字符或一个错误的日期值。
Integer.parse()方法被抛出一个NumberFormatException的unChecked异常。但是这个异常绝对不是一个致命的异常,一般当用户在页面的录入域录入的值不合法时,我们应该提示用户进行重新录入。但是一旦抛出unchecked异常,就没有重试的机会了。像这样的代码造成大量的异常信息显示到页面。使我们的系统看起来非常的脆弱。
同样,SimpleDateFormat.parse()方法也会抛出ParseException的unChecked异常。
这种情况我们都应该捕获这些unChecked异常,并给提示用户重新录入。
ModeAndView handleRequest(HttpServletRequest request,HttpServletResponse response)throws Exception...{
String ageStr = request.getParameter(“age”);
String birthDayStr = request.getParameter(“birthDay”);
int age = 0;
Date birthDay = null;
try...{
age=Integer.parse(ageStr);
}catch(NumberFormatException ex)...{
error.reject(“age”,”不是合法的整数值”);
}
…………
try...{
SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);
birthDay = format.parse(birthDayStr);
}catch(ParseException ex)...{
error.reject(“birthDay”,”不是合法的日期,请录入’MM/dd/yyy’格式的日期”);
}
}
在表示层一定要弄清楚调用方法的是否会抛出unChecked异常,什么情况下会抛出这些异常,并作出正确的处理。
在表示层调用系统的业务方法,一般情况下是无需要捕获异常的。如果调用的业务方法抛出的异常相当于第二个返回值时,在这种情况下是需要捕获业务方法的异常并进行正确的处理。
发表评论
-
高级Java程序员值得拥有的10本书
2015-05-04 07:24 816Java是时下最流行的编程语言之一。市面上也出现了适合初学者 ... -
深入理解java异常处理机制
2015-01-30 09:30 13361. 引子 try…catch…fi ... -
java 运行时参数设置
2015-01-07 09:13 874JVM的运行时参数: -Xms为执行单元内存的1/4, ... -
每个Java开发者都应该知道的5个JDK工具
2014-12-29 12:37 1147JDK是Java语言的软件开 ... -
使用双重锁判定可以大幅降低锁的征用
2014-12-29 12:30 755class ObjInstance { //单例 pri ... -
MAVEN Scope使用说明
2014-11-24 09:40 765在Maven的依赖管理中,经常会用到依赖的scope设置。这 ... -
Spring4 quartz job xml configuration
2014-11-11 09:46 14451. 定义job details public ... -
Add items into list in one line using guava
2014-11-10 10:54 728//@formatter:off fina ... -
配置动态读取(变化)文件 in Spring
2014-11-10 08:51 13301. 从环境变量中读取路径: <bean id=&q ... -
JAVA实现AES加密与解密
2014-11-04 15:34 666package com.eifesun.monitor.up ... -
Netty4.x分析
2014-07-31 11:06 1478官网定义: netty是一个异步、事件驱动的网络应用框架,用 ... -
Ways to sort lists of objects in Java based on multiple fields
2014-07-21 17:19 7801. the first way: Sorting wit ... -
how to parse a String to BigDecimal
2014-07-21 10:08 926private BigDecimal parsePrice( ... -
order list using google guava
2014-07-21 09:08 892Predicate<String> filter ... -
Java 读文件操作
2014-07-08 14:09 8941. only use java core, no exte ... -
怎样使Java 中测试按一定顺序执行
2014-03-10 11:27 1333@FixMethodOrder(MethodSorters. ... -
如何实现在当类初始化时,自动调动某个方法
2014-02-14 14:44 970有两种思路, 1. 将这个类实现为thread类 (or ... -
持续集成JenkinsAPI常见用法
2014-02-10 13:54 43jenkins(持续集成开源工具)提供了丰富的api接口,基 ... -
Sonar 安装与使用
2014-01-13 10:49 1741Sonar 是一个用于代码质量管理的开放平台。通过插件机制, ... -
源代码管理分析工具 Source Navigator的安装与使用
2014-01-13 09:51 1904Source-Navigator是原来redhat开发的一个 ...
相关推荐
ztsc_109339.apk
永磁同步电机的高频正弦电压注入的速度观测,Simulink,PMSM,高频正弦。
智慧燃气发展研究报告
如何通过智能卡读写器SDK接入鸿蒙操作系统?通过智能卡读写器提供的SDK范例可以将智能卡读写器接入在运行鸿蒙操作系统的智能终端设备上。
谭浩强编写的《C程序设计(第五版)》PPT、书中源码、习题答案以及习题库
人力资源+大数据+薪酬报告+涨薪调薪,在学习、工作生活中,越来越多的事务都会使用到报告,通常情况下,报告的内容含量大、篇幅较长。那么什么样的薪酬报告才是有效的呢?以下是小编精心整理的调薪申请报告,欢迎大家分享。相信老板看到这样的报告,一定会考虑涨薪的哦。
分布式驱动汽车稳定性控制。 采用分层式直接横摆力矩控制,上层滑模控制,下层基于轮胎滑移率最优分配。 滑模控制跟踪横摆角速度和质心侧偏角误差。 七自由度整车模型输出实际质心侧偏角和横摆角速度,二自由度模型输出理想质心侧偏角和横摆角速度。 附m文件,有参考文献和说明文档
注意:此文档为最终版本,方便大家记录,但更新主要还是在博客更新
汇川.H5U框架程序,汇川TIT700系列触摸屏框架程序 1.汇川H5U-A8系列cpu 自制封装多个FB功能块程序,轴控制功能块,气缸动作报警功能块,XY矩阵功能块,等等。 只需写动作步序,其他全部调用FB 和HMI可以无实物仿真 仿真HMI地址127.0.0.1 A1349.H5U原框架
学生作业-作业打卡盖章。该项目为html前端项目,依据学生作业提交情况,通过点击名字进行打卡盖章。涉及html、js、css,其中js中涉及监听函数;窗口中的列表数据来源于data.jso,可自行修改
Spring面试专题.pdf
2025年蓝色简约时尚婚礼邀请函模板
深层过滤纸板是一种由纤维素材料制成的平板或薄片,具有过滤液体或气体的能力。它通常由纤维素纤维(如木浆)经过湿法造纸工艺制成,形成一张薄而均匀的纸板。深层过滤纸板设计用于过滤任何类型的液体,包括葡萄酒、油、啤酒和果汁等,广泛应用于食品饮料、制药、化工等领域。 随着酿酒行业和饮料行业的不断壮大,对深层过滤纸板的需求也在增加。深层过滤纸板常用于过滤液体中的杂质和固体颗粒,确保产品的质量和纯度。因此,这些行业的发展推动了过滤纸板的需求。为了满足酿酒行业和饮料行业对过滤效果、速度和成本的不断追求,深层过滤纸板制造商进行了技术创新和改进。他们不断改良过滤纸板的材料、结构和制造工艺,以提高其过滤效率和性能,同时降低生产成本。环保意识的提升推动了过滤纸板行业朝着绿色、可持续发展的方向发展。包括可降解材料的应用,再生纤维的使用以及生产过程的绿色化都是行业发展的趋势。 目前在全球范围内,工业化的发展仍处于高速阶段,企业在生产过程中要求更高的过滤处理标准,从而促进了深层过滤纸板行业的发展。随着生物技术产业的发展,越来越多的实验室需要使用过滤纸板进行细胞和菌群的分离,同时也需要更高精度的滤料来处理许多疾病的检
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
easy-interceptor修改请求头和响应头.zip
代码复现;冷热电气多门互补的微能源网鲁棒优化调度MATLAB复现 随着能源结构调整,集成风/光等可再生能源输入、冷热电气等多种能源互补输出的微能源网得到了逐步发展,如何协调调度微能源网内冷热电气源网荷成为当前研究热点。 建立了冷热电气多能互补的微能源网在孤岛/并网模式下的协调调度模型,并利用供热/供冷系统的热惯性和热/冷负荷的柔性,发挥供热/供冷系统的“储能”功能,以电转气(P2G)装置实现电—气网络双向互通。 模型采用鲁棒线性优化理论将随机优化模型进行确定性转化,取得经济性和鲁棒性的适当折中。 算例仿真验证了温度负荷储能特性对微能源网灵活调度的优化作用和鲁棒性指标对优化结果的协 调作用。 关键词:微能源网;多能互补;温度负荷;储能特性;鲁棒优化
三电平T型变器双闭环PI控制-调制实现在60度坐标系 变器 减少了普通SVPWM的矢量计算时间,在60度坐标系完成高效计算,控制效果很好。 可以发参考资料
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
箱线图(Box Plot)是一种用于展示数据分布的图形工具,能够有效地显示数据的集中趋势和离散程度。以下是箱线图的主要特点和组成部分: 主要特点 数据分布:箱线图可以清晰地展示数据的中位数、四分位数和潜在的异常值。 多组比较:可以将多组数据在同一张图中进行可视化,便于比较不同组之间的差异。 易于理解:由于其结构清晰,读取和理解相对简单。 使用场景 数据分析:用于探讨数据的分布和变化,识别异常值。 统计总结:在数据报告和研究中,用于直观表达数据特征。
ChromeDriver 是一个用于自动化 Chrome 浏览器的工具,它是由 Selenium WebDriver 提供支持的。在测试领域,尤其是Web应用程序的自动化测试中,ChromeDriver扮演着至关重要的角色。标题"chromedriver version 118.0.5993.70"表明这是 ChromeDriver 的一个特定版本,版本号为118.0.5993.70,通常这样的更新会带来性能优化、新功能以及对Chrome浏览器新版本的支持。 描述中的“chromedriver测试版本”意味着这可能是一个用于测试目的的构建,可能包含了最新的改进或者尚未广泛发布的特性。开发者和测试工程师会使用这样的测试版本来确保他们的自动化测试脚本能够兼容即将推出的 ChromeDriver 正式版本。 标签“测试 chromedriver”进一步强调了该软件在测试环境中的应用,特别是与 Chrome 浏览器的自动化测试相关的场景。ChromeDriver 允许测试人员通过编写 Selen。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。