Java开发规范V1.2 - 图文

更新时间:2024-01-02 06:14:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

软件开发项目管理培训

Java开发规范

Java Development Specification

版本 1.2

编写人: 校对人: 复查人: 批准人: 编写时间: 校对时间: 复查时间: 批准时间: 软件开发项目管理培训

修订历史记录

日期 2010-5-10 2010-9-1 2011-6-1 版本 1.0 1.1 1.2 完成编码规范制定 变更说明 增加了第12章安全编码规范 重新完善部分内容并增加了JSP规范 软件开发项目管理培训

目录

第1章 绪论 ________________________________________________________________________________ 1 1.1 目的 _________________________________________________________________________________ 1 1.2 范围 _________________________________________________________________________________ 1 1.3 版权声明 _____________________________________________________________________________ 1 1.4 参考资料 _____________________________________________________________________________ 1 1.5 概述 _________________________________________________________________________________ 1 第2章 代码组织与风格 ______________________________________________________________________ 2 2.1 基本原则 _____________________________________________________________________________ 2 2.2 缩进 _________________________________________________________________________________ 2 2.3 长度 _________________________________________________________________________________ 3 2.4 行宽 _________________________________________________________________________________ 3 2.5 间隔 _________________________________________________________________________________ 3 2.6 对齐 _________________________________________________________________________________ 4 2.7 括号 _________________________________________________________________________________ 5 2.8代码风格 ______________________________________________________________________________ 5 第3章 注释 ________________________________________________________________________________ 6 3.1 基本原则 _____________________________________________________________________________ 6 3.2 JavaDoc _______________________________________________________________________________ 6 3.3 文件与包注释 _________________________________________________________________________ 6 3.4 类、接口注释 _________________________________________________________________________ 7 3.5 方法注释 _____________________________________________________________________________ 8 3.6 其他注释 _____________________________________________________________________________ 9 3.7 注释参考表 ___________________________________________________________________________ 9 第4章 命名 _______________________________________________________________________________ 11 4.1 基本原则 ____________________________________________________________________________ 11 4.2 文件、包 ____________________________________________________________________________ 12 4.3 类、接口 ____________________________________________________________________________ 12 4.4 字段 ________________________________________________________________________________ 12 4.5 方法 ________________________________________________________________________________ 13 4.6 异常 ________________________________________________________________________________ 14 4.7 命名约定表 __________________________________________________________________________ 15 第5章 声明 _______________________________________________________________________________ 17 5.1 基本原则 ____________________________________________________________________________ 17 5.2 包 __________________________________________________________________________________ 17 5.3 类、接口 ____________________________________________________________________________ 17 5.4 方法 ________________________________________________________________________________ 18 5.5 字段定义语法规范 ____________________________________________________________________ 19 5.6 示例 ________________________________________________________________________________ 20 第6章 类与接口 ___________________________________________________________________________ 21 6.1 基本原则 ____________________________________________________________________________ 21 6.2 抽象类与接口 ________________________________________________________________________ 22 6.3 继承与组合 __________________________________________________________________________ 22 6.4 构造方法和静态工厂方法_______________________________________________________________ 22 6.5 toString(),equals(),hashCode()... ___________________________________________________________ 23 第7章 方法 _______________________________________________________________________________ 25 7.1 基本原则 ____________________________________________________________________________ 25 7.2 参数和返回值 ________________________________________________________________________ 26 第8章 表达式与语句 _______________________________________________________________________ 27 8.1 基本原则 ____________________________________________________________________________ 27 8.2 控制语句 ____________________________________________________________________________ 27 8.3 循环语句 ____________________________________________________________________________ 29 第9章 错误与异常 _________________________________________________________________________ 29 9.1 基本原则 ____________________________________________________________________________ 29

软件开发项目管理培训

9.2 已检查异常与运行时异常_______________________________________________________________ 30 9.3 异常的捕捉与处理 ____________________________________________________________________ 31 第10章 测试与BUG跟踪 ____________________________________________________________________ 31 10.1 基本原则 ___________________________________________________________________________ 31 10.2 测试驱动开发 _______________________________________________________________________ 32 10.3 Junit单元测试 _______________________________________________________________________ 32 10.4 自动测试与持续集成 _________________________________________________________________ 32 10.5 Bug跟踪和缺陷处理 __________________________________________________________________ 33 第11章 性能 ______________________________________________________________________________ 33 11.1 基本原则 ___________________________________________________________________________ 33 11.2 String与StringBugffer _________________________________________________________________ 33 11.3 集合 _______________________________________________________________________________ 34 11.4 对象 _______________________________________________________________________________ 34 11.5 同步 _______________________________________________________________________________ 35 11.6 final ________________________________________________________________________________ 35 11.7 垃圾收集和资源释放 _________________________________________________________________ 35 第12章 安全隐患及预防措施 ________________________________________________________________ 36 12.1 会话标识未更新 _____________________________________________________________________ 36 12.2 不充分帐户封锁 _____________________________________________________________________ 38 12.3 可预测的登录凭证 ___________________________________________________________________ 40 12.4 登录错误消息凭证枚举 _______________________________________________________________ 41 12.5 已解密的登录请求 ___________________________________________________________________ 42 12.6 SQL 注入 ___________________________________________________________________________ 45 12.7 跨站点脚本攻击 _____________________________________________________________________ 52 12.8 跨站点请求伪造 _____________________________________________________________________ 53 12.9 数据库错误模式 _____________________________________________________________________ 55 12.10 应用程序错误 ______________________________________________________________________ 56 12.11高速缓存的页面 _____________________________________________________________________ 58 12.12 HTML注释敏感信息泄露 _____________________________________________________________ 59 12.13 文件的替代版本 ____________________________________________________________________ 60 12.14应用程序测试脚本 ___________________________________________________________________ 61 12.15客户端的(JavaScript)Cookie 引用 ____________________________________________________ 62 12.16 BEA WebLogic 管理界面 ______________________________________________________________ 63 第13章 JSP开发规范 _______________________________________________________________________ 65 13.1目录结构 ____________________________________________________________________________ 65 13.2文件命名 ____________________________________________________________________________ 66 13.3基本原则 ____________________________________________________________________________ 67

软件开发项目管理培训

Java 开发规范

第1章 绪论 1.1 目的

本规范的目的是使本组织能以标准的、规范的方式设计和编码。通过建立编码规范,以使每个开发人员养成良好的编码风格和习惯;并以此形成开发小组编码约定,提高程序的可靠性、可读性、可修改性、可维护性和一致性等,增进团队间的交流,并保证软件产品的质量。

1.2 范围

本规范适用于其下所有软件项目、产品等的设计、开发以及维护、升级等。 本规范适用于所有软件开发人员,在整个软件开发过程中必须遵循此规范。

1.3 版权声明 1.4 参考资料

《Java 编程指南》 《Sun Java语言编码规范》 《Effictive Java》

1.5 概述

对于代码,首要要求它必须正确,能够按照设计预定功能去运行;第二是要求代码必须清晰易懂,使自己和其他的程序员能够很容易地理解代码所执行

1

软件开发项目管理培训

的功能等。然而,在实际开发中,每个程序员所写的代码却经常自成一套,很少统一,导致理解困难,影响团队的开发效率及系统的质量等。因此,一份完整并被严格执行的开发规范是非常必须的,特别是对软件公司的开发团队而言。 最根本的原则: 代码虽然是给机器运行的,但却是给人读的!

运用常识。当找不到任何规则或指导方针,当规则明显不能适用,当所有的方法都失效时, 运用常识并核实这些基本原则。这条规则比其它所有规则都重要。常识是必不可少。

当出现该情况时,应当及时收集并提交,以便对本规范进行修改。

第2章 代码组织与风格 2.1 基本原则

代码的组织和风格的基本原则是:便于自己的开发,易于与他人的交流。 因个人习惯和编辑器等可以设臵和形成自己的风格,但必须前后一致,并符合本规范的基本要求和原则。

本章所涉及到的内容一般都可在Java集成编辑环境中进行相应设臵,也可由Ant等调用check style等来进行自动规整。

2.2 缩进

子功能块当在其父功能块后缩进。

当功能块过多而导致缩进过深时当将子功能块提取出来做为子方法。 代码中以TAB(4个字符)缩进,在编辑器中请将TAB设臵为以空格替代,否则在不同编辑器或设臵下会导致TAB长度不等而影响整个程序代码的格式。例如:

缩进示例 : public void methodName(){

2

软件开发项目管理培训

if(some condition){ for(…){ //some sentences }//end for }//end if }

2.3 长度

为便于阅读和理解,单个方法的有效代码长度当尽量控制在100行以内(不包括注释行),当一个功能模块过大时往往造成阅读困难,因此当使用子方法等将相应功能抽取出来,这也有利于提高代码的重用度。

单个类也不宜过大,当出现此类情况时当将相应功能的代码重构到其他类中,通过组合等方式来调用,建议单个类的长度包括注释行不超过1500行。 尽量避免使用大类和长方法。

2.4 行宽

页宽应设臵为80字符。一般不要超过这个宽度, 这会导致在某些机器中无法以一屏来完整显示, 但这一设臵也可以灵活调整。在任何情况下, 超长的语句应该在一个逗号后或一个操作符前折行。一条语句折行后, 应该比原来的语句再缩进一个TAB或4个空格,以便于阅读。

2.5 间隔

类、方法及功能块间等应以空行相隔,以增加可读性,但不得有无规则的大片空行。

操作符两端应当各空一个字符以增加可读性。

相应独立的功能模块之间可使用注释行间隔,并标明相应内容,具体参看附

3

软件开发项目管理培训

录的代码示例 。

2.6 对齐

关系密切的行应对齐,对齐包括类型、修饰、名称、参数等各部分对齐。 连续赋值时当对齐操作符。

当方法参数过多时当在每个参数后(逗号后)换行并对齐。

当控制或循环中的条件比较长时当换行(操作符前)、对齐并注释各条件。 变量定义最好通过添加空格形成对齐,同一类型的变量应放在一起。如下例所示: 对齐示例 :

//变量对齐----------------------------------------------- int count = 100; int length = 0;

String strUserName = null;

Integer[] porductCode = new Integer(2); //产品编码数组 //参数对齐---------------------------------------------- public Connection getConnection(String url,

String userName, String password)

throws SQLException,IOException{ }

//换行对齐----------------------------------------------

public final static String SQL_SELECT_PRODUCT = ?SELECT * ?

+ ? FROM TProduct WHERE Prod_ID = ? + prodID;

//条件对齐---------------------------------------------- if( Condition1 //当条件一

&& Condition2 //并且条件二

4

软件开发项目管理培训

|| Condition3){ //或者条件三 } for(int i = 0; i < productCount.length; //循环终止条件 i++){ } 2.7 括号

{} 中的语句应该单独作为一行,左括号\当紧跟其语句后,右括号\永远单独作为一行且与其匹配行对齐,并尽量在其后说明其匹配的功能模块。 较长的方法以及类、接口等的右括号后应使用//end ...等标识其结束。如: 类的结束符:}//EOC ClassName, 方法结束符:}//end methodName(), 功能块结束:}//end if...userName is null? 循环快结束:}//end for...every user in userList

不要在程序中出现不必要的括号,但有时为了增加可读性和便于理解,当用括号限定相应项。

左括号是否换行等随个人习惯而定,若换行则当与其前导语句首字符对齐。

2.8代码风格

项目 缩进 代码中以TAB(4个字符)缩进 单个方法的有效代码长度当尽量控制在100行以内;单个类的长度包括长度 注释行不超过1500行 行宽 页宽应该设臵为80字符 间隔 类、方法及功能块间等应以空行(1行)相隔,但不得有无规则的大片

5

原则 软件开发项目管理培训

空行;操作符两端应当各空一个字符 对齐 关系密切的行应对齐,对齐包括类型、修饰、名称、参数等各部分对齐 括号 左括号\当紧跟其语句后,右括号\永远单独作为一行且与其匹配行对齐,并尽量在其后说明其匹配的功能模块 第3章 注释 3.1 基本原则

? 注释应该增加代码的清晰度。代码注释的目的是要使代码更易于被其他开发人员等理解。

? 如果你的程序不值得注释,那么它很可能也不值得运行。 ? 避免使用装饰性内容。 ? 保持注释的简洁。

? 注释信息不仅要包括代码的功能,还应给出原因。 ? 不要为注释而注释。

?

除变量定义等较短语句的注释可用行尾注释外,其他注释当避免使用行

尾注释。

3.2 JavaDoc

对类、方法、变量等的注释需要符合JavaDoc规范,对每个类、方法都应详细说明其功能、条件、参数等,并使用良好的HTML标记格式化注释,以使生成的JavaDoc易阅读和理解。

3.3 文件与包注释

在每个文件、包的头部都应该包含该文件的名称、版本、版权以及创建、修改记录等。注意是/**/注释而不是/***/JavaDoc注释。

6

软件开发项目管理培训

注释结构: /* * @(#){类名称}.java {版本}{创建时间} * {某人或某公司具有完全的版权} * {使用者必须经过许可} * {修改记录:修改人、修改时间、修改内容等} */ 文件注释示例: /* ============================================================ * @(#)User.java 1.2 2011/06/01 * ============================================================ * Copyright (c) 2011 ShengLi Oil Field Victorysoft Co.,Ltd. * (http://www.victorysoft.com.cn) All Right Reserver. * ============================================================ * This software is the confidential and proprietary information of * ShengLi Oil Field Victorysoft Co.,Ltd.(\* You shall not disclose such Confidential Information and shall user * it only in accordance with terms of the license agreement * you entered into with VictorySoft. * ============================================================ * 修改人: vseaf * 修改时间: 2011/06/15 * 修改内容: …… * ============================================================ 3.4 类、接口注释

在类、接口定义之前当对其进行注释,包括类、接口的目的、作用、功能、

7

软件开发项目管理培训

继承于何种父类,实现的接口、实现的算法、使用方法、示例程序等。 类注释示例 : /** *

字符串实用类。

(类描述) * * 定义字符串操作时所需要用到的方法,如转换中文、HTML标记处理等。 * * @author: vseaf(作者) * @version: 1.2 (版本) */ public class StringUtil { ? } 3.5 方法注释

依据标准JavaDoc规范对方法进行注释,以明确该方法功能、作用、各参数含义以及返回值等。复杂的算法用/**/在方法内注解出。 参数注释时当注明其取值范围等

返回值当注释出失败、错误、异常时的返回情况。

异常当注释出什么情况、什么时候、什么条件下会引发什么样的异常 。 方法注释示例 ; /** * 执行查询。 * * 该方法调用Statement的executeQuery(sql)方法并返回ResultSet *结果集。 * 8

软件开发项目管理培训

* @param sql 标准的SQL语句 * @return ResultSet结果集,若查询失败则返回null * @throws SQLException 当查询数据库时可能引发此异常 */ public ResultSet executeQuery(String sql) throws SQLException { //Statement和SQL语句都不能为空 if(null != stmt && !StringUtil.isEmpty(sql)){ //返回查询执行结果 return stmt.executeQuery(sql); } return null; }//end executeQuery() 3.6 其他注释

应对重要的变量加以注释,以说明其含义等。

应对不易理解的分支条件表达式加注释。不易理解的循环,应说明出口条件。过长的方法实现,应将其语句按实现的功能分段加以概括性说明。

对于异常处理当注明正常情况及异常情况或者条件,并说明当异常发生时程序当如何处理。

3.7 注释参考表

注释参考表 :

项目 注释内容 参数类型 参数 参数用来做什么 约束或前提条件 示例 9

软件开发项目管理培训

字段描述 注释所有使用的不变量 字段/属性 示例 并行事件 可见性决策 类的目的 已知的问题 类 类的开发/维护历史、版本 注释出采用的不变量 并行策略 文件名/标识信息 版权信息 编译单元 (文件) 许可信息 创建/修改记录 获取成员方法 若可能,说明为什么使用滞后初始化 目的 接口 它应如何被使用以及如何不被使用 局部变量 用处/目的 成员方法做什么以及它为什么做这个 哪些参数必须传递给一个成员方法 成员方法返回什么 已知的问题 任何由某个成员方法抛出的异常 成员方法注释 可见性决策 成员方法是如何改变对象的 包含任何修改代码的历史 如何在适当情况下调用成员方法的例子 适用的前提条件和后置条件 控制结构 代码做了些什么以及为什么这样做 成员方法内部注释 局部变量 难或复杂的代码 处理顺序 包 包的功能和用途

10

软件开发项目管理培训

第4章 命名 4.1 基本原则

规范的命名能使程序更易阅读,从而更易于理解。它们也可以提供一些标识功能方面的信息,有助于更好的理解代码和应用。

? 使用可以准确说明变量/字段/类/接口/包等的完整的英文描述符。例如,采用类似 firstName,listAllUsers 或 CorporateCustomer 这样的名字,严禁使用汉语拼音及不相关单词命名,虽然Java支持Unicode命名,但本规范规定对包、类、接口、方法、变量、字段等不得使用汉字等进行命名。

? 采用该领域的术语。如果用户称他们的“客户” (clients) 为“顾客” (customers),那么就采用术语 Customer 来命名这个类,而不用 Client。

? 采用大小写混合,提高名字的可读性。一般应该采用小写字母,但是类和接口的名字的首字母,以及任何中间单词的首字母应该大写。包名全部小写。

如:com.sun.usertest,其中usertest应全部小写,不应这样:userTest ? 尽量少用缩写,但如果一定要使用,当使用公共缩写和习惯缩写等,如实现(implement)可缩写成impl,经理(manager)可缩写成mgr等,具体参看附录之《常用缩写简表》,严禁滥用缩写。

? 不影响理解名称含义的情况下,尽量避免使用长名字(最好不超过 25 个字母),对于较长单词建议使用缩写,并加注释说明。 ? 避免使用相似或者仅在大小写上有区别的名字。

?

避免使用数字,但可用2代替to,用4代替for等,如:go2Jsp。

11

软件开发项目管理培训

将不希望被实例化的类的缺省构造方法声明成private。

6.2 抽象类与接口

一般而言:接口定义行为,而抽象类定义属性和公有行为,注意两者间的取舍,在设计中,可由接口定义公用的行为,由一个抽象类来实现其部分或全部方法,以给子类提供统一的行为定义,可参考Java集合等实现。

多使用接口,尽量做到面向接口的设计,以提高系统的可扩展性。

6.3 继承与组合

尽量使用组合来代替继承,一则可以使类的层次不至于过深,而且会使类与类,包与包之间的耦合度更小,更具可扩展性。

6.4 构造方法和静态工厂方法

当需要使用多个构造方法创建类时,建议使用静态工厂方法替代这些构造方法(参考《Effictive Java》 Item1),例如:

public class User{ public User(){ super(); //do somethings to create user instance } public static User getInstance(String name,String password){ User u = new User(); u.setName(name); u.setPassword(password);

22

软件开发项目管理培训

return u; }

参看String,Boolean的实现等:

String.valueOf(Longl),Boolean.valueOf(String)...

6.5 toString(),equals(),hashCode()...

每个类都应该重载toString()方法,以使该类能输出必要和有用的信息等。

/** * @see java.lang.Object#toString() */ public String toString() { final StringBuffer sb = new StringBuffer(\sb.append(\.append(\.append(']'); return sb.toString(); }

若一个类需要重载equals()方法,则必须同时重载hashCode()

方法实现方式参考《Effictive Java》Item7,Item8

/** * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals (Object obj) { //空值 23

软件开发项目管理培训

if( null == obj){

return false; }

//引用相等

if (obj == this) {

return true; }

//判断是否为当前类实例

if (!(obj instanceof Actor)) {

return false; }

//若ID相等则认为该对象相等

return this._id == ((Actor) obj).getId (); } /**

* @see java.lang.Object#hashCode() */

public int hashCode () {

int result = 17;//init result //String 对象hashCode

result = (37 * result) + _name.hashCode (); //数值

result = (37 * result) + (int) (_id ^ (_id >>> 32)); //String 对象hashCode

result = (37 * result) + _description.hashCode (); return result; }

6.6 Singleton Class

24

软件开发项目管理培训

单例类使用如下方式声明,并将其缺省构造方法声明成private:

public class Singleton{ private static Singleton instance = new Singleton(); // 私有缺省构造方法,避免被其他类实例化 private Singleton(){ //do something } public static Singleton getInstance(){ if(null == instance){ instance = new Singleton(); } return instance; } }//EOC Singleton

单例类若需要实现序列化,则必须提供readResolve()方法,以使

反序列化出来的类仍然是唯一的实例,参照《Effictive Java》 Item57。

第7章 方法 7.1 基本原则

一个方法只完成一项功能,在定义系统的公用接口方法外的方法应尽可能的缩小其可见性。

避免用一个类的实例去访问其静态变量和方法。 避免在一个较长的方法里提供多个出口:

25

软件开发项目管理培训

//不要使用这钟方式,当处理程序段很长时将很难找到出口点 if(condition){ return A; }else{ return B; } //建议使用如下方式 String result = null; if(condition){ result = A; }else{ result = B; } return result; 7.2 参数和返回值

避免过多的参数列表,尽量控制在5个以内,若需要传递多个参数时,当使用一个容纳这些参数的对象进行传递,以提高程序的可读性和可扩展性。

参数类型和返回值尽量接口化,以屏蔽具体的实现细节,提高系统的可扩展性,例如:

public void joinGroup(List userList){} public List listAllUsers(){} 26

软件开发项目管理培训

第8章 表达式与语句 8.1 基本原则

表达式和语句应当清晰、简洁,易于阅读和理解,避免使用晦涩难懂的语句。

每行至多包含一条执行语句,过长当换行。

避免在构造方法中执行大量耗时的初始化工作,应当将这种工作延迟到被使用时再创建相应资源,如果不可避免,则当使用对象池和Cache等技术提高系统性能。

避免在一个语句中给多个变量赋相同的值。它很难读懂。 不要使用内嵌(embedded)赋值运算符试图提高运行时的效率,这是编译器的工作。

尽量在声明局部变量的同时初始化。唯一不这么做的理由是变量的初始值依赖于某些先前发生的计算。

一般而言,在含有多种运算符的表达式中使用圆括号来避免运算符优先级问题,是个好方法。即使运算符的优先级对你而言可能很清楚,但对其他人未必如此。你不能假设别的程序员和你一样清楚运算符的优先级。

不要为了表现编程技巧而过分使用技巧,简单就好。

8.2 控制语句

判断中如有常量,则应将常量臵与判断式的左侧。如:

27

软件开发项目管理培训

if ( true == isAdmin())... if ( null == user)...

尽量不使用三目条件判断。

所有if语句必须用{}包括起来,即便是只有一句:

if (true){ //do something...... } if (true) i = 0; //不要使用这种 过多的else分句请将其转成switch语句或使用子方法。 每当一个case顺着往下执行时(因为没有break语句),通常应在break语句的位臵添加注释。如:

switch (condition) { case ABC: //statements; //继续下一个CASE case DEF: //statements; break; case XYZ: //statements; break; default: //statements; break; }//end switch 28

软件开发项目管理培训

8.3 循环语句

循环中必须有终止循环的条件或语句,避免死循环。

当在for语句的初始化或更新子句中使用逗号时,避免因使用三个以上变量,而导致复杂度提高。若需要,可以在for循环之前(为初始化子句)或for循环末尾(为更新子句)使用单独的语句。

因为循环条件在每次循环中多会执行一次,故尽量避免在其中调用耗时或费资源的操作,比较一下两种循环的差异:

//不推荐方式____________________________________________ while(index < products.getCount()){ //每此都会执行一次getCount()方法, //若此方法耗时则会影响执行效率 //而且可能带来同步问题,若有同步需求,请使用同步块或同步方法 } //推荐方式______________________________________________ //将操作结构保存在临时变量里,减少方法调用次数 final int count = products.getCount(); while(index < count){ } 第9章 错误与异常 9.1 基本原则

不能有未处理的异常,即不能把异常直接抛给客户;

异常要做日志,不能直接打印到控制台;正式代码中不应出现System.out.println()。

29

软件开发项目管理培训

通常的思想是只对错误采用异常处理:逻辑和编程错误,设臵错误,被破坏的数据,资源耗尽,等等。

通常的法则是系统在正常状态下以及无重载和硬件失效状态下,不应产生任何异常。

对于经常发生的可预计事件不要采用异常。 不要使用异常实现控制结构。 确保状态码有一个正确值。

在本地进行安全性检查,而不是让用户去做。

若有finally子句,则不要在try块中直接返回,亦不要在finally中直接返回。

9.2 已检查异常与运行时异常

已检查异常必须捕捉并做相应处理,不能将已检查异常抛到系统之外去处理。

对可预见的运行时异常当进行捕捉并处理,比如空指针等。通常,对空指针的判断不是使用捕捉NullPointException的方式,而是在调用该对象之前使用判断语句进行直接判断,如:

//若不对list是否为null检查,则其为null时会抛出空指针异常 if(null != list && 0 < list.size()){ for(int i = 0; i < list.size(); i++){ } }

建议使用运行时异常(RuntimeException)代替已检查异常

30

软件开发项目管理培训

(CheckedException),请参考网络资源以对此两种异常做更深入理解。

9.3 异常的捕捉与处理

捕捉异常是为了处理它,不要捕捉了却什么都不处理而抛弃之,最低限度当向控制台输出当前异常,如果你不想处理它,请将该异常抛给它的调用者,对每个捕捉到的异常都应调用日志工具输出异常信息,避免因异常的湮没。

多个异常应分别捕捉并处理,避免使用一个单一的catch来处理。如:

try { //do something }catch(IllegalStateException IllEx){ IllEx.printStackTrace(); //deal with IllEx }catch(SQLException SQLEx){ SQLEx.printStackTrace(); throw SQLEx; //抛给调用者处理 }finally{ //释放资源 } 第10章 测试与Bug跟踪 10.1 基本原则

测试不通过的代码不得提交到svn库release区或者发布。

31

软件开发项目管理培训

不得隐瞒、忽略、绕过任何Bug,有Bug不一定是你的错,但有了Bug不作为就是你的不对了。

多做测试,测试要完全,尽量将各种可能情况都测试通过,尽量将可能的Bug在开发中捕捉并处理掉。 测试要保证可再测试性。

测试应当对数据库等资源不留或少留痕迹,例如,当测试添加一个用户时,在其成功后当及时从数据库中删除该记录,以避免脏数据的产生(由此衍生的一个经验是将添加、获取、删除一起测试)。 对关键功能必须测试并通过,对辅助功能及非常简单之功能可不做测试。

10.2 测试驱动开发

测试驱动开发可很好的避免Bug的发生,并提升程序的质量,有助于提高个人的编程水平等,因此在开发中当逐步转向有测试驱动的开发,先写测试,再写代码。

10.3 Junit单元测试

在Java应用中,单元测试使用Junit及其衍生工具。

在TestCase的setUp()中初始化应用,在tearDown()中释放资源。可由一个基础TestCase完成这些任务,其他TestCase继承之。

10.4 自动测试与持续集成

测试应当由系统自动完成并向相应人员发送测试报告。

32

软件开发项目管理培训

由持续集成工具来完成测试的自动化。

10.5 Bug跟踪和缺陷处理

当系统出现Bug时当由该Bug的负责人(代码负责人)尽快修改之。 Bug的处理根据其优先级高低和级别高低先后处理。 Bug级别和优先级别参见《测试手册》。 禁止隐瞒Bug。

第11章 性能 11.1 基本原则

性能的提升并不是一蹴而就的,而是由良好的编程积累的,虽然任何良好的习惯和经验所提升的性能都十分有限,甚至微乎其微,但良好的系统性能却是由这些习惯等积累而成,不积细流,无以成江海!

11.2 String与StringBugffer

不要使用如下String初始化方法: String str = new String(“abcdef”); 这将产生两个对象,应当直接赋值: String str = “abcdef”;

在处理可变 String 的时候要尽量使用 StringBuffer 类,StringBuffer 类是构成 String 类的基础。String 类将 StringBuffer 类封装了起来,(以花费更多时间为代价)为开发人

33

软件开发项目管理培训

员提供了一个安全的接口。当我们在构造字符串的时候,我们应该用 StringBuffer 来实现大部分的工作,当工作完成后将 StringBuffer 对象再转换为需要的 String 对象。比如:如果有一个字符串必须不断地在其后添加许多字符来完成构造,那么我们应该使用 StringBuffer 对象和她的 append() 方法。如果我们用 String 对象代替 StringBuffer 对象的话,将会花费许多不必要的创建和释放对象的 CPU 时间。

11.3 集合

避免使用Vector和HashTable等旧的集合实现,这些实现的存在仅是为了与旧的系统兼容,而且由于这些实现是同步的,故而在大量操作时会带来不必要的性能损失。在新的系统设计中不当出现这些实现,使用ArrayList代替Vector,使用HashMap代替HashTable。 若却是需要使用同步集合类,当使用如下方式获得同步集合实例: Map map = Collections.synchronizedMap(new HashMap()); 由于数组、ArrayList与Vector之间的性能差异巨大(具体参见《Java fitball》),故在能使用数组时不要使用ArrayList,尽量避免使用Vector。

11.4 对象

? 避免在循环中频繁构建和释放对象。 ? 不再使用的对象应及时销毁。

34

软件开发项目管理培训

? 如无必要,不要序列化对象。

11.5 同步

在不需要同步操作时避免使用同步操作类,如能使用ArrayList时不要使用Vector。

尽量少用同步方法,避免使用太多的 synchronized 关键字。 尽量将同步最小化,即将同步作用到最需要的地方,避免大块的同步块或方法等。

11.6 final

将参数或方法声明成final可提高程序响应效率,故此: 注意绝对不要仅因为性能而将类、方法等声明成final,声明成final的类、方法一定要确信不再被继承或重载!

不需要重新赋值的变量(包括类变量、实例变量、局部变量)声明成final。

所有方法参数声明成final 。

私有(private)方法不需要声明成final 。 若方法确定不会被继承,则声明成final。

11.7 垃圾收集和资源释放

不要过分依赖JVM的垃圾收集机制,因为你无法预测和知道JVM在什么时候运行GC。

尽可能早的释放资源,不再使用的资源请立即释放。

35

软件开发项目管理培训

可能有异常的操作时必须在try的finally块中释放资源,如数据库连接、IO操作等:

Connection conn = null; try{ //do something }catch(Exception e){ //异常捕捉和处理 e.printStackTrack(); }finally{ //判断conn等是否为null if(null != conn){ conn.close(); } }//end try...catch...finally 第12章 安全隐患及预防措施 12.1 会话标识未更新

12.1.1 描述

登陆过程前后会话标识的比较,显示它们并未更新,这表示有可能伪装用户。初步得知会话标识值后,远程攻击者有可能得以充当已登录的合法用户。 12.1.2 安全级别

高。

36

软件开发项目管理培训

12.1.3安全风险

可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务。

12.1.4 解决方案

? 不要接受外部创建的会话标识。

? 始终生成新的会话,供用户成功认证时登录。 ? 防止用户操纵会话标识。

? 请勿接受用户浏览器登录时所提供的会话标识。 12.1.5 技术实现

? 登陆界面和登陆成功的界面一致时

修改后台逻辑,在验证登陆逻辑的时候,先强制让当前session过期,然后用新的session存储信息。

? 登陆界面和登陆成功的界面不一致时

在登陆界面后增加下面一段代码,强制让系统session过期。

request.getSession().invalidate();//清空session Cookie cookie = request.getCookies()[0];//获取cookie cookie.setMaxAge(0);//让cookie过期

37

软件开发项目管理培训

12.2 不充分帐户封锁

12.2.1 描述

程序没有使用锁定功能,可以穷举密码,可以造成蛮力攻击,恶意用户发送大量可能的密码和/或用户名以访问应用程序的尝试。 由于该技术包含大量登录尝试,未限制允许的错误登录请求次数的应用程序很容易遭到这类攻击。 12.2.2 安全级别

高。 12.2.3 安全风险

可能会升级用户特权并通过 Web 应用程序获取管理许可权。 12.2.4 解决方案

请确定允许的登录尝试次数(通常是 3-5 次),确保超出允许的尝试次数之后,便锁定帐户。 为了避免真正的用户因帐户被锁定而致电支持人员的麻烦,可以仅临时性暂挂帐户活动,并在特定时间段之后启用帐户。帐户锁定大约 10 分钟,通常用这样的方法阻止蛮力攻击。

38

软件开发项目管理培训

12.2.5 技术实现

提供锁定信息配臵类,可根据项目特定需求修改此配臵信息。

修改登陆验证逻辑,根据上面的配臵信息提供帐户锁定功能。

39

软件开发项目管理培训

12.3 可预测的登录凭证

12.3.1 描述

发现应用程序会使用可预期的认证凭证(例如:admin+admin、guest+guest)。 攻击者很容易预测用户名和密码,登录应用程序,从而获取未获授权的特权。 12.3.2 安全级别、

高。 12.3.3 安全风险

可能会升级用户特权并通过 Web 应用程序获取管理许可权。 12.3.4 解决方案

不应使用易于预测的凭证(例如:admin+admin、guest+guest、test+test 等),因为它们可能很容易预测,可让用户不当进入应用程序。

12.3.5 技术实现

只要养成良好的习惯,坚决不使用容易预测的名和密码,即可彻底杜绝此类问题。

40

软件开发项目管理培训

12.4 登录错误消息凭证枚举

12.4.1 描述

当试图利用不正确的凭证来登录时,当用户输入无效的用户名和无效的密码时,应用程序会分别生成不同的错误消息。 通过利用该行为,攻击者可以通过反复试验(蛮力攻击技术)来发现应用程序的有效用户名,再继续尝试发现相关联的密码。 12.4.2 安全级别

高。 12.4.3 安全风险

可能会升级用户特权并通过 Web 应用程序获取管理许可权。 12.4.4 解决方案

不论名和密码哪个错误,都提示同样的消息。且同时加上登陆失败次数达到规定的帐户锁定功能。 12.4.5 技术实现

不论名和密码哪个错误,都提示如下所示同样的消息:

41

软件开发项目管理培训

一旦某个帐户连续登陆失败次数达到了规定的数值,就会按配臵的时间被锁定,如下提示:

如此一来,攻击者就没机会穷举帐户和密码了,此类攻击也就不可能发生了!

12.5 已解密的登录请求

12.5.1 描述

通过HTTP POST 发送表单数据,这些数据将在HTTP报文中以明文的形式传输。对于一些敏感的数据(如用户名/密码、信用卡密码)以传统的HTTP报文传输存在巨大的风险。 12.5.2 安全级别

中。

42

软件开发项目管理培训

12.5.3 安全风险

可能会窃取诸如用户名和密码等未经加密即发送了的用户登录信息。

12.5.4 解决方案

(1) 饶过AppScan软件扫描

(2) 对提交的敏感信息,一律以加密方式传给服务器。

(3) 采用基于SSL的HTTPS传输协议,对提交的敏感信息在传输过

程中加密。

敏感信息包括:用户名、密码、社会保险号码、信用卡号码、驾照号码、电子邮件地址、电话号码、邮政编码等。

注意:如果不是基于SSL的HTTPS传输协议的话。对于提交的敏感信息即使加密后,AppScan软件同样认为该漏洞存在。所以避免这一漏洞的有效方案是饶过扫描或者采用基于SSL的HTTPS传输协议。

虽然采取HTTPS传输数据有很高的安全性,但是也有以下几个显著的缺点:

? 需要申请一个合法组织颁发的用来加/解密的证书。 ? 部署、配臵繁琐。

? 同样的硬件环境,效率比HTTP慢很多。 12.5.5 技术实现

(1) 饶过AppScan软件扫描

43

软件开发项目管理培训

经过分析,AppScan对登陆界面的扫描,只扫描输入框的type属性值为password的控件,因此,我们把输入框的type的属性值为password的值改为text,然后用Javascript函数来模拟实现星号代替输入值的密码输入效果即可饶过该扫描。当然,结合方案(2)对密码进行加密传送则更安全。 示例步骤如下:

? 修改登陆页面原来的密码输入框的type属性为hidden。

? 新建一个密码输入控件,并添加对应的Javascript函数。

id=\? 在页面中加入如下js函数

(2) 对于敏感的地址,采用基于SSL的HTTPS传输协议,

HTTPS协议对传输的内容在传输过程中进行加密。

44

软件开发项目管理培训

12.6 SQL 注入

12.6.1 描述

随着B/S模式应用开发的发展,使得使用这种模式编写应用程序的程序员也越来越多。但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。攻击者可以通过互联网的输入区域,利用某些特殊构造的SQL语句插入SQL的特殊字符和指令,提交一段数据库查询代码(一般是在浏览器地址栏进行,通过正常的www端口访问),操纵执行后端的DBMS查询并获得本不为用户所知数据的技术,也就是SQL Injection(SQL注入)。

12.6.2 安全级别

高。 12.6.3 安全风险

可能会查看、修改或删除数据库条目和表。 12.6.4 解决方案

? 过滤掉用户输入中的危险字符。

? 检查用户输入的字段类型,确保用户输入的值和类型(如

45

软件开发项目管理培训

Integer、Date 等)有效,且符合应用程序预期。

? 屏蔽一些详细的错误消息,因为黑客们可以利用这些消息。 ? 使用专业的漏洞扫描工具。

? 企业要在Web应用程序开发过程的所有阶段实施代码的安全 检查。首先,要在部署Web应用之前实施安全测试,这种措施的意义比以前更大、更深远。企业还应当在部署之后用漏洞扫描工具和站点监视工具对网站进行测试。 12.6.5 技术实现

(1)采用过滤器技术。

过滤技术是通过特定过滤函数,去查找每个请求的每个参数对应的值,如果出现了不允许的字符,就会弹出如下提示:

点确定后即可回到请求页面,删除敏感字符即可请求成功! 过滤器ParameterFilter.Java代码如下:

/** * 参数过滤类,过滤普通表单 */ public class ParameterFilter implements Filter { private Pattern scriptPattern; private Pattern sqlPattern; private Pattern letterPattern; private String notProtect = \ private String totalLetter = \

46

本文来源:https://www.bwwdw.com/article/2efx.html

Top