最近在做一个志愿者系统,关键是就我自己一个人,所以也就没人帮忙做前台了,纠结的前台。本来以为今天做好一段落了,结果用ie打开就悲剧了,兼容问题。chrome浏览器和firefox浏览器都正常,为啥坑爹的IE7 8 9都存在兼容问题。还是决定把最近遇到的问题记下来,以备以后查看。
第一个问题像网页中的文字顺序等视图不是期望中的显示效果,去查html标签,一般都是因为html写的不规范,用的模板做的前台,查错时发现好多网页都没<html>和</html>.
第二找了很多js和jquery的日历控件,国外的好多界面都不喜欢,网上说有多炫多炫,但是我看着丑,而且毕竟是国外的,最后发现一款国内的My97DatePicker ,做的不错,简介的界面,一看我就喜欢上了,而且是国内的,对中文支持的很好。
第三纠结了我很长时间的问题,用的是struts2做的文件上传,后来证明这个不是问题,用servlet做上传也有这个问题,上传之后我从session中取用户信息使用,但是诡异的就是取不到用户的信息,我断点跟,最后发现连session都不是同一个了,最后知道是因为在客户端使用了插件做的上传,带flash的插件有时会重新开一个session,所以在上传的这次会话中当然取不到用户信息,最后采用了一个折中的办法,在页面上写一个隐藏域,把用户的主键放到域中,再提交给服务器端,去数据库查找用户再使用。总结如下:
1 网页如果使用了iframe/frameset技术,session就容易出问题。
2 上传的时候,form的编码方式是不一样的,Server端解析的时候,很难说不出问题。
3 如果禁用了Cookie,则Session要靠URL重写来实现,如果同时又是上传,则更难说不出问题。
4. 如果使用了flash插件做的上传,session出了问题,基本就是这个插件的原因
第四 在验证用户不能输入非数字时,最好用onkeydown事件,因为onkeypress在英文输入法还能阻止,用中文输入法就检查不出来了。但是在火狐中没起作用,最后查了一下原因是他们的事件不一样,改了一下代码,如下
$("#pageNo").bind("keydown", function(e) { e=e?e:window.event; var keyCode = e.which?e.which:e.keyCode; if(!((keyCode>=48&&keyCode<=57 || keyCode==8 || keyCode==46))) { return false; } });
改了之后又发现问题了,就是在其他浏览器中文输入法也不能输入非数字,但火狐却能,我就又在onsubmit事件中判定了一下,如果不是输入的值不是介于第一页和最大页数之间,强制改为第一页。兼容问题。。。
第五 有时需要往数据库存大段文字,而又不想用二进制存和文件存,一开始我就指定length=“8000”<property name="comment" length="8000"/>,这样 不行,因为默认string是映射成了varchar类型,而这个字段长好像最长是255,最后想用text类型,但怎么指定都映射不成功,最后发现<property name="comment" type="string" length="8000"/>即可,而且type和length缺一不可,会自动映射成text,当然前提是到数据库表中把原来的表drop掉,因为<property name="hibernate.hbm2ddl.auto">update</property>,理论上应该更新的,但是不drop掉不更新。有人建议这一项设成create,我固执的认为不如用update,因为在开发中会多次更改。而且create 每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
第六 我在批量上传文件时出现了错误,错误如下:
org.hibernate.HibernateException: identifier of an instance of org.mtmagic.volunteerSystem.domain.Document was altered from 138 to 139上网上查了一下是主要是因为springFramwork中处理一级session的dirty数据,出现错误。想了想应该在上传的时候Document还是同一个,导致读到了脏数据,于是就把spring配置文件中的bean的scope改成了prototype。
第七,因为在这个系统中有四个权限,关键有很多每个权限的操作比较类似,比如查看所有文档,不同的是个人只能查看自己的文档,管理员能查看所有人的文档,一开始没注意,把两个方法放到了同一个action中,后来忽然想到虽然对个人来说网页上没入口查看所有的文档,但是他可以直接在浏览器输入url访问,后来不得不又开了一个AdminAction,把方法又移到这个类中一份。在系统开发中,用户权限多的时候不得不多方面注意权限问题,尤其是一个action中放了多个方法,很容易出问题。
第八,hibernate使用many-to-one关联时,如果使用的是单向的关联,则删除one的一端时会发生异常,两种解决办法,在删除one的一端之前把所有的和one有关的many那一端自己编码全部删除,另一种,使用双向关联,但在one这一端使用inverse="true" cascade="all" 这样不仅one这一端不维护关系,而且删除和修改也会把many那一端的外键也给改了或者级联删除。推荐第二种。
第九,注意load和get的区别,load是延迟加载,get是把信息全部查出来,如果不存在对象get会返回null,而load会抛出ObjectNotFoundException。
第十,使用struts2的ModelDriven时注意是否于这个action中的变量冲了。例如,加入ModelDriven<User>,在User中有个变量是userName,而在action中也有个变量是userName,那么action中变量将取不到值,而User中的变量反而有值。
第十一,针对jquery的插件tinymce和validation在验证textarea不能同时工作的问题。原因是tinymce在提交第一次时并没有把信息存到表单中,所以无法验证。经过查了下一,官方作者也给了解决方案,DEMO:http://jquery.bassistance.de/validate/demo/tinymce/,但是我在借鉴了官方代码后是用了如下办法,其他不需要更改,加入如下代码
$(function() { $("input[type='submit']").click(function() { tinyMCE.triggerSave(); }); $("#emailForm").validate({ rules: { body: { required:true } }, errorPlacement: function(label, element) { // position error label after generated textarea if (element.is("textarea")) { label.insertAfter(element.next()); } else { label.insertAfter(element) } } }); });第十二,在用ajax异步请求服务的时候一直报脚本错误,原因是自己忘了设ajax的dataType,看来还是jquery不熟练所致,毕竟刚学没多长时间。
第十三,filter的配置是有顺序的,这里的顺序是指多个filter之间。用struts2时又用了一个权限控制的filter,但是输入个.action结尾的url请求,会报没有这个方法的错误,而不是被权限控制的filter给拦截了。
第十四。jquery用的是flash做的上传,正如上文所说的这样session特别容易出现问题。在IE下面能用,在chrome和firefox就不能用,原因是在第十三中我改了一下filter的拦截顺序,结果被filter拦截了,认定用户没有权限操作。解决办法,在filter截取url,确定是这个url时就不检测session了。
第十五,使用了frame,然后如果session过期时会重定向到登陆页面,但有时候只在一个frame中重定向了解决办法,在登陆页面加上一下js代码
if (window.self != window.top) { window.top.location = window.self.location; }。。。。。。。。。。。。。。