随笔-10  评论-11  文章-20  trackbacks-0
  2011年9月23日
使用w3m上网方法:
   
   第一步,需要安装一个名为w3m的软件工具,打开终端,输入如下命令

  sudo apt-get install w3m w3m-img -y

  第二步,安装好w3m之后,在终端里面启动w3m,打开一个网址,比如w3m www.baidu.com 。现在是不是看到了只有在浏览器下面才能看到的百度首页呢?

  如果您的终端不显示中文请。安装zhcon。安装命令:

  sudo apt-get install zhcon -y

  好了,下面给出w3m的相关帮助文件。

  与vim常用命令vim常用命令集相似,h,j,k,l 可以分别用来做移动键,分别是左,下,上,右。如果你熟习vim操作的话这会是很方便的功能。 < 和 > 用来左右滚屏。

  按q就会提示你退出!

  在需要输入的文本框内按回车,下面就会出现TEXT: ,这时你可以输入你要搜索的文字。再按回车就是返回给文本框。这时再把光标移到”百度搜索”的那个按键,回车,就可以开始搜索了!

  使用 U 来重新输入需要打开的网址。

  B 返回前一个页面。

  多标签操作!

  可以使用 T 按键来打开一个新标签。

  在多个标签内切换呢? 使用 { 和 }就可以了!

  使用 ESC-t 的话会打开标签的菜单让你选择,功能类似系统中的alt-tab功能。

  C-q用于关于当前标签页。

  书签

  C-a 添加书签

  C-b 查看书签

  查找

  / 向后查找当前页面

  ? 向前查找当前页面

  n 查找下一个已查找过的关键字

  N 向前查找已查找过的关键字

  帮助

  H 以上的选项在这里都可以看到!
posted @ 2011-09-23 17:00 Soap MacTavish 阅读(9695) | 评论 (1)编辑 收藏
  2011年4月17日
   在使用SWT构建应用程序时,理解系统底层读取和调度平台GUI事件的线程模型是非常重要的,UI线程的实现方式会影响到在应用程序中使用 Java 线程时必须遵守的规则。

 

本地事件调度

        对于任何的GUI应用程序,不管所使用的是哪一种编程语言和UI工具包,背后的运行机制都是操作系统探测GUI事件并把它们放到应用程序的事件队列中去。这种机制在不同的操作系统平台中大同小异。当用户点击鼠标、键入字符、或者使窗口获得焦点,操作系统就会生成应用程序的GUI事件,例如鼠标点击、键盘输入、或窗口重绘事件。操作系统决定哪一个窗口和应用程序应该接收用户触发的每一个事件并把它放入应用程序的事件队列中。

 

        任何基于窗口的GUI应用程序的底层实现结构都是一个事件循环(event loop),应用程序初始化并运行一个循环(loop),用于从事件队列中读取GUI事件,并作出相应的反应。处理事件的工作必须迅速完成,以保证GUI应用程序能够对用户作出快速反应。

 

        UI事件触发的耗时较长的操作应该在一个单独的线程中执行,这样才能让事件循环主线程能够快速返回,获取应用程序事件队列中的下一个事件。但是,在非UI线程中访问图形界面部件和平台API 必须通过锁和串行化的机制(locking and serialization)来实现。违反这个规则的应用程序会引起系统调用失败,更严重的是锁住整个GUI系统,使GUI失去反应。

 

SWT UI 线程

        SWT 遵循系统平台所直接支持的这种线程模型,应用程序在它的主线程中运行事件循环(event loop),并在主线程中直接调度线程。UI线程就是Display 对象被创建的线程,所有其他的图形部件都必须在这个UI线程中创建。

        既然所有的处理事件的代码是在应用程序的UI线程中触发的,那么处理事件的程序代码就能够不需要任何特殊方法自由访问和调用图形部件。不过,在处理长耗时的事件操作时,需要使用多线程来实现应用程序的功能。

 

注:在非UI线程中调用任何必须在UI线程调用的程序,SWT将会触发一个 SWTException 异常。

 

SWT 应用程序的主线程,包括事件循环,其代码结构如下:

Java代码 复制代码 收藏代码
  1. public static void main (String [] args) {   
  2.    Display display = new Display ();   
  3.    Shell shell = new Shell (display);   
  4.    shell.open ();   
  5.    // start the event loop. We stop when the user has done   
  6.    // something to dispose our window.   
  7.    while (!shell.isDisposed ()) {   
  8.       if (!display.readAndDispatch ())   
  9.          display.sleep ();   
  10.    }   
  11.    display.dispose ();   
  12. }  

        创建图形部件和打开shell 窗口之后,程序读取和分发来自操作系统事件队列的事件,直到shell 窗口被销毁。如果在队列中不存在有效事件,display 进入睡眠状态,把运行机会交给其他程序。

 

        SWT 提供了在后台主线程中调用图形部件代码的访问方法。

 

运行非UI线程

         在非UI 线程中不能直接调用UI 代码,必须提供一个 Runnable对象,在Runable中调用UI代码。Display 类中的syncExec(Runnable) 和 asyncExec(Runnable) 方法用于在事件循环运行期间,在UI 线程中运行这些Runnable对象。

  • syncExec(Runnable)  当非UI 线程中的程序代码依赖于UI 代码的返回值,或者为了确保在返回到主线程之前Runnable 必须执行完成时,应该使用这个方法。SWT 将会阻塞调用线程,直到在应用程序的UI 线程中运行的这个Runnable运行结束为止。例如,一个后台线程需要基于一个窗口的当前尺寸进行某种计算,就会需要同步地运行获取窗口尺寸的代码,然后继续其后面的计算。
  • asyncExec(Runnable)  当程序需要执行一些UI 操作,但在继续执行之前不依赖这些操作必须完成的时候,应该使用这个方法。例如,后台主线程更新进度条,或者重绘一个窗口,它可以异步地发出更新或重绘的请求,并接着继续后面的处理,在这种情况下,后台主线线程的运行时间和Runnable的运行没有必然的关系。
下面的代码片段演示了使用这两个方法的方式:
Java代码 复制代码 收藏代码
  1. // do time-intensive computations   
  2. ...   
  3. // now update the UI. We don't depend on the result,   
  4. // so use async.   
  5. display.asyncExec (new Runnable () {   
  6.    public void run () {   
  7.       if (!myWindow.isDisposed())   
  8.          myWindow.redraw ();   
  9.    }   
  10. });   
  11. // now do more computations   
  12. ...  
        在使用asyncExec 的时候,在runnable 中检查图形部件是否被销毁是一个好的习惯做法,在调用asyncExec和Runnable执行期间主线程中有可能会发生其他的事情,不能保证runnable执行时图形部件当前处于什么状态。

工作台(Workbench)和多线程

        实现SWT应用程序的多线程规则非常明确,你可以控制事件循环的初始化,在应用程序中使用多线程解决复杂问题。

 

        向工作台添加插件时的工作机制要父子一些,下面是使用平台(workbench platform)UI 类的一些“规约”(Rules of engagement),随着eclipse 的不断发布,可能会出现一些例外:

  • 通常,任何添加到平台中的工作台(workbench) UI 扩展都是在工作台的UI 主线程中执行的,除非是明确地把它们添加线程中或者是后台作业(background job)中,例如后台作业进度条。
  • 如果从工作台接收到一个事件,不能保证它是在UI线程中执行的,查阅定义了监听器或事件的类的java文档,如果没有特别说明使用线程,这个类就是一个UI 相关类,可以在工作台主线程中获得和运行。
  • 同样,除非是文档明确说明,平台UI库不能视作是线程安全的。请注意,大部分平台UI类是在触发事件的调用线程中运行监听器的,平台和JFace API调用并不检查是在UI 线程中执行的,这意味着如果在非UI 线程中调用一个能够触发事件的方法,可能会引入问题。从非UI 线程中调用SWT的API,SWT会抛出 SWTException 异常。通常,除非文档中明确规定,避免在别的线程中调用平台UI 代码。
  • 如果你的插件使用多线程或工作台作业(workbench job),必须使用 Display 类的asyncExec(Runnable) 或 syncExec(Runnable) 方法,类调用任何的工作台(workbench)、JFace或SWT 的应用程序接口(API),除非是API明确说明是可以直接调用的。
  • 如果在插件中使用 JFace的IRunnableContext 接口 调用进度监视器(progress monitor),以运行一个操作,IRunnableContext 提供了一个参数来确定是不是在一个新的线程中运行操作。
附:
参考:http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/swt_threading.htm
posted @ 2011-04-17 21:58 Soap MacTavish 阅读(1304) | 评论 (0)编辑 收藏
一.概述
如果你是SWT/Jface的初学者,那么本片所描述的问题很可能是你已经碰到或者将要碰到的。
这是关于多线程开辟的问题,比较常见。

二.问题:
当你在GUI主线程开辟一个新线程,进行其它操作,并且需要更新UI控件,意外发
生了:
Exception in thread "Thread-1" java.lang.NullPointerException。

三。解决方案
使用:Display#asyncExec(Runnable)或者Display#syncExec(Runnable)。
把你的UI更新操作另开一个线程,比如:
Display.getCurrent().asyncExec(new Runnable() {
    public void run() {
        button.setText("update");
    }
};


如果其它数据处理操作耗时不长,可以把这部分代码放入到与UI更新同一个线程,
Display.getCurrent().asyncExec(new Runnable() {
    public void run() {
        //Do business action
        button.setText("update");
    }
};

如果其它数据处理耗时长,那么为了不让UI响应迟钝,应该把逻辑操作和UI更新分开:
Thread t = new Thread(new Runnable() {
    public void run() {
        //Do business action
        Display.getCurrent().asyncExec(new Runnable() {
            public void run() {
                button.setText("update");
            }
        };
       
    }

}
posted @ 2011-04-17 21:57 Soap MacTavish 阅读(302) | 评论 (0)编辑 收藏

要在后台线程里对前台界面组件进行访问.

解决方法是使用Display对象,Display对象主要负责管理事件循环和控制UI线程和其它线程之间的通信.
Display.getDefault().asyncExec(new Runnable(){
    public void run(){
    //对前台界面进行操作
    }
});
  1. package com.tr069im.ui;  
  2.  
  3. import org.eclipse.swt.SWT;  
  4. import org.eclipse.swt.layout.GridData;  
  5. import org.eclipse.swt.widgets.Button;  
  6. import org.eclipse.swt.widgets.Display;  
  7. import org.eclipse.swt.widgets.MessageBox;  
  8. import org.eclipse.swt.widgets.ProgressBar;  
  9. import org.eclipse.swt.widgets.Shell;  
  10.  
  11. /**  
  12.  * 此类通过实现SWT滚动条,说明多线程问题 .解决了后台线程访问前台界面的问题   
  13.  * @author llwbrothers  
  14.  */ 
  15. public class Login implements Runnable {  
  16.     private static Shell shell;  
  17.     private String loginResponse = "right";  
  18.     private static boolean flag = false;  
  19.  
  20.     public Login() {  
  21.  
  22.     }  
  23.  
  24.     public static void main(String[] args) {  
  25.           
  26.         final Display display = Display.getDefault();  
  27.         shell = new Shell(SWT.MIN);  
  28.         shell.setSize(290520);  
  29.         shell.setLocation(3005);  
  30.         shell.setText("SWT多线程");  
  31.  
  32.         // 添加平滑的进度条  
  33.         final ProgressBar pb1 = new ProgressBar(shell, SWT.HORIZONTAL  
  34.                 | SWT.SMOOTH);  
  35.         pb1.setBounds(7228216020);  
  36.         pb1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));  
  37.         // 显示进度条的最小值  
  38.         pb1.setMinimum(0);  
  39.         // 设置进度条的最大值  
  40.         pb1.setMaximum(30);  
  41.  
  42.         // 登录按钮  
  43.         final Button btnLogin = new Button(shell, SWT.FLAT | SWT.PUSH);  
  44.         btnLogin.setBounds(8036311136);  
  45.         btnLogin.setText("取消");  
  46.  
  47.         shell.open();  
  48.         // 异步线程处理其他数据  
  49.         display.asyncExec(new Runnable() {  
  50.             public void run() {  
  51.                 Login pl = new Login();  
  52.                 Thread t = new Thread(pl);  
  53.                 t.start();  
  54.             }  
  55.         });  
  56.         // 添加线程,在线程中处理长时间的任务,并最终反映在平滑进度条上  
  57.         Runnable runnable = new Runnable() {  
  58.             public void run() {  
  59.                 for (int i = 0; i < 30; i++) {  
  60.                     try {  
  61.                         Thread.sleep(100);  
  62.                     } catch (InterruptedException e) {  
  63.                     }  
  64.                     display.asyncExec(new Runnable() {  
  65.                         public void run() {  
  66.                             if (pb1.isDisposed())  
  67.                                 return;  
  68.                             // 进度条递增  
  69.                             pb1.setSelection(pb1.getSelection() + 1);  
  70.                         }  
  71.                     });  
  72.                     if (flag) { // 作为标志,使滚动条起作用  
  73.                         break;  
  74.                     }  
  75.                     if (i == 29) {  
  76.                         open();  
  77.                     }  
  78.                 }  
  79.             }  
  80.         };// 启动这个线程  
  81.         new Thread(runnable).start();  
  82.  
  83.         while (!shell.isDisposed()) { // 如果主窗体没有关闭  
  84.             if (!display.readAndDispatch()) { // 如果display不忙  
  85.                 display.sleep(); // 休眠  
  86.             }  
  87.         }  
  88.         display.dispose(); // 销毁display  
  89.     }  
  90.  
  91.     public void run() {  
  92.         try {  
  93.             // 收到验证信息后进行  
  94.             if (loginResponse.equals("right")) {  
  95.                 // 后台线程访问前台界面  
  96.                 Display.getDefault().asyncExec(new Runnable() {  
  97.                     public void run() {  
  98.                         flag = true;  
  99.                         Shell shell = new Shell(SWT.MIN);  
  100.                         MessageBox messageBox = new MessageBox(shell,  
  101.                                 SWT.ICON_WARNING);  
  102.                         messageBox.setMessage("用户名或密码错误!");  
  103.                         messageBox.open();  
  104.                     }  
  105.                 });  
  106.  
  107.             } else {      
  108.             }  
  109.         } catch (Exception ee) {  
  110.         }  
  111.     }  
  112.  
  113.     public static void open() {  
  114.         Display.getDefault().asyncExec(new Runnable() {  
  115.             public void run() {  
  116.                 // 进度条进行完之后,执行的程序  
  117.             }  
  118.         });  
  119.     }  
  120. }  
posted @ 2011-04-17 21:57 Soap MacTavish 阅读(1289) | 评论 (0)编辑 收藏
  2011年3月25日
S2SH框架集成步骤:

1、框架依赖jar文件
(这些jar包可以去官网自己下载,地址不在连接)

1.1 sping     所依赖工程 spring-framework-2.5.6
     dist\spring.jar          
     lib\cglib\cglib-nodep-2.1_3.jar        
     lib\jakarta-commons\commons-logging.jar        
     lib\aspectj\aspectjweaver.jar和aspectjrt.jar      lib\j2ee\common-annotations.jar

1.2 hibernate   所依赖工程 hibernate-distribution-3.3.2.GA
     hibernate3.jar
     lib\required\jta-1.1.jar        javassist-3.9.0.GA.jar        dom4j-1.6.1.jar        commons-collections-3.1.jar        antlr-2.7.6.jar        slf4j-api-1.5.8.jar
     lib\bytecode\cglib\cglib-2.2.jar
     [二级缓存可选]lib\optional\oscache\oscache-2.1.jar        同时需要把\project\etc\oscache.properties 拷贝到src 下
     [二级缓存可选]lib\optional\ehcache\ehcache-1.2.3.jar  同时需要把\project\etc\ehcache.xml
     [二级缓存可选]lib\optional\c3p0\    配置c3p0数据库连接池的使用 作用等同于apache的dbcp

     *使用hibernate注解:hibernate-annotations-3.4.0.GA\
     hibernate-annotations.jar
     lib\hibernate-commons-annotations.jar
     lib\ejb3-persistence.jar

     *若使用slf的日志还需要:slf4j-1.5.8
     slf4j-nop-1.5.8.jar

1.3 struts2  所依赖工程  struts-2.1.8.1
     lib目录下的:
        struts2-core-2.1.8.1.jar
        xwork-core-2.1.6.jar
        ognl-2.7.3.jar
            freemarker-2.3.15.jar
        commons-fileupload-1.2.1.jar
        commons-io-1.3.2.jar
        struts2-spring-plugin-2.1.8.1.jar
             aopalliance-1.0.jar
        classworlds-1.1.jar
        commons-beanutils-1.7.0.jar
        commons-chain-1.2.jar
        commons-collections-3.2.jar  在hibernate中已经引用          
        commons-digester-2.0.jar        
        commons-lang-2.3.jar
        commons-logging-1.0.4.jar  此文件在spring中已存在
        commons-logging-api-1.1.jar
        commons-validator-1.3.1.jar
        ezmorph-1.0.3.jar
        json-lib-2.1.jar 若使用json可选
        oro-2.0.8.jar
        oval-1.31.jar


2、框架的配置文件

2.1 spring框架配置文件及集成hibernate、二级缓存
        $WEB_ROOT/WEB-INF/applicationContext.xml
            src/ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
           <http://www.springframework.org/schema/beans/spring-beans-2.5.xsd>
           <http://www.springframework.org/schema/context> <http://www.springframework.org/schema/context/spring-context-2.5.xsd>
           <http://www.springframework.org/schema/aop> <http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
           <http://www.springframework.org/schema/tx> <http://www.springframework.org/schema/tx/spring-tx-2.5.xsd>">
    
    <!-- 配置数据源 -->
        <context:property-placeholder location="classpath:jdbc4mysql.properties" />
        <bean id="dataSource"
                class="org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close">
                <property name="driverClassName" value="${driverClassName}" />
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
                <!-- 连接池启动时的初始值 -->
                <property name="initialSize" value="${initialSize}" />
                <!-- 连接池的最大值 -->
                <property name="maxActive" value="${maxActive}" />
                <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
                <property name="maxIdle" value="${maxIdle}" />
                <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以保证应急 -->
                <property name="minIdle" value="${minIdle}" />
        </bean>
        
         <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
         <property name="dataSource" ref="dataSource"/>
         <property name="mappingResources">
            <list>
              <value>cn/tsp2c/sshdemo/domain/User.hbm.xml</value>
            </list>
         </property>
         <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
                hibernate.hbm2ddl.auto=update
                hibernate.show_sql=false
                hibernate.format_sql=false
                hibernate.cache.use_second_level_cache=true
                hibernate.cache.use_query_cache=false
                hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
              </value>
         </property>
         </bean>
        
    <!-- 配置事务管理器 -->
        <bean id="txManager"
                class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource" />
        </bean>
        
        <!-- spring支持两种事务声明方式:注解和xml配置,建议使用注解方式 -->
        <!-- 采用@Transactional注解方式使用事务,在dao类及方法需用注解方式标明事务方式 -->
        <tx:annotation-driven transaction-manager="txManager" />   

     <!-- 用户DAO实现,实现方式:JDBC
    <bean id="userDao" class="cn.tsp2c.sshdemo.dao.impl.UserDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    -->
    <!-- 用户DAO实现,实现方式:hibernte  -->    
    <bean id="userDao" class="cn.tsp2c.sshdemo.dao.impl.hibernate.UserDaoHibernateImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
   
     
        <!-- 用户服务bean -->
        <bean id="userService" class="cn.tsp2c.sshdemo.service.impl.UserServiceImpl" >
           <property name="userDao" ref="userDao"/>
        </bean>
        
        <!-- 用户Action bean,scope=prototype符合struts2的action生成机制 -->
    <bean id="userAction" class="cn.tsp2c.sshdemo.web.action.UserAction" scope="prototype">
        <property name="userService" ref="userService"/>
    </bean>
</beans>

其中集成hibernate需要属性文件:jdbc4mysql.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc\:mysql\://localhost\:3306/sshdemodb?useUnicode\=true&characterEncoding\=utf-8
username=root
password=1234
initialSize=1
maxActive=500
maxIdle=2
minIdle=1

需要配置hibernate的二级缓存,如使用ehcache:在src路径下加入ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
     defaultCache 设置节点为缺省的缓存策略
     maxElementsInMemory 设置内存中最大允许存在的对象数量
     eternal 设置缓存中的对象是否永远不过期
     overflowToDisk 把超出内存设定的溢出的对象存放到硬盘上
     timeToIdleSeconds 设置缓存对象空闲多长时间就过期,过期的对象会被清除掉
     timeToLiveSeconds 设置缓存对象总的存活时间
     diskPersistent 当jvm结束时是否把内存中的对象持久化到磁盘
     diskExpiryThreadIntervalSeconds 设置用于清除过期对象的监听线程的轮询时间
-->
<ehcache>
    <diskStore path="e:\cache"/>
    <defaultCache  maxElementsInMemory="1000" eternal="false" overflowToDisk="true"
        timeToIdleSeconds="120"
        timeToLiveSeconds="180"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="60"/>
        <cache name="cn.tsp2c.sshdemo.domain.User" maxElementsInMemory="100" eternal="false"
    overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="500" diskPersistent="false"/>
</ehcache>

2.2 struts2的配置文件: src/struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "<http://struts.apache.org/dtds/struts-2.0.dtd>">

<struts>
    <!-- 指定web应用的默认编码为UTF-8,功能等同于request.setCharacterEncoding() -->
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    <!-- 指定struts2的请求处理后缀,匹配*.action的所有请求 -->
    <constant name="struts.action.extension" value="action"/>
    <!-- 关闭struts2的!动态方法调用,建议使用通配符匹配方式实现动态方法调用 -->
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
    <!-- 设置浏览器是否缓存静态页面,默认为true,建议:开发阶段关闭,生产环境打开 -->
    <constant name="struts.serve.static.browserCache" value="false" />
    <!-- 当struts.xml修改时自动重新加载,默认为false。建议:开发阶段打开,生产环境关闭 -->
    <constant name="struts.configuration.xml.reload" value="true"/>
    <!-- 开发模式下打开,便于打印详细日志,生产环境下关闭 -->
    <constant name="struts.devMode" value="true" />
    <!-- 设置视图主题为css_xhtml -->
    <constant name="struts.ui.theme" value="simple" />
    <!-- 指定struts中action交由spring创建 -->
    <constant name="struts.objectFactory" value="spring"/>
    
    <package name="base" extends="struts-default">
        <global-results>
               <result name="message">/WEB-INF/page/message.jsp</result>
               <result name="error">/WEB-INF/page/error.jsp</result>
        </global-results>
    </package>
    
    <package name="user" namespace="/user" extends="base">
        <action name="login" class="cn.tsp2c.sshdemo.web.action.LoginAction" method="execute">
            <result name="success">/index.jsp</result>
            <result name="input">/login.jsp</result>
        </action>
        <action name="user_*" class="cn.tsp2c.sshdemo.web.action.UserAction" method="{1}">
            <result name="list">/userlist.jsp</result>
            <result name="add" type="redirect">/useradd.jsp</result>
        </action>
    </package>
</struts>


3、需要把spring、strusts2框架注入到web容器(hibernate框架被spring集成,和web容器没有关系。所以不需要在web.xml中配置)

web.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        <http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd>">
    <!-- 配置spring的xml文件,若配置文件有多个,可用,或空格分隔 -->
        <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>
                        /WEB-INF/applicationContext.xml
                </param-value>
        </context-param>

        <!-- web容器加载struts2配置 -->
        <filter>
                <filter-name>struts2</filter-name>
                <filter-class>
                        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
                </filter-class>
        </filter>
        <filter-mapping>
                <filter-name>struts2</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>

        <!-- web容器加载spring配置 -->
        <listener>
                <listener-class>
                        org.springframework.web.context.ContextLoaderListener
                </listener-class>
        </listener>

        <!-- web容器增加字符集转换的过滤器,由于struts2框架解决了字符集转码,此配置可以注释掉
        <filter>
                <filter-name>encoding</filter-name>
                <filter-class>
                        org.springframework.web.filter.CharacterEncodingFilter
                </filter-class>
                <init-param>
                        <param-name>encoding</param-name>
                        <param-value>UTF-8</param-value>
                </init-param>
        </filter>
        <filter-mapping>
                <filter-name>encoding</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>
    -->
        <!-- 解决hibernate的session关闭导致延迟加载异常的问题 -->
        <!--  
                <filter>
                <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
                <filter-class>
                  org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
                </filter-class>
                </filter>
                <filter-mapping>
                  <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
                  <url-pattern>/*</url-pattern>
                </filter-mapping>
        -->

        <welcome-file-list>
                <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
</web-app>

3.1 web容器集成spring

        <!-- 配置spring的xml文件,若配置文件有多个,可用,或空格分隔 -->
        <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>
                        /WEB-INF/applicationContext.xml
                </param-value>
        </context-param>

        <!-- web容器加载spring配置 -->
        <listener>
                <listener-class>
                        org.springframework.web.context.ContextLoaderListener
                </listener-class>
        </listener>


3.2 web容器集成struts2
        <!-- web容器加载struts2配置 -->
        <filter>
                <filter-name>struts2</filter-name>
                <filter-class>
                        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
                </filter-class>
        </filter>
        <filter-mapping>
                <filter-name>struts2</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>

3.3 关于在session范围内解决hibernate的延迟加载问题

<!-- 解决hibernate的session关闭导致延迟加载异常的问题 -->
<filter>
    <filter-name>HibernateSessionInViewFilter</filter-name>
    <filter-class>
      org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>HibernateSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>


4、如何使用s2sh框架实现MVC

4.1 action

struts.xml:
    <!-- 指定struts中action交由spring创建 -->
    <constant name="struts.objectFactory" value="spring"/>

<action name="user_*" class="cn.tsp2c.sshdemo.web.action.UserAction" method="{1}">
    <result name="list">/userlist.jsp</result>
    <result name="add" type="redirect">/useradd.jsp</result>
</action>

在spring中配置:
<!-- 用户Action bean,scope=prototype符合struts2的action生成机制 -->
    <bean id="userAction" class="cn.tsp2c.sshdemo.web.action.UserAction" scope="prototype">
        <property name="userService" ref="userService"/>
    </bean>

4.2 service
<!-- 用户服务bean -->
<bean id="userService" class="cn.tsp2c.sshdemo.service.impl.UserServiceImpl" >
   <property name="userDao" ref="userDao"/>
</bean>

4.3 dao
<!-- 用户DAO实现,实现方式:JDBC -->
<bean id="userDao" class="cn.tsp2c.sshdemo.dao.impl.UserDaoImpl">
    <property name="dataSource" ref="dataSource"/>
</bean>
posted @ 2011-03-25 20:18 Soap MacTavish 阅读(3089) | 评论 (1)编辑 收藏
  2011年3月22日

原文地址:http://hi.baidu.com/gg7663/blog/item/f7bfb70f74a5c1f536d122b9.html

开发项目涉及到的表太多,一个一个的写JAVA实体类很是费事。MyEclipse提供简便的方法:反向数据库 

***选择表反向的时候一次全选上,省的后面配那个发现关联表选项

步骤大致如下: 
第一步: 
window-->open Perspective-->MyEclipse Java Persistence 
操作后会出现一个视图DB Brower:MyEclipse Derby 

在空白区点击右键,新建一个数据库对象。我用的是mysql,其实我一直想用oracle之类的,只是机子内存小,又懒得倒腾别的,结果截个图吧:

左边的属性按照自己使用的数据库填就行了,左边部分是我建好以后的结果,数据库名叫shop,有个user表 是专门这次测试用的




第二步: 
新建一个WEB项目 
然后选中项目右键-->MyEclipse-->add Hibernate Capabilities 

如果需要用到在实体类上添加注释的话那么选中紧挨着的add Hibernate Annotations Support(据说现在都用annotations了就选上吧!!)

然后下一步选中一个目录存放自动生成hibernate.cfg.xml文件,一般毫无例外的放在src根目录下,下一步选中一个DB Driver中我们第一步建立的那个(对我来说是com.mysql....反正就是自己建的那个呗),然后下一步选中一个目录存放自动生成的HibernateSessionFactory工具类 ,结果出来以后我看了一下,这个hibernateSessionFactory工具类就是一个拿Session的单例,还有一些其它关闭session之类的方法,一看便知。下图是生成的配置文件:



第三步反向生成实体类 

到DB Brower中找到要反向的表选中并且点击右键--->Hibernate Reverse Enginnering

 

看选项:java src folder 源码包,不用多解释,java package——存放将要反转出来的实体类,选择目录(应该是提前建好的com.xxx.model之类的包);Create pojo<>db。。。这个选项选中,就是我们建立从表到简单java 对象(即pojo)的配置,把下面的add hibernate mapping annotations to pojo的选上,其它不管,这个选项用来“添加映射注解到pojo对象上”,它上面的那个选项用来创建xml的,据说不太用了,就用annotation吧!


这样应该就够了,下一步

看图:type Mapping要选上hibernatetypes,这样这些注解都是来自 javax.persistence.*了 (刚观察过!)

id generator 看下拉列表就知道是配置id生成策略的

那两个enable 是说映射关系发现(detection),明白了吧?英文好就是沾光,不用像我一样还得查字典了。


下一步:没啥理解不了的 动手点点就知道了



直接完成,发现代码很漂亮,注释很完美,而且肯定没有错误,几分钟都能搞定数十个表,不得不感叹myeclipse,真是个大金矿。

posted @ 2011-03-22 12:52 Soap MacTavish 阅读(1189) | 评论 (0)编辑 收藏
  2011年3月6日
 记得刚刚接触Linux的时候,自己真是一名不折不扣的菜鸟,通过一年的努力,自己可以单独操作Linux了,我将把以后遇到的比较有用的命令积累在这篇博客上。

     

      1.  Fedora 版Linux   ifconfig
           /sbin/ipconfig

      2.  设置tomcat,系统启动,同时tomcat也启来

           echo "/data/webapp/reg/bin/startup.sh">>/etc/rc.local

      3.  查看系统 Java 进程

           ps -ef|grep java

      4.  设置动态IP

           ifconfig eth0 192.168.1.101 up

      5.  在ubuntu下修改文件

           gedit /etc/profile

      6.  netstat –anput   查看端口占有情况

      7.  killall –9 java   杀死所有系统中java进程

      8.  ./startup.sh ; tail –f /data/webapp/tomcat/logs/catalina.out   启动tomcat,并且查看日志

      9.  vi编辑文件时,误写了,先按ESC 再按u ,可以恢复。

    10.  改变一个文件夹下所有文件的所有者

           chown –R xg.xg folder

    11.  tomcat 随着系统自启动

           1. 把tomcat和程序放到/home/user

           2. 改变tomcat的所有者  chown –R hans.hans tomcat

           3. echo "/home/hans/tomcat/startup.sh">>/etc/profile

    12.  还有一点要提醒修改linux文件时,一定要先备份

    13.  批量修改linux下文件的编码:

          cd /home/hans/test

          find ./ -type f -name "*.c"|while read line;do
          echo $line
          iconv -f GB2312 -t UTF-8 $line > ${line}.utf8
          mv $line ${line}.gb2312
          mv ${line}.utf8 $line
          done

    14.  vi / vim 编辑文件时,显示行号

          vim /etc/vimrc

            在末行处加上 : set number

 

 

 

 

Fedora 12 篇

    1.  Fedora 12 安装后不能远程使用CRT登录:

           ntsysv

           出现图形界面选择ssh服务就OK

    2.  Fedora 12 和 Ubuntu的安装软件有所不同

         Fedora : yum install gcc

         Ubuntu :  apt-get install gcc

    3.  VMware 全屏

         首先 Ctrl+Alt+Enter 全屏 但是linux只是占中间的屏幕,这是因为linux的分辨率与window的分辨率不一样,调整linux的分辨率和windows一样就好了。

    4.  Fedora 9 安装完后不能使用 ifconfig ,还得这样:/sbin/ifconfig 才有效

         vi /etc/profile

          if [ "$EUID" = "0" ]; then
          pathmunge /sbin
          pathmunge /usr/sbin
          pathmunge /usr/local/sbin
          fi

        修改:把第一行注释掉

        #if [ "$EUID" = "0" ]; then
          pathmunge /sbin
          pathmunge /usr/sbin
          pathmunge /usr/local/sbin
          fi

       然后重启,就好使了!         

   5.  安装中文输入法

       yum install scim* -y

posted @ 2011-03-06 10:16 Soap MacTavish 阅读(354) | 评论 (0)编辑 收藏
  2011年2月26日
     摘要:   阅读全文
posted @ 2011-02-26 11:09 Soap MacTavish 阅读(284) | 评论 (0)编辑 收藏

封装起来的方法,用到的思路是:
1.规定好排序规则,这里用的是根据第一列升序排序
2.为要排序的列添加好事件响应


1.这里是排序规则及其实现
package com.bx.ui;

import java.text.Collator;
import java.util.Locale;

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;

public class TableColumnSorter {

 public static void addNumberSorter(final Table table,
   final TableColumn column) {
  column.addListener(SWT.Selection, new Listener() {
   boolean isAscend = true; // 按照升序排序

   public void handleEvent(Event e) {
    int columnIndex = getColumnIndex(table, column);
    TableItem[] items = table.getItems();
    // 使用冒泡法进行排序
    for (int i = 1; i < items.length; i++) {
     String strvalue2 = items[i].getText(columnIndex);
     if (strvalue2.equalsIgnoreCase("")) {
      // 当遇到表格中的空项目时,就停止往下检索排序项目
      break;
     }
     for (int j = 0; j < i; j++) {
      String strvalue1 = items[j].getText(columnIndex);
      // 将字符串类型数据转化为float类型
      float numbervalue1 = Float.valueOf(strvalue1);
      float numbervalue2 = Float.valueOf(strvalue2);
      boolean isLessThan = false;
      if (numbervalue2 < numbervalue1) {
       isLessThan = true;
      }
      if ((isAscend && isLessThan)
        || (!isAscend && !isLessThan)) {
       String[] values = getTableItemText(table, items[i]);
       Object obj = items[i].getData();
       items[i].dispose();
       TableItem item = new TableItem(table, SWT.NONE, j);
       item.setText(values);
       item.setData(obj);
       items = table.getItems();
       break;
      }
     }
    }
    table.setSortColumn(column);
    table.setSortDirection((isAscend ? SWT.UP : SWT.DOWN));
    isAscend = !isAscend;
   }
  });
 }

 public static void addStringSorter(final Table table,
   final TableColumn column) {
  column.addListener(SWT.Selection, new Listener() {
   boolean isAscend = true; // 按照升序排序
   Collator comparator = Collator.getInstance(Locale.getDefault());

   public void handleEvent(Event e) {
    int columnIndex = getColumnIndex(table, column);
    TableItem[] items = table.getItems();
    // 使用冒泡法进行排序
    for (int i = 1; i < items.length; i++) {
     String str2value = items[i].getText(columnIndex);
     if (str2value.equalsIgnoreCase("")) {
      // 当遇到表格中的空项目时,就停止往下检索排序项目
      break;
     }
     for (int j = 0; j < i; j++) {
      String str1value = items[j].getText(columnIndex);
      boolean isLessThan = comparator.compare(str2value,
        str1value) < 0;
      if ((isAscend && isLessThan)
        || (!isAscend && !isLessThan)) {
       String[] values = getTableItemText(table, items[i]);
       Object obj = items[i].getData();
       items[i].dispose();
       TableItem item = new TableItem(table, SWT.NONE, j);
       item.setText(values);
       item.setData(obj);
       items = table.getItems();
       break;
      }
     }
    }
    table.setSortColumn(column);
    table.setSortDirection((isAscend ? SWT.UP : SWT.DOWN));
    isAscend = !isAscend;
   }
  });
 }

 public static int getColumnIndex(Table table, TableColumn column) {
  TableColumn[] columns = table.getColumns();
  for (int i = 0; i < columns.length; i++) {
   if (columns[i].equals(column))
    return i;
  }
  return -1;
 }

 public static String[] getTableItemText(Table table, TableItem item) {
  int count = table.getColumnCount();
  String[] strs = new String[count];
  for (int i = 0; i < count; i++) {
   strs[i] = item.getText(i);
  }
  return strs;
 }

 
 /*
  * table.getColumn(0).addSelectionListener(
     new SelectionAdapter()
     {
      public void widgetSelected(SelectionEvent e)
      {

       //调用排序文件,处理排序
       new TableColumnSorter().addStringSorter(table, table.getColumn(0));
      }
     });
  *
  */
}


2.这里在table中每列实例化的时候添加的列监听事件

/*
   *
   * 添加监听事件
   *
   */
  table.getColumn(0).addSelectionListener(new SelectionAdapter() {
   public void widgetSelected(SelectionEvent e) {

    // 调用排序文件,处理排序
    TableColumnSorter.addStringSorter(table, table
      .getColumn(0));
   }
  });



测试结果就不在截图表示
posted @ 2011-02-26 10:51 Soap MacTavish 阅读(720) | 评论 (0)编辑 收藏
  2010年10月8日
         java的核心是面向对象的思想,初学者可能一时还适应不了这种思想,下面这段代码便是关于这种思想的一次小小的应用,希望能够对刚刚接触java到的读者起到启发作用,不过本人不才,也同样希望看官中的高手们能够提出改进意见。谢谢各位。。

这是一道简单的模拟学生管理系统的小例子:

①: 首先新建一个Student类,里面包含了学生的各个属性,代码如下:

public class Student {
  
//学生的属性:int型的年龄,分数;String型的名字,等级,专业等
  private int age;    
  private int score;
  private String name;
  private String level;
  private String department;
  
  /**************属性的构造方法************/
  //通过getScore获取分数,通过setScore设置分数。
  public int getScore(){
   return score;
  }
  public void setScore(int score){
   this.score=score;
  }
  
  //通过getName获取姓名,通过setName修改姓名。
  public String getName(){
   return name;
  }
  public void setName(String name){
   this.name=name;
  }
  
  //通过getAge获取年龄,通过setAge修改年龄。
  public int getAge(){
   return age;
  }
  public void setAge(int age){
   this.age=age;
  }
  
  //通过getDepartment获取部门,通过setDepartment修改部门。
  public String getDepartment(){
   return department;
  }
  public void setDepartment(String department){
   this.department=department;
  }
  
  //级别方法
  public String getLevel(){
   return level;
  }
  public void setLevel(String level){
   this.level=level;
  }
  
  
}

注:这里其实可以加入类方法
public void Student (int age , int score , String  name , String level , String  department)
        {
                this.age = age;
                this.score = score;
                this.name = name;
                this.level = level;
                this.department = department;
        }
个人认为使用类方法可以在主函数中实例化的时候直接将参数设置好,减少代码量。


②:然后新建一个等级划分类,根据学生分数,划分a,b,c,d四个等级,并在控制台命令行中显示出来,代码如下:

public class GetScore{
 public void getScore(Student[] stuArr){
  for(int i = 0 ; i < stuArr.length ; i++)
  {
  
   if(stuArr[i] != null)
   {
    int z;
    z = stuArr[i].getScore() / 10;
/**************switch函数的应用,本人没有列出每一种的判断只是象征表示了一下,有兴趣的可以自己把分数的每种情况补全***************/
    switch(z){
    case 9:{System.out.println(stuArr[i].getName() + "是A等"); break;}
    case 8:{System.out.println(stuArr[i].getName() + "是B等"); break;}
    case 7:{System.out.println(stuArr[i].getName() + "是C等"); break;}
    default:{System.out.println(stuArr[i].getName() + "是D等");}
   }
   System.out.println(stuArr[i].getName() + "-----" + stuArr[i].getScore() + "-----" + stuArr[i].getAge());    
  }
  
 }
 }
}




③:最后新建主类,里面实例化每一个学生,并且调用等级划分类中的划分函数,代码如下:

 public class MainStu {
 public static void main(String args[]){
  Student[] stuArr= new Student[10];
  
  //实例化每一个学生并在学生类数组里添加每一个新人;
  Student s0 = new Student();
  s0.setName("Soap");
  s0.setAge(22);
  s0.setScore(60);
  s0.setDepartment("计算机");
  stuArr[0] = s0;
  
  Student s1 = new Student();
  s1.setName("Price");
  s1.setAge(21);
  s1.setScore(88);
  s1.setDepartment("计算机");
     stuArr[1] = s1;

  Student s2 = new Student();
  s2.setName("Rouch");
  s2.setAge(24);
  s2.setScore(87);
  s2.setDepartment("计算机");
  stuArr[2] = s2;
  
  Student s3 = new Student();
  s3.setName("Ghost");
  s3.setAge(20);
  s3.setScore(70);
  s3.setDepartment("计算机");
     stuArr[3] = s3;

   /*************方法的调用**********/  
     GetScore g=new GetScore();
     g.getScore(stuArr);  
}
}


希望这段小代码能够对大家有所帮助,谢谢各位的参观。

posted @ 2010-10-08 21:24 Soap MacTavish 阅读(278) | 评论 (0)编辑 收藏
仅列出标题