Let's Go!

发布新日志

  • (zt)Aptana开发EXTJS(3.0)--spket插件的安装配置过程

    2011-03-18 20:23:18


    可以和myeclipse 增加插件一样进行操作

    1.下载安装包含有Eclipse的Aptana Studio;

    2.启动Aptana,然后菜单:Help → Software Updates → Find and Install… → Search for new features to install → New remote site…

    3.名称可以输入: “Spket”,URL是http://www.spket.com/update/

    4.会提示重启Aptana,重启之;

    5.Window → Preferences → Spket → JavaScript. Profiles → New ;

    6.输入“ExtJS”点击OK;

    7.选择“ExtJS” 并点击“Add Library”然后在下拉条中选取“ExtJS”;

    8.选择 “ExtJS”并点击“Add File”,然后在你的./ext-3.x/source目录中选取“ext.jsb” 文件;

    (ext3.0正式版中不包含ext.jsb文件,需要手动Google一下找到rc版3.0中的ext.jsb,同样可以使用)

    9.设置新的ExtJS Profile,选中并点击“JavaScript. Profiles” 对话框右手边的“Defalut”按钮;

    10.重启Aptana;

  • Exception occurred during problem detector org.eclipse.wst.jsdt.core

    2011-03-18 11:21:09

     

    !SESSION 2010-06-14 08:43:34.248 -----------------------------------------------
    eclipse.buildId=unknown
    java.version=1.6.0_13
    java.vendor=Sun Microsystems Inc.
    BootLoader constants: S=win32, ARCH=x86, WS=win32, NL=zh_CN
    Command-line arguments:  -os win32 -ws win32 -arch x86

    This is a continuation of log file E:\workspace\.metadata\.bak_6.log
    Created Time: 2010-06-14 10:46:22.110

    !ENTRY org.eclipse.wst.jsdt.core 4 4 2010-06-14 10:46:22.110
    !MESSAGE Exception occurred during problem detection:
    ----------------------------------- SOURCE BEGIN -------------------------------------

    ----------------------------------- SOURCE END -------------------------------------
    !STACK 0
    java.lang.ClassCastException: org.eclipse.wst.jsdt.internal.compiler.lookup.BaseTypeBinding cannot be cast to org.eclipse.wst.jsdt.internal.compiler.lookup.ReferenceBinding
    at org.eclipse.wst.jsdt.core.infer.InferredType.resolveSuperType(InferredType.java:330)
    at org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope.findInferredSupertype(ClassScope.java:1160)
    at org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope.connectSuperclass(ClassScope.java:840)
    at org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope.connectTypeHierarchy(ClassScope.java:1000)
    at org.eclipse.wst.jsdt.internal.compiler.lookup.CompilationUnitScope.connectTypeHierarchy(CompilationUnitScope.java:696)
    at org.eclipse.wst.jsdt.internal.compiler.lookup.LookupEnvironment.completeTypeBindings(LookupEnvironment.java:316)
    at org.eclipse.wst.jsdt.internal.compiler.Compiler.resolve(Compiler.java:686)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:258)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.buildStructure(CompilationUnit.java:233)
    at org.eclipse.wst.jsdt.internal.core.Openable.generateInfos(Openable.java:241)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:538)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:282)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:268)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getChildren(JavaElement.java:216)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getChildrenOfType(JavaElement.java:230)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.getTypes(CompilationUnit.java:909)
    at org.eclipse.wst.jsdt.internal.core.NameLookup.<init>(NameLookup.java:228)
    at org.eclipse.wst.jsdt.internal.core.JavaProjectElementInfo.newNameLookup(JavaProjectElementInfo.java:346)
    at org.eclipse.wst.jsdt.internal.core.JavaProject.newNameLookup(JavaProject.java:2315)
    at org.eclipse.wst.jsdt.internal.core.SearchableEnvironment.<init>(SearchableEnvironment.java:75)
    at org.eclipse.wst.jsdt.internal.core.SearchableEnvironment.<init>(SearchableEnvironment.java:107)
    at org.eclipse.wst.jsdt.internal.core.CancelableNameEnvironment.<init>(CancelableNameEnvironment.java:32)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:222)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.buildStructure(CompilationUnit.java:233)
    at org.eclipse.wst.jsdt.internal.core.Openable.generateInfos(Openable.java:241)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:538)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:282)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:268)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getChildren(JavaElement.java:216)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getChildrenOfType(JavaElement.java:230)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.getTypes(CompilationUnit.java:909)
    at org.eclipse.wst.jsdt.internal.core.NameLookup.<init>(NameLookup.java:228)
    at org.eclipse.wst.jsdt.internal.core.JavaProjectElementInfo.newNameLookup(JavaProjectElementInfo.java:346)
    at org.eclipse.wst.jsdt.internal.core.JavaProject.newNameLookup(JavaProject.java:2315)
    at org.eclipse.wst.jsdt.internal.core.SearchableEnvironment.<init>(SearchableEnvironment.java:75)
    at org.eclipse.wst.jsdt.internal.core.SearchableEnvironment.<init>(SearchableEnvironment.java:107)
    at org.eclipse.wst.jsdt.internal.core.CancelableNameEnvironment.<init>(CancelableNameEnvironment.java:32)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:222)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.buildStructure(CompilationUnit.java:233)
    at org.eclipse.wst.jsdt.internal.core.Openable.generateInfos(Openable.java:241)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:538)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:282)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:268)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getChildren(JavaElement.java:216)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getChildrenOfType(JavaElement.java:230)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.getTypes(CompilationUnit.java:909)
    at org.eclipse.wst.jsdt.internal.core.NameLookup.<init>(NameLookup.java:228)
    at org.eclipse.wst.jsdt.internal.core.JavaProjectElementInfo.newNameLookup(JavaProjectElementInfo.java:346)
    at org.eclipse.wst.jsdt.internal.core.JavaProject.newNameLookup(JavaProject.java:2315)
    at org.eclipse.wst.jsdt.internal.core.SearchableEnvironment.<init>(SearchableEnvironment.java:75)
    at org.eclipse.wst.jsdt.internal.core.SearchableEnvironment.<init>(SearchableEnvironment.java:107)
    at org.eclipse.wst.jsdt.internal.core.CancelableNameEnvironment.<init>(CancelableNameEnvironment.java:32)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:222)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.buildStructure(CompilationUnit.java:233)
    at org.eclipse.wst.jsdt.internal.core.Openable.generateInfos(Openable.java:241)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:538)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:282)
    at org.eclipse.wst.jsdt.internal.core.JavaElement.getElementInfo(JavaElement.java:268)
    at org.eclipse.wst.jsdt.internal.core.Openable.getBuffer(Openable.java:267)
    at org.eclipse.wst.jsdt.internal.core.Openable.findRecommendedLineSeparator(Openable.java:199)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:289)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:320)
    at org.eclipse.wst.jsdt.internal.core.ReconcileWorkingCopyOperation.makeConsistent(ReconcileWorkingCopyOperation.java:197)
    at org.eclipse.wst.jsdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:96)
    at org.eclipse.wst.jsdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:742)
    at org.eclipse.wst.jsdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:802)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1215)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1192)
    at org.eclipse.wst.jsdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1176)
    at org.eclipse.wst.jsdt.web.core.javascript.JsTranslation.reconcileCompilationUnit(JsTranslation.java:522)
    at org.eclipse.wst.jsdt.web.core.internal.validation.JsValidator.performValidation(JsValidator.java:176)
    at org.eclipse.wst.jsdt.web.core.internal.validation.JsValidator.validateFile(JsValidator.java:337)
    at org.eclipse.wst.jsdt.web.core.internal.validation.JsValidator.validate(JsValidator.java:246)
    at org.eclipse.wst.sse.ui.internal.reconcile.validator.ReconcileStepForValidator.validate(ReconcileStepForValidator.java:292)
    at org.eclipse.wst.sse.ui.internal.reconcile.validator.ReconcileStepForValidator.reconcileModel(ReconcileStepForValidator.java:258)
    at org.eclipse.jface.text.reconciler.AbstractReconcileStep.reconcile(AbstractReconcileStep.java:95)
    at org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorStrategy.reconcile(ValidatorStrategy.java:260)
    at org.eclipse.wst.sse.ui.internal.reconcile.DocumentRegionProcessor.process(DocumentRegionProcessor.java:209)
    at org.eclipse.wst.sse.ui.internal.reconcile.StructuredRegionProcessor.process(StructuredRegionProcessor.java:221)
    at org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor.run(DirtyRegionProcessor.java:641)
    at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

     

     

    回答

    clean下试试呢
    shenhui134 (中级程序员) 2010-06-14
    切换workspace试试
    vvvpig (初级程序员) 2010-06-14
    eclipse问题,不是你代码的问题,换工作区,再不行重装eclipse
    01404421 (高级程序员) 2010-06-26

     

     

    ----------------------

    最后,我切换工作区没问题了。

     

     

     

     

     

     

     

     

  • spket插件的安装与使用完整图文版

    2011-03-17 21:49:01


    下载最新破解版的spket1.6.18

    对于目前的MyEclipse的插件安装是很简单的,把spket1.6.18破解版.zip解压后直接复制到MyEclipse安装目录的dropins文件夹下即可。如图:



     

    安装完成后,启动MyEclipse,打开window—Preferences会发现多处了spket选项:


     

     

    选择spket下的JavaScript. Profiles,如图:


     

     

    点击NEW按钮新建,取名为Ext,这里名字可以任意:
     

     

    之后选中新建的Ext,点击右边的Add Library,如下图,并选取ExtJS
     

    之后如下图,选中红圈内ExtJS,再点击Add File: 

     

    找到EXT中src目录下的ext.jsb2,注意这里,我使用的是EXT3.X,EXT2.X的文件为source目录下的ext.jsb。更需要注意的是 下载EXT后ext.jsb2不在src目录下,需要你手动将它放入src目录,这一点很重要。

     

    之后出现如下图,将所有选项选中即可,此时你的MyEclipse已经具有EXT的自动提示功能了。
     

     

    选中完成后的Ext,点击右边的Default按钮,这样讲EXT的自动提示设置为所有项目的默认方式。

     

    最后选中General—Editors—File Associations,将js文件的默认打开方式设置为spket javascript. editor,这样以后在MyEclipse中编辑js文件就有EXT的自动提示了
     










    接着,你就可以在js代码中自动提示代码






    Ext Theme Builder
    在project目录下,新建一个文件,文件名为ext.theme,打开文件,指定ext的resource文件夹路径,就可以调整ext界面的颜色,效果等,生成自己的css文件









    spket自定义脚本的引用申明及提示



    1. 首先在当前js文件头部使用spket的包含语法引入包含的js:

    显示代码打印1 /** 

    2 * @include "../js/custom.js" 

    3 */



    2.按 ctrl+click即可打开js申明,或ctrl+/ 自动完成提示










     
  • Struts+Spring+Hibernate环境的搭建

    2011-03-17 21:28:49


    文章分类:Java编程 一、 自动加载Struts
    新建一个WebProject的项目,右键单击项目名称->MyEclipse->Add Struts Capabilities
    选择Struts的版本和填写“Base package for new classes”
    例如“Struts1.2”“com.studiozero.myblog.struts”
    点击Finish完成Struts的加载
    二、 自动加载Spring
    右键单击项目名称->MyEclipse->Add Spring Capabilities->加载Spring类包(Spring2.0 Core Libraries+Spring 2.0 Web Libraries)->选择”Copy checked Libraries contents to project folder(TLDs always copied)”->Libraries Folder的值选为” /WebRoot/WEB-INF/lib”,Tag Libraries Installation的值为” /WebRoot/WEB-INF”->单击Next,Folder的值为” WebRoot/WEB-INF”,File的值为” applicationContext.xml”->单击Finish
    三、 自动加载Hibernate
    右键单击项目名称->MyEclipse->Add Hibernate Capabilities->加载Hibernate类包(Hibernate 3.1 Core Libraries+Hibernate 3.1 Advanced Support Libraries+Spring 2.0 ORM/DAO/Hibernate3 Libraries)->选择“Copy checked Libraries jars to project folder and add to build-path”,Libraries Folder的值为” /WebRoot/WEB-INF/lib”->单击Next,选择Spring configuration file(applicationContext.xml)->单价Next,选择Existing Spring configuration file,填写SessionFactory ID的值,例如:sessionFactory->单击Next 选择数据源->填写 BeanId 例如“dataSource”->单击Next,取消对“Create SessionFactory classes”的选择->单击Finish完成对Hibernate的加载
    四、将Struts交给Spring
    <controller>
      <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor" />
      </controller>
       <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
        <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
      </plug-in>
    五、创建包结构
    Com.studiozero.dao(存放DAO),com.studiozero.struts(存放Struts的Action和 Form),com.studiozero.vo(存放Model和hbm文件),com.studiozero.service(存放业务层 类),com.studiozero.util(存放常用的类)
    六、 将数据库表自动导出
    在DB Browser中右键单击要导出的数据表->Hibernate Reverse Engineering->在Java src folder中选择“com.studiozero.vo”,选中一下内容“Hibernate mapping file(*.hbm.xml) for each database table”,“Update hibernate configuration with mapping file location”,“Java Data Object(POJO<>DB Tabe)”,“Java Data Access Object(DAO)(Hibernate 3 only)”,“Generate precise findBy methods”->单击Next设定“ID Generator”一般选择“native”->单击Finish完成数据表的导出



    http://chengzhi-hong.javaeye.com/blog/777411
  • java调用bat文件

    2011-03-17 21:27:09

    2010-10-09

    Runtime.getRuntime().exec("cmd /c del c:\\a.doc");
       //Runtime.getRuntime().exec("notepad");
      //Runtime.getRuntime().exec("cmd /c start c:\\a.doc");
      //Runtime.getRuntime().exec("cmd /c start http://www.baidu.com");
       Runtime.getRuntime().exec("cmd /k start c:\\test.bat");   //java调用bat文件

      mysqldump --user=root --host=localhost --password=pass  zhangwei >c:\zw4.sql

     

    java中如何调用CMD命令

     

     

     

    ★CMD命令★
    1. gpedit.msc-----组策略
    2. sndrec32-------录音机
    3. Nslookup-------IP地址侦测器
    4. explorer-------打开资源管理器
    5. logoff---------注销命令
    6. tsshutdn-------60秒倒计时关机命令
    7. lusrmgr.msc----本机用户和组
    8. services.msc---本地服务设置
    9. oobe/msoobe /a----检查XP是否激活
    10. notepad--------打开记事本
    11. cleanmgr-------垃圾整理
    12. net start messenger----开始信使服务
    13. compmgmt.msc---计算机管理
    14. net stop messenger-----停止信使服务
    15. conf-----------启动netmeeting
    16. dvdplay--------DVD播放器
    17. charmap--------启动字符映射表
    18. diskmgmt.msc---磁盘管理实用程序
    19. calc-----------启动计算器
    20. dfrg.msc-------磁盘碎片整理程序
    21. chkdsk.exe-----Chkdsk磁盘检查
    22. devmgmt.msc--- 设备管理器
    23. regsvr32 /u *.dll----停止dll文件运行
    24. drwtsn32------ 系统医生
    25. rononce -p ----15秒关机
    26. dxdiag---------检查DirectX信息
    27. regedt32-------注册表编辑器
    28. Msconfig.exe---系统配置实用程序
    29. rsop.msc-------组策略结果集
    30. mem.exe--------显示内存使用情况
    31. regedit.exe----注册表
    32. winchat--------XP自带局域网聊天
    33. progman--------程序管理器
    34. winmsd---------系统信息
    35. perfmon.msc----计算机性能监测程序
    2. 36. winver---------检查Windows版本
    37. sfc /scannow-----扫描错误并复原
    38. taskmgr-----任务管理器(2000/xp/2003
    39. winver---------检查Windows版本
    40. wmimgmt.msc----打开windows管理体系结构(WMI)
    41. wupdmgr--------windows更新程序
    42. wscript--------windows脚本宿主设置
    43. write----------写字板
    44. winmsd---------系统信息
    45. wiaacmgr-------扫描仪和照相机向导
    46. winchat--------XP自带局域网聊天
    47. mem.exe--------显示内存使用情况
    48. Msconfig.exe---系统配置实用程序
    49. mplayer2-------简易widnows media player
    50. mspaint--------画图板
    51. mstsc----------远程桌面连接
    52. mplayer2-------媒体播放机
    53. magnify--------放大镜实用程序
    54. mmc------------打开控制台
    55. mobsync--------同步命令
    56. dxdiag---------检查DirectX信息
    57. drwtsn32------ 系统医生
    58. devmgmt.msc--- 设备管理器
    59. dfrg.msc-------磁盘碎片整理程序
    60. diskmgmt.msc---磁盘管理实用程序
    61. dcomcnfg-------打开系统组件服务
    62. ddeshare-------打开DDE共享设置
    63. dvdplay--------DVD播放器
    64. net stop messenger-----停止信使服务
    65. net start messenger----开始信使服务
    66. notepad--------打开记事本
    67. nslookup-------网络管理的工具向导
    68. ntbackup-------系统备份和还原
    69. narrator-------屏幕“讲述人”
    70. ntmsmgr.msc----移动存储管理器
    71. ntmsoprq.msc---移动存储管理员操作请求
    72. netstat -an----(TC)命令检查接口
    73. syncapp--------创建一个公文包
    74. sysedit--------系统配置编辑器
    75. sigverif-------文件签名验证程序
    76. sndrec32-------录音机
    77. shrpubw--------创建共享文件夹
    78. secpol.msc-----本地安全策略
    79. syskey---------系统加密,一旦加密就不能解开,保护windows xp系统的双重密码
    80. services.msc---本地服务设置
    81. Sndvol32-------音量控制程序
    82. sfc.exe--------系统文件检查器
    83. sfc /scannow---windows文件保护
    84. tsshutdn-------60秒倒计时关机命令
    3. 84. tsshutdn-------60秒倒计时关机命令
    85. tourstart------xp简介(安装完成后出现的漫游xp程序)
    86. taskmgr--------任务管理器
    87. eventvwr-------事件查看器
    88. eudcedit-------造字程序
    89. explorer-------打开资源管理器
    90. packager-------对象包装程序
    91. perfmon.msc----计算机性能监测程序
    92. progman--------程序管理器
    93. regedit.exe----注册表
    94. rsop.msc-------组策略结果集
    95. regedt32-------注册表编辑器
    96. rononce -p ----15秒关机
    97. regsvr32 /u *.dll----停止dll文件运行
    98. regsvr32 /u zipfldr.dll------取消ZIP支持
    99. cmd.exe--------CMD命令提示符
    100. chkdsk.exe-----Chkdsk磁盘检查
    101. certmgr.msc----证书管理实用程序
    102. calc-----------启动计算器
    103. charmap--------启动字符映射表
    104. cliconfg-------SQL SERVER 客户端网络实用程序
    105. Clipbrd--------剪贴板查看器
    106. conf-----------启动netmeeting
    107. compmgmt.msc---计算机管理
    108. cleanmgr-------垃圾整理
    109. ciadv.msc------索引服务程序
    110. osk------------打开屏幕键盘
    111. odbcad32-------ODBC数据源管理器
    112. oobe/msoobe /a----检查XP是否激活
    113. lusrmgr.msc----本机用户和组
    114. logoff---------注销命令
    115. iexpress-------木马捆绑工具,系统自带
    116. Nslookup-------IP地址侦测器
    117. fsmgmt.msc-----共享文件夹管理器
    118. utilman--------辅助工具管理器
    119. gpedit.msc-----组策略
    120. explorer-------打开资源管理器

    cmd /c dir 是执行完dir命令后关闭命令窗口。

    cmd /k dir 是执行完dir命令后不关闭命令窗口。

    cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭。

    cmd /k start dir 会打开一个新窗口后执行dir指令,原窗口不会关闭。

    可以用cmd /?查看帮助信息。

     http://chengzhi-hong.javaeye.com/blog/779967

  • myeclipse 优化

    2011-03-17 01:21:22

    2009-10-14
    myeclipse 优化
    文章分类:Java编程

    收集了一些关于解决 MyEclipse 的耗内存的办法,经测试非常有效,整理出来,希望可以方便更多的朋友。

    1、老是弹出Quick update error 、关闭myeclipse的Quick Update自动更新功能
         这个问题的解决办法是关闭自动更新
         Windows > Preferences > MyEclipse Enterprise Workbench > Community Essentials,
         把选项 "Search for new features on startup"的前勾去掉即可。

    2 、关闭updating indexes
          Window > Preferences > Myeclipse Enterprise Workbench > Maven4Myeclipse > Maven>
          禁用Download repository index updates on startup 。 

    在这里我声明下:网上说的这个方法在myeclipse8.0默认情况下根本就找不到,摸索了半天才发现,如果想里面出现maven这个选项,必须选中 Maven4Myeclispse中的Enable Maven4Myeclispse features选项,保存后在操作一次上面的步骤就出现了。


    3 、关闭MyEclipse的自动validation
          validation有一堆,什么xml、jsp、jsf、js等等,我们没有必要全部都去自动校验一下,
          只是需要的时候才会手工校验一 下,速度立马提升好几个档次
          windows > perferences > myeclipse > validation
          将Build下全部勾取消
          如果你需要验证某个文件的时候,我们可以单独去验证它。方法是:
          在需要验证的文件上( 右键 -> MyEclipse -> Run   Validation 。

    4、 启动优化,关闭不需要使用的模块
          一个系统20%的功能往往能够满足80%的需求,MyEclipse也不例外,我们在大多数时候只需要20%的系统功能,
         所以可以将一些不使用的模块禁止 加载启动。
         Window > Preferences > General > Startup andy Shutdown 在这里列出的是MyEclipse启动时加载的模块
         我这里只让它加载tomcat5 勾选 MyEclipse EASIE Tomcat 5 。
         怎样才能知道哪些启动项有用呢?我现在把我知道的启动项用处说一下,还有很多不懂的,
         希望大家懂的回复在下面    啊:
              WTP :一个跟myeclipse差不多的东西,主要差别是 WTP 是免费的,如果使用myeclipse,这个可以取消
              Mylyn:组队任务管理工具,类似于 CVS ,以任务为单位管理项目进度,没用到的可以取消
              Derby:一种保存成 jar 形式的数据库,我没用到,取消
              一大排以 MyEclipse EASIE 打头的启动项:myeclipse 支持的服务器,只选自己用的,其他取消,
             比如我只选了    tomcat 。

    5 、去掉MyEclipse的拼写检查(如果你觉的有用可以不去)
          拼写检查会给我们带来不少的麻烦,我们的方法命名都会是单词的缩写,他也会提示有错,
          所以最好去掉,没有多大的用处
          Window > perferences > General > Editors > Text Editors > Spelling > 将Enable spell checking复选框的勾选去掉。 

    6 、去掉MyEclipse繁杂的自带插件自动加载项
          Window > perferences > General > Startup and Shutdown > 将Plug-ins activated on startup
          中的复选框有选择性的勾   选去掉。

    7 、修改MyEclipse编辑JSP页面时的编辑工具
          Window > perferences > General > Editors > File Associations >
          在File types 中选择 *.jsp > 在Associated editors 中将"MyEclipse JSP Editor"设置为默认。

    8 、修改MyEclipse安装目录的eclipse.ini文件,加大JVM的非堆内存 
          具体内容如下:
         -clean
         -showsplash
         com.genuitec.myeclipse.product.ide
         –launcher.XXMaxPermSize
         256m
         -vmargs
         -Xms128m
         -Xmx512m
         -Duser.language=en
         -XX:PermSize=128M
         -XX:MaxPermSize=256M
         把下面的那个 -XX:MaxPermSize 调大,比如 -XX:MaxPermSize=512M,再把 -XX:PermSize 调成跟
         -XX:MaxPermSize一样大


    9.去除不需要加载的模块

       一个系统20%的功能往往能够满足80%的需求,MyEclipse也不例外,我们在大多数时候只需要20%的系统功能,所以可以将一些不使用的模块禁止加载启动。通过Windows - Preferences打开配置窗口,依次选择左侧的General - Startup and Shutdown,这个时候在右侧就显示出了Eclipse启动时加载的模块,可以根据自己的实际情况去除一些模块。
    windows–>perferences–>general–>startup and shutdown


    关掉没用的启动项:

    怎样才能知道哪些启动项有用呢?我现在把我知道的启动项用处说一下,还有很多不懂的,希望大家懂的回复在下面啊:
        WTP :一个跟myeclipse差不多的东西,主要差别是 WTP 是免费的,如果使用   myeclipse,这个可以取消
        Mylyn:组队任务管理工具,类似于 CVS ,以任务为单位管理项目进度,没用到的可以取消
        Derby:一种保存成 jar 形式的数据库,我没用到,取消
    一大排以 MyEclipse EASIE 打头的启动项:myeclipse 支持的服务器,只选自己用的,其他取消,比如我只选了tomcat

    取消MyEclipse在启动时自动验证项目配置文件

    默认情况下MyEclipse在启动的时候会自动验证每个项目的配置文件,这是一个非常耗时的过程,可以在Preferences窗口依次选择 MyEclipse - Validation,然后在右侧的Validator列表中只保留 Manual 项就可以了。如果需要验证的时候只需要选中文件,然后右键选择 MyEclipse - Run Validation就可以了。

    windows–>perferences–>myeclipse–>validation
    把 除了manual 下面的全部点掉,build下只留 classpath dependency Validator


    手工验证方法:

    在要验证的文件上,单击鼠标右键–>myeclipse–>run validation

    拼写检查会给我们带来不少的麻烦,我们的方法命名都会是单词的缩写,他也会提示有错,所以最好去掉,没有多大的用处:
    windows–>perferences–>general–>validation->editors->Text Editors->spelling

    myeclipse 打开 jsp 的默认编辑器不好,会同时打开预览
    windows–>perferences–>general–>editors->file associations,

    把默认改成 MyEclipse JSP Edito















    图片
    用户名:   密码: 登录
    注册
    铁书
    欢迎!!
     
    主页博客相册|个人档案 |好友
         
    查看文章
             
    myeclipse8.0优化设置
    2011-01-04 13:32

    1、老是弹出Quick update error 、关闭myeclipse的Quick Update自动更新功能
         这个问题的解决办法是关闭自动更新

    Autuomatic Updates Scheduler:myeclipse自动更新选项,讨厌每次开启Myeclipse右下角都一直在读取的可以选择关闭。


         Windows > Preferences > MyEclipse Enterprise Workbench > Community Essentials,
         把选项 "Search for new features on startup"的前勾去掉即可。

    或者(找不到上面那项的)

         Windows > Preferences >Install/Update>Automatic Updates 去掉勾选

    2 、关闭updating indexes
          Window > Preferences > Myeclipse Enterprise Workbench > Maven4Myeclipse > Maven>
          禁用Download repository index updates on startup 。

    在这里我声明下:网上说的这个方法在myeclipse8.0默认情况下根本就找不到,摸索了半天才发现,如果想里面出现maven这个选项,必须选中 Maven4Myeclispse中的Enable Maven4Myeclispse features选项,保存后在操作一次上面的步骤就出现了。

    3 、关闭MyEclipse的自动validation
          validation有一堆,什么xml、jsp、jsf、js等等,我们没有必要全部都去自动校验一下,
          只是需要的时候才会手工校验一 下,速度立马提升好几个档次
          windows > perferences > myeclipse > validation
          将Build下全部勾取消
          如果你需要验证某个文件的时候,我们可以单独去验证它。方法是:
          在需要验证的文件上( 右键 -> MyEclipse -> Run   Validation 。

    4、 启动优化,关闭不需要使用的模块
          一个系统20%的功能往往能够满足80%的需求,MyEclipse也不例外,我们在大多数时候只需要20%的系统功能,
         所以可以将一些不使用的模块禁止 加载启动。
         Window > Preferences > General > Startup andy Shutdown 在这里列出的是MyEclipse启动时加载的模块
         我这里只让它加载tomcat5 勾选 MyEclipse EASIE Tomcat 5 。
         怎样才能知道哪些启动项有用呢?我现在把我知道的启动项用处说一下,还有很多不懂的,
         希望大家懂的回复在下面    啊:
              WTP :一个跟myeclipse差不多的东西,主要差别是 WTP 是免费的,如果使用myeclipse,这个可以取消
              Mylyn:组队任务管理工具,类似于 CVS ,以任务为单位管理项目进度,没用到的可以取消
              Derby:一种保存成 jar 形式的数据库,我没用到,取消
              一大排以 MyEclipse EASIE 打头的启动项:myeclipse 支持的服务器,只选自己用的,其他取消,
             比如我只选了    tomcat 。

    5 、去掉MyEclipse的拼写检查(如果你觉的有用可以不去)
          拼写检查会给我们带来不少的麻烦,我们的方法命名都会是单词的缩写,他也会提示有错,
          所以最好去掉,没有多大的用处
          Window > perferences > General > Editors > Text Editors > Spelling > 将Enable spell checking复选框的勾选去掉。

    6 、去掉MyEclipse繁杂的自带插件自动加载项
          Window > perferences > General > Startup and Shutdown > 将Plug-ins activated on startup
          中的复选框有选择性的勾   选去掉。

    7 、修改MyEclipse编辑JSP页面时的编辑工具
          Window > perferences > General > Editors > File Associations >
          在File types 中选择 *.jsp > 在Associated editors 中将"MyEclipse JSP Editor"设置为默认。

    8 、修改MyEclipse安装目录的eclipse.ini文件,加大JVM的非堆内存
          具体内容如下:
         -clean
         -showsplash
         com.genuitec.myeclipse.product.ide
         --launcher.XXMaxPermSize
         256m
         -vmargs
         -Xms128m
         -Xmx512m
         -Duser.language=en
         -XX:PermSize=128M
         -XX:MaxPermSize=256M
         把下面的那个 -XX:MaxPermSize 调大,比如 -XX:MaxPermSize=512M,再把 -XX:PermSize 调成跟
         -XX:MaxPermSize一样大

     

     

    统一默认编码

    1,修改新建项目默认编码:Window->Preferences->General->Workspace->Text file encoding 将其修改为UTF-8.

    2.根据文件修改默认编码:windows---->preferences---->myeclipse---->file and editors下所有选项中的encoding 修改为

    IS010646/Unicode(UTF-8) 即统一编码为UTF-8.


  • OOJ-面向对象的JAVASCRIPT --- extjs

    2011-03-17 01:16:17

    《ExtJs教程-dojochina(30集已全部发布)》(ExtJs)[DVDRip]
    http://www.verycd.com/topics/2806750/
    优酷视频
     


    http://dev.firnow.com/course/1_web/javascript/Javascriptxl/20100719/448233.html




    http://dev.firnow.com/course/1_web/javascript/Javascriptxl/20100719/448233.html

    OOJ-面向对象的JAVASCRIPT(一)





    现代编程都有一个共性,无任是新语言,还是发展健全的语言,都有一套面向对象编程的理论。

      WEB前端开发的JAVASCRIPT也不例外。最近着迷发展的JAVASCRIPT,也想把自己的想法和前人的经验总结下,让更多的IT农民工学习研究。

     

    一、面向对象的基础理论

        百度知道里讲诉的已经非常清晰: http://baike.baidu.com/view/125370.htm ,这里纯理论的知识大家就自我学习。

     

    二、OOJ概述

      javascript面向对象编程与一般的C++,C#等开发语言结构还不一致。它即面向对象,又类似于一般的结构性语言。

     

      JavaScript. 对象是词典

      在 C++ 或 C# 中,在谈论对象时,是指类或结构的实例。对象有不同的属性和方法,具体取决于将它们实例化的模板(即类)。而 JavaScript. 对象却不是这样。在 JavaScript. 中,对象只是一组名称/值对,就是说,将 JavaScript. 对象视为包含字符串关键字的词典。我们可以使用熟悉的“.”(点)运算符或“[]”运算符,来获得和设置对象的属性,这是在处理词典时通常采用的方法。以下代码段:

    var userObject = new Object();
    userObject.lastLoginTime = new Date();
    alert(userObject.lastLoginTime);   

     的功能与下面的代码段完全相同:


    var userObject = {}; // equivalent to new Object()
    userObject[“lastLoginTime”] = new Date();
    alert(userObject[“lastLoginTime”]);

     我们还可以直接在 userObject 的定义中定义 lastLoginTime 属性,如下所示:


    var userObject = { “lastLoginTime”: new Date() };
    alert(userObject.lastLoginTime);

    这里大家需要注意的是: JavaScript. 对象/词典只接受字符串关键字

    如果记住 JavaScript. 对象是词典,您就不会对此感到吃惊了,毕竟,我们一直在向词典添加新关键字(和其各自的值)。

    接下来,我们了解下JAVASCRIPT的对象方法,若要理解对象方法,首先需要仔细了解一下 JavaScript. 函数。

      JavaScript. 函数的奇特性

    大家了解的很多编程语言中,函数和对象通常被视为两样不同的东西。在 JavaScript. 中,其差别很模糊 — JavaScript. 函数实际上是具有与它关联的可执行代码的对象。请如此看待普通函数:


    function func(x) {
        alert(x);
    }
    func(“blah”);

     这就是通常在 JavaScript. 中定义函数的方法。但是,还可以按以下方法定义该函数,您在此创建匿名函数对象,并将它赋给变量 func 


    var func = function(x) {
        alert(x);
    };
    func(“blah2”);

     甚至也可以像下面这样,使用 Function 构造函数:  


    var func = new Function(“x”, “alert(x);”);
    func(“blah3”);

     此示例表明函数实际上只是支持函数调用操作的对象。最后一个使用 Function 构造函数来定义函数的方法并不常用,但它展示的可能性非常有趣,因为您可能注意到,该函数的主体正是 Function 构造函数的 String 参数。这意味着,您可以在运行时构造任意函数。

    为了进一步演示函数是对象,您可以像对其他任何 JavaScript. 对象一样,在函数中设置或添加属性:

    function sayHi(x) {
        alert(“Hi, “ + x + “!”);
    }
    sayHi.text = “Hello World!”;
    sayHi[“text2”] = “Hello World... again.”;

    alert(sayHi[“text”]); // displays “Hello World!”
    alert(sayHi.text2); // displays “Hello World... again.”

     

    作为对象,函数还可以赋给变量、作为参数传递给其他函数、作为其他函数的值返回,并可以作为对象的属性或数组的元素进行存储等等。下面提供了这样一个示例:

     


    // assign an anonymous function to a variable
    var greet = function(x) {
        alert(“Hello, “ + x);
    };
    greet(“MSDN readers”);

    // passing a function as an argument to another
    function square(x) {
        return x * x;
    }
    function operateOn(num, func) {
        return func(num);
    }
    // displays 256
    alert(operateOn(16, square));

    // functions as return values
    function makeIncrementer() {
        return function(x) { return x + 1; };
    }
    var inc = makeIncrementer();
    // displays 8
    alert(inc(7));

    // functions stored as array elements
    var arr = [];
    arr[0] = function(x) { return x * x; };
    arr[1] = arr[0](2);
    arr[2] = arr[0](arr[1]);
    arr[3] = arr[0](arr[2]);
    // displays 256
    alert(arr[3]);

    // functions as object properties
    var bj = { “toString” : function() { return “This is an object.”; } };
    // calls obj.toString()
    alert(obj);

     

     

    记住这一点后,向对象添加方法将是很容易的事情:只需选择名称,然后将函数赋给该名称。因此,我通过将匿名函数分别赋给相应的方法名称,在对象中定义了三个方法:

     


    var myDog = {
        “name” : “Spot”,
        “bark” : function() { alert(“Woof!”); },
        “displayFullName” : function() {
            alert(this.name + “ The Alpha Dog”);
        },
        “chaseMrPostman” : function() {
            // implementation beyond the scope of this article
        }   
    };
    myDog.displayFullName();
    myDog.bark(); // Woof!

     

     

    C++/C# 开发人员应当很熟悉 displayFullName 函数中使用的“this”关键字 — 它引用一个对象,通过对象调用方法(使用 Visual Basic 的开发人员也应当很熟悉它,它在 Visual Basic 中叫做“Me”)。因此在上面的示例中,displayFullName 中的“this”的值是 myDog 对象。但是,“this”的值不是静态的。通过不同对象调用“this”时,它的值也会更改以便指向相应的对象,如下所示。

    “this”随对象更改而更改

     


    function displayQuote() {
        // the value of “this” will change; depends on
        // which object it is called through
        alert(this.memorableQuote);   
    }

    var williamShakespeare = {
        “memorableQuote”: “It is a wise father that knows his own child.”,
        “sayIt” : displayQuote
    };

    var markTwain = {
        “memorableQuote”: “Golf is a good walk spoiled.”,
        “sayIt” : displayQuote
    };

    var scarWilde = {
        “memorableQuote”: “True friends stab you in the front.”
        // we can call the function displayQuote
        // as a method of oscarWilde without assigning it
        // as oscarWilde’s method.
        //”sayIt” : displayQuote
    };

    williamShakespeare.sayIt(); // true, true
    markTwain.sayIt(); // he didn’t know where to play golf

    // watch this, each function has a method call()
    // that allows the function to be called as a
    // method of the object passed to call() as an
    // argument.
    // this line below is equivalent to assigning
    // displayQuote to sayIt, and calling oscarWilde.sayIt().
    displayQuote.call(oscarWilde); // ouch!

     

     

    上面代码中最后一行表示的是将函数作为对象的方法进行调用的另一种方式。请记住,JavaScript. 中的函数是对象。每个函数对象都有一个名为 call 的方法,它将函数作为第一个参数的方法进行调用。就是说,作为函数第一个参数传递给 call 的任何对象都将在函数调用中成为“this”的值。这一技术对于调用基类构造函数来说非常有用,稍后将对此进行介绍。

    有一点需要记住,绝不要调用包含“this”(却没有所属对象)的函数。否则,将违反全局命名空间,因为在该调用中,“this”将引用全局对象,而这必然会给您的应用程序带来灾难。例如,下面的脚本将更改 JavaScript. 的全局函数 isNaN 的行为。一定不要这样做!


    alert(“NaN is NaN: “ + isNaN(NaN));

    function x() {
        this.isNaN = function() {
            return “not anymore!”;
        };
    }
    // alert!!! trampling the Global object!!!
    x();

    alert(“NaN is NaN: “ + isNaN(NaN));

     

          到这里,我们已经介绍了如何创建对象,包括它的属性和方法。但如果注意上面的所有代码段,您会发现属性和方法是在对象定义本身中进行硬编码的。但如果需要更好地控制对象的创建,该怎么做呢?例如,您可能需要根据某些参数来计算对象的属性值。或者,可能需要将对象的属性初始化为仅在运行时才能获得的值。也可能需要创建对象的多个实例(此要求非常常见)。

         在 C# 中,我们使用类来实例化对象实例。但 JavaScript. 与此不同,因为它没有类。您将在下一节中看到,您可以充分利用这一情况:函数在与“new”运算符一起使用时,函数将充当构造函数。
     
    构造函数而不是类
    前面提到过,有关 JavaScript. OOP 的最奇怪的事情是,JavaScript. 不像 C# 或 C++ 那样,它没有类。在 C# 中,在执行类似下面的操作时:

    Dog spot = new Dog();

    将返回一个对象,该对象是 Dog 类的实例。但在 JavaScript. 中,本来就没有类。与访问类最近似的方法是定义构造函数,如下所示: 


    function DogConstructor(name) {
        this.name = name;
        this.respondTo = function(name) {
            if(this.name == name) {
                alert(“Woof”);       
            }
        };
    }

    var spot = new DogConstructor(“Spot”);
    spot.respondTo(“Rover”); // nope
    spot.respondTo(“Spot”); // yeah!

     

    那么,结果会怎样呢?暂时忽略 DogConstructor 函数定义,看一看这一行:


    var spot = new DogConstructor(“Spot”);

     

    “new”运算符执行的操作很简单。首先,它创建一个新的空对象。然后执行紧随其后的函数调用,将新的空对象设置为该函数中“this”的值。换句话说,可以认为上面这行包含“new”运算符的代码与下面两行代码的功能相当:


    // create an empty object
    var spot = {};
    // call the function as a method of the empty object
    DogConstructor.call(spot, “Spot”);

     

    正如在 DogConstructor 主体中看到的那样,调用此函数将初始化对象,在调用期间关键字“this”将引用此对象。这样,就可以为对象创建模板!只要需要创建类似的对象,就可以与构造函数一起调用“new”,返回的结果将是一个完全初始化的对象。这与类非常相似,不是吗?实际上,在 JavaScript. 中构造函数的名称通常就是所模拟的类的名称,因此在上面的示例中,可以直接命名构造函数 Dog: 


    // Think of this as class Dog
    function Dog(name) {
        // instance variable
        this.name = name;
        // instance method? Hmmm...
        this.respondTo = function(name) {
            if(this.name == name) {
                alert(“Woof”);       
            }
        };
    }

    var spot = new Dog(“Spot”);

     

     

    在上面的 Dog 定义中,我定义了名为 name 的实例变量。使用 Dog 作为其构造函数所创建的每个对象都有它自己的实例变量名称副本(前面提到过,它就是对象词典的条目)。这就是希望的结果。毕竟,每个对象都需要它自己的实例变量副本来表示其状态。但如果看看下一行,就会发现每个 Dog 实例也都有它自己的 respondTo 方法副本,这是个浪费;您只需要一个可供各个 Dog 实例共享的 respondTo 实例!通过在 Dog 以外定义 respondTo,可以避免此问题,如下所示:

    function respondTo() {
        // respondTo definition
    }

    function Dog(name) {
        this.name = name;
        // attached this function as a method of the object
        this.respondTo = respondTo;
    }

     

    这样,所有 Dog 实例(即用构造函数 Dog 创建的所有实例)都可以共享 respondTo 方法的一个实例。但随着方法数的增加,维护工作将越来越难。最后,基本代码中将有很多全局函数,而且随着“类”的增加,事情只会变得更加糟糕(如果它们的方法具有相似的名称,则尤甚)。但使用原型对象可以更好地解决这个问题,这是下一节的主题。

     

    三、Javascript核心理论原型

    在使用 JavaScript. 的面向对象编程中,原型对象是个核心概念。在 JavaScript. 中对象是作为现有示例(即原型)对象的副本而创建的,该名称就来自于这一概念。此原型对象的任何属性和方法都将显示为从原型的构造函数创建的对象的属性和方法。可以说,这些对象从其原型继承了属性和方法。当您创建如下所示的新 Dog 对象时:


    var buddy = new Dog(“Buddy“);

    buddy 所引用的对象将从它的原型继承属性和方法,尽管仅从这一行可能无法明确判断原型来自哪里。对象 buddy 的原型来自构造函数(在这里是函数 Dog)的属性。

    在 JavaScript. 中,每个函数都有名为“prototype”的属性,用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。这是一种循环引用,图A1 更好地说明了这种循环关系。

    图A1 每个函数的原型都有一个 Constructor 属性

     

    现在,通过“new”运算符用函数(上面示例中为 Dog)创建对象时,所获得的对象将继承 Dog.prototype 的属性。在图A1 中,可以看到 Dog.prototype 对象有一个回指 Dog 函数的构造函数属性。这样,每个 Dog 对象(从 Dog.prototype 继承而来)都有一个回指 Dog 函数的构造函数属性。代码段B1 中的代码证实了这一点。图A2 显示了构造函数、原型对象以及用它们创建的对象之间的这一关系。

    代码段B1


    var spot = new Dog(“Spot”);

    // Dog.prototype is the prototype of spot
    alert(Dog.prototype.isPrototypeOf(spot));

    // spot inherits the constructor property
    // from Dog.prototype
    alert(spot.constructor == Dog.prototype.constructor);
    alert(spot.constructor == Dog);

    // But constructor property doesn’t belong
    // to spot. The line below displays “false”
    alert(spot.hasOwnProperty(“constructor”));

    // The constructor property belongs to Dog.prototype
    // The line below displays “true”
    alert(Dog.prototype.hasOwnProperty(“constructor”));

     

    图A2-实例继承其原型

     

    某些读者可能已经注意到代码段B1 中对 hasOwnProperty 和 isPrototypeOf 方法的调用。这些方法是从哪里来的呢?它们不是来自 Dog.prototype。实际上,在 Dog.prototype 和 Dog 实例中还可以调用其他方法,比如 toString、toLocaleString 和 valueOf,但它们都不来自 Dog.prototype。您会发现,就像 .NET Framework 中的 System.Object 充当所有类的最终基类一样,JavaScript. 中的 Object.prototype 是所有原型的最终基础原型。(Object.prototype 的原型是 null。)
    在此示例中,请记住 Dog.prototype 是对象。它是通过调用 Object 构造函数创建的(尽管它不可见):

     


    Dog.prototype = new Object();

     

     

    因此,正如 Dog 实例继承 Dog.prototype 一样,Dog.prototype 继承 Object.prototype。这使得所有 Dog 实例也继承了 Object.prototype 的方法和属性。
    每个 JavaScript. 对象都继承一个原型链,而所有原型都终止于 Object.prototype。注意,迄今为止您看到的这种继承是活动对象之间的继承。它不同于继承的常见概念,后者是指在声明类时类之间的发生的继承。因此,JavaScript. 继承动态性更强。它使用简单算法实现这一点,如下所示:当您尝试访问对象的属性/方法时,JavaScript. 将检查该属性/方法是否是在该对象中定义的。如果不是,则检查对象的原型。如果还不是,则检查该对象的原型的原型,如此继续,一直检查到 Object.prototype。图A3 说明了此解析过程。

     

     

    图A3 在原型链中解析 toString() 方法
    JavaScript. 动态地解析属性访问和方法调用的方式产生了一些特殊效果:

        * 继承原型对象的对象上可以立即呈现对原型所做的更改,即使是在创建这些对象之后。
        * 如果在对象中定义了属性/方法 X,则该对象的原型中将隐藏同名的属性/方法。例如,通过在 Dog.prototype 中定义 toString 方法,可以改写 Object.prototype 的 toString 方法。
        * 更改只沿一个方向传递,即从原型到它的派生对象,但不能沿相反方向传递。

    代码段B2 说明了这些效果。B2还显示了如何解决前面遇到的不需要的方法实例的问题。通过将方法放在原型内部,可以使对象共享方法,而不必使每个对象都有单独的函数对象实例。在此示例中,rover 和 spot 共享 getBreed 方法,直至在 spot 中以任何方式改写 toString 方法。此后,spot 有了它自己版本的 getBreed 方法,但 rover 对象和用新 GreatDane 创建的后续对象仍将共享在 GreatDane.prototype 对象中定义的那个 getBreed 方法实例。

    代码段B2-继承原型


    function GreatDane() { }

    var rover = new GreatDane();
    var spot = new GreatDane();

    GreatDane.prototype.getBreed = function() {
        return “Great Dane”;
    };

    // Works, even though at this point
    // rover and spot are already created.
    alert(rover.getBreed());

    // this hides getBreed() in GreatDane.prototype
    spot.getBreed = function() {
        return “Little Great Dane”;
    };
    alert(spot.getBreed());

    // but of course, the change to getBreed
    // doesn’t propagate back to GreatDane.prototype
    // and other objects inheriting from it,
    // it only happens in the spot object
    alert(rover.getBreed());

     

     

    静态属性和方法
    有时,您需要绑定到类而不是实例的属性或方法,也就是,静态属性和方法。在 JavaScript. 中很容易做到这一点,因为函数是可以按需要设置其属性和方法的对象。由于在 JavaScript. 中构造函数表示类,因此可以通过在构造函数中设置静态方法和属性,直接将它们添加到类中,如下所示:

    function DateTime() { }

        // set static method now()
        DateTime.now = function() {
            return new Date();
        };

        alert(DateTime.now());

     

     

    在 JavaScript. 中调用静态方法的语法与在 C# 中几乎完全相同。这不应当让人感到吃惊,因为构造函数的名称实际上是类的名称。这样,就有了类、公用属性/方法,以及静态属性/方法。还需要其他什么吗?当然,私有成员。但 JavaScript. 本身并不支持私有成员(同样,也不支持受保护成员)。任何人都可以访问对象的所有属性和方法。但我们有办法让类中包含私有成员,但在此之前,您首先需要理解闭包。

     

    闭包
    不了解JAVASCRIPT就不要说JAVASCRIPT多么的简单或有多么的难学。JavaScript. 实际上是功能强大、表现力强而且非常简练的语言。它甚至具有其他更流行的语言才刚刚开始支持的功能。
    JavaScript. 的更高级功能之一是它支持闭包,这是 C# 2.0 通过它的匿名方法支持的功能。闭包是当内部函数(或 C# 中的内部匿名方法)绑定到它的外部函数的本地变量时所发生的运行时现象。很明显,除非此内部函数以某种方式可被外部函数访问,否则它没有多少意义。示例可以更好说明这一点。
    假设需要根据一个简单条件筛选一个数字序列,这个条件是:只有大于 100 的数字才能通过筛选,并忽略其余数字。为此,可以编写类似代码段B3 中的函数。

    代码段B3 -根据谓词筛选元素


    function filter(pred, arr) {
        var len = arr.length;
        var filtered = []; // shorter version of new Array();
        // iterate through every element in the array...
        for(var i = 0; i < len; i++) {
            var val = arr[i];
            // if the element satisfies the predicate let it through
            if(pred(val)) {
                filtered.push(val);
            }
        }
        return filtered;
    }

    var someRandomNumbers = [12, 32, 1, 3, 2, 2, 234, 236, 632,7, 8];
    var numbersGreaterThan100 = filter(
        function(x) { return (x > 100) ? true : false; },
        someRandomNumbers);

    // displays 234, 236, 632
    alert(numbersGreaterThan100);

     

    但是,现在要创建不同的筛选条件,假设这次只有大于 300 的数字才能通过筛选,则可以编写下面这样的函数:


    var greaterThan300 = filter(
        function(x) { return (x > 300) ? true : false; },
        someRandomNumbers);

     

    然后,也许需要筛选大于 50、25、10、600 如此等等的数字,但作为一个聪明人,您会发现它们全部都有相同的谓词“greater than”,只有数字不同。因此,可以用类似下面的函数分开各个数字:


    function makeGreaterThanPredicate(lowerBound) {
        return function(numberToCheck) {
            return (numberToCheck > lowerBound) ? true : false;
        };
    }

     

    这样,您就可以编写以下代码:


    var greaterThan10 = makeGreaterThanPredicate(10);
    var greaterThan100 = makeGreaterThanPredicate(100);
    alert(filter(greaterThan10, someRandomNumbers));
    alert(filter(greaterThan100, someRandomNumbers));

     

    通过观察函数 makeGreaterThanPredicate 返回的内部匿名函数,可以发现,该匿名内部函数使用 lowerBound,后者是传递给 makeGreaterThanPredicate 的参数。按照作用域的一般规则,当 makeGreaterThanPredicate 退出时,lowerBound 超出了作用域!但在这里,内部匿名函数仍然携带 lowerBound,甚至在 makeGreaterThanPredicate 退出之后的很长时间内仍然如此。这就是我们所说的闭包:因为内部函数关闭了定义它的环境(即外部函数的参数和本地变量)。

    开始可能感觉不到闭包的功能很强大。但如果应用恰当,它们就可以非常有创造性地帮您将想法转换成代码,这个过程非常有趣。在 JavaScript. 中,闭包最有趣的用途之一是模拟类的私有变量。

    模拟私有属性
    现在介绍闭包如何帮助模拟私有成员。正常情况下,无法从函数以外访问函数内的本地变量。函数退出之后,由于各种实际原因,该本地变量将永远消失。但是,如果该本地变量被内部函数的闭包捕获,它就会生存下来。这一事实是模拟 JavaScript. 私有属性的关键。假设有一个 Person 类:

    function Person(name, age) {
        this.getName = function() { return name; };
        this.setName = function(newName) { name = newName; };
        this.getAge = function() { return age; };
        this.setAge = function(newAge) { age = newAge; };
    }

     

    参数 name 和 age 是构造函数 Person 的本地变量。Person 返回时,name 和 age 应当永远消失。但是,它们被作为 Person 实例的方法而分配的四个内部函数捕获,实际上这会使 name 和 age 继续存在,但只能严格地通过这四个方法访问它们。因此,您可以:


    var ray = new Person(“Ray”, 31);
    alert(ray.getName());
    alert(ray.getAge());
    ray.setName(“Younger Ray”);
    // Instant rejuvenation!
    ray.setAge(22);
    alert(ray.getName() + “ is now “ + ray.getAge() +
          “ years old.”);

     

    未在构造函数中初始化的私有成员可以成为构造函数的本地变量,如下所示:


    function Person(name, age) {
        var occupation;
        this.getOccupation = function() { return occupation; };
        this.setOccupation = function(newOcc) { ccupation =
                             newOcc; };
     
        // accessors for name and age   
    }

     

    注意,这些私有成员与我们期望从 C# 中产生的私有成员略有不同。在 C# 中,类的公用方法可以访问它的私有成员。但在 JavaScript. 中,只能通过在其闭包内拥有这些私有成员的方法来访问私有成员(由于这些方法不同于普通的公用方法,它们通常被称为特权方法)。因此,在 Person 的公用方法中,仍然必须通过私有成员的特权访问器方法才能访问私有成员:


    Person.prototype.somePublicMethod = function() {
        // doesn’t work!
        // alert(this.name);
        // this one below works
        alert(this.getName());
    };

     

    Douglas Crockford 是著名的发现(或者也许是发布)使用闭包来模拟私有成员这一技术的第一人。他的网站 javascript.crockford.com 包含有关 JavaScript. 的丰富信息,任何对 JavaScript. 感兴趣的开发人员都应当仔细研读。

     

    从类继承
    到这里,我们已经了解了构造函数和原型对象如何使您在 JavaScript. 中模拟类。您已经看到,原型链可以确保所有对象都有 Object.prototype 的公用方法,以及如何使用闭包来模拟类的私有成员。但这里还缺少点什么。您尚未看到如何从类派生,这在 C# 中是每天必做的工作。遗憾的是,在 JavaScript. 中从类继承并非像在 C# 中键入冒号即可继承那样简单,它需要进行更多操作。另一方面,JavaScript. 非常灵活,可以有很多从类继承的方式。
    例如,有一个基类 Pet,它有一个派生类 Dog,如图A4 所示。这个在 JavaScript. 中如何实现呢?Pet 类很容易。您已经看见如何实现它了:

    图A4-类图

     


    // class Pet
    function Pet(name) {
        this.getName = function() { return name; };
        this.setName = function(newName) { name = newName; };
    }

    Pet.prototype.toString = function() {
        return “This pet’s name is: “ + this.getName();
    };
    // end of class Pet

    var parrotty = new Pet(“Parrotty the Parrot”);
    alert(parrotty);

     

    现在,如何创建从 Pet 派生的类 Dog 呢?在图A4 中可以看到,Dog 有另一个属性 breed,它改写了 Pet 的 toString 方法(注意,JavaScript. 的约定是方法和属性名称使用 camel 大小写,而不是在 C# 中建议的 Pascal 大小写)。代码段B3 显示如何这样做。

    代码段B3-从PET类派生


    // class Dog : Pet
    // public Dog(string name, string breed)
    function Dog(name, breed) {
        // think Dog : base(name)
        Pet.call(this, name);
        this.getBreed = function() { return breed; };
        // Breed doesn’t change, obviously! It’s read only.
        // this.setBreed = function(newBreed) { name = newName; };
    }

    // this makes Dog.prototype inherits
    // from Pet.prototype
    Dog.prototype = new Pet();

    // remember that Pet.prototype.constructor
    // points to Pet. We want our Dog instances’
    // constructor to point to Dog.
    Dog.prototype.constructor = Dog;

    // Now we override Pet.prototype.toString
    Dog.prototype.toString = function() {
        return “This dog’s name is: “ + this.getName() +
            “, and its breed is: “ + this.getBreed();
    };
    // end of class Dog

    var dog = new Dog(“Buddy”, “Great Dane”);
    // test the new toString()
    alert(dog);

    // Testing instanceof (similar to the is operator)
    // (dog is Dog)? yes
    alert(dog instanceof Dog);
    // (dog is Pet)? yes
    alert(dog instanceof Pet);
    // (dog is Object)? yes
    alert(dog instanceof Object);

     

    所使用的原型 — 替换技巧正确设置了原型链,因此假如使用 C#,测试的实例将按预期运行。而且,特权方法仍然会按预期运行。

     

    模拟命名空间
    在 C++ 和 C# 中,命名空间用于尽可能地减少名称冲突。例如,在 .NET Framework 中,命名空间有助于将 Microsoft.Build.Task.Message 类与 System.Messaging.Message 区分开来。JavaScript. 没有任何特定语言功能来支持命名空间,但很容易使用对象来模拟命名空间。如果要创建一个 JavaScript. 库,则可以将它们包装在命名空间内,而不需要定义全局函数和类,如下所示:

    var MSDNMagNS = {};

    MSDNMagNS.Pet = function(name) { // code here };
    MSDNMagNS.Pet.prototype.toString = function() { // code };

    var pet = new MSDNMagNS.Pet(“Yammer”);

     

    命名空间的一个级别可能不是唯一的,因此可以创建嵌套的命名空间:


    var MSDNMagNS = {};
    // nested namespace “Examples”
    MSDNMagNS.Examples = {};

    MSDNMagNS.Examples.Pet = function(name) { // code };
    MSDNMagNS.Examples.Pet.prototype.toString = function() { // code };

    var pet = new MSDNMagNS.Examples.Pet(“Yammer”);

     

    可以想象,键入这些冗长的嵌套命名空间会让人很累。 幸运的是,库用户可以很容易地为命名空间指定更短的别名:


    // MSDNMagNS.Examples and Pet definition...

    // think “using Eg = MSDNMagNS.Examples;”
    var Eg = MSDNMagNS.Examples;
    var pet = new Eg.Pet(“Yammer”);
    alert(pet);

     

    如果看一下 Microsoft AJAX 库的源代码,就会发现库的作者使用了类似的技术来实现命名空间(请参阅静态方法 Type.registerNamespace 的实现)。有关详细信息,请参与侧栏“OOP 和 ASP.NET AJAX”。

    应当这样编写 JavaScript. 代码吗?
    您已经看见 JavaScript. 可以很好地支持面向对象的编程。尽管它是一种基于原型的语言,但它的灵活性和强大功能可以满足在其他流行语言中常见的基于类的编程风格。但问题是:是否应当这样编写 JavaScript. 代码?在 JavaScript. 中的编程方式是否应与 C# 或 C++ 中的编码方式相同?是否有更聪明的方式来模拟 JavaScript. 中没有的功能?每种编程语言都各不相同,一种语言的最佳做法,对另一种语言而言则可能并非最佳。
    在 JavaScript. 中,您已看到对象继承对象(与类继承类不同)。因此,使用静态继承层次结构建立很多类的方式可能并不适合 JavaScript。也许,就像 Douglas Crockford 在他的文章 Prototypal Inheritance in JavaScript. 中说的那样,JavaScript. 编程方式是建立原型对象,并使用下面的简单对象函数建立新的对象,而后者则继承原始对象:

    function object(o) {
            function F() {}
            F.prototype = o;
            return new F();
        }

     

    然后,由于 JavaScript. 中的对象是可延展的,因此可以方便地在创建对象之后,根据需要用新字段和新方法增大对象。

    这的确很好,但它不可否认的是,全世界大多数开发人员更熟悉基于类的编程。实际上,基于类的编程也会在这里出现。按照即将颁发的 ECMA-262 规范第 4 版(ECMA-262 是 JavaScript. 的官方规范),JavaScript. 2.0 将拥有真正的类。因此,JavaScript. 正在发展成为基于类的语言。但是,数年之后 JavaScript. 2.0 才可能会被广泛使用。同时,必须清楚当前的 JavaScript. 完全可以用基于原型的风格和基于类的风格读取和写入 JavaScript. 代码。

     

    ...更多内容请看下篇文章

     

    四、作者总结

      面向对象的JAVASCRIPT编程技术极大的拓展了JAVASCRIPT的应用。对WEB2.0的发展起到了关键性的作用。作为新一代的IT农民工,学习掌握这门奇特的语言将在未来的工作中受益匪浅。

          随着交互式胖客户端 AJAX 应用程序的广泛使用,越来越多的程序员开始学习和使用JAVASCRIPT,我也将在未来一段时间内不断的学习使用JAVASCRIPT更多的与ASP.NET之间的结合。

      本文献给刚出茅庐的农民工们!希望大家在城市的建设中发挥自己最大的能量。

      本文作者:朱峰(Peter Zhu)

      发表时间:2010-05-31

     

    五、本文参考引用文章列表

          1. 使用面向对象的技术创建高级Web 应用程序 http://msdn.microsoft.com/zh-cn/magazine/cc163419.aspx

          2. 百度知道 http://baike.baidu.com/view/125370.htm

          3. OOJ-面向对象的JAVASCRIPT. - PeterZhu

     

      

     

    http://dev.firnow.com/course/1_web/javascript/Javascriptxl/20100719/448234.html

    OOJ-面向对象的JAVASCRIPT(二)



    本文继上篇文章介绍javascript. 匿名函数以及闭包的特性

    1、什么叫匿名函数?

      匿名函数:就是没有函数名的函数。

      函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途。

    1、函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式

    第一种:这也是最常规的一种


    function double( x ){

        return 2 * x; 

    }

     

    第二种:这种方法使用了Function构造函数,把参数列表和函数体都作为字符串,很不方便,不建议使用。


    var double = new Function( 'x'  , ' return 2 * x;');

     

    第三种:


    var double = function( x ) { return 2* x; }

     

    注意 '='右边的函数就是一个匿名函数,创造完毕函数后,又将该函数赋给了变量double。

    2、匿名函数的创建

    第一种方式:就是上面所讲的定义square函数,这也是最常用的方式之一。

    第二种方式:

     




    (function( x , y){

        alert( x + y);

    })(2 ,3 );//函数的自调用的形式,直接可以得出结果。

     

    这里创建了一个匿名函数(在第一个括号内),第二个括号用于调用该匿名函数,并传入参数。

     

    2、闭包

    闭包的英文单词是closure,这是JavaScript中非常重要的一部分知识,因为使用闭包可以大大减少我们的代码量,使我们的代码看上去更加清晰等等,总之功能十分强大。

    闭包的含义:闭包说白了就是函数的嵌套,内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕(这点涉及JavaScript作用域链)。

    示例一:


    function checkClosure(){

        var str = 'rain-man';

        setTimeout(

            function(){ alert( str ); } //这是一个匿名函数

        , 2000);

    }//这个函数要求延迟2秒执行。

    checkClosure();

     

    这个例子看上去十分的简单,仔细分析下它的执行过程还是有许多知识点的:checkClosure函数的执行是瞬间的(也许用时只是0.00001 毫秒),在checkClosure的函数体内创建了一个变量str,在checkClosure执行完毕之后str并没有被释放,这是因为 setTimeout内的匿名函数存在这对str的引用。待到2秒后函数体内的匿名函数被执行完毕,str才被释放。


     


    //示例二:优化代码

    function forTimeout( x, y){

        alert( x + y );

    }

    function delay( x , y  , time ){

        setTimeout( 'forTimeout(' +  x + ',' +  y + ')' , time );  

    }

    /**

     *上面的delay函数十分难以阅读,也不容易编写,但如果使用闭包就可以让代码更加清晰

    function delay( x , y , time ){

        setTimeout(

            function(){

                forTimeout( x , y )

            }        

        , time ); 

    }

    */

     

    举例

    匿名函数最大的用途是创建闭包(这是JavaScript语言的特性之一),并且还可以构建命名空间,以减少全局变量的使用。

     


    //示例三:
    var Event = {};
    (function(){
    var addEvent = function(){ /*代码的实现省略了*/ };
    function removeEvent(){}
    oEvent.addEvent = addEvent;
    oEvent.removeEvent = removeEvent;
    })();

     

     

    在这段代码中函数addEvent和removeEvent都是局部变量,但我们可以通过全局变量oEvent使用它,这就大大减少了全局变量的使用,增强了网页的安全性。

    我们要想使用此段代码:oEvent.addEvent( document.getElementById('box') , 'click' , function(){} );


     
    //示例四:

    var rainman = (function( x , y ){
        return x + y;
    })( 2 , 3 );
    /**
     *也可以写成下面的形式,因为第一个括号只是帮助我们阅读,但是不推荐使用下面这种书写格式。
    var rainman = function( x , y ){
        return x + y;
    }( 2 , 3 );
    */

     

    在这里我们创建了一个变量rainman,并通过直接调用匿名函数初始化为5,这种小技巧有时十分实用。




    示例五:

    var uter = null;
    (function(){
    var ne = 1;
    function inner (){
        one += 1;
        alert( one );
    }
    outer = inner;
    })();
    outer();    //2
    outer();    //3
    outer();    //4

     

    这段代码中的变量one是一个局部变量(因为它被定义在一个函数之内),因此外部是不可以访问的。但是这里我们创建了inner函数,inner函数是可以访问变量one的;又将全局变量outer引用了inner,所以三次调用outer会弹出递增的结果。

    注意

    一:闭包允许内层函数引用父函数中的变量,但是该变量是最终值。




    示例六:

    /**
    <body>
    <ul>
        <li>one</li>
        <li>two</li>
        <li>three</li>
        <li>one</li>
    </ul>
    */

    var lists = document.getElementsByTagName('li');
    for(var i = 0 , len = lists.length ; i < len ; i++ ){
        lists[ i ].onmouseover = function(){
            alert( i );       };
    }

     

    你会发现当鼠标移过每一个<li>元素时,总是弹出4,而不是我们期待的元素下标。这是为什么呢?注意事项里已经讲了(最终值)。显然这种解释过于简单,当mouseover事件调用监听函数时,首先在匿名函数( function(){ alert(i); })内部查找是否定义了 i,结果是没有定义;因此它会向上查找,查找结果是已经定义了,并且i的值是4(循环后的i值);所以,最终每次弹出的都是4。

     


    ################

    推荐第一个解决方法,因为第一种解决方法完全利用了闭包的优点,运用匿名函数的自调用技术。

    ################

    解决方法一:

    var lists = document.getElementsByTagName('li');
    for(var i = 0 , len = lists.length ; i < len ; i++ ){
        (function( index ){
            lists[ index ].onmouseover = function(){
                alert( index );  
            };                  
        })( i );//利用闭包的函数自调用的特性,当i的值传到匿名函数之后,匿名函数就可以自己调用,然后得出结果。
    }

    解决方法二:
    var lists = document.getElementsByTagName('li');
    for(var i = 0 , len = lists.length ; i < len ; i++ ){
        lists[ i ].$$index = i;    //通过在Dom元素上绑定$$index属性记录下标
        lists[ i ].onmouseover = function(){
            alert( this.$$index );  
        };
    }

    解决方法三:

    function eventListener( list , index ){
        list.onmouseover = function(){
            alert(index);
        };
    }

    var lists = document.getElementsByTagName('li');
    for(var i = 0 , len = lists.length ; i < len ; i++ ){
        eventListener( lists[ i ] , i );
    }




















  • java 获取从键盘输入的数据

    2011-03-15 17:20:09

    package com.sina.interf.test;

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Scanner;

    public class InputTest {

     /**
      * @param args
      */
     public static void main(String[] args) {
      // TODO Auto-generated method stub

       // 方法1 使用 scanner
      System.out.println("请输入文件名 input the file name");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        System.out.println(str);
        System.out.println(str.length());
      
      // 方法2 使用 BufferedReader
        try{     
           BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));     
           System.out.println("Please input a number:");     
           String str1=reader.readLine();  //获取字符串     
          System.out.println(str1);
          System.out.println(str1.length());
           // str1 = str1.trim();  
          // String[] arr = str1.split("\\s+");  
           //for(int i =0;i<arr.length;i++) {  
           //   arr[i]=arr[i].trim();  
           //   System.out.println(arr[i]+"  ===   "+Math.log10(Integer.valueOf(arr[i])));  
           //}  
         }catch (Exception e){     
          e.printStackTrace();     
          System.out.println("fail");  
         }
     }

    }

  • Linux下结合SecureCRT通过rz上传文件及sz下载文件

    2011-03-15 16:54:13

    1.安装软件
    aptitude search sz
    p   funcoeszz                            - script. with 65 useful mini applications       
    p   lrzsz                                - Tools for zmodem/xmodem/ymodem file transfer

    aptitude install lrzsz

    点击Session Options -> Terminal -> X/Y/Zmodem,可以设置上传及下载的目录,这样在linux下输入命令rz时后默认切换到Upload后面所指定的目录,在linux下输入命令sz 文件名时,文件默认下载到Download后面所指定的目录。



    2.上传
    debian:/home/tmp# ls
    default

    输入rz命令即可上传文件,文件上传到服务器的当前目录。
    debian:/home/tmp# rz
    rz waiting to receive.
    Starting zmodem transfer.  Press Ctrl+C to cancel.
      100%     686 bytes  686 bytes/s 00:00:01       0 Errors

    文件csft.conf是新上传到linux服务器上面的文件。
    debian:/home/tmp# ls
    csft.conf  default


    经我自己亲身测试,上传大点的文件时会导致上传中止,此时只有通过SSH Secure File Transfer Client或WinSCP之类的软件来上传了。

    3.下载
    debian:/home/software/coreseek-3.2.13/testpack/etc# ls
    csft.conf              csft_demo_python_pymssql.conf  pysource
    csft_demo_python.conf  csft_mysql.conf

    输入“sz + 文件名”即可下载,文件默认下载到SecureCRT中所指定的目录下。
    debian:/home/software/coreseek-3.2.13/testpack/etc# sz csft.conf
    rz
    Starting zmodem transfer.  Press Ctrl+C to cancel.
      100%     686 bytes  686 bytes/s 00:00:01       0 Errors

    延伸阅读:
    http://yangzhongfei.blog.163.com/blog/static/461098752010320103811488/
    http://blog.csdn.net/Channels_net/archive/2010/05/07/5567038.aspx
    http://www.baidu.com/s?wd=linux+rz+sz

     

    转自: http://iamcaihuafeng.blog.sohu.com/159696800.html

  • linux下使用scp在服务器之间拷贝文件

    2011-03-15 16:53:16

     

     

     

    CentOS, 本地服务器,ip: 192.168.1.111
    Ubuntu, 远程服务器,ip: 192.168.1.112

    1.拷贝远程服务器的目录到本地服务器
    远程服务器192.168.1.112上面/tmp目录下面有个test目录,里面有个文件名为test,内容也为test
    root@ubuntu:/tmp# cat test/test
    test

    拷贝远程服务器192.168.1.112的目录/tmp/test到当前目录下。
    [root@CentOS_Test_Server tmp]# scp -r root@192.168.1.112:/tmp/test ./
    The authenticity of host '192.168.1.112 (192.168.1.112)' can't be established.
    RSA key fingerprint is 64:76:a6:1e:23:76:ec:25:5e:c2:f3:ef:fc:ad:48:7b.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '192.168.1.112' (RSA) to the list of known hosts.
    root@192.168.1.112's password:
    test                                                                            100%    5     0.0KB/s   00:00

    注意拷贝到本地服务器后形成的目录结构为/tmp/test,而不是/tmp/tmp/test,一定要注意,这里比较容易混淆,经过自己亲自测试,再碰到类似的问题心里就有底了。
    [root@CentOS_Test_Server tmp]# ls test/
    test

    2.拷贝远程服务器的文件到本地服务器
    将1中拷贝过来的目录test删除
    rm -rf test

    [root@CentOS_Test_Server tmp]# ls -l | grep test | grep -v "grep"

    拷贝远程服务器192.168.1.112的文件/tmp/test/test到当前目录下。
    [root@CentOS_Test_Server tmp]# scp root@192.168.1.112:/tmp/test/test ./
    root@192.168.1.112's password:
    test                                                                            100%    5     0.0KB/s   00:00
    [root@CentOS_Test_Server tmp]# ls -l | grep test | grep -v "grep"
    -rw-r--r-- 1 root  root     5 Sep 22 14:07 test

    3.拷贝本地服务器的目录到远程服务器
    在/tmp目录下面建立目录dir111,在此目录下创建文件file111,内容为file111
    [root@CentOS_Test_Server tmp]# mkdir dir111
    [root@CentOS_Test_Server tmp]# echo 'content111' > dir111/file111
    [root@CentOS_Test_Server tmp]# cat dir111/file111
    content111

    拷贝本地服务器的目录dir111到远程服务器的目录/tmp下

    与上述1中类似,拷贝到远程服务器后形成的目录结构为/tmp/dir111,而不是/tmp/tmp/dir111,一定要注意,这里比较容易混淆。

    不管拷贝命令是scp -r dir111 root@192.168.1.112:/tmp还是scp -r /tmp/dir111 root@192.168.1.112:/tmp,在远程服务器上面生成的目录结构均一样,我亲自测试过了。

    [root@CentOS_Test_Server tmp]# scp -r /tmp/dir111 root@192.168.1.112:/tmp
    root@192.168.1.112's password:
    file111                                                                         100%   11     0.0KB/s   00:00    

    远程服务器192.168.1.112上面的内容
    root@ubuntu:/tmp# ls
    dir111  test  vmware-root
    root@ubuntu:/tmp# cat dir111/file111
    content111

    4.拷贝本地服务器的文件到远程服务器
    [root@CentOS_Test_Server tmp]# scp dir111/file111 root@192.168.1.112:/tmp
    root@192.168.1.112's password:
    file111                                                                         100%   11     0.0KB/s   00:00

    远程服务器192.168.1.112上面的内容
    root@ubuntu:/tmp# ls
    dir111 file111  test  vmware-root

    延伸阅读:
    http://www.baidu.com/s?wd=linux+scp
    http://www.google.com/search?hl=en&source=hp&q=linux+scp

     

    转自:  http://iamcaihuafeng.blog.sohu.com/160060113.html

  • CURL用法

    2011-03-15 16:52:06

    CURL是一个超强的命令行工具,其功能非常强大,有Linux/Unix版本的,也有Windows版本的,我平时就经常在Windows下面使用curl做一些测试,非常方便,有时用curl做测试比用浏览器做测试要快得多,方便得多。

    1.curl命令帮助选项
    C:\>curl --help
    Usage: curl [options...] <url>
    Options: (H) means HTTP/HTTPS only, (F) means FTP only
     -a/--append        Append to target file when uploading (F)
     -A/--user-agent <string> User-Agent to send to server (H)
        --anyauth       Tell curl to choose authentication method (H)
     -b/--cookie <name=string/file> Cookie string or file to read cookies from (H)
        --basic         Enable HTTP Basic Authentication (H)
     -B/--use-ascii     Use ASCII/text transfer
     -c/--cookie-jar <file> Write cookies to this file after operation (H)
     -C/--continue-at <offset> Resumed transfer offset
     -d/--data <data>   HTTP POST data (H)
        --data-ascii <data>   HTTP POST ASCII data (H)
        --data-binary <data>  HTTP POST binary data (H)
        --negotiate     Enable HTTP Negotiate Authentication (H)
        --digest        Enable HTTP Digest Authentication (H)
        --disable-eprt  Prevent curl from using EPRT or LPRT (F)
        --disable-epsv  Prevent curl from using EPSV (F)
     -D/--dump-header <file> Write the headers to this file
        --egd-file <file> EGD socket path for random data (SSL)
        --tcp-nodelay   Set the TCP_NODELAY option
     -e/--referer       Referer URL (H)
     -E/--cert <cert[:passwd]> Client certificate file and password (SSL)
        --cert-type <type> Certificate file type (DER/PEM/ENG) (SSL)
        --key <key>     Private key file name (SSL)
        --key-type <type> Private key file type (DER/PEM/ENG) (SSL)
        --pass  <pass>  Pass phrase for the private key (SSL)
        --engine <eng>  Crypto engine to use (SSL). "--engine list" for list
        --cacert <file> CA certificate to verify peer against (SSL)
        --capath <directory> CA directory (made using c_rehash) to verify
                        peer against (SSL)
        --ciphers <list> SSL ciphers to use (SSL)
        --compressed    Request compressed response (using deflate or gzip)
        --connect-timeout <seconds> Maximum time allowed for connection
        --create-dirs   Create necessary local directory hierarchy
        --crlf          Convert LF to CRLF in upload
     -f/--fail          Fail silently (no output at all) on errors (H)
        --ftp-create-dirs Create the remote dirs if not present (F)
        --ftp-pasv      Use PASV instead of PORT (F)
        --ftp-ssl       Enable SSL/TLS for the ftp transfer (F)
     -F/--form. <name=content> Specify HTTP multipart POST data (H)
        --form-string <name=string> Specify HTTP multipart POST data (H)
     -g/--globoff       Disable URL sequences and ranges using {} and []
     -G/--get           Send the -d data with a HTTP GET (H)
     -h/--help          This help text
     -H/--header <line> Custom header to pass to server (H)
     -i/--include       Include protocol headers in the output (H/F)
     -I/--head          Show document info only
     -j/--junk-session-cookies Ignore session cookies read from file (H)
        --interface <interface> Specify network interface to use
        --krb4 <level>  Enable krb4 with specified security level (F)
     -k/--insecure      Allow curl to connect to SSL sites without certs (H)
     -K/--config        Specify which config file to read
     -l/--list-only     List only names of an FTP directory (F)
        --limit-rate <rate> Limit transfer speed to this rate
     -L/--location      Follow Location: hints (H)
        --location-trusted Follow Location: and send authentication even
                        to other hostnames (H)
     -m/--max-time <seconds> Maximum time allowed for the transfer
        --max-redirs <num> Maximum number of redirects allowed (H)
        --max-filesize <bytes> Maximum file size to download (H/F)
     -M/--manual        Display the full manual
     -n/--netrc         Must read .netrc for user name and password
        --netrc-optional Use either .netrc or URL; overrides -n
        --ntlm          Enable HTTP NTLM authentication (H)
     -N/--no-buffer     Disable buffering of the output stream
     -o/--output <file> Write output to <file> instead of stdout
     -O/--remote-name   Write output to a file named as the remote file
     -p/--proxytunnel   Operate through a HTTP proxy tunnel (using CONNECT)
        --proxy-anyauth  Let curl pick proxy authentication method (H)
        --proxy-basic   Enable Basic authentication on the proxy (H)
        --proxy-digest  Enable Digest authentication on the proxy (H)
        --proxy-ntlm    Enable NTLM authentication on the proxy (H)
     -P/--ftp-port <address> Use PORT with address instead of PASV (F)
     -q                 If used as the first parameter disables .curlrc
     -Q/--quote <cmd>   Send command(s) to server before file transfer (F)
     -r/--range <range> Retrieve a byte range from a HTTP/1.1 or FTP server
        --random-file <file> File for reading random data from (SSL)
     -R/--remote-time   Set the remote file's time on the local output
        --retry <num>   Retry request <num> times if transient problems occur
        --retry-delay <seconds> When retrying, wait this many seconds between each
        --retry-max-time <seconds> Retry only within this period
     -s/--silent        Silent mode. Don't output anything
     -S/--show-error    Show error. With -s, make curl show errors when they occur
        --socks <host[:port]> Use SOCKS5 proxy on given host + port
        --stderr <file> Where to redirect stderr. - means stdout
     -t/--telnet-option <OPT=val> Set telnet option
        --trace <file>  Write a debug trace to the given file
        --trace-ascii <file> Like --trace but without the hex output
     -T/--upload-file <file> Transfer <file> to remote site
        --url <URL>     Spet URL to work with
     -u/--user <user[:password]> Set server user and password
     -U/--proxy-user <user[:password]> Set proxy user and password
     -v/--verbose       Make the operation more talkative
     -V/--version       Show version number and quit
     -w/--write-out [format] What to output after completion
     -x/--proxy <host[:port]> Use HTTP proxy on given port
     -X/--request <command> Specify request command to use
     -y/--speed-time    Time needed to trig speed-limit abort. Defaults to 30
     -Y/--speed-limit   Stop transfer if below speed-limit for 'speed-time' secs
     -z/--time-cond <time> Transfer based on a time condition
     -0/--http1.0       Use HTTP 1.0 (H)
     -1/--tlsv1         Use TLSv1 (SSL)
     -2/--sslv2         Use SSLv2 (SSL)
     -3/--sslv3         Use SSLv3 (SSL)
        --3p-quote      like -Q for the source URL for 3rd party transfer (F)
        --3p-url        source URL to activate 3rd party transfer (F)
        --3p-user       user and password for source 3rd party transfer (F)
     -4/--ipv4          Resolve name to IPv4 address
     -6/--ipv6          Resolve name to IPv6 address
     -#/--progress-bar  Display transfer progress as a progress bar

    2.查找页面源代码中的指定内容
    例如查找京东商城首页含有js的代码
    C:\>curl www.360buy.com | find "js"
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
     19  158k   19 31744    0     0  53531      0  0:00:03 --:--:--  0:00:03 65947<s
    cript type="text/javascript" src="http://misc.360buyimg.com/201006/js/jquery-1.2
    .6.pack.js"></script>
    <script. type="text/javascript" src="http://misc.360buyimg.com/201007/js/g.base.j
    s"></script>
     76  158k   76  121k    0     0  10763      0  0:00:15  0:00:11  0:00:04  7574<s
    pan><a href="http://www.360buy.com/help/ziti/jiangsu.aspx#jssq" target="_blank">
    宿迁</a></span>
     99  158k   99  158k   <span><a href="http://www.360buy.com/hel p/ziti/jiangsu.a
    spx#jsnt" target="_blank0">南通</a></span>
    100  158k  100  158k    0     0  12557      0  0:00:12  0:00:12 --:--:-- 18859
            <script. type="text/javascript" src="http://misc.360buyimg.com/201007/js/
    jd.lib.js"></script>
            <script. type="text/javascript" src="http://misc.360buyimg.com/201007/js/
    p.index.js"></script>
            <script. type="text/javascript" src="http://wl.360buy.com/wl.js" ></scrip
    t>
    document.write(unescape("%3Cscript. src='" + gaJsHost + "google-analytics.com/ga.
    js' type='text/javascript'%3E%3C/script%3E"));

    2.发送POST请求
    a.传递一个参加时可以不用双引号
    C:\>curl -d action=get_basic_info http://localhost/1616.net/apps/contact/www/mobile.php
    [{"contact_id":"3","last_update_time":"1285832338","md5":"7b682e0c3ed3b3bddb3219
    a533477224"},{"contact_id":"2","last_update_time":"1286529929","md5":"49ac542f51
    19512682b72f1d44e6fe81"},{"contact_id":"1","last_update_time":"1285830870","md5"
    :"3926cb3b0320327c46430c6539d58e5e"}]

    b.传递多个参加时必须用双引号,否则会报错
    C:\>curl -d "action=edit&contact_id=2&name=testurl" http://localhost/1616.net/apps/contact/www/mobile.php
    1

    3.下载文件
    比如下载百度首页的内容为baidu.html
    C:\>curl -o baidu.html www.baidu.com
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  6218  100  6218    0     0  61564      0 --:--:-- --:--:-- --:--:--  173k

    4.将网站产生的cookie内容写入到文件中
    用curl -c cookie.txt www.baidu.com
    产生的文件cookie.txt的内容如下:
    # Netscape HTTP Cookie File
    # http://www.netscape.com/newsref/std/cookie_spec.html
    # This file was generated by libcurl! Edit at your own risk.

    .baidu.com    TRUE    /    FALSE    2147483647    BAIDUID    3EC2799E83C7187A26CBBA67CCB71822:FG=1

    5.测试域名绑定
    输入命令
    C:\>curl -H "Host:www.baidu.com" http://202.108.22.5/
    ip地址202.108.22.5是ping域名www.baidu.com以后返回的ip地址。
    则返回百度首页所有的内容

    如果随便输入一个域名www.abc.com,而ip地址不改变,则返回内容是空的,因为域名与ip地址不匹配了,这样就可以测试域名绑定是否正确了。
    C:\>curl -H "Host:www.abc.com" http://202.108.22.5/
    curl: (52) Empty reply from server
    查看更多
    http://www.blogkid.net/archives/2668.html

    6.查看网站头信息
    C:\>curl -I www.baidu.com
    HTTP/1.1 200 OK
    Date: Fri, 08 Oct 2010 15:32:06 GMT
    Server: BWS/1.0
    Content-Length: 6218
    Content-Type: text/html;charset=gb2312
    Cache-Control: private
    Expires: Fri, 08 Oct 2010 15:32:06 GMT
    Set-Cookie: BAIDUID=6E8167DF4E04A22A0659BBA1BE2905E7:FG=1; expires=Fri, 08-Oct-4
    0 15:32:06 GMT; path=/; domain=.baidu.com
    P3P: CP=" OTI DSP COR IVA OUR IND COM "
    Connection: Keep-Alive

    7.查看URL跳转
    C:\>curl -L -I www.google.com
    HTTP/1.1 302 Found
    Location: http://www.google.com.hk/url?sa=p&hl=zh-CN&cki=PREF%3DID%3Dd0fa5e644a9
    f891c:FF%3D2:LD%3Dzh-CN:NW%3D1:TM%3D1286551973:LM%3D1286551973:S%3DPQB5WhVsd17Bq
    38k&q=http://www.google.com.hk/&ust=1286552003174649&usg=AFQjCNEwGJlI-YF0TG-6BiW
    ILw7U2qsr5Q
    Cache-Control: private
    Content-Type: text/html; charset=UTF-8
    Set-Cookie: PREF=ID=d0fa5e644a9f891c:NW=1:TM=1286551973:LM=1286551973:S=oAe_1PXO
    MrFd73Jy; expires=Sun, 07-Oct-2012 15:32:53 GMT; path=/; domain=.google.com
    Set-Cookie: NID=39=C_aIB4kMtsJnMR5kwJKF9XAhB9_sEKTp5Qe-Y6Zcu7nNVrrBmKrr-687Zhf_r
    -wVNniv4kbb8BRCBR52EN2HdxaL2lGCBxUlEWjkGdZctAqdjyzZbwTb2Hh05UgYMTIO; expires=Sat
    , 09-Apr-2011 15:32:53 GMT; path=/; domain=.google.com; HttpOnly
    Date: Fri, 08 Oct 2010 15:32:53 GMT
    Server: gws
    Content-Length: 458
    X-XSS-Protection: 1; mode=block

    HTTP/1.1 302 Found
    Location: http://www.google.com.hk/
    Cache-Control: private
    Content-Type: text/html; charset=UTF-8
    Set-Cookie: PREF=ID=d0fa5e644a9f891c:FF=2:LD=zh-CN:NW=1:TM=1286551973:LM=1286551
    973:S=PQB5WhVsd17Bq38k; expires=Sun, 07-Oct-2012 15:32:53 GMT; path=/; domain=.g
    oogle.com.hk
    Date: Fri, 08 Oct 2010 15:32:53 GMT
    Server: gws
    Content-Length: 222
    X-XSS-Protection: 1; mode=block

    HTTP/1.1 200 OK
    Date: Fri, 08 Oct 2010 15:32:53 GMT
    Expires: -1
    Cache-Control: private, max-age=0
    Content-Type: text/html; charset=Big5
    Set-Cookie: PREF=ID=3f9f2340941ea76f:NW=1:TM=1286551973:LM=1286551973:S=m9wrFWJe
    Jbk4aFK2; expires=Sun, 07-Oct-2012 15:32:53 GMT; path=/; domain=.google.com.hk
    Set-Cookie: NID=39=Mlebw-qjMEK1ABTu-W1YWoQ-Tk27--cOtwLLrDWhmU8y0fqwgeyNz06XBZsYG
    9yNwSCO_Ryzzt7q1GUXHgrM2jijr9vmLsW9ZXT2k6pve8f-IrdMyLJok4lRImiskdLR; expires=Sat
    , 09-Apr-2011 15:32:53 GMT; path=/; domain=.google.com.hk; HttpOnly
    Server: gws
    X-XSS-Protection: 1; mode=block
    Transfer-Encoding: chunked

    curl: (18) transfer closed with outstanding read data remaining

    延伸阅读:
    http://blog.chinaunix.net/u/5591/showart.php?id=1957520
    http://www.blogkid.net/archives/2668.html
    http://www.baidu.com/s?wd=curl
    http://www.google.com/search?hl=en&source=hp&q=curl
    http://blog.s135.com/post/389/

     

     

    转载自: http://iamcaihuafeng.blog.sohu.com/160735369.html

  • java- 在myeclipse中如何搭配extjs的开发环境

    2011-03-15 11:00:13

     

    myeclipse 开发 在myeclipse中如何搭配extjs的开发环境

     

     
      首先,打开myeclipse,安装开发extjs利器IDE(Spket)。选择help->Install/Update还是看图吧:
      
      点击New Remote Site...
      
      然后按OK就行了,接下来就是finish
      安装成功以后打开Window->Preferences就可以看到Spket了。
      接下来就是点开Spket->javaScript. Profiles如下图:
      
      点New...,在Name对话框中输入extjs
      
      点OK
      选中extjs点击右下方的Default,然后点Add Library,选择ExtJS
      
      然后选中ExtJS,点Add File,找到已经下载到本地的ext文件,我的是ext-2.3.0中的source中的ext.jsb
      
      打开之后可以看到下面的界面:
      
      点OK就行了。
      安装这个Spket还有一种方法如下:
      1.首先手头上要有spket-1.6.18.zip文件,从www.spket.com这个网站可以下载到。
      我现在使用的版本是1.6.18;
      2.spket-1.6.18.zip文件解压,复制文件夹所有目录,如:E:extjs\ext-2.3.0\spket-1.6.18,如果没有意外,下一级目录应该是eclipse,千万不要复制eclipse;
      3.切换到eclipse所在目录,并进入links目录(如果不存在,自己创建一个),如:
      D\Program Files\MyEclipse 6.5\eclipse\links,

    D:\Program Files\Genuitec\MyEclipse 8.x Latest\dropins  (我用的这个)

    在目录中创建一个文本文件,文件名为:"spket.1.6.18.link",用记事本打开文件,输入内容:path=E:\\extjs\\ext-2.3.0\\spket-1.6.18;
      4.重新启动MyEclipse,如果安装成功,在Window->Preferences中会出现Spket的选项。
      5.下面的图能说明问题
      
      然后,打开MyEclipsefile->new选择Web Service Project(Optional Maven Support),
      
      新建一个工程命名为(ch01):
      
      在ch01目录下的WebRoot下创建一个文件夹example:
      
      
      在example目录下新建一个helloworld.html:
      
      
      接下来这步很重要,大家要注意:
      从本地文件里复制ext-2.3.0WebRoot目录下。
      文件结构如下:
      
      下面是helloworld.html的代码: 要包含这三个类(这个很重要):
      



      而且这三个类先后的顺序不能改。大家自己弄时,路径根据自己的路径要调整,这个是很容易错的地方。
      最后,有MyEclipseMyEclipse下的
      
      ,启动服务器(可以是MyEclipse自带的tomcat,也可以是自己安装在本地的tomcat)。
      
      然后在它的右边把你的工程重新部署一下,然后打开浏览器,在地址栏输入:http://localhost:8080/ch01/example/helloworld.html回车就行了。
      运行结果:
      

      当你看到那个很炫的Hello World的时候,说明你已经成功了。

     

    来源:http://www.08.la/news2010/newshtml/YeJieDongTai/KaiFa/18233.html


    hello.html



    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>hello.html</title>
       
        <meta. http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta. http-equiv="description" content="this is my page">
        <meta. http-equiv="content-type" content="text/html; charset=UTF-8">
       
        <link rel="stylesheet" type="text/css" href="../ext-3.3.1/resources/css/ext-all.css" />
      <script. type="text/javascript" src="../ext-3.3.1/adapter/ext/ext-base.js"></script>
      <script. type="text/javascript" src="../ext-3.3.1/ext-all.js"></script>
       
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

      </head>
     
      <body>
        This is my HTML page. <br>
        <script>
        Ext.onReady(function () {
        //弹出警告对话框.
        //Ext.MessageBox.alert("hello", "Hello ,Hyey.wl Come to ExtJS World!");
        //弹出Window窗体.
        var win = new Ext.Window({ title: "Hello", width: 300, height: 200, html: '<h1>Hello Easy ExtJS Open Source Window</h1>' });
        win.show();
    });
    </script>
       
      </body>
    </html>

     

      myeclipse_开发_在myeclipse中如何搭配extjs的开发环境.rar(828 KB)



  • java-Eclipse or Meclipse 增加插件说明

    2011-03-15 10:17:26


    MyEclipse 增加插件:
     1.将下载的插件,设置目录,形式如  dir\eclipse\plugins,
       jar文件放到eclipse\plugins下面
     形式如下所示:
     D:\green_soft\mylib\tools\net.sf.jadclipse_3.3.0\eclipse\plugins\net.sf.jadclipse_3.3.0.jar

    2.修改.link文件
    path=dir
    例如:
    path=D:\\green_soft\\mylib\\tools\\ajax\\spket-1.6.18

    3.然后将 .link 文件放到 MyEclipse安装目录下:

    C:\Program Files\Genuitec\MyEclipse 8.x Latest\dropins

    4. 重新启动MyEclipse,如果安装成功,在Window->Preferences中会出现Spket的选项。

     

     

    eclipse 增加插件:

    直接将下载的jar包放至eclipse 的 plugins目录下,重启eclipse.

    D:\green_soft\eclipse\plugins


    或者采用上面myeclipse的方式


     

  • log4j详解与实战

    2011-03-01 14:10:40

    参考资料:

    http://www.javaeye.com/topic/378077
    log4j是一个非常强大的log记录软件,下面我们就来看看在项目中如何使log4j。

    1.首先当然是得到log4j的jar档,推荐使用1.2.X版,下载地址:

    http://logging.apache.org/log4j/1.2/download.html

    2. 下载jar包后将其配置到工程的lib中

    3.  在src下新建log4j配置文件---- log4j.properties  
     #debug>info>error  
     
    #1
    #log4j.rootLogger=debug,appender1  
    #log4j.appender.appender1=org.apache.log4j.ConsoleAppender  
    #log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout

    #log4j.rootLogger=debug,appender1
    #log4j.appender.appender1=org.apache.log4j.FileAppender
    #log4j.appender.appender1.File=c:/Log4JDemo02.log  
    #log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout

    #log4j.rootLogger=debug,appender1
    #log4j.appender.appender1=org.apache.log4j.FileAppender
    #log4j.appender.appender1.File=c:/Log4JDemo02.html 
    #log4j.appender.appender1.layout=org.apache.log4j.HTMLLayout

     

    #log4j.rootLogger=debug,appender1,appender2  
    log4j.appender.appender1=org.apache.log4j.ConsoleAppender  
    log4j.appender.appender1.layout=org.apache.log4j.PatternLayout  
    #log4j.appender.appender1.layout.ConversionPattern=[%d{yy/MM/dd HH:mm:ss:SSS}][%C-%M] %m%n 
    log4j.appender.appender1.layout.ConversionPattern=[%p][%d{yy/MM/dd HH:mm:ss:SSS}][%l]:%m%n
    log4j.appender.appender2=org.apache.log4j.FileAppender
    log4j.appender.appender2.File=c:/Log4JDemo06.log  
    log4j.appender.appender2.layout=org.apache.log4j.PatternLayout  
    log4j.appender.appender2.layout.ConversionPattern=[%d{HH:mm:ss:SSS}][%C-%M] -%m%n


    #sheng lue gen ,zhi she zhi te ding bao de ji bie he mu di di
    log4j.logger.com.cl.test.log=debug,appender1  
    #log4j.logger.com.cl.test=info,appender1,appender2  

    3. 新建一个测试类 LogTest1

    package com.cl.test.log;

    import org.apache.log4j.Logger ;

    public class LogTest1 {
     
     private static Logger logger = Logger.getLogger(LogTest1.class) ;

     /**
      * @param args
      */
     public static void main(String[] args) {
      // TODO Auto-generated method stub
      System.out.println("=====");
      
      new LogTest1().myMethodSay() ;
      
     }

     public void myMethodSay(){
      this.logger.debug("debug message") ;
      this.logger.info("info message") ;
      this.logger.error("error message") ;
     }
     
     
    }

     

    4. 运行测试类,查看日志输出:

     

    其他:

    通过配置文件可知,我们需要配置3个方面的内容:

    1、根目录(级别和目的地);

    2、目的地(控制台、文件等等);

    3、输出样式。

     

    mylog4j.rar(365 KB)

     

    log4jDemo.rar(374 KB)

  • 转-Loadrunner测试MySql数据库性能,测试SQL语句性能的脚本例子

    2011-03-01 14:09:31

    此代码为Loadrunner 8 通过C API类型的Vuser测试MySQL性能,或者测试sql语句性能的脚本

    view plaincopy to clipboardprint?
    /*需要的表结构如下
    CREATE TABLE `test_data` (
    `order_id` BIGINT UNSIGNED NOT NULL COMMENT 'Order numbers. Must be unique.',
    `status` BOOL NOT NULL DEFAULT '0' COMMENT 'Whether data has been used or not. A value of 0 means FALSE.',
    `date_used` DATETIME NULL COMMENT 'Date/time that the data was used.',
    UNIQUE (
        `order_id`
    )
    ) ENGINE = innodb COMMENT = 'LoadRunner test data';
    */
    Action()
    {
    int rc;  
    int db_connection; // 数据库连接
    int query_result; // 查询结果集 MYSQL_RES
    char** result_row; // 查询的数据衕
      
    char *server = "localhost";
    char *user = "root";
    char *password = "123456";
    char *database = "test";
    int port = 3306;
    int unix_socket = NULL;  
    int flags = 0;  
      
    // 找到libmysql.dll的所在位置.
    rc = lr_load_dll("C:\\Program Files\\MySQL\\MySQL Server 5.1\\bin\\libmysql.dll");
    if (rc != 0) {
        lr_error_message("Could not load libmysql.dll");
        lr_abort();
    }
      
    // 创建MySQL对象
    db_connection = mysql_init(NULL);
    if (db_connection == NULL) {
        lr_error_message("Insufficient memory");
        lr_abort();
    }
      
    // 连接到MySQL数据库
    rc = mysql_real_connect(db_connection, server, user, password, database, port, unix_socket, flags);
    if (rc == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
      
    // 向数据库插入数据
    // 此处的 {ORDER_ID} 是一个参数,简单测试时可以用一个常数代替
    lr_save_string (lr_eval_string("INSERT INTO test_data (order_id) VALUES ({ORDER_ID})"),"paramInsertQuery");  
    rc = mysql_query(db_connection, lr_eval_string("{paramInsertQuery}"));
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
      
    // 从数据库读取一个数据并显示
    rc = mysql_query(db_connection, "SELECT order_id FROM test_data WHERE status IS FALSE LIMIT 1");
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    query_result = mysql_use_result(db_connection);
    if (query_result == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    // 如果结果集包含多行数据,需要多次调用 mysql_fetch_row 直到返回NULL
    result_row = (char **)mysql_fetch_row(query_result);  
    if (result_row == NULL) {
        lr_error_message("Did not expect the result set to be empty");
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    // 保存参数,用于删除这行数据
    lr_save_string(result_row[0], "paramOrderID");
    lr_output_message("Order ID is: %s", lr_eval_string("{paramOrderID}"));
    mysql_free_result(query_result);
      
    // 在事务里更新一行数据,需要用InnoDB引擎
    rc = mysql_query(db_connection, "BEGIN"); //启动事务
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    // 使用 "FOR UPDATE" 锁住要更新的数据行
    rc = mysql_query(db_connection, "SELECT order_id FROM test_data WHERE status IS FALSE LIMIT 1 FOR UPDATE");  
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    query_result = mysql_use_result(db_connection);
    if (query_result == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    result_row = (char **)mysql_fetch_row(query_result);  
    if (result_row == NULL) {
        lr_error_message("没有查询到结果");
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    lr_save_string(result_row[0], "paramOrderID");
    lr_output_message("Order ID is: %s", lr_eval_string("{paramOrderID}"));
    mysql_free_result(query_result);
    lr_save_string(lr_eval_string("UPDATE test_data SET status=TRUE, date_used=NOW() WHERE order_id='{paramOrderID}'"),"paramUpdateQuery");
    rc = mysql_query(db_connection, lr_eval_string("{paramUpdateQuery}"));
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    rc = mysql_query(db_connection, "COMMIT"); // 提交事务
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
      
    // 再次查找数据,应该为空了,因为前面的事务更新了标志
    rc = mysql_query(db_connection, "SELECT order_id FROM test_data WHERE status IS FALSE LIMIT 1");
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    query_result = mysql_use_result(db_connection);
    if (query_result == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    result_row = (char **)mysql_fetch_row(query_result);
    if (result_row == NULL) {
        lr_output_message("Result set is empty as expected");
        mysql_free_result(query_result);
    } else {
        lr_error_message("Did not expect the result set to contain any rows");
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
      
    // 删除数据
    lr_save_string(lr_eval_string("DELETE FROM test_data WHERE order_id = '{paramOrderID}'"),"paramDeleteQuery");
    rc = mysql_query(db_connection, lr_eval_string("{paramDeleteQuery}"));
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
      
    // 释放MySQL资源
    mysql_close(db_connection);
        return 0;
    }
    /*需要的表结构如下
    CREATE TABLE `test_data` (
    `order_id` BIGINT UNSIGNED NOT NULL COMMENT 'Order numbers. Must be unique.',
    `status` BOOL NOT NULL DEFAULT '0' COMMENT 'Whether data has been used or not. A value of 0 means FALSE.',
    `date_used` DATETIME NULL COMMENT 'Date/time that the data was used.',
    UNIQUE (
        `order_id`
    )
    ) ENGINE = innodb COMMENT = 'LoadRunner test data';
    */
    Action()
    {
    int rc;
    int db_connection; // 数据库连接
    int query_result; // 查询结果集 MYSQL_RES
    char** result_row; // 查询的数据衕

    char *server = "localhost";
    char *user = "root";
    char *password = "123456";
    char *database = "test";
    int port = 3306;
    int unix_socket = NULL;
    int flags = 0;

    // 找到libmysql.dll的所在位置.
    rc = lr_load_dll("C:\\Program Files\\MySQL\\MySQL Server 5.1\\bin\\libmysql.dll");
    if (rc != 0) {
        lr_error_message("Could not load libmysql.dll");
        lr_abort();
    }

    // 创建MySQL对象
    db_connection = mysql_init(NULL);
    if (db_connection == NULL) {
        lr_error_message("Insufficient memory");
        lr_abort();
    }

    // 连接到MySQL数据库
    rc = mysql_real_connect(db_connection, server, user, password, database, port, unix_socket, flags);
    if (rc == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }

    // 向数据库插入数据
    // 此处的 {ORDER_ID} 是一个参数,简单测试时可以用一个常数代替
    lr_save_string (lr_eval_string("INSERT INTO test_data (order_id) VALUES ({ORDER_ID})"),"paramInsertQuery");
    rc = mysql_query(db_connection, lr_eval_string("{paramInsertQuery}"));
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }

    // 从数据库读取一个数据并显示
    rc = mysql_query(db_connection, "SELECT order_id FROM test_data WHERE status IS FALSE LIMIT 1");
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    query_result = mysql_use_result(db_connection);
    if (query_result == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    // 如果结果集包含多行数据,需要多次调用 mysql_fetch_row 直到返回NULL
    result_row = (char **)mysql_fetch_row(query_result);
    if (result_row == NULL) {
        lr_error_message("Did not expect the result set to be empty");
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    // 保存参数,用于删除这行数据
    lr_save_string(result_row[0], "paramOrderID");
    lr_output_message("Order ID is: %s", lr_eval_string("{paramOrderID}"));
    mysql_free_result(query_result);

    // 在事务里更新一行数据,需要用InnoDB引擎
    rc = mysql_query(db_connection, "BEGIN"); //启动事务
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    // 使用 "FOR UPDATE" 锁住要更新的数据行
    rc = mysql_query(db_connection, "SELECT order_id FROM test_data WHERE status IS FALSE LIMIT 1 FOR UPDATE");
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    query_result = mysql_use_result(db_connection);
    if (query_result == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    result_row = (char **)mysql_fetch_row(query_result);
    if (result_row == NULL) {
        lr_error_message("没有查询到结果");
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    lr_save_string(result_row[0], "paramOrderID");
    lr_output_message("Order ID is: %s", lr_eval_string("{paramOrderID}"));
    mysql_free_result(query_result);
    lr_save_string(lr_eval_string("UPDATE test_data SET status=TRUE, date_used=NOW() WHERE order_id='{paramOrderID}'"),"paramUpdateQuery");
    rc = mysql_query(db_connection, lr_eval_string("{paramUpdateQuery}"));
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    rc = mysql_query(db_connection, "COMMIT"); // 提交事务
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }

    // 再次查找数据,应该为空了,因为前面的事务更新了标志
    rc = mysql_query(db_connection, "SELECT order_id FROM test_data WHERE status IS FALSE LIMIT 1");
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }
    query_result = mysql_use_result(db_connection);
    if (query_result == NULL) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }
    result_row = (char **)mysql_fetch_row(query_result);
    if (result_row == NULL) {
        lr_output_message("Result set is empty as expected");
        mysql_free_result(query_result);
    } else {
        lr_error_message("Did not expect the result set to contain any rows");
        mysql_free_result(query_result);
        mysql_close(db_connection);
        lr_abort();
    }

    // 删除数据
    lr_save_string(lr_eval_string("DELETE FROM test_data WHERE order_id = '{paramOrderID}'"),"paramDeleteQuery");
    rc = mysql_query(db_connection, lr_eval_string("{paramDeleteQuery}"));
    if (rc != 0) {
        lr_error_message("%s", mysql_error(db_connection));
        mysql_close(db_connection);
        lr_abort();
    }

    // 释放MySQL资源
    mysql_close(db_connection);
    return 0;
    }

     

     

     

    http://www.51testing.com/?uid-128935-action-viewspace-itemid-230798

  • java - spring ioc Aop 原理代码

    2011-02-23 18:10:17

     

    com_springIOC_AOP.rar(5.34 KB)

    1.关于spring ioc

     这段时间也着实好好的看了下spring的相关书籍,对其也有了大概和初步的认识和理解,虽然之前也一直听说spring是一个非常优秀的开源框架,可一直没有机会学习和使用(是不是有点落伍了?呵呵),所以呢,这段时间就重点学习了spring(一个星期的时间当然是入门级的啦~~)

      大家一直都说spring的IOC如何如何的强大,其实我倒觉得不是IOC如何的强大,说白了IOC其实也非常的简单。我们先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对象的时候,一般都是直接使用关键字类new一个对象,那这样有什么坏处呢?其实很显然的,使用new那么就表示当前模块已经不知不觉的和new的对象耦合了,而我们通常都是更高层次的抽象模块调用底层的实现模块,这样也就产生了模块依赖于具体的实现,这样与我们JAVA中提倡的面向接口面向抽象编程是相冲突的,而且这样做也带来系统的模块架构问题。很简单的例子,我们在进行数据库操作的时候,总是业务层调用DAO层,当然我们的DAO一般都是会采用接口开发,这在一定程度上满足了松耦合,使业务逻辑层不依赖于具体的数据库DAO层。但是我们在使用的时候还是会new一个特定数据库的DAO层,这无形中也与特定的数据库绑定了,虽然我们可以使用抽象工厂模式来获取DAO实现类,但除非我们一次性把所有数据库的DAO写出来,否则在进行数据库迁移的时候我们还是得修改DAO工厂类。

      那我们使用IOC能达到什么呢?IOC,就是DAO接口的实现不再是业务逻辑层调用工厂类去获取,而是通过容器(比如spring)来自动的为我们的业务层设置DAO的实现类。这样整个过程就反过来,以前是我们业务层主动去获取DAO,而现在是DAO主动被设置到业务逻辑层中来了,这也就是反转控制的由来。通过IOC,我们就可以在不修改任何代码的情况下,无缝的实现数据库的换库迁移,当然前提还是必须得写一个实现特定数据库的DAO。我们把DAO普遍到更多的情况下,那么IOC就为我们带来更大的方便性,比如一个接口的多个实现,我们只需要配置一下就ok了,而不需要再一个个的写工厂来来获取了。这就是IOC为我们带来的模块的松耦合和应用的便利性。

      那为什么说IOC很简单呢?说白了其实就是由我们平常的new转成了使用反射来获取类的实例,相信任何人只要会用java的反射机制,那么自己写一个IOC框架也不是不可能的。比如:

    ……
    public ObjectgetInstance(String className) throws Exception
    {
      Object bj = Class.forName(className).newInstance();
      Method[] methods = obj.getClass().getMethods();
      for (Method method : methods) {
        if (method.getName().intern() == "setString") {
          method.invoke(obj, "hello world!");
        }
      }
    }
    ……

      上面的一个方法我们就很简单的使用了反射为指定的类的setString方法来设置一个hello world!字符串。其实可以看到IOC真的很简单,当然了IOC简单并不表示spring的IOC就简单,spring的IOC的功能强大就在于有一系列非常强大的配置文件维护类,它们可以维护spring配置文件中的各个类的关系,这才是spring的IOC真正强大的地方。在spring的Bean定义文件中,不仅可以为定义Bean设置属性,还支持Bean之间的继承、Bean的抽象和不同的获取方式等等功能。

      下次俺再把spring的Bean配置的相关心得和大家一起分享下,如果说的不好,大家可以提意见哦,可千万不要仍臭鸡蛋,嘿嘿~~~~ 


    2.关于spring aop

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理)
    好长时间没有用过Spring了. 突然拿起书.我都发现自己对AOP都不熟悉了.
    其实AOP的意思就是面向切面编程.
    OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多解决解决问题的方法中的共同点,是对OO思想的一种补充!
    还是拿人家经常举的一个例子讲解一下吧:
    比如说,我们现在要开发的一个应用里面有很多的业务方法,但是,我们现在要对这个方法的执行做全面监控,或部分监控.也许我们就会在要一些方法前去加上一条日志记录,
    我们写个例子看看我们最简单的解决方案
    我们先写一个接口IHello.java代码如下:
    1package sinosoft.dj.aop.staticaop;
    2
    3public interface IHello {
    4    /** *//**
    5     * 假设这是一个业务方法
    6     * @param name
    7     */
    8    void sayHello(String name);
    9}
    10
    里面有个方法,用于输入"Hello" 加传进来的姓名;我们去写个类实现IHello接口
    package sinosoft.dj.aop.staticaop;

    public class Hello implements IHello {

        public void sayHello(String name) {
            System.out.println("Hello " + name);
        }

    }

    现在我们要为这个业务方法加上日志记录的业务,我们在不改变原代码的情况下,我们会去怎么做呢?也许,你会去写一个类去实现IHello接口,并依赖Hello这个类.代码如下:
    1package sinosoft.dj.aop.staticaop;
    2
    3public class HelloProxy implements IHello {
    4    private IHello hello;
    5
    6    public HelloProxy(IHello hello) {
    7        this.hello = hello;
    8    }
    9
    10    public void sayHello(String name) {
    11        Logger.logging(Level.DEBUGE, "sayHello method start.");
    12        hello.sayHello(name);
    13        Logger.logging(Level.INFO, "sayHello method end!");
    14
    15    }
    16
    17}
    18
    其中.Logger类和Level枚举代码如下:
    Logger.java
    1package sinosoft.dj.aop.staticaop;
    2
    3import java.util.Date;
    4
    5public class Logger{
    6    /** *//**
    7     * 根据等级记录日志
    8     * @param level
    9     * @param context
    10     */
    11    public static void logging(Level level, String context) {
    12        if (level.equals(Level.INFO)) {
    13            System.out.println(new Date().toLocaleString() + " " + context);
    14        }
    15        if (level.equals(Level.DEBUGE)) {
    16            System.err.println(new Date() + " " + context);
    17        }
    18    }
    19
    20}
    21Level.java

    1package sinosoft.dj.aop.staticaop;
    2
    3public enum Level {
    4    INFO,DEBUGE;
    5}
    6那我们去写个测试类看看,代码如下:
    Test.java
    1package sinosoft.dj.aop.staticaop;
    2
    3public class Test {
    4    public static void main(String[] args) {
    5        IHello hello = new HelloProxy(new Hello());
    6        hello.sayHello("Doublej");
    7    }
    8}
    9运行以上代码我们可以得到下面结果:

    Tue Mar 04 20:57:12 CST 2008 sayHello method start.
    Hello Doublej
    2008-3-4 20:57:12 sayHello method end!
    从上面的代码我们可以看出,hello对象是被HelloProxy这个所谓的代理态所创建的.这样,如果我们以后要把日志记录的功能去掉.那我们只要把得到hello对象的代码改成以下:
    1package sinosoft.dj.aop.staticaop;
    2
    3public class Test {
    4    public static void main(String[] args) {
    5        IHello hello = new Hello();
    6        hello.sayHello("Doublej");
    7    }
    8}
    9
    上面代码,可以说是AOP最简单的实现!
    但是我们会发现一个问题,如果我们像Hello这样的类很多,那么,我们是不是要去写很多个HelloProxy这样的类呢.没错,是的.其实也是一种很麻烦的事.在jdk1.3以后.jdk跟我们提供了一个API   java.lang.reflect.InvocationHandler的类. 这个类可以让我们在JVM调用某个类的方法时动态的为些方法做些什么事.让我们把以上的代码改一下来看看效果.
    同样,我们写一个IHello的接口和一个Hello的实现类.在接口中.我们定义两个方法;代码如下 :

    IHello.java
    1package sinosoft.dj.aop.proxyaop;
    2
    3public interface IHello {
    4    /** *//**
    5     * 业务处理A方法
    6     * @param name
    7     */
    8    void sayHello(String name);
    9    /** *//**
    10     * 业务处理B方法
    11     * @param name
    12     */
    13    void sayGoogBye(String name);
    14}
    15

    Hello.java

    1package sinosoft.dj.aop.proxyaop;
    2
    3public class Hello implements IHello {
    4
    5    public void sayHello(String name) {
    6        System.out.println("Hello " + name);
    7    }
    8    public void sayGoogBye(String name) {
    9        System.out.println(name+" GoodBye!");
    10    }
    11}
    12
    我们一样的去写一个代理类.只不过.让这个类去实现java.lang.reflect.InvocationHandler接口,代码如下:
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.InvocationHandler;
    4import java.lang.reflect.Method;
    5import java.lang.reflect.Proxy;
    6
    7public class DynaProxyHello implements InvocationHandler {
    8
    9    /** *//**
    10     * 要处理的对象(也就是我们要在方法的前后加上业务逻辑的对象,如例子中的Hello)
    11     */
    12    private Object delegate;
    13
    14    /** *//**
    15     * 动态生成方法被处理过后的对象 (写法固定)
    16     *
    17     * @param delegate
    18     * @param proxy
    19     * @return
    20     */
    21    public Object bind(Object delegate) {
    22        this.delegate = delegate;
    23        return Proxy.newProxyInstance(
    24                this.delegate.getClass().getClassLoader(), this.delegate
    25                        .getClass().getInterfaces(), this);
    26    }
    27    /** *//**
    28     * 要处理的对象中的每个方法会被此方法送去JVM调用,也就是说,要处理的对象的方法只能通过此方法调用
    29     * 此方法是动态的,不是手动调用的
    30     */
    31    public Object invoke(Object proxy, Method method, Object[] args)
    32            throws Throwable {
    33        Object result = null;
    34        try {
    35            //执行原来的方法之前记录日志
    36            Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
    37           
    38            //JVM通过这条语句执行原来的方法(反射机制)
    39            result = method.invoke(this.delegate, args);
    40            //执行原来的方法之后记录日志
    41            Logger.logging(Level.INFO, method.getName() + " Method Start!");
    42        } catch (Exception e) {
    43            e.printStackTrace();
    44        }
    45        //返回方法返回值给调用者
    46        return result;
    47    }
    48
    49}
    50
    上面类中出现的Logger类和Level枚举还是和上一上例子的实现是一样的.这里就不贴出代码了.

    让我们写一个Test类去测试一下.代码如下:
    Test.java
    1package sinosoft.dj.aop.proxyaop;
    2
    3public class Test {
    4    public static void main(String[] args) {
    5        IHello hello = (IHello)new DynaProxyHello().bind(new Hello());
    6        hello.sayGoogBye("Double J");
    7        hello.sayHello("Double J");
    8       
    9    }
    10}
    11
    运行输出的结果如下:
    Tue Mar 04 21:24:03 CST 2008 sayGoogBye Method end .
    Double J GoodBye!
    2008-3-4 21:24:03 sayGoogBye Method Start!
    Tue Mar 04 21:24:03 CST 2008 sayHello Method end .
    Hello Double J
    2008-3-4 21:24:03 sayHello Method Start!
    由于线程的关系,第二个方法的开始出现在第一个方法的结束之前.这不是我们所关注的!
    从上面的例子我们看出.只要你是采用面向接口编程,那么,你的任何对象的方法执行之前要加上记录日志的操作都是可以的.他(DynaPoxyHello)自动去代理执行被代理对象(Hello)中的每一个方法,一个java.lang.reflect.InvocationHandler接口就把我们的代理对象和被代理对象解藕了.但是,我们又发现还有一个问题,这个DynaPoxyHello对象只能跟我们去在方法前后加上日志记录的操作.我们能不能把DynaPoxyHello对象和日志操作对象(Logger)解藕呢?
    结果是肯定的.让我们来分析一下我们的需求.
    我们要在被代理对象的方法前面或者后面去加上日志操作代码(或者是其它操作的代码),
    那么,我们可以抽象出一个接口,这个接口里就只有两个方法,一个是在被代理对象要执行方法之前执行的方法,我们取名为start,第二个方法就是在被代理对象执行方法之后执行的方法,我们取名为end .接口定义如下 :
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.Method;
    4
    5public interface IOperation {
    6    /** *//**
    7     * 方法执行之前的操作
    8     * @param method
    9     */
    10    void start(Method method);
    11    /** *//**
    12     * 方法执行之后的操作
    13     * @param method
    14     */
    15    void end(Method method);
    16}
    17
    我们去写一个实现上面接口的类.我们把作他真正的操作者,如下面是日志操作者的一个类:
    LoggerOperation.java
    package sinosoft.dj.aop.proxyaop;

    import java.lang.reflect.Method;

    public class LoggerOperation implements IOperation {

        public void end(Method method) {
            Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
        }

        public void start(Method method) {
            Logger.logging(Level.INFO, method.getName() + " Method Start!");
        }

    }

    然后我们要改一下代理对象DynaProxyHello中的代码.如下:
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.InvocationHandler;
    4import java.lang.reflect.Method;
    5import java.lang.reflect.Proxy;
    6
    7public class DynaProxyHello implements InvocationHandler {
    8    /** *//**
    9     * 操作者
    10     */
    11    private Object proxy;
    12    /** *//**
    13     * 要处理的对象(也就是我们要在方法的前后加上业务逻辑的对象,如例子中的Hello)
    14     */
    15    private Object delegate;
    16
    17    /** *//**
    18     * 动态生成方法被处理过后的对象 (写法固定)
    19     *
    20     * @param delegate
    21     * @param proxy
    22     * @return
    23     */
    24    public Object bind(Object delegate,Object proxy) {
    25       
    26        this.proxy = proxy;
    27        this.delegate = delegate;
    28        return Proxy.newProxyInstance(
    29                this.delegate.getClass().getClassLoader(), this.delegate
    30                        .getClass().getInterfaces(), this);
    31    }
    32    /** *//**
    33     * 要处理的对象中的每个方法会被此方法送去JVM调用,也就是说,要处理的对象的方法只能通过此方法调用
    34     * 此方法是动态的,不是手动调用的
    35     */
    36    public Object invoke(Object proxy, Method method, Object[] args)
    37            throws Throwable {
    38        Object result = null;
    39        try {
    40            //反射得到操作者的实例
    41            Class clazz = this.proxy.getClass();
    42            //反射得到操作者的Start方法
    43            Method start = clazz.getDeclaredMethod("start",
    44                    new Class[] { Method.class });
    45            //反射执行start方法
    46            start.invoke(this.proxy, new Object[] { method });
    47            //执行要处理对象的原本方法
    48            result = method.invoke(this.delegate, args);
    49//            反射得到操作者的end方法
    50            Method end = clazz.getDeclaredMethod("end",
    51                    new Class[] { Method.class });
    52//            反射执行end方法
    53            end.invoke(this.proxy, new Object[] { method });
    54
    55        } catch (Exception e) {
    56            e.printStackTrace();
    57        }
    58        return result;
    59    }
    60
    61}
    62
    然后我们把Test.java中的代码改一下.测试一下:
    package sinosoft.dj.aop.proxyaop;

    public class Test {
        public static void main(String[] args) {
            IHello hello = (IHello)new DynaProxyHello().bind(new Hello(),new LoggerOperation());
            hello.sayGoogBye("Double J");
            hello.sayHello("Double J");
           
        }
    }
    结果还是一样的吧.

    如果你想在每个方法之前加上日志记录,而不在方法后加上日志记录.你就把LoggerOperation类改成如下:
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.Method;
    4
    5public class LoggerOperation implements IOperation {
    6
    7    public void end(Method method) {
    8        //Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
    9    }
    10
    11    public void start(Method method) {
    12        Logger.logging(Level.INFO, method.getName() + " Method Start!");
    13    }
    14
    15}
    16
    运行一下.你就会发现,每个方法之后没有记录日志了. 这样,我们就把代理者和操作者解藕了!

    下面留一个问题给大家,如果我们不想让所有方法都被日志记录,我们应该怎么去解藕呢.?
    我的想法是在代理对象的public Object invoke(Object proxy, Method method, Object[] args)方法里面加上个if(),对传进来的method的名字进行判断,判断的条件存在XML里面.这样我们就可以配置文件时行解藕了.如果有兴趣的朋友可以把操作者,被代理者,都通过配置文件进行配置 ,那么就可以写一个简单的SpringAOP框架了.

  • java 动态代理范例 InvocationHandler与Proxy,拦截与代理 (转载)

    2011-02-23 17:51:05

    java 动态代理范例 InvocationHandler与Proxy,拦截与代理 (转载)

    JDK1.2以后提供了动态代理的支持,程序员通过实现java.lang.reflect.InvocationHandler接口提供一个拦截处理器,然后通过java.lang.reflect.Proxy得到一个代理对象,通过这个代理对象来执行商业方法,在商业方法被调用的同时,执行处理器会被自动调用。    

     

    Java动态代理只能对实现了接口的类生成代理,不能针对类。其实现主要是通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现。

     

         接口类源代码:

    Java代码
    1. public interface HelloWorld {   
    2.     public void sayHelloWorld();   
    3. }  

     

         实现类源代码:

    Java代码
    1. public class HelloWorldImpl implements HelloWorld {   
    2.     public void sayHelloWorld() {   
    3.         System.out.println("Hello World!");   
    4.     }   
    5. }  

     

         拦截器源代码:

    Java代码
    1. public class HelloWorldHandler implements InvocationHandler {   
    2.     //目标对象   
    3.     private Object targetObject;   
    4.        
    5.     public HelloWorldHandler(Object targetObject){   
    6.         this.targetObject = targetObject;   
    7.     }   
    8.        
    9.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
    10.         System.out.println("方法调用前。。。");   
    11.   
    12.         Object result = method.invoke(this.targetObject, args);   
    13.   
    14.         System.out.println("方法调用结束");   
    15.            
    16.         return result;   
    17.     }   
    18. }  

     

         测试代码:

    Java代码
    1. public class HelloWorldTest {   
    2.     public static void main(String[] args) {   
    3.         //业务对象   
    4.         HelloWorld obj = new HelloWorldImpl();   
    5.            
    6.         //拦截器对象   
    7.         HelloWorldHandler handler = new HelloWorldHandler(obj);   
    8.            
    9.         //返回业务对象的代理对象   
    10.         HelloWorld proxy = (HelloWorld)Proxy.newProxyInstance(   
    11.                 obj.getClass().getClassLoader(),    
    12.                 obj.getClass().getInterfaces(),    
    13.                 handler);   
    14.            
    15.         //通过代理对象执行业务对象的方法   
    16.         proxy.sayHelloWorld();   
    17.     }   
    18. }  

     

         测试结果:

    Html代码
    1. 方法调用前。。。   
    2. Hello World!   
    3. 方法调用结束  
    http://chenjumin.javaeye.com/blog/339554

     

    代码打包:

    com.rar(1.8 KB)

     

  • java中InvocationHandler 用于实现代理

    2011-02-23 15:03:25

     

    java中InvocationHandler 用于实现代理

    InvocationHandler 用于实现代理。

    如果不用InvocationHandler接口实现代理的话,我们写代码是这样的:
    定义一个接口:

    Java code

    interface Greet
    {
        void sayHello(String name);

        void goodBye();
    }

     

    实现这个接口:

    Java code

    class GreetImpl implements Greet
    {
        public void sayHello(String name)
        {
            System.out.println("Hello " + name);
        }

        public void goodBye()
        {
            System.out.println("Good bye.");
        }
    }

     

    实现一个代理类

    Java code

    public class SimpleProxy implements Greet
    {
        private Greet greet = null;

        SimpleProxy(Greet greet)
        {
            this.greet = greet;
        }

        public void sayHello(String name)
        {
            System.out.println("--before method sayHello");
            greet.sayHello(name);
            System.out.println("--after method sayHello");
        }

        public void goodBye()
        {
            System.out.println("--before method goodBye");
            greet.goodBye();
            System.out.println("--after method goodBye");
        }

        /**
         * @param args
         */
        public static void main(String[] args)
        {        Greet tmp = new GreetImpl();        //生成代理
            Greet greet = new SimpleProxy(tmp);
         greet.sayHello("walter");
            greet.goodBye();

        }
    }

    ===============================================================================

    代理其实没什么的,再看看如果实现了InvocationHandler接口,
    我们怎样实现代理。
    还是要实现原来的Greet接口。
    接口的实现还是GreetImpl。

    Java code

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;

    public class DebugProxy implements java.lang.reflect.InvocationHandler
    {
        private Object obj;

        public static Object newInstance(Object obj)
        {
            return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                    obj.getClass().getInterfaces(), new DebugProxy(obj));
        }

        private DebugProxy(Object obj)
        {
            //Greet接口的實現:GreetImpl
            this.obj = obj;
        }

         //Method m:調用的方法
       //Object[] args:方法要傳入的參數     //invoke实现对GreetImpl中方法的调用,同时也可以在这里加入自己想要实现的操作,    //虽然调用原GreetImpl中的方法重要,但我想这里更看重的是通过自定义处理实现GreetImpl中没有的功能
        public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
        {
            Object result;
            try
            {
                //自定義的處理
                System.out.println("--before method " + m.getName());
                //調用GreetImpl中方法
                result = m.invoke(obj, args);
            }catch(InvocationTargetException e)
            {
                throw e.getTargetException();
            }catch(Exception e)
            {
                throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
            }finally
            {
                System.out.println("--after method " + m.getName());
            }
            return result;
        }

        /**
         * @param args
         */
        public static void main(String[] args)
        {
            Greet tmp = new GreetImpl();
           
            Greet greet = (Greet) DebugProxy.newInstance(tmp);
               //生成的greet和tmp有相同的hashCode
               //通过DebugProxy构造的greet比原temp拥有更多功能
           greet.sayHello("walter");
               greet.goodBye();
        }
    }

    转自:http://blog.csdn.net/aladdinty/archive/2009/03/11/3982007.aspx

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jbgtwang/archive/2009/08/14/4446426.aspx

  • 留空

    2011-02-23 15:01:47

    httpunit+Junit/TestNG 进行接口测试/http测试 留空。
  • java String的equals,intern方法 (转载)

    2011-02-23 13:22:01

    java String的equals,intern方法

    JAVA中的equals和==的区别

     

    ==比较的是2个对象的地址,而equals比较的是2个对象的内容。

    显然,当equals为true时,==不一定为true;

     

    基础知识的重要性,希望引起大家的重视,包括自己在内

    很多困惑和疑问而且均来自于最基础的知识

    折腾了一阵子又查了查书,终于对 String 这个特殊的对象有了点感悟

    public class TestString {

        public static void main(String[] args) {

            String s1 = "Monday";

            String s2 = "Monday";

        }

    }

    有什么问题呢?

    1. 来自 String 的忧虑

    上面这段程序中,到底有几个对象呢?

    可能很多人脱口而出:两个,s1 和 s2

    为什么?

    String 是 final 类,它的值不可变。

    看起来似乎很有道理,那么来检测一下吧,稍微改动一下程序

    就可以看到结果了:

    public class TestString {

        public static void main(String[] args) {

            String s1 = "Monday";

            String s2 = "Monday";

            if (s1 == s2)

                System.out.println("s1 == s2");

            else

                System.out.println("s1 != s2");

        }

    }

    呵呵,很多人都会说已经不止两个对象了

    编译并运行程序,输出:s1 == s2

    啊!

    为什么 s1 == s2 ?

    == 分明是在说:s1 与 s2 引用同一个 String 对象 -- "Monday"!

    2. 千变万化的 String

    再稍微改动一下程序,会有更奇怪的发现:

    public class TestString {

        public static void main(String[] args) {

            String s1 = "Monday";

            String s2 = new String("Monday");

            if (s1 == s2)

                System.out.println("s1 == s2");

            else

                System.out.println("s1 != s2");

            if (s1.equals(s2))

                System.out.println("s1 equals s2");

            else

                System.out.println("s1 not equals s2");

        }

    }

    我们将 s2 用 new 操作符创建

    程序输出:

    s1 != s2

    s1 equals s2

    嗯,很明显嘛

    s1 s2分别引用了两个"Monday"String对象

    可是为什么两段程序不一样呢?

    3. 在 String 的游泳池中游泳

    哈哈,翻了翻书终于找到了答案:

    原来,程序在运行的时候会创建一个字符串缓冲池

    当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会

    在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被

    放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1

    将 s2 引用 s1 所引用的对象"Monday"

    第二段程序中,使用了 new 操作符,他明白的告诉程序:

    “我要一个新的!不要旧的!”与是一个新的"Monday"Sting对象被创

    建在内存中。他们的值相同,但是位置不同,一个在池中游泳

    一个在岸边休息。哎呀,真是资源浪费,明明是一样的非要分开做什么呢?

    4. 继续潜水

    再次更改程序:

    public class TestString {

        public static void main(String[] args) {

            String s1 = "Monday";

            String s2 = new String("Monday");

            s2 = s2.intern();

            if (s1 == s2)

                System.out.println("s1 == s2");

            else

                System.out.println("s1 != s2");

            if (s1.equals(s2))

                System.out.println("s1 equals s2");

            else

                System.out.println("s1 not equals s2");

        }

    }

    这次加入:s2 = s2.intern();

    哇!程序输出:

    s1 == s2

    s1 equals s2

    原来,程序新建了 s2 之后,又用intern()把他打翻在了池里

    哈哈,这次 s2 和 s1 有引用了同样的对象了

    我们成功的减少了内存的占用

    5. == 与 equals() 的争斗

    String 是个对象,要对比两个不同的String对象的值是否相同

    明显的要用到 equals() 这个方法

    可是如果程序里面有那么多的String对象,有那么多次的要用到 equals ,

    哦,天哪,真慢啊

    更好的办法:

    把所有的String都intern()到缓冲池去吧

    最好在用到new的时候就进行这个操作

    String s2 = new String("Monday").intern();

    嗯,大家都在水池里泡着了吗?哈哈

    现在我可以无所顾忌的用 == 来比较 String 对象的值了

    真是爽啊,又快又方便!

     

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ameyume/archive/2010/08/16/5815756.aspx

     

    q956140151 发表于2010年12月4日 18:57:34  IP:114.250.111.*举报回复删除
    请问在什么情况下会加入到常量池中呢?ameyume 发表于2010年12月4日 19:26:52  IP:211.102.166.*举报回复删除
    回复 q956140151:那就在使用String s1 = "abc";时,会把abc加入到常量池中。还有一种情况是通过new创建的,但又执行了intern()函数后,会加入到常量池中,例如String s2 = new String("abc"); s2 = s2.intern();这时s2指向的就是常量池中的“abc”。我是这样理解的。
    q956140151 发表于2010年12月4日 21:29:19  IP:114.250.111.*举报回复删除
    回复 ameyume:String s = "ab"+"cd"; 会创建几个对象?分别在哪?对于new String("abc"); 在编译时不会将"abc"加到常量池中吗?
    ameyume 发表于2010年12月4日 22:01:05  IP:211.102.166.*举报回复删除
    回复 q956140151:如果要求没有在缓冲池中找到abcd,则在缓冲池中创建一个abcd字符串,即一个对象。 new的对象不会放在常量池中,new的是在堆中单独开辟内存。

    ameyume 发表于2010年12月4日 22:03:10  IP:211.102.166.*举报回复删除
    回复 ameyume:可参考 http://apps.hi.baidu.com/share/detail/10892143


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ameyume/archive/2010/08/16/5815756.aspx

Open Toolbar