Java桌面应用程序发布

java桌面,java桌面应用,桌面应用发布,java,exe,jsmooth,installer,安装包

最近用Java做了一个单机桌面程序, 就是想看看用Java开发桌面程序到底能够达到什么样的程度.

通常网上介绍的开发桌面程序(这里没有特指则都指用Java开发桌面程序)都是说用工具打包成一个jar,然后通过配置MANIFAST.MF来配置主程序和第三方类库.以后就可以通过双击jar使用本地的jvm来执行.

我这里在用一些工具把jar包装成exe,再把依赖的资源文件和exe一起发布为windows安装包.
使用的工具:
ant/eclipse – 把程序打包为jar
proguard4.0beta -混淆
jsmooth0.9.9 – 把jar打包为exe
HM NIS Edit2.0.3 -制作安装包程序

一个完整的发布过程应该还包括:加密,签名,这里暂不涉及。
下面我详细的说一下这四个步骤

第一步:把程序打包为jar
首先用ant或者eclipse打包程序为可执行的jar。也就是要在MANIFEST.MF指定main class,然后如果又第三方库的话还要指定Class-Path,如:
Manifest-Version: 1.0
Main-Class: com.modofo.mobarbr.Launcher
Class-Path: lib/ibatis.jar lib/spring.jar lib/commons- logging.jar lib/quaqua.jar lib/commons-dbcp.jar lib/commons-pool.jar lib/alloy.jar

注意:
1.Manifest-Version必须要指定,否则MANIFEST.MF文件将无效,也就是和没有一样
2.Class-Path里每一个jar要以一个空格隔开
3.如果用Eclipse打包的话,最好是使用自己写一个MANIFEST.MF,而不要让Eclipse自己去生成,因为自动生成的无法设置Class-Path
4.Class-Path中的路径指的是打包好的jar包执行所在的路径的相对路径,好像有点表达的不清楚:),例如
如果你打包好的jar叫modofo.jar并放到了D盘的根目录下,那么你需要在D:/lib中放入那些第三方依赖包,这样你的jar才能执行。
(我一开始以为是要把这些也打包到jar里)
第二步:混淆
使用proguard4.0beta,这是一个很强大的优化混淆工具,使用很简单,可以用。不详细介绍。还有一个国内的Java混淆器,感觉不是很好用,可能是不会用吧。
我的程序因为用到了spring,所以混淆起来不太方便,后来也就没有混淆。看来用spring做桌面程序有点问题,DI的信息都暴露了?有没有把文本文件也混淆掉的工具呢?-这个似乎把问题搞复杂了。-为什么要混淆呢? – 2007-11-11

第三步:把jar打包为exe
jsmooth,最新版本0.9.9,
可以设置依赖包的位置,jre的位置,这样你可以同时在制作安装包时捆绑一个jre,用你随同程序发布的jre。不过这样的代价是在发布的时候把jre也打包进去,80多兆阿!
jsmooth同时支持ant,你可以把这个过程也整合到build.xml里不需要每次都手动生成

<taskdef name=”jsmoothgen” classname=”net.charabia.jsmoothgen.ant.JSmoothGen” classpath=”resources/jsmoothgen-ant.jar” /> –定义task,指定路径
<target name=”genexe” depends=”archive”>
<copy todir=”${dist.dir}/db”>
<fileset dir=”db” />
</copy>
<copy todir=”${dist.dir}/lib”>
<fileset dir=”lib” />
</copy>
<jsmoothgen project=”resources/mobarbr.jsmooth” skeletonroot=”resources/skeletons” /> –必须要指定jsmooth配置文件,是你用jsmooth的配置程序生成的文档,skeletons是jsmooth用到的骨架文件,必须要指定
</target>

打包之后的文件路径结构:
projectroot
|_dist
| |_lib/*.jar
| |_db/*.*
| |_jre/*.* (如果有jre,你需要把jre所有文件copy到这里)
| |_myapp.jar
| |_myapp.exe
|_build.xml

这个时候如果把dist下的文件做成压缩包就可以发布了,绿色且跨平台的。如果这个已经满足了要求,下面的可以不用看了 。

第四步:制作安装包程序
NSIS是一个很很牛x的制作安装程序工具,但是它是要自己编写脚本。我懒,但我知道我不是第一个懒人,所以在sf上找到了 HM NIS Edit,可以通过一个配置向导直接生成NSIS脚本,进而生成安装包,向导很简单基本不需要看帮助,试几次就应该可以用的很熟了。
生成好的安装包在安装时可以选择安装的component,可以配置jre作为可选组件,这样用户在安装你的程序时可以选择不安装jre。
NSIS还会自动帮你生成卸载程序。
这样一个 myapp-setup.exe文件就生成了,运行起来和一般的window程序几乎没有差别。(启动稍稍慢一点),但它只是在window下使用的。

此外还试用了其他的安装包程序:
advanced installer:很强大,但是收费,推荐
installjammer:开源,但安装过程不支持中文
小兵安装包制作工具:国产,但收费
NSIS开源社区最流行的打包程序,需要学习脚本,但有NIS Edit,一切就简单了。
上面的过程基本没有涉及很细节的地方,如果要细节的话每一步都需要一篇详细介绍还要截图(都说了我很懒了),我觉得最重要的是工具的使用,怎么在各种各样的工具里找到最适合你使用的。
如果有问题可以一起探讨

如何实现改变JTable中的曾选中过的cell的背景

 

2006/5/14

扩展一个JTable,增加一个List记录每次点击选择的cell,将其index记录.然后用一个Renderer,如果cell被选择过,则修改背景颜色为红色.使用时候先实例化一个MyTable,在setCellRenderer.

public class MyTable extends JTable {

private ArrayList selected;

public MyTable() {
super();
selected = new ArrayList();

}
//将选中的cell列,行数记录
public void addSelected(Point p){
if(selected.contains(p)){
selected.remove(p);
}else{
selected.add(p);
}
}

//某个cell是否被记录过

public boolean hasSelected(int row, int column) {
return selected.contains(new Point(row,column));
}

}
实现一个renderer,当cell的index在记录历史中,则修改其背景

public class MyRenderer extends DefaultTableCellRenderer{
public MyRenderer(){
super();
setHorizontalAlignment(SwingConstants.CENTER);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
MyTable mt = (MyTable)table;
if(isSelected){
mt.addSelected(new Point(row,column));
}
if(mt.hasSelected(row,column)){
this.setBackground(Color.RED);
}else{
this.setBackground(Color.WHITE);
}
return this;
}
}

啥是Spring

(最初发布在JavaResearch.org,现在整理好放到自己的地方.)

有人说spring aop+ spring ioc, 才~~~是spring
简单一点,是一个容器. 什么容器,容纳什么?是对象,或者说bean的容器.
那为什么叫轻量级容器呢?相对于EJB container,使用spring不需要写符合容器规范的代码,即容器不会”侵入”了你的代码.

这 个容器会提供你的应用(程序)中用到的所有对象,并对这些对象进行统一的生命周期管理和组装.在通常的开发中,我们在需要某个对象的时候只是 new MyObject(). 在Java中,这样没有什么不好,因为gc会打理好”善后”工作,是系统级的. 而用spring,在需要某个对象 时,只要向容器请求相应的对象,spring会找到并准备好这些对象并提供给你.她也会打理好”善后”工作,但是是在应用级的.
另一方面,spring还会帮助你打理对象之间的依赖关系.
比如原来的做法:

class A{
}
class B{
A a ;
public B(){ a = new A();}
}

而使用spring的做法
class A{
}
class B{
A a;
public B(){}
void setA(A a){this.a=a}
A getA(){return this.a}
}
(希望你不要单纯地认为spring会写很多代码)
但 从前一个方面,你可能觉得spring只是一个对象容器.从这里你就应该看出,spring是bean容器,因为spring需要你的类符合bean规 范:相应于每一个成员域,都需要提供setter和getter方法.spring要使用这些方法来注入依赖关系,也就是 dependence injection, 或者inversion of control. 我个人觉得还是di更容易理解,直到现在我还是要考虑 怎么去向别人很好的解释ioc.控制反转(倒转),我的理解是就如同上面的两个例子里看到的,依赖(控制)不在体现在代码逻辑里(如第一个例子),而是在 配置文件里,而在代码中我们只提供注入点(也就是setter和getter).

希望我对IoC的概念的讲解能够给你一些启发.
你 可能要问了,为什么我要这样做呢?原来的做法有什么不妥的地方么?没有什么不妥,只是两种理念而已,没有绝对的好还是不好,但我还是给你我的解释–我理 解的IoC的好处,希望有所帮助.通常在程序设计的时候,我们在需要某些功能时,会相应的去设计一些方法,然后根据OO去将方法和一成员变量组成一个类. 实际上,我们最终设计出的程序是:一组类的实例互相交互完成某个特定的任务.
除了一些核心的业务方法,以外我们还要做组装对象的工作.比如我有了 一个工厂,里面有很多机器,机器在开动时要装配相应的模具.那么在工厂的生产过程中, 首先我要有工厂,机器,模具这样三个类.然后我的”动作”有:装 配,开机.通常的做法我们要做装配,然后再去开机.而用spring,我们只是专注于开机.这样我们就把装配这个动作抽离出了核心的”生产过程”.当某些 机器改变了装配模具时,不在需要修改核心业务代码.这就是解耦.如:

public class Production{
public static void main(String[] args){
Factory factory = (Factory)BeanFactory.getBean(“factory”);
factory.launchProduction();
}
}

class Factory{
Machine machine1,machine2;
void launchProduction(){
machine1.start(); machine2.start();
}
// setters and getters
}

class Machine{
Tool tool;
void start(){
}
// setters and getters
}

在launchProduction()方法中只需要开动每台机器即可.而不需要每次都装配机器.装配的工作交给了别人.现在只要按下start按钮.生产就开始了!要是原来:

void launchProduction(){
machine1 = new MachineA();
machine1.setTool(new ToolA());
machine2 = new MachineB();
machine2.setTool(new ToolB());
machine1.start();
machine2.start();
}

这就是工作分工,是不是感觉轻松了许多?从此以后,我们都是面向构件去开发,而不需要过多地在代码中体现构件之间的依赖关系.

AOP
推荐你看一下<<effective enterprise java>>的第一章,对AOP有很清晰,易懂的解释.其实AOP并非很艰深晦涩的概念,但是从架构角度去理解她的重要性可能不是我这样的new fish一时半会儿可以领悟到的.
我这里只是想说,有些概念你要知道是怎么回事,但理解到多深,除了天赋以外更多的是经验和悟.所以不要心急.–像是在自我解嘲.
也许在不知不觉中你就使用了很多AOP的概念,比如servlet里的filter,比如在写一个command类时,给她的调用类在每次调用command时前后加上:preProcess和postProcess…
我不想解释太多,<<eej>>的解释已经足够.

Hope helps.

OSGi 技术

作者:OSGi.org
翻译:ZhangV 2006-03-13
原文出自:OSGi.org
原文链接:http://www.osgi.org/osgi_technology/index.asp?section=2

简介

OSGi 规范为网络化的服务定义了一个标准的,面向组件的计算环境.给网络设备添加OSGi服务平台,使之可以有能力在网络的任何地点管理软件组件的生命周期.组 件可以在运行期间被安装,更新或删除,无需打断设备的其他操作.软件组件是可以动态查找和使用其他组件的库或程序.软件组件可以通过购买或自行开发. OSGi联盟已经开发了许多标准的组件接口,诸如HTTP服务器,配置,日志管理,安全,用户管理,xml等等这些常用功能.可以从不同的提供商那里获得 这些即插即用的兼容实现.

软件组件体系正面临一个日益凸现的问题:大量需要开发和维护的配置.而标准化的OSGi组件体系极大的简化了这个配置过程.

框架
OSGi规范的核心组件是OSGi框架.他为应用提供了一个被称为包捆(bundle)标准环境.OSGi包括这样四层:
L0.执行环境
L1.模块
L2.生命周期管理
L3.服务注册表
此外还包含一个安全系统.

执行环境就是Java环境.J2SE,CDC,CLDC,MIDP等都是合法的执行环境.OSGi同时根据核心定义(foundation profile)和一个最简版本制定了一个标准的执行环境.
模块层定义了类装载策略.OSGi框架是一个强大的类装载模型.以Java为基础但加入了模块化的思想.在Java中,只有一个包含了所有的可用类和资源类路径.OSGi的模块层还为一个模块提供了私有类以及模块之间的连接.
生命周期层将包捆动态地安装,启动,停止,更新和卸载,包捆依赖于模块层的类装载但提供了一套API来在运行期管理所有的模块.扩展的依赖机制用于确保正确模块依赖关系.
服 务注册表为包捆提供一个互操作模型实现动态性.包捆可以通过传统的类共享来互操作,但是类共享在当动态安装和卸载代码时会表现得很不稳定.服务注册表提供 了一个易于理解的模型来在包捆之间共享对象.大量的事件被定义于处理服务之间的交互.服务如同Java对象一样,可以代表任何事物.许多服务和对象是一样 的,像http服务器,服务就是现实中的一个对象,比如一个附近的蓝牙电话.

安全是建立在Java和Java2安全模型之上.语言级的限 制避免了许多可能出现的隐患(The language by design limits many possible constructs). 比 如,病毒常用的缓冲区溢出是不可能的.访问修饰符可以限制代码的可见性.OSGi通过”允许私有类”扩展了这一模型,在标准Java中不包含这种机制. Java2安全模型提供一个易理解的模型来检查代码对资源的访问权限.OSGi加入了完全的对访问请求动态管理.

标准服务

在框架之上,OSGi联盟制定了许多服务.服务由一个Java接口定义.包捆可以实现这个接口并把实现注册到服务注册表.服务的用户可以从服务注册表中找到他,或者对服务的加入或取消做出反应.
以下各部分给出OSGi release 3服务的一个简单介绍.更多资料可以找OSGi服务平台release 3的书籍或PDF下载.要注意每个服务都是先被抽象地定义然后由不同厂商独立实现.

框架服务

OSGi 框架提供一个权限管理服务(permission admin service ),一个包管理服务(package admin servie),和一 个启动级别服务(start level service).这些服务是可选的 and direct the orperation of the Framework(不知道怎么译).
• 访问管理(Permission Admin) – 当前或将来的包捆的访问权限可以通过这个服务来操作.
• 包管理(Package Admin) – 包捆之间共享类和资源.包捆的更新可能需要系统重新更新包捆之间的依赖关系.该服务提供系统实际包的共享状态并刷新共享的包.如,取消或者重新计算依赖关系.
• 启动级别(Start Level) – 启动级别是一个包捆的集合,这个集合中的包捆必须一同运行或者要在其他服务启动之前初始化.启动级别服务设置当前的启动级别,制定某个包捆的启动级别,查看当前设置.

系统服务

系 统服务提供横向功能(horizontal function),这些在每个真实的系统中都是存在的.比较常见的有,日志服务 (Log Service),配置管理服务(Configuration Admin Service),设备访问服务 (Device Access Service),用户管理服务(User Admin SErvice),IO连接服务 (IO Connector Service)和参数选择服务(Preferences Service).
• 日志服务 – 信息,警告,调试信息的纪录,或者处理错误.他接收日志纪录信息然后分配他们给其他订阅了这些信息的包捆
• 配置管理服务 – 该服务提供一个易伸缩的动态模型来设置和获得配置信息
• 设备访问服务 – 设备访问是配置一个驱动器到一个新设备并自动下载实现该驱动器的包捆的机制
• 用户管理服务 – 该服务使用一个用户信息数据库(私有和公有)来鉴权和授权.
• IO连接服务 – 实现了CDC/CLDC的javax.microedition.io包作为一个服务.该服务允许包捆提供新的,可选协议方案.
• 参数选择服务 – 提供属性数据库的访问.和Windows的注册表或Java的Preferences类.

协议服务
OSGi联盟定义了以下外部协议服务:
• Http服务 – 一个servlet容器.包捆可以提供servlet.OSGi的动态更新机制服务平台使得Http服务变得非常诱人,加入新的servlet而不需要重启.

• UPnp 服务 – 通用即插即用(Universal Plug and Play)是一个正在兴起的用于用户电子设备的标准,OSGi UPnP 将一个 UPnP网络设备映射到服务注册表.或者,将一个服务映射到UPnP网络(该服务在release 3中被推荐).
• Jini服务 – Jini是一个网络协议,用于在网络上发现Jini服务并下载执行.(该服务在release 3中被推荐).

其他服务
• 关联管理服务(Wire Admin Service) – 通常包捆会自己建立查找服务的规则.但是在很多情况下,这是一个发布时需要考虑的问题.因此关联管理服务会通过一个配置文件把不同的服务连接起来.使用消费者和生产者的概念来达到对象之间的互操作.
• XML解析服务 – 允许一个包捆定位一个解析器并使用相应的属性.与JAXP兼容.

结论
OSGi规范的适用范围很广.因为它通过一个很简单的层使得同一个虚拟机的Java组件高效率的交互.通过一个扩展的安全模型来使组件运行在一个安全的环境中.通过恰当的访问限制,组件可以被重用和组合.OSGi 框架还提供了一个扩展的部署机制来让这种交互可行,安全.

各 个领域构建在OSGi之上的中间件的大量出现,这就给OSGi软件组件创造了一个很大的软件市场. The rigid definition of the OSGi Service Platform enables components that can run on a variety of devices, from very small to very big.

采用OSGi规范可以降低软件开发成本,同时提供新的商业机会.

进一步阅读
OSGi Service Platform, Release 3下载:
http://www.osgi.org/osgi_technology/download_specs2.asp?section=2
或买书:
https://secure.inventures.com/osgi/sales/R3Book_order_form.asp

OSGi联盟的技术白皮书:
http://www.osgi.org/documents/osgi_technology/osgi-sp-overview.pdf
更深入介绍OSGi的白板白皮书(whiteboard whitepaper):
http://www.osgi.org/documents/osgi_technology/whiteboard.pdf

SpringWebFlow – 重用与抽象框架

作者:Edmon Begoli May 5, 2005
翻译:ZhangV 2005-07-22
原文出自:DevX.com
原文链接:http://www.devx.com/webdev/Article/28041/0/page/1

Spring WebFlow是一个全新的Web框架,她带给我们一种全新且高度结构化的Web应用构建方法.让我们来看看她的一些特性.
Spring框架正准备推出一种新的技术.在下一个版本中(1.3,预计在2005年夏天发布)Spring将正式将Spring WebFlow整合进来.Spring WebFlow是一个及其优秀的Web开发框架,用于在Web应用内部创建和配置可重用的Web流程.

熟悉Spring的人可能先入为主地以为Spring WeFlow和SpringMVC没有什么区别.那就错了.Spring MVC是一个轻量级的Web开发框架,而Spring WebFlow 则提出一种全新的视角.她使得Web架构师们可以将精力集中在Web应用开发的抽象层次上:Web流程的逻辑结构和Web事件条件的定义.此外,她还提出许多新的概念.(稍后会介绍到)

本文将回顾这一个新框架前的一些关键概念,用一个经典的用户登录例子来分析流程标记语言的主要组成元素并向您解释为什么WebFlow如此诱人.(读者必需要有Spring 1.2基础).

Spring WebFlow 概念和组件
作为一个Web框架,WebFlow无论在理论上还是在实际开发上都有诸多优点.深厚的软件工程学架构保证了他的稳定性,同时,其组件合理,易于理解,易于使用.
事实上,它更适合中大型应用的开发,因为它的组件模型专门针对架构重用,高效管理性和可配置性进行了优化.

用例研究
本文以一个常见的web应用流程作为示例, 一个身份认证流程,讲解它的一些代码片断.一个Web认证的全过程包括:登录表单,注册表单,认证action,注册action,以及对这些action的结构修饰.这个例子用来展示那些修饰登录表单的组件的配置.

自动操作架构
Spring WebFlow以有限状态机(Finite State machine)的概念为基础.Web应用内部的用户交互行为和事务被建模为一般的状态机,这是一种非常流行的软件工程建模方法.(见图1).自动机为基础的设计是一种很好的设计方法,同时正在越来越收到应用架构的青睐 — 因为它在对Web交互行为建模时显得相对清晰且严谨.

WebFlow的核心组件
一个Spring WebFlow应用中包含一个或多个流程,通常每个流程包括执行Action的动作状态(ActionStates),显示状态(ViewStates),跳转动作(Transitions).

流程
一个流程是一个预先定义好的用户交互行为的集合,表示为一个由动作状态和显示状态构成的树,状态之间通过跳转联系.
下面的登录注册是一个webflow的例子,包含了一些典型的构件,例如loginForm,ActionState,transition.这些构件通过一个XML文件描述:
<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE webflow PUBLIC “-//SPRING//DTD WEBFLOW//EN”
“http://www.springframework.org/dtd/spring-webflow.dtd”>
<webflow id=”LoginSequence” start-state=”loginForm”>

<action-state id=”loginForm”>
<action bean=”loginFormAction”/>
<transition on=”success” to=”formView”/>
</action-state>

<view-state id=”formView” view=”enterCredentials”>
<transition on=”submit” to=”bindAndValidateForm”/>
</view-state>

<end-state id=”successView” view=”displayMain”/>
这个流程以loginForm开始,以”successView”结束(修饰主页面”displayMain” 的组件.流程可以通过XML文档配置,或者AbstractFlowBuilder的子类.

动作状态(ActionStates)

ActionStates对用户事件或其他事件进行响应.ActionStates自身又可以包含其他可执行的Action和transition.下面的代码配置了”loginForm”这个ActionState.

<action-state id=”loginForm”>
<action bean=”loginFormAction”/>
<transition on=”success” to=”formView”/>
</action-state>

动作(Actions)

Action是ActionState可以连接,重用,声明调用的最小单位.Action继承自AbstractAction类,该类实现了doExecuteAction方法.这个方法的参数:RequestContext,WebFlow(其中封装了所有流程相关的数据).loginForm动作状态通过Spring的自动装配特性调用LoginFormAction动作.doExecute
Action方法被自动调用,同时可以处理一些登录准备,预先装入等操作.

public LoginFormAction extends AbstractAction{

protected Event doExecuteAction(RequestContext context)
throws Exception{
//perform some login specific setup operations

}//end method

}//end class

显示状态(ViewState)

ViewState初始化对显示组件(jsp,tile等)的修饰操作.下面是一个ViewState的配置代码
<view-state id=”formView” view=”enterCredentials”>
<transition on=”submit” to=”bindAndValidateForm”/>
</view-state>
当来自loginForm的ActionState返回一个”success”时,这个ViewState将会被调用.它将修饰”enterCredentials”显示组件(可以是一个常见的struts forward).

跳转(Transition)

和通常的状态机一样,WebFlow定义了状态以及状态之间跳转动作.这些跳转动作很类似struts中的ActionForward.同样是负责连接两个状态.

后继动作(Continuation)

后继动作(Continuation)允许你回退并重新开始程序执行流程 — 从程序执行的角度来看是一个适时的逆流程.Continuation的概念最早来自编程语言,但是却从来没有被用于像Java,VB,C++这样主流的编程语言中.WebFlow创造性地实现了continuation.由于continuation可以用来持久和重造任何一个流程状态,从而提供给你极大的自由.

重用

WebFlow中的流程定义,如登录流程,有针对性地被结构化以便重用.他们定义封装了自己的生命周期.这些定义可以很容易的用支持Spring的其他Web组件配置重用.架构师应该识别出并定义通用的流程,如登录,搜索等以便今后的重用.
此外,Action如果正确的设计与Spring的结合,也可以被重用.他们可以同时被不同流程的action state使用.这些重用,既有应用级的又有流程级的,增强了维护性和代码可读性.

与struts结合

WebFlow与struts的结合部分地通过标准的Spring类和org.springframework.web.struts包中的一些配置.要与WebFlow相关概念(Action,ActionFlow)结合只需要注册WebFlow规格的struts action,并像普通的WebFlow action一样使用.

下面的配置代码来自struts-config.xml,描述了Struts的Action如何配置成流程的入口.注意WebFlow规格的Action类(org.springframework.web.flow.struts.FlowAction)和属性”flowId”,它们将Action与登陆流程连接起来.例子中的登录流程在Spring的应用上下文(ApplicationContext)中作为一个loginFlow的bean管理.你还需要将这个流程注册为一个由Spring管理的bean.

<!- flow actions ->
<action path=”/loginFlow”
type=”org.springframework.web.flow.struts.FlowAction”
name=”actionForm” scope=”request”
className=”org.springframework.web.flow.struts.FlowActionMapping”>
<set-property property=”flowId” value=”loginAction” />
</action>

在这个例子中还用到了Spring中的RequestProcessor(org.springframework.web.struts.BindingRequestProcessor),是Spring的自动绑定form和bean.这一特性避免再去写单独的ActionForm对象.

<controller processorClass=”org.springframework.web.struts.BindingRequestProcessor”/>

同时,它还要求一个使用工具类来自动绑定Web表单中的值到一个对象.

<plug-in className=”org.springframework.web.struts.BindingPlugin”/>

WebFlow的预发布现在可以下载,其中包含一个样例应用(“birthdate”),详细描述了这个整合过程.

如果你正在着手建立一个Web应用,Spring是一个非常不错的选择.Spring MVC非常容易上手并且可以很方便的同其他组件整合.另一方面,即将出现的Spring WebFlow将提供给你各种复杂的新特性.使你能够开发出高度重用和结构化的Web应用.如果你在开发的是一个大规模的企业应用,这一点是很重要的.这也是为什么struts如此流行.

总的来说,J2EE Web框架目前处在一种群雄逐鹿的状态,没有一个领导者.Struts是最流行的,但是它的主架构师也是主要的开发者已经抛弃了它.被称为Struts取代者的JSF目前还没有获得足够的影响力.而同时,其他的框架正在慢慢开始流行.

你也许会问,”我应该选择哪个?”Spring WebFlow出现可以让你以后再去考虑这个问题.WebFlow允许你在不需要较大改动的情况下方便的切换框架.像前面说过的,Spring WebFlow是一个抽象的框架,可以让你只专注于业务流程和重用.无论是Struts,JSF还是Spring MVC都可以作为它的业务流程实现.因此,你也就不需要马上作出上面说的那个选择了.

Shell Tips

#1 查找文件修改时间为某一段时间的文件:

touch -c 0901000007 file.start
touch file.end

find /local/Tomcat55/0/cluster/machine0/webapps/Pcclass -newer file.start ! -newer file.end > app_modified_since01Sep.txt -ls

find /jpmorgan/apps/pcclass -newer file.start ! -newer file.end > pcc_modified_since01Sep.txt -ls

#2 find records which dont contain “up to date” in the log.txt file to compile.log
cat log.txt | grep -v ‘up to date’ >> compile.log

#3 获取文件总行数
wc -l /jpmorgan/apps/pcclass/temp/1.txt | cut -c1-8
获取文件夹下文件个数:
ls /etc | wc -l

(see:http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+wc)

#4 文本替换
echo “a test” | tr t p
echo “a test” | tr aest 1234
echo “a test” | tr -d t
echo “a test” | tr ‘[:lower:]’ ‘[:upper:]’

#5 sed (Stream EDitor) 正则替换(pattern replacement)
(see:http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+sed)
replace “one” with “another”, one occurrence:
echo “Replace one word” | sed -e s/one/another/

replace all the letter in “aeiouy” with “_” – g:
echo “This is a test” | sed -e s/[aeiouy]/_/g
Th_s _s _ t_st

#6 替换文件中的某个字符串
replace all “a” in 1.txt with “b”:
way 1:echo `sed ‘s/a/b/g’ 1.txt` > 2.txt
!!!-this will lose the line separator
way 2: use awk, better way, more flexible and programatical
awk ‘{
if($0==”aaa”) {print “bbb”}
else print $0
}’ 1.txt > 2.txt

#7 tail

分析日志时,把最后1000行输出到另一个文件.使用tail命令
tail -1000 Pcclassind.log > /tmp/dhanush.log
在控制台输出日志文件(文件更新会随时显示到控制台)
tail -f /local/Tomcat55/1/cluster/machine3/logs/catalina.out

#8 date time
Year=`date | cut -f 6 -d ” “`
month=`date | cut -f 2 -d ” “`
day=`date | cut -f 3 -d ” ” `

#9 查看文件夹所占空间
du -s foldername/
(http://www.computerhope.com/unix/udu.htm )

#10查看所有java进程
ps -ef | grep java

alloy破解[转贴]

alloy的许可证分成四个部分,每个部分之间用#号分隔,第一部分是许可证过期时间,第二部分是用户名,第三和第四部分是两个36进制的整数,其中第三部分是校验码,第四部分是一个随机数(我是这么认为的,第四部分写死成一个常量也没有什么关系)。
好了,了解了许可证的构造之后,我们来了解一下alloy检验许可证是否合法和过期的过程。
一:分离许可证的各个部分。
二:判断日期部分的长度,如果长度大于1,就构造一个过期时间,否则过期时间为null。(这下子我们就可以通过使日期部分的长度不超过1来让alloy永不过期了^-^)。
三:调用Long.parseLong(String, int)方法解析出第三和第四部分两个36进制整数的10进制的值。
四:使用java.util.zip.CRC32来计算校验值,计算的过程是把从第四部分得到的10进值整数对127取模,然后加上第一、二两个部分(包括中间的#号),这样就构造出一个字符串,然后调用CRC32.update()方法计算这个字符串的校验值。
五:使用getValue()方法从CRC32中取得校验值,然后将这个校验值与从第三部分获得的10进制数值比较,如果相等,则校验成功。随后就是判断当前日期是否过期的操作了。
这大致就是alloy验证许可证的过程,我们反过来做一遍,就可以得到我们自己的许可证了。下面就是我写的构造许可证的方法,供大家参考。

public String generate(String user)
{
String exp = “x”;
String rand = “torresg”;
long l = Long.parseLong(rand, 36);
CRC32 crc32 = new CRC32();
crc32.update((l % 127L + exp + “#” + user).getBytes());
String checksum = Long.toString(crc32.getValue(), 36);
return exp + “#” + user + “#” + checksum + “#” + rand;
}

另外就是过期时间不能为空,因为alloy中另外某个地方要对这个时间进行处理。为空的话也会验证失败。所以过期时间要使用一个长度为1的字符串。

com.incors.plaf.alloy.AlloyLookAndFeel.setProperty(“alloy.licenseCode”,
“v#ej_technologies#uwbjzx#e6pck8”);
try {
javax.swing.LookAndFeel alloyLnF = new com.incors.plaf.alloy.AlloyLookAndFeel (); javax.swing.UIManager.setLookAndFeel(alloyLnF);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
// You may handle the exception here
ex.printStackTrace();
}