amp@java

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  99 随笔 :: 0 文章 :: 228 评论 :: 0 Trackbacks

#

    JSF只能采用POST的方法进行FORM提交,同一页面要显示不同的内容,只有通过POST来改变参数或者通过SESSION传递变量。有时候有大量相似的页面,这些页面只有很少一部分不同(例如不同用户、不同角色、不同页码等),通过跟在URL后面的query string本来可以很容易地实现,但在JSF里却不行,只要一提交,马上就把?后面那串东西丢掉。假如有一个页面,根据URL后面的id参数来显示FORM的内容,提交的时候如果验证出错,那个FORM的内容就丢失了,显示一个莫名其妙的页面,因为这时候那个id参数已经没有了。还有常用的分页操作,本来在URL后面加上个页码就可以了,但是JSF的分页控件却只能通过POST来翻页,一刷新就出来个“重试”“取消”的对话框,让人烦恼。如果页面内容根据不同用户角色有细微不同,就得每个角色建立一个页面,每个页面对应一个managed bean,这些页面的内容基本相同,bean的内容也基本相同,却要分别建立,一点重用的机会都没有。今天做的一个东西就遇到了这种问题:
一个简单的审批流程,只有3个角色,申请者、审批者、执行者,整个流程是这样的:申请者填单->审批者查看并审批->执行者执行并填入结果->申请者查看。这样,每种角色都有两种列表:未回复和已回复,这两种列表在三个角色里面都是相似的,但有细微区别:
申请者 审批者 执行者
未回复列表 自己已发出但未被执行者执行的列表 申请者已提交但自己未审批的列表 审批已通过但自己未执行的列表
已回复列表 自己已发出且执行者已执行的列表 申请者已提交且自己已审批的列表 审批已通过且自己已执行的列表

这些列表的不同之处在于:已登录用户的角色(可以从session中得到,但一个用户可能有多种角色,他可能以不同的角色查看列表),列表的当前状态(对每种角色都有两种状态),列表的页码。由于每个列表都有可能有大量数据,所以必须用到分页。通过JSF的DataTable空间和DataScroller控件可以简单地实现分页,然而,这种分页导致URL后面的参数无效了,这样一来,这六种列表就必须通过6个页面来显示了,通过页面的名称来区分当前用户的角色、所查看的列表的状态,每个页面通过POST来决定页码。本来一个页面+一个bean+3个参数就可以决定,现在需要6个页面+6个bean来完成了。

list.jsp?type=0&role=0&page=1->type0_role0.jsp
list.jsp?type=0&role=1&page=1->type0_role1.jsp
list.jsp?type=0&role=2&page=1->type0_role2.jsp
list.jsp?type=1&role=0&page=1->type1_role0.jsp
list.jsp?type=1&role=1&page=1->type1_role1.jsp
list.jsp?type=1&role=2&page=1->type1_role2.jsp

假如有n种状态m种角色那岂不是要n*m个页面+n*m个bean?

有点想放弃JSF这个鸡肋了。

希望有高手给条生路走走!
posted @ 2008-06-04 19:48 amp@java 阅读(2345) | 评论 (11)编辑 收藏

刚刚才知道,原来Java的线程是不能重启的,也就是说,当线程的run()方法执行到最后一行,退出之后,这个线程就结束了,不能再通过start()方法重启启动这个线程,只能重新构造一个线程对象,再调用其start()方法来启动,但这个对象和原来那个对象已经不同了。
为了实现某个线程对象的“重启”功能,可以在它的run()方法的最外层加上一个循环语句:
1 public void run(){
2   while(!stop){
3     //do something
4   }
5 }

这样,只要stop不为true,run()方法就不会结束,不断地“重启”。
如果run()方法里面还有一个循环,那么就要两个停止标志:
1 public void run(){
2   while(!stop){
3     //do something
4     while(!stop && !restart){
5       //do other thing
6     }
7   }
8 }
9 
这样,如果需要“重启”线程,只要把restart设为true即可,如果要退出线程,只要把stop设为true即可。
posted @ 2008-04-22 10:56 amp@java 阅读(4174) | 评论 (0)编辑 收藏

之前用过一个带CheckBox的Tree控件,叫dhtmlXTree,支持xml数据,功能很好很强大,但是有个问题怎么也解决不了,不知道什么原因,就是第一次显示的时候能够正常显示树形列表,但第二次进入相同页面就会显示错误,所有图片都看不见,只看到其中的文字,而且这时候整个浏览器像死了一样,点击上面的任何链接都没反应,必须关闭重新打开才有效,或者等上十几分钟才反应过来,不知道是不是一直在后台运行某个Javascript脚本。虽然这个控件的源代码可以看到,但是一条注释都没有,都不知道哪个部分出了问题。

在google上搜索替代方案时,看到了BlueShoes的树形控件,具有多种形态,包括CheckBox,RadioButton等,每种形态都有例子,而且有详细的规范的文档(phpdocument,与JavaDoc类似),关键是代码里面也有详细的注释,可以看到每个部分的实现原理。与dhtmlXTree使用XML存储数据不同的是,这个树形控件使用多维数组来存储数据,似乎可读性和效率稍差,但出错的几率也少了,不需要用到浏览器的XML处理。与前者一样也支持IE5。

关于BlueShoes的树形控件的详细的情况可以看这里:http://www.blueshoes.org/en/javascript/tree/

那个网站上还有很多其他控件,也是很优秀的,虽然它的后台是php框架,但客户端控件同样可以用于JSP。
posted @ 2008-02-26 11:28 amp@java 阅读(446) | 评论 (0)编辑 收藏

浏览器的缓存有时候显得很讨厌,明明已经更新了内容,就是不显示新的,只要URL不变,浏览器就不会去检查服务器是否已经更新,而是用缓存里的东西,起码在IE里是这样。
使用AJAX经常需要动态更新某一过程的状态,例如短信发送的状态,如果相隔几秒查询一次,URL不变的话,显示出来的状态永远不会改变,因为浏览器第一次获取了内容之后就不再更新了。
为了解决这个问题,最简单的办法就是在URL后面加上一个不断改变的查询字符串(query string),例如:
request.jsp?q=q&date=(new Date()).getTime()
红色部分就是不断改变的查询字符串。

感谢http://wangcheng.javaeye.com/blog/135887的提示

http://batmanwl.blog.sohu.com/71841783.html这里还可以看到多种解决方案
posted @ 2008-02-26 10:33 amp@java 阅读(805) | 评论 (1)编辑 收藏

通过JavaME的WMA可选包发送短信时,手机会提示是否允许程序发送该短信,虽然不太影响应用,但每次都要按一下允许也很不爽。从网上看到有人说对jar包签名后就不会出现这种情况了,但是签名的证书要向两个大公司买,因为手机里面一般只内置了那两个大公司的根证书,而且手机不允许安装新的根证书,这不分明是圈钱吗?不知道当初制定这个标准的家伙收了那两个公司多少黑钱!虽然这样会使很多病毒不能运行,但是那两个公司又不是上帝,给钱就可以买到证书了,他们又没什么力量也不会去研究购买证书的人要干什么,如果有恶意的人只要花点钱,同样可以造出带签名的病毒来。
但是办法总是有的,有人另辟蹊径,通过非常手段给手机安装一个自己制作的根证书。详细过程可以看这里:http://browndrf.blogspot.com/,原理就是利用了NOKIA某些型号的手机可以通过web下载证书并安装的漏洞。我实验了一下,整个过程其实不用那么复杂,不需要用到NOKIA的签名工具,直接用SUN WTK的签名工具就可以了,也不需要通过网络安装程序,跟平时安装没签名的程序一样。
然而,签了名的程序同样需要确认才能发送短信!而且比没签名的程序更麻烦,还要在MIDLet-Permissions里面填上一大堆许可,不签名的软件这个项根本不用填。唯一的好处是安装的时候不会提示程序不受信任,而且不能用无签名的同名程序覆盖。但是这种安装过程的问题并不需要多大关注,因为安装只是很少的时间,关键是使用。
后来在这里:http://blog.csdn.net/zhengyun_ustc/archive/2006/04/07/654226.aspx又发现一篇文章,说明能够安装根证书的不过是个别机型的漏洞,是不符合MIDP 2.0安全标准的,算了,这个问题还是没法解决,死心!
JavaME真的有点像鸡肋,它最大的优点是跨平台,但各种手机的支持程度又各不相同,一点点小的差异就搞得人晕头转向。而且各种各样的限制使得它最多就弄点小游戏玩玩,要连接网络还得一堆的许可,程序大了还容易莫名其妙地崩溃。真是食之无味,弃之可惜。
可是,我还是要搞……
posted @ 2008-02-01 18:41 amp@java 阅读(322) | 评论 (0)编辑 收藏

Bouncy Castle(http://www.bouncycastle.org/)是一个庞大的加密类库,支持Java和C#,其中Java部分发布的源代码压缩包就有24M左右,支持JDK 1.0~5.0,支持J2ME(现在叫JavaME)。
但是,这个类库使用起来并不那么方便,它并没有与普通Java类库那样以Jar形式发布立即可用的二进制类库,而只发布源代码,源代码包含了多份,包括JDK1.0,JDK1.1,JDK1.2,JDK1.3,JDK1.4,JDK1.5,J2ME等,每种环境都有少量文件不一样,有多个用于Ant的build xml,分别用于各种不同的JDK,但是每个xml定义了多个target,不知道哪个target才能build出可用的类库来,选中了其中某个target有可能会出现错误,build不下去。文档太简单,基本没讲到怎么生成可用的类库,网上的相关文档也很少。我尝试了两天才终于把第一个MIDP加密测试程序运行成功。
我的应用只是实现Java ME的加密,所以这里讲的只是针对JavaME的,JavaSE应该会简单一点。

打开下载下来的压缩包(crypto-138.zip),会发现里面有一堆文件夹和一堆文件,其中一个文件夹叫j2me,于是第一反应就是打开它看看里面是什么,发现里面只有少量的源代码文件,看来这只是适用于j2me的一部分源代码而已,其他通用的部分不在这里。
还有一个j2me.xml,是一个Ant的build文件,在eclipse里面用ant打开以后,发现里面有很多target,除了what(输出一些信息)和init(建立几个目录,复制一些文件)这两个能执行成功之外,其他几乎都是失败的,所以通过这个东西是搞不出我们可用的classes来的。
没办法,只有一个个目录地看,在一个zips目录里面发现cldc_sources.zip,里面的源代码文件有很多,有点像了,于是就把它解压后放到一个Eclipse ME测试项目的src目录下,找到org.bouncycastle.crypto.examples包,里面有个MIDPTest.java文件,还有个midp_test.jad,看来这个是用来测试用的MIDP了,调出WTK的模拟器来运行一下,果然是,成功了。
下一步是在手机上运行。如果不混淆,生成的JAR包有1.6M之巨,不管了,先试一下。安装到手机上,到最后出现“授权失败”的提示,安装不成功。记起原来找文档时在index.html里面看到有这么一句话:The final caveat to this is that as the j2me distribution includes some compatibility classes starting in the java package, you need to use an obfuscator to change the package names before attempting to import a midlet using the BC API. 似乎因为用于j2me的版本有几个以java开头的包,里面包含了一些兼容类,可能是用于补充CLDC的不足,由于java开头的包是系统包,是不允许修改的,所以不处理过的话安装会失败。必须先用混淆器弄一下才行。Eclipse ME配置混淆器十分简单,我使用的是ProGuard。参照http://www.cnjm.net/eclipseme/docs/configuring.html配置即可。然后运行Create Obfuscated Package生成混淆过的包,只有13K。安装在Nokia 6681上,成功,运行,也成功了。尝试修改一下MIDPTest.java,在whichCipher方法里面,把返回值改为其他数字(0-4),就可以修改加密方式,但是由于DES加密使用的密钥长度为64bit,而默认的key是"0123456789abcdef0123456789abcdef",运行DES是会提示密钥太长,我开始以为把key改为4个字符就可以(因为Java使用Unicode,每个字符2字节,4个字符8字节=64bit),却出现了数组越界的异常,其实这个key并不是直接用作密钥,还要经过处理的。尝试了8个字符也不行,最后发现16个字符就可以了,应该是每两个字符对应一个16进制数。测试程序是对“www.bouncycastle.org”这个字符串进行加密和解密,速度还是挺快的,几乎感觉不到需要时间(在手机上启动Java程序本来就比较慢)。

中间还碰到一个问题,由于我是把源代码直接复制到一个原来建立好的MIDP项目里,那个MIDP项目里已经有个默认的JAD文件,但是里面没有表示要运行的Midlet,生成Jar包之后,安装到手机上到最后会出现安装文件无效的提示。打开那个JAD文件,在Midlets标签里点击Add按钮,把org.bouncycastle.crypto.examples.MIDPTest添加进去即可。

以上测试使用的环境是:
JDK 1.5.02
Eclipse 3.2.0
Eclipse ME 1.7.7 http://eclipseme.org
Sun WTK 2.5.2 for CLDC
ProGuard 4.1 http://proguard.sourceforge.net/



刚刚发现Bouncy Castle的下载页面http://www.bouncycastle.org/latest_releases.html里面有专用于J2ME的源代码发行包,里面只包含用于J2ME的代码,如果仅用在J2ME下的话,这个应该比较简单,不用找半天。
posted @ 2008-01-25 19:59 amp@java 阅读(1438) | 评论 (1)编辑 收藏

有时候我们需要通过程序自动发送一些纯文字的信息,通过SMS可以达到目的,但当文字达到一定长度时,就必须分割成多条短信(一般60汉字一条),增加了费用,通过MMS可以解决这一问题,MMS最大支持100KB的内容,假设每个汉字3byte(使用UTF-8编码),能发送33K个汉字,一次可以发送一篇文章了。
Now SMS/MMS提供了一个Web界面用于发送彩信,通过Apache HttpClient,我们可以模拟浏览器的行为向web服务器提交表单,发送彩信。Now SMS/MMS的Web界面提供了很多选项,但发送纯文字彩信的话我们只需要填写接收者,主题(可选),内容即可,把对应的表单内容POST到当前页面,就能发送一条彩信。(待续)
posted @ 2007-10-01 14:22 amp@java 阅读(1157) | 评论 (0)编辑 收藏

Now SMS/MMS是一个强大的短信/彩信发送服务器,它内置了彩信中心,在某些运营商的网络内可以通过普通的短信猫发送彩信,而不需要使用支持GPRS的短信猫,也就是说系统本身就具有了运营商的彩信中心的功能。然而,在中国移动的网络内是不能实现这种方式发送彩信的,必须通过移动梦网的彩信中心转发。
彩信的发送其实是两个过程:
1、向目标手机发送一条普通的提醒短信,其中包含了发送者号码、彩信的URL等信息,该URL指向彩信中心的某个web目录下的某个彩信文件;
2、目标手机接收到这条提醒短信后,主动发起GPRS连接,根据短信中的URL向彩信中心提取该彩信,并显示出来。
Now SMS/MMS 自带的彩信中心其实就是一个支持手机连接的web服务器,它把制作好的彩信放在某个web目录下,手机连接时就可以下载。
然而,实践证明,如果使用中国移动的SIM卡,无论使用的是什么短信猫,都不能通过系统自带的彩信中心发送彩信。
要设置成通过移动公司的彩信中心发送彩信,必须把系统的默认设置——使用自带的MMSC(彩信中心)——改为使用移动公司的MMSC。方法如下:
在Now SMS/MMS Gateway配置程序中选择MMSC Routing,然后点击Add按钮,在弹出的对话框中建立一个新的MMSC配置,其中Acount Name和Account Description可以随便填,只是用来识别配置名称,因为系统可以设置多个MMSC。Default Sender Address必须留空,否则发送很难成功(有极少部分能够发送成功)。Allow Sender Address Override前的复选框也必须留空。Route messages to this account for recipient phone number(s)不用填(这是一个掩码,只有符合要求的号码才用这个路由,按照官方文档的说法,不填的话是不会用这个路由的,但实际上把它设成默认路由的话,即使不填也会用这个,也许填上+861*,1*会好些,表示中国的手机都用这个发)。Route messages to VASP via选择MM1,之后会出现更多的输入框,点击Look up Operator Seetings,出现一个选择运营商的对话框,很幸运,中国移动在里面,选择China - China Mobile,然后OK即可,系统自动把适合中国移动的内容填了进去。但是Network Connection和Modem Used两个下拉列表还没选好。这里必须使用对应的GPRS猫的调制解调器(在控制面板-电话和调制解调器选项-调制解调器-添加,按照提示一步步就能找到GPRS猫,看好哪个调制解调器对应哪个端口,从而知道哪个调制解调器对应哪个GPRS猫)。填好这些东西后点击Test Connection可以检测连接,成功就可以了,检测时间比较长,要耐心等待。填好之后点击OK,在MMSC Routing标签页里的Additional Routes里面就能看到刚才的那个配置名称,然后在Default Route里面选择刚才的配置名称作为默认路由就可以了。
之后打开MMSC标签,配置自带的MMSC。虽然我们使用的是中国移动的MMSC,但通过web发送彩信时,必须先发送到系统自带的MMSC,再转发到移动的MMSC,所以必须把系统的MMSC也配置好。这里就是普通web服务器的配置(还有SMTP的配置,可选),把端口和IP选好后,还要注意Local Host Name or IP Address里要填入一个本机的IP,如果在仅在内网使用,可以直接填本机IP(外网的情况没有研究过,看看说明书先)。其他默认的就可以了。
再打开Web标签页,把Web服务器配置好。
打开浏览器,输入http://服务器IP:web服务器端口/,就能看到发送各种短信、彩信的链接,然后就可以发送彩信进行测试了。如果发送不成功,可以打开Serial #标签页,把底下的三个Debug选项都勾上,再发送一下,然后在Now SMS/MMS 的安装目录下找到MMSCDEBUG.LOG等几个LOG文件查看究竟是什么问题。文件太大会导致发送失败,系统不会自动检查的。文件大小的上限还不清楚,但超过100KB似乎就肯定不行。
今天搞了一天这个东西,终于能正常发送彩信了。在这里备忘一下。慢慢再作深入研究。


感谢:http://blog.csdn.net/phiger/archive/2006/12/19/1449176.aspx

官方文档:http://www.nowsms.com/documentation/ProductDocumentation/mms_notifications_and_content/Connecting_to_operator_MMSC.htm#SendingMMSMessages
posted @ 2007-09-18 19:32 amp@java 阅读(5387) | 评论 (18)编辑 收藏

一个使用了JSTL的JSP页面,当字符集设为GB18030时,总会随机的出现一些乱码,莫名其妙的,有时候有,有时候没有,刷新一下可能会变,也可能不变;最令人懊恼的是,利用JSTL生成的JavaScript语句经常会漏掉一两个字母,害得整个JS程序段出错,每次漏的字目都不一样,根本没法改。
似乎google搜不到相关信息,没办法,后来把编码改为UTF-8,就不会再出现这种情况了,但不知道以后还会不会出现。
有时候上网易,也会见到一些字符出现乱码,刷新一下就没有了,看来这是JSP的通病,为什么就没有人提出解决方案呢?
posted @ 2007-09-10 19:48 amp@java 阅读(1349) | 评论 (7)编辑 收藏

通过JDBC-ODBC桥连接某个ACCESS数据库,并把一个逗号分隔文本文件插入到某个表中,如果插入过程中没有其他程序使用该数据库,只需要20多秒就可以完成;如果插入的同时,还用ACCESS程序打开了那个mdb文件,虽然没有任何操作,但运行相同的插入程序,竟然需要80多秒,性能下降4倍!!
ACCESS=垃圾!
posted @ 2007-07-15 02:15 amp@java 阅读(1494) | 评论 (0)编辑 收藏

仅列出标题
共10页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last