blogjava-凯发k8网页登录

blogjava-凯发k8网页登录http://www.blogjava.net/wangxinsh55/category/9197.htmlzh-cnfri, 08 apr 2011 08:49:05 gmtfri, 08 apr 2011 08:49:05 gmt60设置mysql允许外部ip连接的解决方法http://www.blogjava.net/wangxinsh55/archive/2011/04/08/347870.htmlsimonesimonefri, 08 apr 2011 03:42:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2011/04/08/347870.htmlhttp://www.blogjava.net/wangxinsh55/comments/347870.htmlhttp://www.blogjava.net/wangxinsh55/archive/2011/04/08/347870.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/347870.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/347870.html设置mysql允许外部ip连接的解决方法
   mysql默认情况下,只允许localhost连接,如果需要外部ip连接到mysql,需要向mysql数据库里的“user”表里添加相关授权。
   例如:让newuser用户使用newpwd密码从ip:192.168.1.3主机链接到mysql服务器  
  
   具体步骤:
   mysql>grant all privileges on *.* to identified by 'newpwd' with grant option;
   mysql>flush privileges;   
  
   grant语法:
   grant 权限名(所有的权限用all) on    库名(*全部).表名(*全部) to  '要授权的用户名表示所有的ip,可以只些一个ip) identified by "密码";
身份检查使用user表(host, user和password)3个范围列执行。服务器只有在user表记录的host和user列匹配客户端主机名和用户名并且提供了正确的密码时才接受连接。
在user表host值的指定方法:
    * host值可以是主机名或ip号,或'localhost'指出本地主机。
    * 你可以在host列值使用通配符字符“%”和“_”。
    * host值'%'匹配任何主机名,空host值等价于'%'。它们的含义与like操作符的模式匹配操作相同。例如,'%'的host值与所有主机名匹配,而'%.mysql.com'匹配mysql.com域
的所有主机。


simone 2011-04-08 11:42
]]>
前端开发 ie 中的常用调试工具[转]http://www.blogjava.net/wangxinsh55/archive/2009/03/02/257350.htmlsimonesimonemon, 02 mar 2009 07:47:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2009/03/02/257350.htmlhttp://www.blogjava.net/wangxinsh55/comments/257350.htmlhttp://www.blogjava.net/wangxinsh55/archive/2009/03/02/257350.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/257350.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/257350.html一些前端开发 ie 中的常用调试工具:

microsoft script debugger —— companion.js need to install this
companion.js —— javascript debugger for ie , like console api feature
ie developer toolbar —— like firebug (dom/css etc)
fiddler —— web debugging proxy
httpwatch —— http viewer
fiddler
一个很强大的http流查看工具
http://www.fiddlertool.com/fiddler/

httpwatch
数据分析工具,头消息接受/发送的查看,post数据查看.等等
http://www.httpwatch.com

ie developer toolsbar
ie下的firebug.html及css调试工具
http://www.windowsmarketplace.com/details.aspx?itemid=2695980

companion.js
ie下的javascript调试工具.福音啊!福音啊!!福音啊!!!
http://www.my-debugbar.com/wiki/companionjs/homepage

firebug
强的没话说了已经….如果你不知道这是什么….那我更没话说了….
https://addons.mozilla.org/en-us/firefox/addon/1843

web developer
firefox下的查看工具,可以查看js,css等页面信息
https://addons.mozilla.org/en-us/firefox/addon/60

yslow
why slow?页面性能优化查看器.基于firebug
http://developer.yahoo.com/yslow

javascript debugger
firefox下的javascript调试工具,比firebug有更强大的调试功能.
https://addons.mozilla.org/en-us/firefox/addon/216

opera developer tools
opera下的dom,css查看工具,类似firebug.
http://dev.opera.com/articles/view/opera-developer-tools/

webkit
safari下的开发调试工具
http://nightly.webkit.org/

 



simone 2009-03-02 15:47
]]>
webservice大讲堂之axis2 http://www.blogjava.net/nokiaguy/category/37087.htmlhttp://www.blogjava.net/wangxinsh55/archive/2009/02/13/254560.htmlsimonesimonefri, 13 feb 2009 07:34:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2009/02/13/254560.htmlhttp://www.blogjava.net/wangxinsh55/comments/254560.htmlhttp://www.blogjava.net/wangxinsh55/archive/2009/02/13/254560.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/254560.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/254560.html
值得关注



simone 2009-02-13 15:34
]]>
安装loadrunner9的心得http://www.blogjava.net/wangxinsh55/archive/2009/02/13/254525.htmlsimonesimonefri, 13 feb 2009 03:27:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2009/02/13/254525.htmlhttp://www.blogjava.net/wangxinsh55/comments/254525.htmlhttp://www.blogjava.net/wangxinsh55/archive/2009/02/13/254525.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/254525.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/254525.html 记得第一次安装lr9.0时,破解文档还没有出来,当时安装也不顺,最终无缘使用。
这次不单单找到了破解文档,而且安装过程异常顺利。直接使用默认安装后,用lr8.0中的mlr5lprg.dll、lm70.dll覆盖lr9.0安装目录下“bin”文件夹中的对应文件。即可开始使用lr9.0了。
呵呵,因为卸载的lr8.1已经添加过去用户限制的注册信息了,
golba-100: aeamauik-yafekekjjkeea-bcjgi
      web-10000: aeabexfr-ytiekekjjmfkekekwbraunqju-kbygb
这里lr9.0就默认了那些注册信息。
进入一切正常。


附:一份他人的破解文档参考
打开loadrunner,发现以下几个dll可能和注册有关,mlr5lprg.dll、licensebundles.dll、lm50.dll、lm70.dll。
最后确认mlr5lprg.dll、lm70.dll是关键dll。
破解方法类似与lr8.1
a、用lr8.0中的mlr5lprg.dll、lm70.dll覆盖lr9.0安装目录下“bin”文件夹中的对应文件;
b、然后使用老的注册码就可以使用了;
c、golba-100: aeamauik-yafekekjjkeea-bcjgi
      web-10000: aeabexfr-ytiekekjjmfkekekwbraunqju-kbygb

可能会遇到的问题
在破解的过程中我还遇到了个问题,就是通过上述的方法注册时提示“license security violation……”,无法注册。
该问题可通过如下办法解决:
a、手动修改注册表,删除下面内容:
[hkey_local_machine\software\mercury interactive\loadrunner\license2]

[hkey_local_machine\software\mercury interactive\loadrunner\license2\history]
"aibgebfw-jved-zkekekekekebdnqaf-kbrdn"=""

[hkey_local_machine\software\mercury interactive\loadrunner\license2\permanentlicense]
@="aibgebfw-jved-zkekekekekebdnqaf-kbrdn"
"last"="aibgebfw-jved-zkekekekekebdnqaf-kbrdn"

[hkey_local_machine\software\mercury interactive\loadrunner\license2\temporarylicense]
@="aebgebfs-akekekeke-kauca"

[hkey_local_machine\software\classes\interface\{87b3add4-21eb-11d5-93ef-00105aa0fd2d}]
@="icontrol"

b、可使用网上的朋友提供的lr_delete_license.exe文件删除上述的注册表内容。由于这个程序是针对8.1的,可能会报错,但是不影响使用。
申明
最后得感谢hp公司的大度,并没有对注册模块做大的修改,这可以让我们取巧使用。最后请大家不要以此用于商业运作,仅供个人学习参考,请大家支持正版软件。

simone 2009-02-13 11:27
]]>
windows 2003操作系统25招加速方法http://www.blogjava.net/wangxinsh55/archive/2007/06/05/122226.htmlsimonesimonetue, 05 jun 2007 11:56:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2007/06/05/122226.htmlhttp://www.blogjava.net/wangxinsh55/comments/122226.htmlhttp://www.blogjava.net/wangxinsh55/archive/2007/06/05/122226.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/122226.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/122226.html微软的windown server 2003尽管它是对应服务器的,但仍然有不少朋友蠢蠢欲动,欲升之而后快。可是,安装之后你就会发现麻烦多多,这样功能没有,那样功能打不开,甚至连听歌,玩游戏也成问题了。

  其实,server 2003在xp的基础强化了安全性和稳定性,不得不关闭了一些工作站系统。我们是把win 2003当工作站用,当然要重新打开这些服务,让它重获新生啦。那些用不着的服务器功能,也一并减肥去掉吧。

  1、关闭服务器向导

  装完win 2003,你会发现“管理您的服务器”出现,把左下角的“登录时不要显示该页”勾上。如果你在开机时找不到,可以进入控制面板-管理工具-管理你的服务器中找到

  2、用户帐号登录

  2003使用服务器的ctrl alt del登录方式,没有win xp的登录欢迎,还是建立一个帐号登录有个性化。在开始-运行-输入“lusrmgr.msc”-本地用户和组。在用户中右键点击建立“新用户”,输入账号信息并建立账号。

  接着把新建的账号添加到管理员组,右键点击你新建的用户,选择属性-隶属于-添加add..-高级-现在查找,双击管理员,得到administrator相近的权限。

  3、关闭事件跟踪程序

  服务器必不可少的功能之一,开始-运行-输入“gpedit.msc”,打开组策略编辑器,在右边的计算机配置-管理模板-系统,双击“显示关闭事件跟踪程序”,设置为己禁用,以后关机画面就和win2000相同了

  4、程序的动态分配

  右键点击“我的电脑”图标,进入属性-高级-性能-设置-高级,选择分配处理器和内存资源都选择为“程序”使用。

  5、关闭错误报告

  右键点击“我的电脑”图标,进入属性-高级-错误报告,选择“禁用错误报告”,并且去掉“但在发生严重错误时通知我”的勾。

  6、隐藏文件

  win2003默认是显示所有文件夹的,可以设法来隐藏:在资源管理器或我的电脑上,选择工具-文件夹选项-查看,不显示隐藏文件和文件夹。

  7、关闭internet explorer的增强安全配置

  这个新组件会把ie安全设置到最高,跟本没法进行正常的浏览行为,在它弹出的时间,先选中“以后不要显示这个信息”,当然,最省事的方法是在控制面板--添加程序--添加或删除windows组件中卸载增强安全配置。

  然后,找开ie,在工具-internet选项-安全,点击默认级别,设置为中级即可。

  8、安装java虚拟机

  自从win xp开始,java已经没有内置在系统中,微软这招够毒啊,为此,我们只好另外安装,而且需要去掉高级安全才能安装。

  9、开启硬件加速

  桌面点击右键,进入属性-设置-高级-疑难解答,开启完全的硬件加速,这时会出现黑屏,然后回复正常。

  10、开启directx加速

  开始-运行-输入dxdiag-显示,把directdraw、direct3d、agp纹理加速都启用。要注意的是,负责2d的directdraw和direct3d有时不能并用,只能开启其中一样。

  11、声音加速

  开始-运行-输入dxdiag-声音,把“声音的硬件加速级别”拉到“完全加速”。

  12、提高开/关机速度

  如果你的内存有768mb或以上,可以禁用虚拟内存,xp内核的内存管理已经相当优秀,而且虚拟内存(pagefile.sys)和休眠模式(hiberfil.sys)采用不同的文件,可以避免win9x系统禁用虚拟内存出现的无法正常待机和休眠。在我们的测试系统上,开机一整天,关机仅仅用了9秒钟。

  右键点击“我的电脑”图标,进入属性-高级-性能-设置-高级-虚拟内存-更改,勾上无分页文件,然后按设置并确定。

  无论在什么时候,增加内存都是提高相对速度的最快方法,因此,如果不是经常进行高级计算、图像处理、dx9 3d游戏的朋友,升级时尽可能先考虑内存容量。

13、安装directx 9b

  不仅可以加速多媒体应用,而且能够减少被别人利用系统漏洞攻击的机率。

  14、安装防火墙

  即使win2003的安全性高,而且我们也经常升级系统补丁,但亦无法保证不被攻击。可是,win2003需要特殊的程序,普通单机软件无法安装,必须使用服务器版的程序。推荐:symantec norton antivirus企业版病毒防火墙 personal firewall 2003网络防火墙。
 15、提高系统性能

  右键点击“我的电脑”图标,进入属性-高级-性能-设置,调整为最佳性能。

  16、加速任务栏

  除了将“任务栏保持在其它窗口的前端”其它全部去掉,原因如下:

  自动隐藏任务栏:避免找不到任务栏,而且占用系统

  分组相似任务栏按钮:程序过于集中,很难找到

  显示时钟:有手表或手机就无须用时钟

  隐藏不活动图标:不知道现在使用了那些应用程序

  17、自定义经典开始菜单

  只使用“显示运行”和“在开始菜单中显示小图标”,其它都是扩展任务栏,以及增加特效和功能的,紧记!功能越少越快

  18、提高显示速度

  右键点击桌面进入显示属性,把桌面墙纸和屏幕保护都关掉,在外观-效果中,把所有勾去掉。

  19、资源管理器提速

  在资源管理器或我的电脑上,选择工具-文件夹选项-常规,选择“使用windows传统风格的文件夹”。

  把“隐藏受保护的操作系统文件”和“隐藏己知文件类型的扩展名”之外所有的选项都去掉。特别是“记住每个文件夹的视图设置”、“鼠标指向文件夹和桌面项时显示提示信息”、“在文件夹提示中显示文件大小信息”这几项关掉,去掉个性化设置。

  第三是资源管理器的优化,查看中使用“列表”形式,以最小的图标和信息显示内容。在工具栏菜单中,把标准按钮和链接都去掉,这些功能全部通过快捷键可以实现,多留无益。

  20、关掉桌面图标

  在桌面上按右键,选择排列图标,去掉显示桌面图标的勾,关掉所有图标,节省大量资源。

  21、ie的优化

  ie的界面优化基本和资源管理器相同,都是尽可能减少功能条,只留下地址栏。不过,在工具-internet选项中就有许多好玩东西了。

  常规-可以更改的凯发k8网页登录主页用空白页,开启时无须载入任何网页,速度飞

  高级-多媒体,去掉“启用自动图像大小调整”,直接显示整幅图像,减少ie的工作量。

  浏览,去掉“启用脱机项目按计划同步”,在宽带包月如此流行的今天,脱机还有什么用?

  去掉“使用平滑滚动”,让左边的导航条,按照正常的page up/down方式快速翻页。

  去掉“下载完成后发出通知”,download完就算还通知什么,多此一举。

  去掉“在地址栏中显示转到按钮”,转到的网址我们都没多大用处。

  去掉“自动检查internet explorer更新”,手动更新永远比自动更新要快,而且无须让ie经常留意是否需要更新。

  22、关掉自动更新

  在“我的电脑”图标上按右键,系统属性-自动更新,去掉“保持我的计算机最新”。让我们养成自己定时更新的好习惯,可以让大家避免再受到“冲击波”之类的病毒袭击。

  23、关闭远程协助

  在“我的电脑”图标上按右键,系统属性-远程中,一般情况下把远程协助全部关掉,避免不必要的麻烦。

  24、使用耗电模式

  为了让电脑经常处于最佳状态,把所有的省电模式关掉,在控制面板-电源使用方案中选择“演示”方案,从不关闭监视器、硬盘或进行系统待机。

  25、键盘速度

  在控制面板-键盘中,把“重复延迟”和“重复速度”都拉到右边,文字编辑的时候立即见功。



simone 2007-06-05 19:56
]]>
xp系统修复http://www.blogjava.net/wangxinsh55/archive/2007/05/11/116793.htmlsimonesimonefri, 11 may 2007 08:55:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2007/05/11/116793.htmlhttp://www.blogjava.net/wangxinsh55/comments/116793.htmlhttp://www.blogjava.net/wangxinsh55/archive/2007/05/11/116793.html#feedback1http://www.blogjava.net/wangxinsh55/comments/commentrss/116793.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/116793.html在“运行”中输入sfc /scannow即可

simone 2007-05-11 16:55
]]>
j2me技术——跟我学制作pak文件 http://www.blogjava.net/wangxinsh55/archive/2007/02/13/99736.htmlsimonesimonetue, 13 feb 2007 09:23:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2007/02/13/99736.htmlhttp://www.blogjava.net/wangxinsh55/comments/99736.htmlhttp://www.blogjava.net/wangxinsh55/archive/2007/02/13/99736.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/99736.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/99736.html  
  由于前些时间,一些matrixer常问关于j2me中使用pak文件的问题。本人虽学艺不深,但满怀热心的做了一番探索,现将制作pak文件的看法和方法公布出来,大家多多提意见。
  
  一、什么是pak文件:
  
  pak文件就是将多个文件打包为一个单独文件,在这个文件中保存着多个文件的数据,当然还有一些描述文件结构的数据。所以将“pak”作为文件的后缀是一种常规的用法,大家可以自定义其它的文件后缀。
  
  二、为什么使用pak文件:
  
  由于midp对发布安装的j2me程序大小进行了限制,所以缩小发布程序就意味着能够提供更多的程序或者内容(如图片、音乐)给用户。而通过研究发现zip/jar算法对大文件的压缩率高于对等量的多个小文件的压缩率。
  
  当然还有其它方法,这里简单做一下讨论比如使用混淆器proguard的“-overloadaggressively”选项使jar文件缩小,但也会导致一些错误,因为这种方法生成jar中的class符合java byte code标准,但是与java语法相悖,严重的可能造成一些jre对object的序列化错误。
  
  所以使用pak方法将程序中要用到的资源(图片、音乐、文本)组合为单一文件是一个安全有效的方法。而且对于一些商用程序,完全可以在pak文件中对文件数据进行加密,很好的保护了作者和公司的权益。本人的sample中使用了简单的“加减法”加密,对于手机这类设备来讲是一个效率较高的选择。
  
  三、pak文件的结构:
  
  大家可以自己设计pak文件结构,本人这里只是抛砖引玉的作个sample。下面就是本人设计的pak文件结构:
  
  pak file header:pak文件的头部
  
  * 签名:6字节char数组 * 版本号:32位float * 文件table数量:32位整数 * 密码行为:8位字节 * 密码:8位字节 * 文件唯一id:10字节char数组 * 保留位:32位整数(4字节)
  
  file table:pak文件中包含文件的列表,在一个pak文件中一个被包含的文件对应一个file table。
  
  * 文件名:30字节char数组 * 文件大小:32位整型 * 文件在pak文件中的位移:32位整数
  
  concatenated file data:按file table的顺序连接在一起的文件数据。
  * 文件数据
  
  四、程序框架:
  
  说明:由于pak文件的制作和使用分别要使用两个java应用领域:j2se和j2me,所以本人将pakutil类制作了2个版本(j2se和j2me)。
  
  程序框架如下:
  1。pakheader类,定义了pak文件头。
  2。pakfiletable类,定义pak文件table。
  3。pakutil类(j2se版),具备两个功能:将多个png图片合成一个pak文件,并使用简单的加减加密法对其进行加密;从pak文件中取出png图片,构造byte数组(可以用来构造image对象)或者写为文件。
  pakutil类(j2me版),具备的功能:从pak文件中取出png图片,构造byte数组(可以用来构造image对象)。
  
  五、pakheader和pakfiletable类:
  
  pakheader.java:
  package cn.org.matrix.gmatrix.gamelab.util.pak;/** * pak文件头: * 结构: *
  签名:6字节char数组 *  版本号:32位float *
  文件table数量:32位整数 *
  密码行为:8位字节 *  密码:8位字节 *
  文件唯一id:10字节char数组 *
  保留位:32位整数(4字节) * @author cleverpig * */class pakheader {
  //定义文件唯一id长度
  public static final int uniqueid_length=10;
  //定义文件签名长度
  public static final int signature_length=6;
  //定义加法运算
  public static final int addition_cipheraction=0;
  //定义减法运算
  public static final int subtract_cihoeraction=1;
  //文件签名
  private char[] signature=new char[signature_length];
  //版本号
  private float version=0f;
  //文件table数量
  private long numfiletableentries=0;
  //密码使用方法:在原数据上进行加法还是减法
  private byte cipheraction=addition_cipheraction;
  //密码值
  private byte ciphervalue=0x00;
  //唯一id
  private char[] uniqueid=new char[uniqueid_length];
  //保留的4字节
  private long reserved=0;
  public pakheader(){
  }
  /**
  * 构造方法
  * @param signature 签名
  * @param version 版本
  * @param numfiletableentries 文件table数量
  * @param cipheraction 密码使用方法
  * @param ciphervalue 密码值
  * @param uniqueid 唯一id
  * @param reserved 保留的2字节
  */
  public pakheader(char[] signature,float version,
  long numfiletableentries,byte cipheraction,
  byte ciphervalue,char[] uniqueid,long reserved){
  for(int i=0;i  ;
  this.version=version;
  this.cipheraction=cipheraction;
  this.numfiletableentries=numfiletableentries;
  this.ciphervalue=ciphervalue;
  for(int i=0;i  this.reserved=reserved;
  }        
  public byte getciphervalue() {
  return ciphervalue;    
  }
  public void setciphervalue(byte ciphervalue) {
  this.ciphervalue = ciphervalue;
  }
  public long getnumfiletableentries() {
  return numfiletableentries;
  }
  public void setnumfiletableentries(long numfiletableentries) {
  this.numfiletableentries = numfiletableentries;
  }
  public long getreserved() {
  return reserved;
  }
  public void setreserved(long reserved) {
  this.reserved = reserved;
  }
  public char[] getuniqueid() {
  return uniqueid;
  }
  public void setuniqueid(char[] uniqueid) {
  for(int i=0;i  ;    
  }    
  public float getversion() {
  return version;
  }    
  public void setversion(float version) {
  this.version = version;
  }
  public byte getcipheraction() {
  return cipheraction;
  }
  public void setcipheraction(byte cipheraction) {
  this.cipheraction = cipheraction;
  }
  public char[] getsignature() {
  return signature;
  }
  public void setsignature(char[] signature) {
  for(int i=0;i  ;    
  }
  /**
  * 返回pakheader的大小
  * @return 返回pakheader的大小
  */    
  public static int size(){
  return signature_length 4 4 1 1 uniqueid_length 4;
  }
  public string tostring(){
  string result="";
  result ="\t签名:" new string(this.signature).trim()
   "\t版本号:" this.version
   "\t文件table数量:" this.numfiletableentries
   "\t密码行为:" this.cipheraction
   "\t密码:" this.ciphervalue            
   "\t文件唯一id:" new string(this.uniqueid).trim()             "\t保留位:" this.reserved;        
  return result;    
  }}
  
  pakfiletable.java
  package cn.org.matrix.gmatrix.gamelab.util.pak;/** * pak文件table类 * 文件table结构: *
  文件名:30字节char数组 *
  文件大小:32位整型 *
  文件在pak文件中的位移:32位整数 * @author cleverpig * */class pakfiletable {
  public static final int filename_length=30;
  //文件名
  private char[] filename=new char[filename_length];
  //文件大小
  private long filesize=0l;
  //文件在pak文件中的位移
  private long offset=0l;
  public pakfiletable(){
  }
  /**
  * 构造方法
  * @param filename 文件名
  * @param filesize 文件大小
  * @param offset 文件在pak文件中的位移
  */
  public pakfiletable(char[] filename,
  long filesize,long offset){
  for(int i=0;i  ;        this.filesize=filesize;
  this.offset=offset;
  }
  public char[] getfilename() {
  return filename;
  }
  public void setfilename(char[] filename) {
  for(int i=0;i  ;    
  }
  public long getfilesize() {
  return filesize;
  }
  public void setfilesize(long filesize) {
  this.filesize = filesize;
  }
  public long getoffset() {
  return offset;
  }
  public void setoffset(long offset) {
  this.offset = offset;
  }
  /**
  * 返回文件table的大小
  * @return 返回文件table的大小
  */    
  public static int size(){
  return filename_length 4 4;
  }
  public string tostring(){
  return "\t文件名:" new string(this.filename).trim()
   "\t文件大小:" this.filesize
   "\t文件位移:" this.offset;
  }}
  
  六、pakutil类(j2se版):
  
  pakutil.java
  package cn.org.matrix.gmatrix.gamelab.util.pak;import java.io.*;
  import java.util.vector;
  /** * pak工具类 * 功能:
  *1.将多个png图片合成一个pak文件,并使用简单的加减加密法对其进行加密;
  * 2.从pak文件中取出png图片,构造byte数组(可以用来构造image对象)或者写为文件 * @author cleverpig * */public class pakutil {
  public pakutil(){
  }
  /**
  * 返回文件长度
  * @param filepath 文件路径
  * @return 文件长度
  */
  private long getfilesize(string filepath){
  file file=new file(filepath);
  return file.length();
  }
  /**
  * 返回文件名
  * @param filepath 文件路径
  * @return 文件名
  */
  
  private string getfilename(string filepath){
  file file=new file(filepath);
  return file.getname();
  }
  /**
  * 计算文件位移的起始点
  * @return 文件位移的起始点
  */
  private long workoutoffsetstart(pakheader header){
  //计算出文件头 文件table的长度
  return pakheader.size() header.getnumfiletableentries()*pakfiletable.size();
  }
  /**
  * 计算文件位移
  * @param fileindex 文件序号
  * @param lastfileoffset 上一个文件位移
  * @return 文件在pak文件中的位移
  */
  private long workoutnextoffset(long sourcefilesize,long lastfileoffset){
  return lastfileoffset sourcefilesize;    
  }
  /**
  * 生成文件table
  * @param sourcefilename 源文件名
  * @param sourcefilesize 源文件长度
  * @param currentfileoffset 当前文件位移
  * @return 生成的pakfiletable对象
  */    
  private pakfiletable generatefiletable(string sourcefilename,
  long sourcefilesize,long currentfileoffset){
  pakfiletable ft=new pakfiletable();
  ft.setfilename(sourcefilename.tochararray());
  ft.setfilesize(sourcefilesize);
  ft.setoffset(currentfileoffset);
  return ft;
  }
  /**
  * 将char字符数组写入到dataoutputstream中
  * @param towritechararray 被写入的char数组
  * @param dos dataoutputstream
  * @throws exception
  */    
  private void writechararray(char[] towritechararray,dataoutputstream dos) throws exception{
  for(int i=0;i  }        
  /**
  * 使用文件头中的密码对数据进行加密
  * @param buff 被加密的数据
  * @param bufflength 数据的长度
  * @param header 文件头
  */
  private void encryptbuff(byte[] buff,int bufflength,pakheader header){
  for(int i=0;i  switch(header.getcipheraction()){
  case pakheader.addition_cipheraction:
  buff[i] =header.getciphervalue();
  break;
  case pakheader.subtract_cihoeraction:
  buff[i]-=header.getciphervalue();
  break;
  }
  }
  }
  /**
  * 使用文件头中的密码对数据进行解密
  * @param buff 被解密的数据
  * @param bufflength 数据的长度
  * @param header 文件头
  */
  private void decryptbuff(byte[] buff,int bufflength,pakheader header){
  for(int i=0;i  switch(header.getcipheraction()){
  case pakheader.addition_cipheraction:
  buff[i]-=header.getciphervalue();
  break;
  case pakheader.subtract_cihoeraction:
  buff[i] =header.getciphervalue();
  break;
  }
  }
  }
  /**
  * 制作pak文件
  * @param sourcefilepath 源文件路径数组
  * @param destinatefilepath 目的文件路径(pak文件)
  * @param cipheraction 密码行为
  * @param ciphervalue 密码
  * @throws exception
  */
  public void makepakfile(string[] sourcefilepath,
  string destinatefilepath,pakheader header) throws exception{
  pakfiletable[] filetable=new pakfiletable[sourcefilepath.length];
  //计算文件位移起始点
  long fileoffset=workoutoffsetstart(header);
  //逐个建立文件table
  for(int i=0;i  string sourcefilename=getfilename(sourcefilepath[i]);
  long sourcefilesize=getfilesize(sourcefilepath[i]);
  pakfiletable ft=generatefiletable(sourcefilename,sourcefilesize,fileoffset);
  //计算下一个文件位移
  fileoffset=workoutnextoffset(sourcefilesize,fileoffset);
  filetable[i]=ft;
  }
  //写入文件头
  file wfile=new file(destinatefilepath);
  fileoutputstream fos=new fileoutputstream(wfile);
  dataoutputstream dos=new dataoutputstream(fos);
  writechararray(header.getsignature(),dos);
  dos.writefloat(header.getversion());
  dos.writelong(header.getnumfiletableentries());
  dos.writebyte(header.getcipheraction());
  dos.writebyte(header.getciphervalue());
  writechararray(header.getuniqueid(),dos);
  dos.writelong(header.getreserved());
  //写入文件table
  for(int i=0;i  writechararray(filetable[i].getfilename(),dos);
  dos.writelong(filetable[i].getfilesize());
  dos.writelong(filetable[i].getoffset());
  }
  //写入文件数据
  for(int i=0;i  file ftfile=new file(sourcefilepath[i]);
  fileinputstream ftfis=new fileinputstream(ftfile);
  datainputstream ftdis=new datainputstream(ftfis);
  byte[] buff=new byte[256];
  int readlength=0;
  while((readlength=ftdis.read(buff))!=-1){
  encryptbuff(buff,readlength,header);
  dos.write(buff,0,readlength);
  }
  ftdis.close();
  ftfis.close();
  }
  dos.close();
  }
  /**
  * 从datainputstream读取char数组     * @param dis datainputstream
  * @param readlength 读取长度
  * @return char数组
  * @throws exception
  */
  private char[] readchararray(datainputstream dis,int readlength) throws exception{
  char[] readchararray=new char[readlength];
  for(int i=0;i  readchararray[i]=dis.readchar();
  }
  return readchararray;
  }
  /**
  * 从pak文件中读取文件头
  * @param dis datainputstream
  * @return pakheader
  * @throws exception
  */
  private pakheader readheader(datainputstream dis) throws exception{
  pakheader header=new pakheader();
  char[] signature=readchararray(dis,pakheader.signature_length);
  header.setsignature(signature);
  header.setversion(dis.readfloat());
  header.setnumfiletableentries(dis.readlong());
  header.setcipheraction(dis.readbyte());
  header.setciphervalue(dis.readbyte());
  char[] uniqueid=readchararray(dis,pakheader.uniqueid_length);
  header.setuniqueid(uniqueid);
  header.setreserved(dis.readlong());
  return header;
  }
  /**
  * 读取所有的文件table
  * @param dis datainputstream
  * @param filetablenumber 文件表总数
  * @return 文件table数组
  * @throws exception
  */
  private pakfiletable[] readfiletable(datainputstream dis,int filetablenumber) throws exception{
  pakfiletable[] filetable=new pakfiletable[filetablenumber];
  for(int i=0;i  pakfiletable ft=new pakfiletable();
  ft.setfilename(readchararray(dis,pakfiletable.filename_length));
  ft.setfilesize(dis.readlong());
  ft.setoffset(dis.readlong());
  filetable[i]=ft;
  }        
  return filetable;
  }
  /**
  * 从pak文件读取文件到byte数组
  * @param dis datainputstream
  * @param filetable pakfiletable
  * @return byte数组
  * @throws exception
  */
  private byte[] readfilefrompak(datainputstream dis,pakheader header,pakfiletable filetable) throws exception{
  dis.skip(filetable.getoffset()-workoutoffsetstart(header));
  //
  int filelength=(int)filetable.getfilesize();
  byte[] filebuff=new byte[filelength];
  int readlength=dis.read(filebuff,0,filelength);
  if (readlength  system.out.println("读取数据长度不正确");
  return null;
  }
  else{
  decryptbuff(filebuff,readlength,header);
  return filebuff;
  }
  }
  /**
  * 将buffer中的内容写入到文件
  * @param filebuff 保存文件内容的buffer
  * @param filename 文件名
  * @param extractdir 文件导出目录
  * @throws exception
  */
  private void writefilefrombytebuffer(byte[] filebuff,string filename,string extractdir) throws exception{
  string extractfilepath=extractdir filename;
  file wfile=new file(extractfilepath);
  fileoutputstream fos=new fileoutputstream(wfile);
  dataoutputstream dos=new dataoutputstream(fos);
  dos.write(filebuff);
  dos.close();
  fos.close();
  }
  /**
  * 从pak文件中取出指定的文件到byte数组,如果需要的话可以将byte数组写为文件
  * @param pakfilepath pak文件路径
  * @param extractfilename pak文件中将要被取出的文件名
  * @param writefile 是否需要将byte数组写为文件
  * @param extractdir 如果需要的话可以将byte数组写为文件,extractdir为取出数据被写的目录文件
  * @return byte数组
  * @throws exception
  */
  public byte[] extractfilefrompak(string pakfilepath,
  string extractfilename,boolean writefile,string extractdir) throws exception{
  file rfile=new file(pakfilepath);
  fileinputstream fis=new fileinputstream(rfile);
  datainputstream dis=new datainputstream(fis);
  pakheader header=readheader(dis);
  pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries());
  boolean find=false;        int fileindex=0;
  for(int i=0;i  string filename=new string(filetable[i].getfilename()).trim();
  if (filename.equals(extractfilename)){
  find=true;
  fileindex=i;
  break;
  }
  }
  if (find==false){
  system.out.println("没有找到指定的文件");
  return null;        
  }      
  else{
  byte[] buff=readfilefrompak(dis,header,filetable[fileindex]);
  if (writefile){
  writefilefrombytebuffer(buff,extractfilename,extractdir);
  }            
  else{
  dis.close();
  fis.close();
  }
  return buff;
  }
  }
  /**
  * 从pak文件中取出指定的pak文件的信息
  * @param pakfilepath pak文件路径
  * @return 装载文件头和文件table数组的vector
  * @throws exception
  */
  public vector showpakfileinfo(string pakfilepath) throws exception{
  file rfile=new file(pakfilepath);
  fileinputstream fis=new fileinputstream(rfile);
  datainputstream dis=new datainputstream(fis);
  pakheader header=readheader(dis);
  pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries());        vector result=new vector();
  result.add(header);
  result.add(filetable);
  return result;
  }
  public static void main(string[] argv) throws exception{
  pakutil pu=new pakutil();
  //构造文件头
  char[] signature=new char[pakheader.signature_length];
  signature=new string("012345").tochararray();
  char[] uniqueid=new char[pakheader.uniqueid_length];
  uniqueid=new string("0123456789").tochararray();
  pakheader header=new pakheader();
  header.setsignature(signature);
  header.setnumfiletableentries(3);
  header.setcipheraction((byte)pakheader.addition_cipheraction);
  header.setciphervalue((byte)0x0f);
  header.setuniqueid(uniqueid);
  header.setversion(1.0f);
  header.setreserved(0l);
  string[] filepatharray={"f:\\eclipse3.1rc3\\workspace\\gmatrixproject_j2se\\testfiles\\apple.png",
  "f:\\eclipse3.1rc3\\workspace\\gmatrixproject_j2se\\testfiles\\cushaw.png",
  "f:\\eclipse3.1rc3\\workspace\\gmatrixproject_j2se\\testfiles\\flash.png"};
  string extractfilepath="f:\\eclipse3.1rc3\\workspace\\gmatrixproject_j2se\\testfiles\\test.pak";
  //制作pak文件
  system.out.println("制作pak文件...");
  pu.makepakfile(filepatharray,extractfilepath,header);
  system.out.println("制作pak文件完成");
  //从pak文件中取出所有的图片文件
  vector pakinfo=pu.showpakfileinfo(extractfilepath);
  header=(pakheader)pakinfo.elementat(0);
  system.out.println("pak文件信息:");
  system.out.println("文件头:");
  system.out.println(header);
  pakfiletable[] filetable=(pakfiletable[])pakinfo.elementat(1);
  for(int i=0;i  system.out.println("文件table[" i "]:");
  system.out.println(filetable[i]);
  }
  string restoredir="f:\\eclipse3.1rc3\\workspace\\gmatrixproject_j2se\\testfiles\\extract\\";
  string restorefilename=null;
  byte[] filebuff=null;
  for(int i=0;i  restorefilename=new string(filetable[i].getfilename()).trim();
  system.out.println("从pak文件中取出" restorefilename "文件...");
  filebuff=pu.extractfilefrompak(extractfilepath,restorefilename,true,restoredir);
  system.out.println("从pak文件中取出" restorefilename "文件保存在" restoredir "目录");
  }
  }}
  
  七、pakutil类(j2me版):
  
  pakutil.java
  package cn.org.matrix.gmatrix.gamelab.util.pak;
  import java.io.*;
  import java.util.vector;
  /** * pak工具类 * 功能: * 从pak文件中取出png图片,构造byte数组(可以用来构造image对象) * @author cleverpig * */public class pakutil {
  public pakutil(){
  }
  /**
  * 计算文件位移的起始点
  * @return 文件位移的起始点
  */
  private long workoutoffsetstart(pakheader header){
  //计算出文件头 文件table的长度
  return pakheader.size() header.getnumfiletableentries()*pakfiletable.size();
  }
  /**
  * 从datainputstream读取char数组
  * @param dis datainputstream
  * @param readlength 读取长度
  * @return char数组
  * @throws exception
  */
  private char[] readchararray(datainputstream dis,int readlength) throws exception{
  char[] readchararray=new char[readlength];
  for(int i=0;i  readchararray[i]=dis.readchar();
  }
  return readchararray;
  }
  /**
  * 从pak文件中读取文件头
  * @param dis datainputstream
  * @return pakheader
  * @throws exception
  */
  private pakheader readheader(datainputstream dis) throws exception{
  pakheader header=new pakheader();
  char[] signature=readchararray(dis,pakheader.signature_length);
  header.setsignature(signature);
  header.setversion(dis.readfloat());
  header.setnumfiletableentries(dis.readlong());
  header.setcipheraction(dis.readbyte());
  header.setciphervalue(dis.readbyte());
  char[] uniqueid=readchararray(dis,pakheader.uniqueid_length);
  header.setuniqueid(uniqueid);
  header.setreserved(dis.readlong());
  return header;
  }
  /**
  * 读取所有的文件table
  * @param dis datainputstream
  * @param filetablenumber 文件表总数
  * @return 文件table数组
  * @throws exception
  */
  private pakfiletable[] readfiletable(datainputstream dis,int filetablenumber) throws exception{
  pakfiletable[] filetable=new pakfiletable[filetablenumber];
  for(int i=0;i  pakfiletable ft=new pakfiletable();
  ft.setfilename(readchararray(dis,pakfiletable.filename_length));
  ft.setfilesize(dis.readlong());
  ft.setoffset(dis.readlong());
  filetable[i]=ft;
  }
  return filetable;
  }
  /**
  * 从pak文件读取文件到byte数组
  * @param dis datainputstream
  * @param filetable pakfiletable
  * @return byte数组
  * @throws exception
  */    
  private byte[] readfilefrompak(datainputstream dis,pakheader header,pakfiletable filetable) throws exception{
  dis.skip(filetable.getoffset()-workoutoffsetstart(header));
  //
  int filelength=(int)filetable.getfilesize();
  byte[] filebuff=new byte[filelength];
  int readlength=dis.read(filebuff,0,filelength);
  if (readlength  system.out.println("读取数据长度不正确");
  return null;
  }
  else{
  decryptbuff(filebuff,readlength,header);
  }        
  return filebuff;
  }
  /**
  * 使用文件头中的密码对数据进行解密
  * @param buff 被解密的数据
  * @param bufflength 数据的长度
  * @param header 文件头
  */
  private void decryptbuff(byte[] buff,int bufflength,pakheader header){
  for(int i=0;i  switch(header.getcipheraction()){
  case pakheader.addition_cipheraction:
  buff[i]-=header.getciphervalue();
  break;
  case pakheader.subtract_cihoeraction:
  buff[i] =header.getciphervalue();
  break;
  }
  }
  }
  /**
  * 从pak文件中取出指定的文件到byte数组
  * @param pakresourceurl pak文件的资源路径
  * @param extractresourcename pak文件中将要被取出的文件名
  * @return byte数组    
  * @throws exception
  */    
  public byte[] extractresourcefrompak(string pakresourceurl
  ,string extractresourcename) throws exception{
  inputstream is=this.getclass().getresourceasstream(pakresourceurl);
  datainputstream dis=new datainputstream(is);
  pakheader header=readheader(dis);//
  system.out.println("文件头:");//
  system.out.println(header);
  pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries());//
  for(int i=0;i  system.out.println("文件table[" i "]:");//
  system.out.println(filetable[i]);//
  }
  boolean find=false;
  int fileindex=0;
  for(int i=0;i  string filename=new string(filetable[i].getfilename()).trim();
  if (filename.equals(extractresourcename)){
  find=true;
  fileindex=i;
  break;
  }
  }
  if (find==false){
  system.out.println("没有找到指定的文件");
  return null;
  }
  else{
  byte[] buff=readfilefrompak(dis,header,filetable[fileindex]);
  return buff;
  }
  }
  /**
  * 从pak文件中取出指定的pak文件的信息
  * @param pakresourcepath pak文件资源路径
  * @return 装载文件头和文件table数组的vector
  * @throws exception
  */
  public vector showpakfileinfo(string pakresourcepath) throws exception{
  inputstream is=this.getclass().getresourceasstream(pakresourcepath);
  datainputstream dis=new datainputstream(is);
  pakheader header=readheader(dis);
  pakfiletable[] filetable=readfiletable(dis,(int)header.getnumfiletableentries());
  vector result=new vector();
  result.addelement(header);
  result.addelement(filetable);
  return result;
  }
  public static void main(string[] argv) throws exception{
  pakutil pu=new pakutil();
  string extractresourcepath="/test.pak";
  //从pak文件中取出所有的图片文件
  vector pakinfo=pu.showpakfileinfo(extractresourcepath);
  pakheader header=(pakheader)pakinfo.elementat(0);
  system.out.println("pak文件信息:");
  system.out.println("文件头:");
  system.out.println(header);
  pakfiletable[] filetable=(pakfiletable[])pakinfo.elementat(1);
  for(int i=0;i  system.out.println("文件table[" i "]:");
  system.out.println(filetable[i]);
  }
  string restorefilename=null;       
  byte[] filebuff=null;
  for(int i=0;i  restorefilename=new string(filetable[i].getfilename()).trim();
  system.out.println("从pak文件中取出" restorefilename "文件数据...");
  filebuff=pu.extractresourcefrompak(extractresourcepath,restorefilename);
  system.out.println("从pak文件中取出" restorefilename "文件数据完成");
  }   
   }}
  
  八、源代码使用简介:
  
  pak过程:j2se版的pakutil将testfiles目录中的三个png文件pak成为test.pak文件。
  unpak过程:j2se版的pakutil将testfiles目录中test.pak文件释放到testfiles\extract目录下;j2me版的pakutil从res目录中的test.pak文件读取出其中所包含的3个png文件数据并装入到byte数据,用来构造image对象,大家请运行pakutiltestmidlet.java便可看到输出的信息。

simone 2007-02-13 17:23
]]>
motorola手机应用程序设计入门http://www.blogjava.net/wangxinsh55/archive/2007/02/01/97170.htmlsimonesimonethu, 01 feb 2007 03:32:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2007/02/01/97170.htmlhttp://www.blogjava.net/wangxinsh55/comments/97170.htmlhttp://www.blogjava.net/wangxinsh55/archive/2007/02/01/97170.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/97170.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/97170.html前言

  本文内容的所有操作皆在windows 200操作系统上经过测试。如果您在不同的平台上验证本文内容,例如windows 98或是windows me,则我们无法保证会有相同的结果。

  简介

  不知从什幺时候开始,我们突然感觉到周围的人各各拥有一只手机。利用手机与别人沟通成了我们生活的一部份。北欧某些先进国家的人民可以利用手机购买自动售货机所出售的商品;他们也可以在从事行动商务(m-commence) 交易时利用手机做为一种认证工具。在日本,行动电话的许多附加功能更是年轻人文化的一部分。即将来临的3g,无线宽频的美梦带给了人们对无线通讯未来的期待。

  然后,有些厂商开始行销它们自己生产的pda,好象没有一台pda在手,就不像现代人似的。各式各样的pda充斥市面,畅销的与不畅销的,让人眼花撩乱。这时产生了一个大问题--要我们同时携带手机和pda是一件很麻烦的事情-就算它们都还算轻薄短小。如果可以把手机和pda合而为一岂不是更方便吗? 于是听到消费者心声的厂商,开始有推出手机和pda合而为一的产品,从nokia 9000、motorola a6188(太极),到最近要推出的ericsson r380、nokia 9210,都是手机与pda结合的例子,虽然因为售价的关系,但是这些产品仍然是许多人梦寐以求的高阶产品。

  尽管有了pda与手机结合的产品出现,我们仍然觉得有所不足,我想大家一定发现了,就是应用程序的不足,虽然手机和pda 结合了,可是这些产品上的pda功能看起来似乎是死的。我们可以任意在palmos、windows ce、epoc等pda上使用c/c 或是java编写这些平台上的应用程序,但是却从未有过机会将我们写好的程序下载到这些手机上执行(即使有些手机的pda也是使用epoc,如ericsson r380)。

  相信厂商也听到我们这些喜欢到处写程序的工程师的心声了,所以从2000年年底开始,即将陆陆续续有许多支持java的手机即将推出,当然,这些厂商也提供了在手机上开发程序的sdk,我们终于可以在手机上面写些小程序自娱了!这是以前等了很久的美梦。

  手机平台的多样性与复杂性,和pda比较起来可以说是有过之而无不及,于是大家就可以知道 - 哈!又是java派上用场的时候了。我们都知道在浏览器上执行的java程序叫做applet,在palmos上执行的java程序叫做spotlet,然而在手机上执行的应用程序我们称做midlet,相信对大家来说都是一个陌生的名词,这也就是本篇文章所要介绍的主角。

  支持java的手机大厂目前已知有nokia (预计在2001年年初推出一款支持java的手机nokia 9210)、motorola(会先在支持integrated digital enhanced network(iden)网络的手机上支持java,然后再推出支持java的gsm手机,该公司的手机大致会在2002年前全部支持java)以及ntt docomo(将在明年第二季度左右推出支持java的手机)。

  虽然这些大公司都准备支持java,不过在决定编写本文时,只有motorola将其sdk开放于网站上供程序开发者下载测试,所以本文内容都是根据motorola j2me sdk所编写。又由于这些手机市面上无法取得,所以我们的程序都是在sdk内附的模拟器中执行,相信最后这些手机上市时,我们所编写的midlet应该会很容易并成功地在motorola的手机上执行才对。

  如何取得motorola j2me sdk

  我们要做的第一件事情当然还是要先取得sdk罗!请直接到https://commerce.motorola.com/idenonline/ideveloper/下载motorola j2me sdk drop 7。如果您不是iden? developer的会员,请先在网络上注册(免费)。注册成功之后,motorola会将密码寄到您的email信箱之中,然后使用该密码登入网页上的my development center。进入之后选择网页上头的tools & resources以进入可下载的开发工具的网页,请选择motorola j2me sdk components developer edition, drop 7.0下方的下载超连结以下载sdk,整个sdk的大小约为3 mb左右。

  请注意下载前的download page for motorola j2me? sdk安装说明,里头会告诉你安装密码,请先行记下。稍后当您在您的电脑上安装motorola j2me sdk的时候,会询问您安装密码,所以请务必记下该密码。

  motorola j2me sdk的安装

  安装需求

  根据官方需求,安装motorola j2me sdk的基本配备为:

   pentium 100 mhz微处理器
   64 mb ram
   windows nt workstation 4.0配合service pack 3 / win98
   (本文是在windows 2000 professional中文版上测试)
   约6 mb的硬盘空间
   java 2 sdk 1.2.2
   (本文使用java 2 sdk 1.3.0_01作测试)

  安装motorola j2me sdk

  要安装新版motorola j2me sdk之前,请先确认您已经将旧版的motorola j2me sdk完全删除。您可以由控制台里头的 「新增/删除程序」的功能删除旧版motorola j2me sdk。之后再将旧版motorola j2me sdk安装所在路径清除即可。

  解开您从motorola网站上下载的zip文件,您会看到一个名为motorola_sdk.exe的文件,双击此文件即可开始安装动作。请注意,在安装时系统会要求您输入密码,请输入之前所纪录的安装密码即可。

  motorola j2me sdk目录结构

  当您成功地安装motorola j2me sdk之后,其目录结构如下图:




  midlet程序结构

  在手机上执行的程序我们统称midlet,其程序结构很简单,与大家熟悉的applet结构有异曲同工之妙。

  每一个midlet程序都必须继承自javax.microedition.midlet.midlet类别,并实做三个函式,它们分别是:

protected void startapp()
protected void pauseapp()
protected void destroyapp(boolean unconditional)

  而一个midlet程序的起始与结束之流程我们以下图来表示:



  编写并编译midlet

  请先到您的motorola j2me sdk安装目录下的demo\midlets目录底下新建一个名为hellomidlet.java的文件,其内容为:

hellomidlet.java
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class hellomidlet extends midlet
{
hellomidlet()
{
}

protected void startapp() throws midletstatechangeexception
{
}

protected void pauseapp()
{
}

protected void destroyapp(boolean unconditional)
throws midletstatechangeexception
{
}
}

  在demo\midlets目录之中您会看到一个名为compileall.bat的批处理文件,前面有提到,这个批处理文件除了可以帮助您编译所有内附范例程序之外,还可以简化您自己所编写的midlet之编译流程。
请在命令列视窗输入: compileall hellomidlet.java 如果成功编译,屏幕上输出的结果如下图所示:



  从屏幕上的输出,您可以发现,要让midlet可以在手机上执行,大体上还是要经过两个动作(与spotlet相似),分别是编译(compiling)以及预先审核(preverifying)。

  从这个简短的midlet制作流程里头,相信大家可以发现,比起纯粹用sun的cldc编写能在kvm上执行的spotlet要简单上许多。原因是compileall.bat这个批处理文件帮我们做掉大部分dirty work。
那幺,如果您写好的程序并非放在demo\midlets目录之中,是否就无法编译了? 从compileall.bat里头,我们可以发现它帮我们完成上述两项工作的指令。如果我们写好的程序放在demo\midlets目录以外的地方,您可以执行下面的指令,您仍然可以成功地制作midlet:
(我们假设您的motorola j2me sdk安装在d:\motosdk目录之中,并将您自行编写的hellomidlet.java置于d:\jdk1.3.0_01\my目录之中。同时我们假设您在d:\jdk1.3.0_01\my目录底下执行下面指令。)
编译:

javac -o -bootclasspath d:\motosdk\lib hellomidlet.java

  注意: -bootclasspath指向类函数库的所在位置。

  预先审核:

d:\motosdk\bin\preverifier -classpath d:\motosdk\lib;. -d . hellomidlet

  注意:

  1 . -classpath指向类函数库的所在位置,也要指向我们所编写的midlet所在的位置。

  2 .–d指向您希望预先编译类文件产生之后所放置的路径,如果写"."表示本目录,会覆盖掉原先未经过预先编译的类文件。如果您没有指定,则预设值为".\output"目录。

  当然,如果您嫌自己手动操作很麻烦,您可以将compileall.bat复制到其它目录之中,并更改其编译指令与预先审核指令之中和类函数库有关的相关设定即可。

  提到compileall.bat,顺便向各位读者说明一下,在前面有提到,compileall.bat可以帮助您编译所有位于demo\midlets目录下的范例程序,您只要在命列列下直接输入: compileall即可。compileall.bat会自动当您编译的package有以下几项:

com.mot.j2me.midlets.bounce
com.mot.j2me.midlets.imagetests
com.mot.j2me.midlets.paddleball
com.mot.j2me.midlets.scribble
com.mot.j2me.midlets.tests
com.mot.j2me.midlets.tutorials

  如果您希望compileall.bat自动帮您编译其它package底下的程序,请您开启compileall.bat,修改其compileclass环境变数的设定即可。

  修改并执行midlet

  写好程序之后,大家最希望的事情当然就是让它在手机上执行,不过由于目前大家无法取得motorola这些支持java的手机,所以我们只能在motorola j2me sdk内附的模拟器上执行我们写好的midlet。相信手机正式推出时,应该可以顺利地在手机上执行。底下笔者将告诉您如何使用motorola j2me sdk内附的模拟器来测试您所编写的midlet。

  在这之前,由于之前我们所编写的范例程序只是简单的midlet空壳,我们必须让它能够在模拟器上显示出一些信息才可以,因此请修改上一个程序范例,使它的内容如下:

hellomidlet.java
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class hellomidlet extends midlet
{
private display firstdisplay ;
private form firstform ;
hellomidlet()
{
firstdisplay = display.getdisplay(this) ;
firstform = new form("hello midlet") ;
stringitem firststritem = new stringitem("hello","midlet") ;
firstform.append(firststritem) ;
}

protected void startapp() throws midletstatechangeexception
{
firstdisplay.setcurrent(firstform) ;
}

protected void pauseapp()
{
}

protected void destroyapp(boolean unconditional)
throws midletstatechangeexception
{
}
}

  请将此文件放置在\demo\midlets目录下。编译完成之后,请将目录切换到scripts子目录之中,您会在此目录里发现一些写好的批处理文件。请在该目录下执行这些批处理文件指令以启动模拟器。执行的指令与执行结果如下所示:

  指令: runemul hellomidlet

  输出结果
  指令: runmotoi1000 hellomidlet

  输出结果
  指令: runmotoiden hellomidlet

  输出结果
  指令: runstartac hellomidlet

  输出结果

 指令: runmydevice hellomidlet
 输出结果:
  error loading property file: c:/properties/mydevice.props (系统找不到指定的路径。)会出现错误信息是因为您没有指定属于是用者自订的手机外观的缘故,后面将会教您如何设定用户自订的手机外观。


  如果我们将写好的程序放在demo\midlets目录以外的地方,您可以执行下面的指令,仍然可以成功地启动模拟器并执行midlet:

  (我们假设您的motorola j2me sdk安装在d:\motosdk目录之中,并将您自行编写的hellomidlet.java置于d:\jdk1.3.0_01\my目录之中。同时我们假设您在d:\jdk1.3.0_01\my目录底下执行下面指令。)

  执行一般模拟器

java -djava.library.path=d:\motosdk\lib
-classpath d:\motosdk\bin\emulator.jar;d:\motosdk\bin\configtool.jar com.mot.tools.j2me.emulator.emulator

-classpath.;d:\motosdk\lib javax.microedition.midlet.appmanager hellomidlet

-jsa 1 1

 请注意:

  第一个-classpath设定,-classpath与路径名称之间有空格。

  第二个-classpath设定,-classpath与路径名称之间没有空格。

  执行模拟器并套用i1000手机外观

java -djava.library.path=d:\motosdk\lib
-classpath d:\motosdk\bin\emulator.jar;d:\motosdk\bin\configtool.jar com.mot.tools.j2me.emulator.emulator

-classpath.;d:\motosdk\lib
-devicefile resources\motorolai1000.props
javax.microedition.midlet.appmanager

hellomidlet
-jsa 1 1
请注意:
 第一个-classpath设定,-classpath与路径名称之间有空格。
 第二个-classpath设定,-classpath与路径名称之间没有空格。

  执行模拟器并套用iden手机外观

java -djava.library.path=d:\motosdk\lib
-classpath d:\motosdk\bin\emulator.jar;d:\motosdk\bin\configtool.jar com.mot.tools.j2me.emulator.emulator

-classpath.;d:\motosdk\lib
-devicefile resources\motorolaidenplatform.props
javax.microedition.midlet.appmanager

hellomidlet
-jsa 1 1
请注意:
 第一个-classpath设定,-classpath与路径名称之间有空格。
 第二个-classpath设定,-classpath与路径名称之间没有空格。

  执行模拟器并套用startac手机外观

java -djava.library.path=d:\motosdk\lib
-classpath d:\motosdk\bin\emulator.jar;d:\motosdk\bin\configtool.jar com.mot.tools.j2me.emulator.emulator

-classpath.;d:\motosdk\lib
-devicefile resources\startac.props
javax.microedition.midlet.appmanager

hellomidlet
-jsa 1 1
请注意:
 第一个-classpath设定,-classpath与路径名称之间有空格。
 第二个-classpath设定,-classpath与路径名称之间没有空格。

  执行模拟器并套用用户自订手机外观

java -djava.library.path=d:\motosdk\lib
-classpath d:\motosdk\bin\emulator.jar;d:\motosdk\bin\configtool.jar com.mot.tools.j2me.emulator.emulator

-classpath.;d:\motosdk\lib
-devicefile <您的props文件所在的绝对路径>javax.microedition.midlet.appmanager

hellomidlet
-jsa 1 1
请注意:
 第一个-classpath设定,-classpath与路径名称之间有空格。
 第二个-classpath设定,-classpath与路径名称之间没有空格。
 如果您将您的props文件放在d:\motosdk\bin的resources目录之下,则上述指令只要改成:-devicefile resources\<您的props文件名>

  注意,当您您直接使用上述指令启动模拟器,如果出现底下错误信息:

  error loading property file: resources/defaultdevice.props (系统找不到指定的路径。)
这是因为您没有将d:\motosdk\bin目录下的resources子目录复制到d:\jdk1.3.0_01\my目录之下的缘故。

  对midlet进行调试

  编写palmos上的spotlet时,我们可以利用system.out.println()函式帮我们印出一些讯息以帮助调试,那幺在手机上的midlet呢? 原则上,我们还是可以利用system.out.println()函式做一些输出。当模拟器执行时,就会在命令列上输出一些讯息。

  另外,在palmos上,有kvmutil.prc可以帮助我们纪录程序所输出的讯息。那手机上呢? 因为没有实际的机器可以测试,因此这个问题到现在还不得而知,相信motorola到时候会有完善的凯发天生赢家一触即发官网的解决方案吧!
在motorola j2me sdk内附的说明文件之中,概略地提到了调试的问题,里头提到,往后如果我们要进行机上调试(on-device debugging)的话,必须要满足几个条件:

  机器本身要具备调试相关功能,并与kdwp(kvm debug wire protocol)兼容。因为调试时,调试工具需要利用kdwp和机器上交谈以取得调试信息。

  制造厂商本身要提供下载midlet到手机上以进行调试的方法。

  提供对midlet调试的工具,必须支持手机在利用kdwp调试时所使用的传输接口(例如串行口或udp)。
嗯,看起来能够进行调试,midlet程序的编写应该是很方便的事情了。

  motorola j2me sdk对中文的支持

  相信看过run!pc 11月号的文章「利用java 编写palmos应用程序基础篇」的读者,在编写palmos上的spotlet时一定会遇到中文无法正常显示的问题。中文的问题分成两个部分,一个是在用户接口上的中文问题,一个是在命令列输出(利用system.out.println()函式所做的输出)上的中文问题,请大家做个小实验,将前面我们所编写的程序改如下:

hellomidlet.java
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class hellomidlet extends midlet
{
private display firstdisplay ;
private form firstform ;
hellomidlet()
{
firstdisplay = display.getdisplay(this) ;
firstform = new form("哈罗!midlet") ;
stringitem firststritem = new stringitem("哈罗","米德列特") ;
firstform.append(firststritem) ;
system.out.println("midlet启动") ;
}

protected void startapp() throws midletstatechangeexception
{
firstdisplay.setcurrent(firstform) ;
}

protected void pauseapp()
{
}

protected void destroyapp(boolean unconditional)
throws midletstatechangeexception
{
}
}

  将本midlet编译并经过预身审核之后,我们开启模拟器来执行此midlet,底下为执行结果:
  
用户接口输出:命令列输出
我们从结果发现,预设的编译指令会让用户接口正常输出中文,而命令列无法输出正确的中文。
  
  接着请将compileall.bat之中原本的指令

javac -o -bootclasspath ..\..\lib %compileclass%

  修改为

javac –encoding iso8859_1 -o -bootclasspath ..\..\lib %compileclass%

  之后,重新编译此midlet执行结果:

用户接口输出: 命令列输出
我们从结果发现,预设的编译指令会让用户接口无法正常输出中文,而命令列却可以输出正确的中文。

  这个结果与palmos上所做的中文测试结果有所不同。

  当您编写spotlet时,如果您使用javac 。。。指令时,您会发现模拟器上的用户接口输出是乱码,可是命令列上的输出却可以正常输出中文。但是如果您使用的是javac -encoding iso8859_1 。。。指令,则cldc内附模拟器上的用户接口输出或是命令列上的输出全部都变成乱码,无法正常输出中文(这个部分是因为cldc内附模拟器实做的问题,造成与实际机器的结果有差异)。

  总之,如果之前您所编写的spotlet无法在装有中文系统的实际机器或pose上正常输出中文,请您也如法炮制,在编译指令中加入-encoding iso8859_1,就可以在实际机器或pose上看到正常的中文字了。

  会产生此问题的主因,主要是因为编译好的java类文件(byte code)之中,所有的文字编码都采用utf8。举例来说,当您在程序码里用到"启动"这两个中文字时,

   "起"这个字的big5编码为b1d2。

   "动"这个字的big5编码为b0ca。

  我们会使用javac xxxx.java来编译原始码以产生类文件。其实这行指令,在繁体中文的windows环境底下,相当于javac -encoding "big5" xxxx.java。也就是说,当编译器读取到big5编码范围的中文字时,会自动将此big5码经过「big5è unicode 对照表」将big5转为unicode,也就是说,经过查表之后,

   “起”这个字的unicode编码为555f。

   “动”这个字的unicode编码为5272。

  然后再利用utf8编码将此unicode转为utf8,储存在类文件之中,因此,如果您用ultraedit之类的文字编辑器查看类文件时,您会看到,

   "起"这个字的utf8编码为e5959f。

   "动"这个字的utf8编码为e58b95。

  接着,当我们在程序执行时如果要将中文输出,则jvm会负责读进utf8码,然后将其转回unicode,最后依据您所使用的系统环境预设的编码转回big5,再输出至屏幕上。

  可是经过测试结果,kvm似乎只有做到把utf8读进来,转换回unicode之后就直接输出了。少了转回big5的步骤,因此,操作系统把unicode当作big5来处理,自然就找不到该码所对应的中文字了,也因此输出的是一堆 ????? 的符号。这也是我们在palmos上即使装了中文系统,也无法正常显示中文的缘故。

  ok,既然知道kvm只帮我们做了一半的工作,那事情就好办了,我们只要让utf8转回之后,仍然保有big5的编码方式即可,于是我们使用指令javac -encoding iso8859_1 xxxx.java,请编译器不要将程序码中中文big5编码的两个byte视为一体(因为视为一体就会引发查询big5 è unicode对照表的工作),只要将中文当作是普通的西欧字母字集即可,因此,当我们使用了上述指令,您会发现类文件之中的中文变成,

   "起"这个字的utf8编码为c2b1 c392。

   "动"这个字的utf8编码为c2b0 c38a。

  大家可以发现编译器把b1、d2、b0、ca个别当作一个码来处理。于是,当kvm读到此编码时,就会将他们转回b1d2以及b0ca,然后kvm直接输出,就可以正常地使用中文了。

  最后总结整个问题,就笔者的推断,cldc内附的模拟器再没有使用javac –encoding iso8859_1 xxxx.java指令之前,会在用户接口使命令列输出乱码,这才是正常的结果, 而motorola j2me sdk内附模拟器的用户接口中文之所以没问题,很可能只是因为模拟器操作的差异。因此根据kvm的输出结果来看,很可能在实际的手机上,我们都必须加上-encoding iso8859_1选项才能正确输出中文吧!

  在此特别感谢静宜大学资管系的唐恺隆(kailung.tang@msa.hinet.net)同学。因为笔者于他经过热烈的讨论之后,我们才能对j2me的中文问题有更深入的认识

  支持motorola j2me sdk的开发工具

  在编写本文的时候,支持midlet开发的集成开发环境(ide)只有motorola j2me sdk附带文件之中所提到的codewarrior而已。相信其它厂商,如borland,应该也会很快地利用其产品jbuilder的opentools api来支持midlet的开发才对,更何况borland jbuilder目前已经有spotlet的凯发天生赢家一触即发官网的解决方案了。

  因为笔者无法拿到codewarrior作测试,所以无法在此提供大家相关信息,相信如果有机会的话,会另外以专文向大家介绍如何利用codewarrior编写midlet。

  motorola j2me sdk附带文件在附录的部分有对利用codewarrior开发midlet做简单的介绍,相信对初学者来说,已经相当足够了。

  motorola j2me sdk内含的辅助开发工具

  在motorola j2me sdk之中内含三项辅助开发工具,可以便利我们的程序开发工作,它们分别是:

  j2me模拟器(j2me emulator)

  让您可以在您的pc上模拟motorola将来会支持j2me的手机装置。如此一来就可以在pc上直接测试写好的程序。

  bytecode验证器(bytecode verifier)

  此验证器用来验证类文件(classfile)之中的bytecode不会对存储器做非法的存取。并确认载入虚拟机器的类文件所做的所有动作皆符合java虚拟机器规格(java virtual machine specification)。

  配置编辑器(configuration editor)

  让您能够建立或修改device profile。

  在motorola j2me sdk内附的文件之中对这三个工具有详细的说明,笔者在此就不再赘述了。


  附录:范例程序

  motorola j2me sdk之中内附许多有趣的范例,它们位于demo/midlets/目录底下。有兴趣继续精进的读者可以由这些范例学到更多有关midlet的深入技巧,由于这些范例的执行画面过大,所以在本文之中就将他们省略,请读者们自行参考说明文件。

  这些范例程序有:

bounce
com.mot.j2me.midlets.bounce.bounce
paddleball
com.mot.j2me.midlets.paddleball.paddleball
scribble
com.mot.j2me.midlets.scribble.scribble
fontdemo
com.mot.j2me.midlets.tutorials.fontdemo
graphicsdemo
com.mot.j2me.midlets.tutorials.graphicsdemo
recordstoredemo
com.mot.j2me.midlets.tutorials.recordstoredemo
udp tutorial application
com.mot.j2me.midlets.tutorials.udpreceive
alerttest
com.mot.j2me.midlets.tests.alerttest
choicegrouptest
com.mot.j2me.midlets.tests.choicegrouptest
datefieldtest
com.mot.j2me.midlets.tests.datefieldtest
formtest
com.mot.j2me.midlets.tests.formtest
gaugetest
com.mot.j2me.midlets.tests.gaugetest
keyeventstest
com.mot.j2me.midlets.tests.keyeventstest
textboxtest
com.mot.j2me.midlets.tests.textboxtest
textfieldtest
com.mot.j2me.midlets.tests.textfieldtest
tickertest
com.mot.j2me.midlets.tests.tickertest

  网络资源

  ◎网站

  motorola官方网站 http://www.motorola.com/java/

  metrowerks(codewarrior) http://www.metrowerks.com

simone 2007-02-01 11:32
]]>
几个不错的电子图书下载网站http://www.blogjava.net/wangxinsh55/archive/2006/11/08/79841.htmlsimonesimonewed, 08 nov 2006 06:09:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2006/11/08/79841.htmlhttp://www.blogjava.net/wangxinsh55/comments/79841.htmlhttp://www.blogjava.net/wangxinsh55/archive/2006/11/08/79841.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/79841.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/79841.htmlhttp://www.ibook8.com







国内真正免费的书籍下载网站:
(其中包含优秀it站点)
好东西大家分享!!!




非常好的c 教程网站



simone 2006-11-08 14:09
]]>
几个较好的数据库分页过程 http://www.blogjava.net/wangxinsh55/archive/2006/05/26/48279.htmlsimonesimonefri, 26 may 2006 03:02:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2006/05/26/48279.htmlhttp://www.blogjava.net/wangxinsh55/comments/48279.htmlhttp://www.blogjava.net/wangxinsh55/archive/2006/05/26/48279.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/48279.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/48279.html一 oracle
create or replace procedure page(
    p_num integer,
    p_size integer,
    condition clob,
    table_name varchar,
    p_rowset out sys_refcursor)
as
begin
open p_rowset for
    'select *
        from (
            select rownum r, t1.*
                from (
                    select '|| table_name || '.* from '|| table_name || ' ' 
                      || condition || 'order by happentime desc) t1
               where rownum <= ' || p_size*p_num || ' ) t2
        where t2.r > ' || p_size*(p_num-1);
end page;

二 mssql
create procedure page
    @p_num int,
    @p_size int,
    @condition text,
    @table_name nvarchar(100),
    @current_page_size int
as
if @p_num = 1
   execute('select top ' @p_size ' * from ' @table_name ' ' @condition ' order by happentime desc')
else
   if @current_page_size != @p_size
      execute('select * from(
                    select top ' @current_page_size ' * from ' @table_name ' ' @condition ' order by happentime
              ) as t order by happentime desc')
   else
      begin
      declare @tmp int
      set @tmp = @p_size * @p_num
      execute('select * from(
                    select top ' @p_size ' * from(
                         select top ' @tmp ' * from ' @table_name ' ' @condition ' order by happentime desc
                    ) as t1 order by happentime
              ) as t2 order by happentime desc')
      end
go

三 sybase
create procedure page
    @p_num int,
    @p_size int,
    @condition  nvarchar(3000),
    @table_name nvarchar(100),
    @current_p_size int
as
declare @str_p_size varchar(20),
        @str_tmp varchar(20),
        @str_current_p_size varchar(20),
     @i_rowcount int 
begin
 select @str_tmp=cast(@p_size * @p_num as varchar(20))
 select @str_p_size=cast(@p_size as varchar(20))
 select @str_current_p_size=cast(@current_p_size as varchar(20))
 
 if @p_num = 1
  begin
   set @i_rowcount=@p_size*@p_num
   set rowcount @i_rowcount
   execute('select  * from ' @table_name ' ' @condition ' order by happentime desc')
  end
 else
  if @current_p_size != @p_size
   begin
    set rowcount @current_p_size
    execute('select  * into #temp from ' @table_name ' ' @condition ' order by happentime 
             select * from #temp order by happentime desc')
   end
  else
   begin
    set @i_rowcount=@p_size*@p_num
    set rowcount @i_rowcount
    execute('select  * into #temp1 from ' @table_name ' ' @condition ' order by happentime desc
       select top ' @str_p_size ' * into #temp2 from #temp1 order by happentime
       select * from #temp2 order by happentime desc')
   end
end

simone 2006-05-26 11:02
]]>
http协议基础http://www.blogjava.net/wangxinsh55/archive/2006/03/30/38293.htmlsimonesimonethu, 30 mar 2006 09:39:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2006/03/30/38293.htmlhttp://www.blogjava.net/wangxinsh55/comments/38293.htmlhttp://www.blogjava.net/wangxinsh55/archive/2006/03/30/38293.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/38293.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/38293.htmlhttp(hypertexttransferprotocol)是超文本传输协议的缩写,它用于传送www方式的数据,关于http协议的详细内容请参考rfc2616。http协议采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请求的方法、uri、协议版本、以及包含请求修饰符、客户信息和内容的类似于mime的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。

通常http消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。http的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

通用头域

通用头域包含请求和响应消息都支持的头域,通用头域包含cache-control、connection、date、pragma、transfer-encoding、upgrade、via。对通用头域的扩展要求通讯双方都支持此扩展,如果存在不支持的通用头域,一般将会作为实体头域处理。下面简单介绍几个在upnp消息中使用的通用头域。

cache-control头域

cache-control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置cache-control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下:

public指示响应可被任何缓存区缓存。
private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
no-cache指示请求或响应消息不能缓存
no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

date头域

date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,date:mon,31dec200104:25:57gmt。date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。

pragma头域

pragma头域用来包含实现特定的指令,最常用的是pragma:no-cache。在http/1.1协议中,它的含义和cache-control:no-cache相同。

请求消息

请求消息的第一行为下面的格式:
methodsprequest-urisphttp-versioncrlfmethod表示对于request-uri完成的方法,这个字段是大小写敏感的,包括options、get、head、post、put、delete、trace。方法get和head应该被所有的通用web服务器支持,其他所有方法的实现是可选的。get方法取回由request-uri标识的信息。head方法也是取回由request-uri标识的信息,只是可以在响应时,不返回消息体。post方法可以请求服务器接收包含在请求中的实体信息,可以用于提交表单,向新闻组、bbs、邮件群组和数据库发送消息。

sp表示空格。request-uri遵循uri格式,在此字段为星号(*)时,说明请求并不用于某个特定的资源地址,而是用于服务器本身。http-version表示支持的http版本,例如为http/1.1。crlf表示换行回车符。请求头域允许客户端向服务器传递关于请求或者关于客户机的附加信息。请求头域可能包含下列字段accept、accept-charset、accept-encoding、accept-language、authorization、from、host、if-modified-since、if-match、if-none-match、if-range、if-range、if-unmodified-since、max-forwards、proxy-authorization、range、referer、user-agent。对请求头域的扩展要求通讯双方都支持,如果存在不支持的请求头域,一般将会作为实体头域处理。

典型的请求消息:


gethttp://class/download.microtool.de:80/somedata.exe
host:download.microtool.de
accept:*/*
pragma:no-cache
cache-control:no-cache
referer:http://class/download.microtool.de/
user-agent:mozilla/4.04[en](win95;i;nav)
range:bytes=554554-

上例第一行表示http客户端(可能是浏览器、下载程序)通过get方法获得指定url下的文件。棕色的部分表示请求头域的信息,绿色的部分表示通用头部分。

host头域

host头域指定请求资源的intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。http/1.1请求必须包含主机头域,否则系统会以400状态码返回。

referer头域

referer头域允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的uri没有自己的uri地址,referer不能被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址。

range头域

range头域可以请求实体的一个或者多个子范围。例如,

表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999

但是服务器可以忽略此请求头,如果无条件get包含range请求头,响应会以状态码206(partialcontent)返回而不是以200(ok)。

user-agent头域

user-agent头域的内容包含发出请求的用户信息。

响应消息

响应消息的第一行为下面的格式:

http-versionspstatus-codespreason-phrasecrlf
http-version表示支持的http版本,例如为http/1.1。status-code是一个三个数字的结果代码。reason-phrase给status-code提供一个简单的文本描述。status-code主要用于机器自动识别,reason-phrase主要用于帮助用户理解。status-code的第一个数字定义响应的类别,后两个数字没有分类的作用。第一个数字可能取5个不同的值:

1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求

响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和request-uri进一步的信息。响应头域包含age、location、proxy-authenticate、public、retry-after、server、vary、warning、www-authenticate。对响应头域的扩展要求通讯双方都支持,如果存在不支持的响应头域,一般将会作为实体头域处理。

典型的响应消息:


http/1.0200ok
date:mon,31dec200104:25:57gmt
server:apache/1.3.14(unix)
content-type:text/html
last-modified:tue,17apr200106:46:28gmt
etag:"a030f020ac7c01:1e9f"
content-length:39725426
content-range:bytes554554-40279979/40279980
上例第一行表示http服务端响应一个get方法。棕色的部分表示响应头域的信息,绿色的部分表示通用头部分,红色的部分表示实体头域的信息。

location响应头

location响应头用于重定向接收者到一个新uri地址。

server响应头

server响应头包含处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。

实体

请求消息和响应消息都可以包含实体信息,实体信息一般由实体头域和实体组成。实体头域包含关于实体的原信息,实体头包括allow、content-base、content-encoding、content-language、content-length、content-location、content-md5、content-range、content-type、etag、expires、last-modified、extension-header。extension-header允许客户端定义新的实体头,但是这些域可能无法未接受方识别。实体可以是一个经过编码的字节流,它的编码方式由content-encoding或content-type定义,它的长度由content-length或content-range定义。

content-type实体头

content-type实体头用于向接收方指示实体的介质类型,指定head方法送到接收方的实体介质类型,或get方法发送的请求介质类型content-range实体头

content-range实体头用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:

content-range:bytes-unitspfirst-byte-pos-last-byte-pos/entity-legth
例如,传送头500个字节次字段的形式:content-range:bytes0-499/1234如果一个http消息包含此节(例如,对范围请求的响应或对一系列范围的重叠请求),content-range表示传送的范围,content-length表示实际传送的字节数。

last-modified实体头

last-modified实体头指定服务器上保存内容的最后修订时间。

 



simone 2006-03-30 17:39
]]>
http 1.1支持的状态代码http://www.blogjava.net/wangxinsh55/archive/2006/03/30/38258.htmlsimonesimonethu, 30 mar 2006 07:00:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2006/03/30/38258.htmlhttp://www.blogjava.net/wangxinsh55/comments/38258.htmlhttp://www.blogjava.net/wangxinsh55/archive/2006/03/30/38258.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/38258.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/38258.html101 switching protocols 服务器将遵从客户的请求转换到另外一种协议
200 ok 一切正常,对get和post请求的应答文档跟在后面。
201 created 服务器已经创建了文档,location头给出了它的url。 
202 accepted 已经接受请求,但处理尚未完成。 
203 non-authoritative information 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝 
204 no content 没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而servlet可以确定用户文档足够新,这个状态代码是很有用的
205 reset content 没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容
206 partial content 客户发送了一个带有range头的get请求,服务器完成了它
300 multiple choices 客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在location应答头指明。 
301 moved permanently 客户请求的文档在其他地方,新的url在location头中给出,浏览器应该自动地访问新的url。 
302 found 类似于301,但新的url应该被视为临时性的替代,而不是永久性的。 
303 see other 类似于301/302,不同之处在于,如果原来的请求是post,location头指定的重定向目标文档应该通过get提取
304 not modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供if-modified-since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。 
305 use proxy 客户请求的文档应该通过location头所指明的代理服务器提取
307 temporary redirect 和302(found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是post,即使它实际上只能在post请求的应答是303时才能重定向。由于这个原因,http 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的get和post请求;如果是307应答,则浏览器只能跟随对get请求的重定向。 
400 bad request 请求出现语法错误。 
401 unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含一个www-authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的authorization头后再次发出请求。 
403 forbidden 资源不可用。
404 not found 无法找到指定位置的资源
405 method not allowed 请求方法(get、post、head、delete、put、trace等)对指定的资源不适用。
406 not acceptable 指定的资源已经找到,但它的mime类型和客户在accpet头中所指定的不兼容
407 proxy authentication required 类似于401,表示客户必须先经过代理服务器的授权。
408 request timeout 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。 
409 conflict 通常和put请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。
410 gone 所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。 
411 length required 服务器不能处理请求,除非客户发送一个content-length头。 
412 precondition failed 请求头中指定的一些前提条件失败
413 request entity too large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个retry-after头 
414 request uri too long uri太长 
416 requested range not satisfiable 服务器不能满足客户在请求中指定的range头
500 internal server error 服务器遇到了意料不到的情况,不能完成客户的请求
501 not implemented 服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的put请求 
502 bad gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答 
503 service unavailable 服务器由于维护或者负载过重未能应答。例如,servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个retry-after头 
504 gateway timeout 由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答 
505 http version not supported 服务器不支持请求中所指明的http版本


simone 2006-03-30 15:00
]]>
常用正则表达式http://www.blogjava.net/wangxinsh55/archive/2006/03/30/38231.htmlsimonesimonethu, 30 mar 2006 04:52:00 gmthttp://www.blogjava.net/wangxinsh55/archive/2006/03/30/38231.htmlhttp://www.blogjava.net/wangxinsh55/comments/38231.htmlhttp://www.blogjava.net/wangxinsh55/archive/2006/03/30/38231.html#feedback0http://www.blogjava.net/wangxinsh55/comments/commentrss/38231.htmlhttp://www.blogjava.net/wangxinsh55/services/trackbacks/38231.html"^\\d $"  //非负整数(正整数   0) 
"^[0-9]*[1-9][0-9]*$"  //正整数 
"^((-\\d )|(0 ))$"  //非正整数(负整数   0) 
"^-[0-9]*[1-9][0-9]*$"  //负整数 
"^-?\\d $"    //整数 
"^\\d (\\.\\d )?$"  //非负浮点数(正浮点数   0) 
"^(([0-9] \\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9] )|([0-9]*[1-9][0-9]*))$"  //正浮点数 
"^((-\\d (\\.\\d )?)|(0 (\\.0 )?))$"  //非正浮点数(负浮点数   0) 
"^(-(([0-9] \\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9] )|([0-9]*[1-9][0-9]*)))$"  //负浮点数 
"^(-?\\d )(\\.\\d )?$"  //浮点数 
"^[a-za-z] $"  //由26个英文字母组成的字符串 
"^[a-z] $"  //由26个英文字母的大写组成的字符串 
"^[a-z] $"  //由26个英文字母的小写组成的字符串 
"^[a-za-z0-9] $"  //由数字和26个英文字母组成的字符串 
"^\\w $"  //由数字、26个英文字母或者下划线组成的字符串 
"^[\\w-] (\\.[\\w-] )*@[\\w-] (\\.[\\w-] ) $"    //email地址 
"^[a-za-z] ://(\\w (-\\w )*)(\\.(\\w (-\\w )*))*(\\?\\s*)?$"  //url


匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了

匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ascii字符计1)

匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行

匹配html标记的正则表达式:< (\s*?)[^>]*>.*?|< .*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力

匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

匹配email地址的正则表达式:\w ([- .]\w )*@\w ([-.]\w )*\.\w ([-.]\w )*
评注:表单验证时很实用

匹配网址url的正则表达式:[a-za-z] ://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求

匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-za-z][a-za-z0-9_]{4,15}$
评注:表单验证时很实用

匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822

匹配腾讯qq号:[1-9][0-9]{4,}
评注:腾讯qq号从10000开始

匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字

匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位

匹配ip地址:\d \.\d \.\d \.\d
评注:提取ip地址时有用

匹配特定数字:
^[1-9]\d*$    //匹配正整数
^-[1-9]\d*$   //匹配负整数
^-?[1-9]\d*$   //匹配整数
^[1-9]\d*|0$  //匹配非负整数(正整数 0)
^-[1-9]\d*|0$   //匹配非正整数(负整数 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0 |0)$  //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0 |0$   //匹配非负浮点数(正浮点数 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0 |0$  //匹配非正浮点数(负浮点数 0)
评注:处理大量数据时有用,具体应用时注意修正

匹配特定字符串:
^[a-za-z] $  //匹配由26个英文字母组成的字符串
^[a-z] $  //匹配由26个英文字母的大写组成的字符串
^[a-z] $  //匹配由26个英文字母的小写组成的字符串
^[a-za-z0-9] $  //匹配由数字和26个英文字母组成的字符串
^\w $  //匹配由数字、26个英文字母或者下划线组成的字符串
评注:最基本也是最常用的一些表达式



simone 2006-03-30 12:52
]]>
网站地图