J2EE应用开发问题总结及最佳实践.ppt

上传人:max****ui 文档编号:6357769 上传时间:2020-02-23 格式:PPT 页数:53 大小:503KB
返回 下载 相关 举报
J2EE应用开发问题总结及最佳实践.ppt_第1页
第1页 / 共53页
J2EE应用开发问题总结及最佳实践.ppt_第2页
第2页 / 共53页
J2EE应用开发问题总结及最佳实践.ppt_第3页
第3页 / 共53页
点击查看更多>>
资源描述
J2EE应用开发问题总结及最佳实践 2 内容 J2EE应用开发和移植中遇到的问题总结J2EE应用上线后遇到的问题总结J2EE应用开发部署最佳实践一些例子分析 3 J2EE应用开发和移植中遇到的问题总结 数据库部分 问题一 使用Oracle数据库 大于4k的附件上传有问题 会报java sql SQLException Connectionresetbypeer socketwriteerror错误解答 附件上传过程是先上传到应用服务器 再以二进制形式保存到BLOB字段 上传组件采用SmartUpload 上传过程没有问题 问题出在对BLOB字段的操作上 在获取到附件的流对象后 用PreparedStatement的ps setBinaryStream 然后再ps executeUpdate 这种方式对小于4k的附件没有问题 大于4k就会报错 解决办法是在插入BLOB字段值时 要先用SELECTBLOBCOLFROMTABLENAMEFORUPDATE查询和锁定该字段 然后再做更新 4 J2EE应用开发和移植中遇到的问题总结 数据库部分 问题二 对OracleBLOB字段的处理问题解答 在Weblogic中 只能支持weblogic自带的对OracleBLOB处理的类 而在WebSphere中 只能支持Oracle自带的处理BLOB的类 因此在程序中根据条件分支判断应用服务器的类型来决定用哪个类处理BLOB 5 J2EE应用开发和移植中遇到的问题总结 数据库部分 问题三 流程定义文件加载问题 加载流程定义文件的过程就是解析并将文件中的流程描述信息提交到数据库表 在一个连接事务中 如果多次调用PreparedStatement的addBatch executeBatch 方法做批量数据更新 会报oracle jdbc dbaccess DBData clearItem错误 解答 应用服务器中数据源的PreparedStatementCacheSize默认设置为10 需要改为0不缓存或者改为100 就可以使用executeBatch 了 6 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题一 JSP自定义标签属性大小写解答 在使用系统自定义的标签属性时 属性名必须严格区分大小写 否则JSP编译不通过 7 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题二 URL编码问题 通过单击打印按钮请求一些报表打印页面时编译出错 会抛出传入的参数不合法的异常解答 由于URL编码格式引起的 如jbtsxf xfcl bb jsp where aab001like D 在URL编码中以 开头后面跟两位16进制编码代表一些特殊字符 这里的 D 不对应任何特殊字符 所以出错 解决办法是将URL串中的特殊字符用对应的URL编码代替 如把 用 25代替 具体可以参考以下网址 8 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题三 文件名的大小写解答 通过include引入文件时也要区分文件路径的大小写 系统中绝大部分JSP的head和body开始部分都会引入系统公用的两个文件 即 htmlHead jsp和 bodyStart jsp 但在不少地方被引用为 htmlhead jsp和 bodystart jsp 这在WebSphere上会引起编译错误 9 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题四 JSP标准标签属性值误用问题解答 如 flush属性应该只有true和false两个有效值 如果flush取其它值 JSP编译也不通过 10 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题五 JSP中importVector类的问题解答 在JSP中已经import了classA 而classA中已经import了Vector 因此JSP里面要应用Vector的时候就没有再去importVector 导致编译出错 11 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题六 value 解答 jsp param里面的name属性不能使用jsp表达式赋值 参考jsp1 2specname是不能使用表达式的 修改name为定义好的字符串常量 12 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题七 某个页面readfile jsp有时候能正常访问 有时候出现http404解答 readfile jsp中需要用到某个htc文件 但该htc文件的路径有误导致IE在最后渲染时提示找不到文件 需要修改htc路径 13 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题八 某个jsp页面使用引入HTML页面 出现乱码解答 引入的HTML页面也必须使用进行声明 由于是静态引入方式 修改这些包含页面后 对原来的jsp也应该进行重新编译才能获得效果 但是只适用于WebSphere6 如果是采用动态引入方式的话 就不需要手动进行重新编译 14 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题九 在一个jsp页面中包含下载内容 调用了response getOutputStream 方法时 抛出exception解答 在jsp中已经隐含一个变量out 相当于调用了response getPrintWriter 因此再次调用response getOutputStream 时会抛出输出流已经获得的异常 可以修改代码 不采用jsp调用形式 改用servlet直接使用流输出 15 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题十 不要用关键字来定义变量解答 在执行之前 代码定义一个变量Stringorg 其中org属于关键字 因此编译的错误 16 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题十一 JSP中使用ShowModalDialog弹出一个新窗口会造成session丢失解答 改成用Window open 17 J2EE应用开发和移植中遇到的问题总结 JSP部分 问题十二 jsp forward抛出异常 java lang IllegalStateException jsp error attempt to clear flushed buffer解答 在有jsp forward语句的jsp中 不能有其他html的元素的输出 18 J2EE应用开发和移植中遇到的问题总结 体系架构部分 问题 在实现异步消息侦听的功能时 采用一个非容器受管的线程实现javax jms messageListener接口来完成 并没有使用MDB 导致在WebSphere上出现异常错误 被迫要改成同步侦听的方式 使性能下降 解答 在J2EE规范中提倡采用MDB来完成异步消息侦听的工作 而不接受自己用线程来实现的做法 这样做的好处是因为MDB是受EJB容器管理的一个组件 开发和维护简单 移植性好 19 内容 J2EE应用开发和移植中遇到的问题总结J2EE应用上线后遇到的问题总结J2EE应用开发部署最佳实践一些例子分析 20 J2EE应用上线后遇到的问题总结 使用开源组件 问题一 采用SmartUpload组件实现文件上传功能 SmartUpload组件本身存在一定的缺陷 容易造成内存泄漏 解答 通过对heapdump文件进行分析 对系统出现的OutOfMemory现象 是因为在SmartUpload中有一段代码不是十分严密 会在某种情况下出现死循环 然后导致系统内存溢出 不能正常提供服务 解决的办法是对SmartUpload的代码进行部分修改 使之不产生死循环 具体的分析过程请参考附件一 21 J2EE应用上线后遇到的问题总结 优化对数据库的访问 问题二 某些jdbc语句过于庞大 导致该语句的执行时间过长而锁住了jdbc连接等资源不被释放 解答 建议检查sql语句的效率 把一个语句中执行的复杂操作优化成效率高的sql语句来执行 selectsqlb currenthj currentstate sum jjbs0 sum jjbs1 sum jjbs2 sum tbbs1 tbdwbhfromTodolistwheresqlb 101 and currenthj 001 orcurrenthj 006 orcurrenthj 011 or and clr st001 orclrisnull and tbdwbhlike 44 groupbysqlb currenthj currentstate tbdwbhorderbysqlb currenthj currentstate tbdwbh selectsqlb currenthj currentstate sum jjbs0 sum jjbs1 sum jjbs2 sum tbbs1 tbdwbhfromTodolistwheresqlb 101 and currenthjin 001 006 011 016 021 031I1 031I2 031I3 031J1 031J2 031J3 031K1 031K2 031K3 031M1 031M2 031M3 041 050 052 056 061 062 063 066 071 076 078 081 086 087 088 089 090 091 092 096 101 106 108 111 and clr st001 orclrisnull and tbdwbhlike 44 groupbysqlb currenthj currentstate tbdwbhorderbysqlb currenthj currentstate tbdwbh 22 J2EE应用上线后遇到的问题总结 问题三 防火墙策略的影响解答 假如应用服务器连接数据库的时候要通过防火墙的话 那么要仔细设置策略中的超时部分 不要与应用服务器连接数据库的超时设置相抵触 如果防火墙的超时设置要短于应用服务器的设置 那么数据库连接就会被防火墙频繁的截断 从而引起性能的下降 23 J2EE应用上线后遇到的问题总结 优化对数据库的访问 问题四 要珍惜jdbc连接资源解答 jdbc连接是非常宝贵的资源 当要用到的时候才去获取 而不要占住了一个连接却不使用它 也不要使用完了不释放它 这样会使应用程序的效率很低 总结来说 就是在初始化的时候对datasource作一次jndilookup的动作 然后接下来当要使用jdbc连接的时候通过getConnection获取连接 在使用完毕后通过conn close 关闭 使之返回到连接池中被其他代码使用 24 J2EE应用上线后遇到的问题总结 使用开源框架 问题五 慎用各种开源的框架解答 目前各种开源的框架非常流行 例如hibernate tapestry struts spring等等 这些框架使用起来也会简化开发的工作量 但是一定要注意这些框架下的合理参数配置 否则会引起系统级别的性能问题 例如在出入境的性能问题中 基本上都是因为这些框架下的参数没有正确的配置引起太多对象堆积在内存空间中不能被释放 造成内存泄漏 具体问题的分析办法请参考附件二和附件三 25 J2EE应用上线后遇到的问题总结 问题六 关于WAS做集群的问题解答 应用程序的开发应该与应用服务器的拓扑结构相独立 而不应该成为部署的障碍 例如像广东省出入境如此庞大的系统 总共包括19台刀片服务器来运行应用服务器 如果能够建立起集群的环境 无论从部署 维护还有性能方面都能大大提高 26 内容 J2EE应用开发和移植中遇到的问题总结J2EE应用上线后遇到的问题总结J2EE应用开发部署最佳实践一些例子分析 27 J2EE应用开发部署最佳实践 开发部分 整体考虑开发应遵循标准的软件工程方法论开发应遵循J2EE规范开发尽量使用成熟的框架以及开发模式变量名 类名 对象名 包名应该遵循命名规范对象的构造尽量避免在被经常调用的代码中创建对象对于集合类 collection 应尽量初始化它的大小JVM会自动指定缺省大小如果超过 JVM会重新创建一个 释放掉原来的对象 加大JVM负担 28 J2EE应用开发部署最佳实践 开发部分 当一个类的多个实例在其本地的变量里访问一个特定的对象时 最好将这个变量设计为静态 static 的 而不是每个实例中变量里都存放那个对象的引用尽量重用对象的引用 而不是new注意释放容器对象中所保存的指向别的对象的引用尽量使用primitive数据类型当只是访问一个类的某个方法时 不要创建该类的对象 而是将该方法设计成一个static的方法 尽量简化类的继承关系和设计简单的构造函数创建简单数据类型的数组要比初始化一个这样的数组快 创建一个复杂类型的数组要比克隆一个这样的数组快 29 J2EE应用开发部署最佳实践 开发部分 字符串 String 事实 String对象是不可改变的如果字符串在程序中可能被改变 比如增加 接或删除字符 就应使用StringBuffer 创建具有初始大小的StringBuffer对象 尽量重用该对象 而不使用 操作分析字符串中的字符时 就不要使用String或StringBuffer 而是使用字符数组 特别是在循环中分析字符时更应该如此尽量少用StringTokenizer 它的方法的性能比较差 30 J2EE应用开发部署最佳实践 开发部分 输入输出 Input Output 小块小块的读写数据会非常慢 因此 尽量大块的读写数据使用BufferedInputStream和BufferedOutputStream来批处理数据以提高性能对象的序列化 serialization 非常影响I O的性能 尽量少用对不需序列化的类的域使用transient关键字 以减少序列化的数据量 31 J2EE应用开发部署最佳实践 开发部分 循环 Loop 循环常量 在循环中它的值不会改变 因此 它的值应该在循环外先计算出来 本地变量 LocalVariable 在方法中使用本地变量比使用对象的属性消耗较少的资源 在循环中却不一样 因为循环中的代码要反复地被运行 因此 尽量少地在循环中创建对象和变量 尽早结束循环 如果循环体在满足一定条件就可以结束 就应尽快结束 32 J2EE应用开发部署最佳实践 开发部分 集合类 Collections Collection这是集合类的基本接口 它为一组对象提供了一些简单的方法 List具有可以控制的顺序 但并没有定义或限制按什么排序Set不能包含重复的元素Map将一个键 Key 影射到一个值 Value 不允许有重复的键Vector和ArrayListVector的方法都是同步的 Synchronized 是线程安全的 thread safe 33 J2EE应用开发部署最佳实践 开发部分 ArrayList的方法不是 由于线程的同步必然要影响性能 因此 ArrayList的性能比Vector好当Vector或ArrayList中的元素超过它的初始大小时 Vector会将它的容量翻倍 而ArrayList只增加50 的大小 这样 ArrayList就有利于节约内存空间Hashtable和HashMap类似Vector和ArrayList 比如Hashtable的方法是同步的 而HashMap的不是ArrayList和LinkedListArrayList的内部实现是基于内部数组Object 34 J2EE应用开发部署最佳实践 开发部分 LinkedList的内部实现是基于一组连接的记录 更像链表结构当操作是在一列数据的后面添加数据而不是在前面或中间 并且需要随机地访问其中的元素时 使用ArrayList会提供比较好的性能当操作是在一列数据的前面或中间添加或删除数据 并且按照顺序访问其中的元素时 就应该使用LinkedList了如果两种情形交替出现 可以考虑使用List这样的通用接口 而不用关心具体的实现 由实现去保证性能 35 J2EE应用开发部署最佳实践 开发部分 方法 method Java编译器会把一些代码转为代码嵌入 提高性能Final static private同步 Synchronized 使用同步方法比使用非同步方法的性能要低应尽量少使用同步方法同步方法的代码本身就不应该再同步了 36 J2EE应用开发部署最佳实践 开发部分 EJB部分为EJB实现本地接口始终通过会话Bean访问实体Bean尽量缓存对EJBHome的访问当使用EJB组件时 始终使用会话Facades尽量使用无状态会话bean 而不是有状态会话bean尽量使用容器管理的事务 37 J2EE应用开发部署最佳实践 开发部分 Servlet部分init 做尽可能多的工作只在初始化是执行一次尽可能少地使用Synchronize确保不要synchronize整个类不要用任何实例变量被所有在线的用户使用不要使用SingleThreadModel虽然是thread safe 但性能太差 对于非Java群体 不要在cookies中存对象使用HttpSession代替 38 J2EE应用开发部署最佳实践 开发部分 JSP部分保持尽量少的Java代码JSP中的Java代码很难维护和测试绝对不要将业务逻辑放在JSP中编写helperclasses从数据生成HTMLOneofthefewtimesputtinghardcodingHTMLinJavais okay 理想情况下只使用 tags 在每一个JSP只包含用于显示数据的简单对象有时称之为 viewbean 但不用是一个真的JavaBean限定JSP只做显示工作 抵制在其中编写的商业逻辑的诱惑 39 J2EE应用开发部署最佳实践 开发部分 JSP部分如果在页面中你要共享组件和项目 使用如下表格E g 对于菜单 标题栏 页脚 等等可以使用HTML或者JSPinclude指令可以包括静态HTML 或者其它JSP不要忘记在整个JSP中使用try catch如果在JSP中抛出一个异常 它不能被servlet捕获作为替代 将所有有异议的代码放在头部 将这一部分封装在try catch中 40 J2EE应用开发部署最佳实践 开发部分 数据库访问部分规格化 Normalization 数据库结构针对常用的SQL操作建立索引 删除多余的索引尽量使用PreparedStatements合理运用PreparedStatement和连接池考虑批量执行SQL命令考虑使用数据库存储过程及时关闭不用的Statement ResultSet Connection等对象 但不是在finalize方法内 41 J2EE应用开发部署最佳实践 开发部分 HttpSession部分确保放在session中的每一个对象要实现Serializable orExternalizable 不是必须的 但在分布式应用中是一个好的方法避免在session中存放大对象手工使session无效Canonlydothisifapplicationhasexplicit logout function如果在JSP中不需要session 禁用它 42 J2EE应用开发部署最佳实践 开发部分 其它JSP中保持尽量少的Java代码尽可能减少HTTP数据传输的总量和频度尽量使用局部变量不要重复初始化变量只有在必要时才运用线程安全的类在servlet EJB中不要使用多线程尽量使用日志记录框架类如log4j输出跟踪信息 而不是使用简单的System out println 从正式发行的软件中删除调试信息 43 J2EE应用开发部署最佳实践 开发部分 备注 WAS是遵循J2EE标准的成熟的应用服务器 可用性99 999 其可靠性远高于应用 在系统出现问题时 请首先考虑应用的问题 44 J2EE应用开发部署最佳实践 部署管理部分 根据应用状况设置JAVA堆大小根据应用状况设置webcontainerthreadpoolsize大小根据应用状况设置ORBthreadpoolsize大小根据应用状况设置JDBCconnectionpoolsize大小根据应用状况设置JDBCconnection的prefetchsize大小多个应用共用jar包时使用共享库尽量缓存会话 有状态会话beanDM上的结点数 Nodes 30每个节点上的server数 Applicationserverspernode 20 45 J2EE应用开发部署最佳实践 部署管理部分 每个单元中的server数 Totalnumberofapplicationserverspercell 60即总的 applicationserversxnodes 60每个sever上的应用数 Applicationsperapplicationserver 100每个应用上的EJB数 EJBsperapplication 250在生产平台尽量少打日志具备规范的生产 测试平台 生产平台 最好物理分开 限制可以接触到生产平台的人员借助测试工具进行大于生产压力的压力测试根据压力测试结果 调整系统参数 WAS参数 然后继续测试以验证调整效果 46 J2EE应用开发部署最佳实践 部署管理部分 应用必须经过开发平台测试 才能上测试平台 经过测试平台测试才能正式上生产 47 内容 J2EE应用开发和移植中遇到的问题总结J2EE应用上线后遇到的问题总结J2EE应用开发部署最佳实践一些例子分析 48 一些例子分析 无意识的集合对象保留Vectorv newVector 10 for inti 1 i 100 i Objecto newObject v add o o null 问题 上面用的Vector中的临时对象Object被释放了吗 回答 没有 49 一些例子分析 显示的赋Null值起作用吗 定义 赋空变量是指简单地将null值显式地赋值给这个变量 相对于让该变量的引用失去其作用域最佳实践正确地设置变量的作用域 而不要显式地赋空它们显式赋空变量一般应该没有影响但是 在一些场合下会对性能产生巨大的负面影响例如 迭代的或者递归的赋空集合内的元素使得这些集合中的对象能够满足垃圾收集的条件实际上是增加了系统的开销而不是帮助垃圾收集 50 一些例子分析 所以前面的例子中 怎么样才是相对比较好的办法让JVM把Vector里面的申请的Object回收 正解 For inti 1 i 100 i v remove o 51 一些例子分析 局部作用域一个例子publicstaticStringscopingExample Stringname StringBuffersb newStringBuffer sb append hello append name returnsb toString 问题 当方法执行完后 StringBuffer能被回收吗 静态作用域一个例子staticStringBuffersb newStringBuffer publicstaticStringscopingExample Stringname sb newStringBuffer sb append hello append name sb append nicetoseeyou returnsb toString 问题 当方法执行完后 StringBuffer能被回收吗 52 一些例子分析 例子一 当该方法执行时 运行时栈保留了一个对StringBuffer对象的引用 这个对象是在程序的第一行产生的 在这个方法的整个执行期间 栈保存的这个对象引用将会防止该对象被当作垃圾 当这个方法执行完毕 变量sb也就失去了它的作用域 相应地运行时栈就会删除对该StringBuffer对象的引用 于是不再有对该StringBuffer对象的引用 现在它就可以被当作垃圾收集了 栈删除引用的操作就等于在该方法结束时将null值赋给变量sb例子二 现在sb是一个静态变量 所以只要它所在的类还装载在Java虚拟机中 它也将一直存在 该方法执行一次 一个新的StringBuffer将被创建并且被sb变量引用 在这种情况下 sb变量以前引用的StringBuffer对象将会死亡 成为垃圾收集的对象 也就是说 这个死亡的StringBuffer对象被程序保留的时间比它实际需要保留的时间长得多 如果再也没有对该scopingExample方法的调用 它将会永远保留下去 53 总结 你不能调优一个坏的应用你不能调优一个坏的应用你不能调优一个坏的应用你不能调优一个坏的应用你不能调优一个坏的应用你不能调优一个坏的应用你不能调优一个坏的应用你不能调优一个坏的应用
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!