jeffy

BlogJava 首页 新随笔 联系 聚合 管理
  70 Posts :: 1 Stories :: 14 Comments :: 0 Trackbacks

#

     如果userDAO设置了autowire="byName" ,假设ServiceImpl有一个属性名为userDAO,Spring就会在配置文件里查找有没有名字为userDAO的bean, 自动为ServiceImpl注入。
     如果bean有两个属性,一个想默认注入,一个想自定义,只要设定了autowire,然后显式的声明那个想自定义的,就可以达到要求。这就应了需求,在需要特别配置的时候就提供配置,否则给我一个默认注入。
    还可以在根部的<beans>节点写一句default-autovwrie="byName",可以让文件里的所有bean 都默认autowrie。不过有人认为开发期可以这样,但Production Server上不应该使用Autowire。但有人认为那些自定义一次的地方比如TranscationManager应该详细定义,而Dao,Service这种大量重复定义的bean就可以这样做。

posted @ 2006-03-01 11:18 Live-in Java 阅读(5402) | 评论 (1)编辑 收藏

前 言    http://www.365key.com/gluttony/%E5%B7%A5%E4%BD%9C%E6%B5%81/

    本文没有抛出可运行的范例,仅仅是程序片断而已,不过在 OSWorkflow 的 Wiki 上,Quake Wang 已把官方入门教程完整地翻译成中文了,有兴趣的读者可去阅读。关于 OSWorkflow 更加细节性的内容,可参考官方手册,相信你在了解了入门教程后,可轻松阅读官方手册。
   
OSWorkflow 概念

    在商用和开源世界里,OSWorkflow 都不同于这些已有的工作流系统。最大不同在于 OSWorkflow 有着非常优秀的灵活性。在开始接触 OSWorkflow 时可能较难掌握(有人说不适合工作流新手入门),比如,OSWorkflow 不要求图形化工具来开发工作流,而推荐手工编写 xml 格式的工作流程描述符。它能为应用程序开发者提供集成,也能与现有的代码和数据库进行集成。这一切似乎给正在寻找快速“即插即用”工作流解决方案的人制造了麻烦,但研究发现,那些“即插即用”方案也不能在一个成熟的应用程序中提供足够的灵活性来实现所有需求。
   
OSWorkflow 优势

    OSWorkflow 给你绝对的灵活性。OSWorkflow 被认为是一种“低级别”工作流实现。与其他工作流系统能用图标表现“loops(回路)”和“conditions(条件)”相比,OSWorkflow 只是手工“编码(coded)”来实现的。但这并不能说实际的代码是需要完全手工编码的,脚本语言能胜任这种情形。OSWorkflow 不希望一个非技术用户修改工作流程,虽然一些其他工作流系统提供了简单的 GUI 用于工作流编辑,但像这样改变工作流,通常会破坏这些应用。所以,进行工作流调整的最佳人选是开发人员,他们知道该怎么改变。不过,在最新的版本中,OSWorkflow 也提供了 GUI 设计器来协助工作流的编辑。

    OSWorkflow 基于有限状态机概念。每个 state 由 step ID 和 status 联合表现(可简单理解为 step 及其 status 表示有限状态机的 state)。一个 state 到另一 state 的 transition 依赖于 action 的发生,在工作流生命期内有至少一个或多个活动的 state。这些简单概念展现了 OSWorkflow 引擎的核心思想,并允许一个简单 XML 文件解释工作流业务流程。

OSWorkflow 核心概念
   
step(步骤)
    一个 step 是工作流所处的位置。可能从一个 step 流转到另外一个 step(或者有时候还是停留在一样的 step)。举例来说,一个 OA 系统的请假流程,它的 step 名称可能有“本部门审批阶段”,“办公室审批阶段”,“总经理审批阶段”等。
 
status(状态)
    工作流 status 是一个用来描述工作流程中具体步骤状态的字符串。OSWorkflow 的有 Underway(进行中)、Queued(等候处理中)、Finished(完成)三种 status。
 
action(动作)
    action 指定了可能发生在 step 内的转变,会导致 step 的变更。在 OA 系统中,“本部门审批阶段”可能有“拒绝”或“批准”两个 action。action 和 step 之间的关系是,step 说明“在哪里”,action 说明“可以去哪里”。 一个 action 典型地由两部分组成:可以执行此动作的 condition(条件),以及执行此动作的 result(结果)。
 
condition(条件)
    类似于逻辑判断,可包含“AND”和“OR”逻辑。比如一个请假流程中的“本部门审批阶段”,该阶段利用“AND”逻辑,判断流程状态是否为等候处理中,以及审批者是否为本部门主管。
   
result(结果)
    Result 代表指向新的 step 及其 step status,也可能进入 split 或者 join。Result 分为两种, contidional-result (有条件结果),只有条件为真时才使用该结果,和 unconditional-result(无条件结果),当条件不满足或没有条件时使用该结果。

split/join(分离/连接)
流程的切分和融合。很简单的概念,split 提供多个 result;join 则判断多个 current step 的状态,提供一个 result。

OSWorkflow 包用途分析及代码片断
   
com.opensymphony.workflow
    该包为整个 OSWorkflow 引擎提供核心接口。例如 com.opensymphony.workflow.Workflow 接口,可以说,实际开发中的大部分工作都是围绕该接口展开的,该接口有 BasicWorkflow、EJBWorkflow、OfbizWorkflow 三个实现类。

com.opensymphony.workflow.basic
    该包有两个类,BasicWorkflow 与 BasicWorkflowContext。BasicWorkflow 不支持事务,尽管依赖持久实现,事务也不能包裹它。BasicWorkflowContext 在实际开发中很少使用。

  public void setWorkflow(int userId) {
  Workflow workflow = new BasicWorkflow(Integer.toString(userId));
 }

com.opensymphony.workflow.config
    该包有一个接口和两个该接口的实现类。在 OSWorkflow 2.7 以前,状态由多个地方的静态字段维护,这种方式很方便,但是有很多缺陷和约束。最主要的缺点是无法通过不同配置运行多个 OSWorkflow 实例。实现类 DefaultConfiguration 用于一般的配置文件载入。而 SpringConfiguration 则是让 Spring 容器管理配置信息。

  public void setConfiguration(SpringConfiguration configuration) {
  SpringConfiguration configuration = configuration;
workflow.setConfiguration(configuration);
 }

com.opensymphony.workflow.ejb
    该包有两个接口 WorkflowHome 和 WorkflowRemote。该包的若干类中,最重要的是 EJBWorkflow,该类和 BasicWorkflow 的作用一样,是 OSWorkflow 的核心,并利用 EJB 容器管理事务,也作为工作流 session bean 的包装器。

com.opensymphony.workflow.loader
    该包有若干类,用得最多的是 XxxxDescriptor,如果在工作流引擎运行时需要了解指定的动作、步骤的状态、名字,等信息时,这些描述符会起到很大作用。

  public String findNameByStepId(int stepId,String wfName) {
  WorkflowDescriptor wd = workflow.getWorkflowDescriptor(wfName);
  StepDescriptor stepDes = wd.getStep(stepId);
  return stepDes.getName();
 }

com.opensymphony.workflow.ofbiz
    OfbizWorkflow 和 BasicWorkflow 在很多方面非常相似,除了需要调用 ofbiz 的 TransactionUtil 来包装事务。

com.opensymphony.workflow.query
    该包主要为查询而设计,但不是所有的工作流存储都支持查询。通常,Hibernate 和 JDBC 都支持,而内存工作流存储不支持。值得注意的是 Hibernate 存储不支持混合型查询(例如,一个查询同时包含了 history step 上下文和 current step 上下文)。执行一个查询,需要创建 WorkflowExpressionQuery 实例,接着调用 Workflow 对象的 query 方法来得到最终查询结果。

  public List queryDepAdmin(int userId,int type) {
  int[] arr = getSubPerson(userId,type);

  //构造表达式
  Expression[] expressions = new Expression[1 + arr.length];
  Expression expStatus = new FieldExpression(FieldExpression.STATUS,
    FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, "Queued");
  expressions[0] = expStatus;

  for (int i = 0; i < arr.length; i++) {
   Expression expOwner = new FieldExpression(FieldExpression.OWNER,
     FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS,
     Integer.toString(arr[i]));
   expressions[i + 1] = expOwner;
  }

  //查询未完成流编号
  List wfIdList = null;
  try {
   WorkflowExpressionQuery query = new WorkflowExpressionQuery(
     new NestedExpression(expressions, NestedExpression.AND));
   wfIdList = workflow.query(query);
  } catch (Exception e) {
   e.printStackTrace();
  }


com.opensymphony.workflow.soap
    OSWorkflow 通过 SOAP 来支持远端调用。这种调用借助 WebMethods 实现。

com.opensymphony.workflow.spi
    该包可以说是 OSWorkflow 与持久层打交道的途径,如当前工作流的实体,其中包括:EJB、Hibernate、JDBC、Memory、Ofbiz、OJB、Prevayler。

  HibernateWorkflowEntry hwfe = (HibernateWorkflowEntry) getHibernateTemplate()
     .find("from HibernateWorkflowEntry where Id="
         + wfIdList.get(i)).get(0);

com.opensymphony.workflow.util
该包是 OSWorkflow 的工具包,包括了对 BeanShell、BSF、EJB Local、EJB Remote、JNDI 的支持。

小 结

    由于本人所在公司希望在 OA 系统中引入工作流引擎,经过分析决定采用 OSWorkflow 引擎。利用 OSWorkflow,已经在系统中实现了请假条流程原型,该流程结合 OA 系统中已有的 RBAC 模型进行逐级审核。我个人认为要用 OSWorkflow 让某个流程跑起来似乎很麻烦,主要是需要扩展和自己实现的太多。
   
    另外,引用一段 Quake Wang 的原话:电子政务/OA 如果要使用workflow engine的话,shark,jbpm 之类的workflow engine有点杀鸡用牛刀的味道。shark 和 jbpm 都强迫你使用它的用户模型,怎样把企业现有的用户模型(包括组织结构)映射过来是很繁琐的事情,比如常见的 OA 应用中,申请者对应的部门负责人为下一个流程的人工参与者,使用 shark 或者 jbpm 都得绕一圈,通过现有的人力资源系统,获得用户,再对应过来。这还仅仅是一个简单的需求,更不用说国内企业千奇百怪的组织结构,以及各种特殊流程,用 wfmc 或者其他所谓的 workflow 通用标准去做不怎么标准的事情。吃力不讨好。用 osworkflow 这种基于状态机的 workflow engine 反而会轻松很多,而且它也没有强迫你使用它的用户模型。另外纠正一点:osworkflow 不仅仅支持简单的 BeanShell,还支持 java class,bsf,ejb。如果做电子政务/OA 的话,觉得目前 osworkflow 是最适用的 opensource workflow engine。
                                           (申明:本文来源于网络,摘录于此,仅为日后方便查看)

posted @ 2006-03-01 10:37 Live-in Java 阅读(1569) | 评论 (0)编辑 收藏

介绍Tapestry的相关中文网址:
http://www.netbei.com/Article/jsp/Tapestry/Index.html


Tapestry是一个开源的基于servlet的应用程序框架,它使用组件对象模型来创建动态的,交互的web应用。一个组件就是任意一个带有jwcid属性的html标记。其中jwc的意思是Java Web Component。Tapestry使得java代码与html完全分离,利用这个框架开发大型应用变得轻而易举。并且开发的应用很容易维护和升级。Tapestry支持本地化,其错误报告也很详细。Tapestry主要利用javabean和xml技术进行开发。 

第一个应用程序 

在介绍第一个应用之前,先介绍一下Tapestry的安装。从sourceforge下载其最新版,解压后,将lib目录下的jar文件放到CLASSPATH中,将其中的war文件放到tomcat的webapp目录下。然后就可以通过http://localhost:8080/tutorial访问其tutorial应用。 
在Tapestry中一个应用程序有以下几部分组成,我们以其自身带的HelloWorld程序为例介绍: 

Servlet: 
这是一个应用的主体部分:servlet类,这个类必须是ApplicationServlet的子类,并且必须实现getApplicationSpecificationPath()方法。示例如下: 


import com.primix.tapestry.*; 
public class HelloWorldServlet extends ApplicationServlet 

protected String getApplicationSpecificationPath() 

return "/tutorial/hello/HelloWorld.application"; 




/tutorial/hello/HelloWorld.application是一个应用的说明文件。 
Application Specification: 
其实就是描述这个应用的一个xml文件,在这个应用中有许多参数需要设置,engine-class将在下面介绍,page中的name属性指定html文件名,specification-path指定对这个页面的说明文件。在一个应用中可以有很多个page,但必须有一个page的name为"Home",因为当访问你的应用时,首先显示的就是这个page。 

<?xml version="1.0" encoding="UTF-8"?>; 
<!DOCTYPE application PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd">; 
<application name="Hello World Tutorial" engine-class="com.primix.tapestry.engine.SimpleEngine">; 
<page name="Home" specification-path="/tutorial/hello/Home.jwc"/>; 
</application>; 


Application Engine: 

当客户连接到Tapestry应用时,Tapestry将会创建一个Engine对象(类似于session)。通常我们程序中的application engine 一般是SimpleEngine类的一个实例,当然这个类的子类也可以。 

Page Specification: 
跟应用说明相似,页说明也是一个xml描述文件: 


<?xml version="1.0" encoding="UTF-8"?>; 
<!DOCTYPE specification PUBLIC "-//Howard Ship//Tapestry Specification 1.1//EN" "http://tapestry.sf.net/dtd/Tapestry_1_1.dtd">; 
<specification class="com.primix.tapestry.BasePage"/>; 


因为这个应用是静态的,所以使用com.primix.tapestry.BasePage即可,如果是动态的应用,则需在这个文件中定义一些component,当然使用BasePage为基类的派生类也可以。 
html页面: 
这个应用的html页面非常简单: 


<html>; 
<head>; 
<title>;Hello World</title>; 
</head>; 
<body>; 
<b>;HelloWorld</b>; 
</body>; 
</html>; 


注意上面所讲到的各种文件都要放到放在WAR的WEB-INF/classes目录下。
一个复杂的应用 

在这个应用中我们以一个简单的学生管理系统为例介绍一下Tapestry的常用功能。我们要实现学生的增加和显示,因此我们需要两个html页面。至于StudentServlet类和Student.application我们就不描述了,在Student.application中定义了两个page:Home和EditStudent,具体看附件。学生数据存放在数据库中,我们用Student类表示数据中的一条记录,用StudentFactory类检索学生数据,这两个类用到了一个JDBC包装器,关于这个JDBC包装器可以见我的另外一篇文章<<对一个简单的 JDBC 包装器的扩展及应用>;>;。 
首先看一下Home.html 


<html>; 
<head>; 
<title>;学生管理</title>; 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">; 
</head>; 
<body bgcolor="#FFFFFF">; 
<p align="center">;学生列表</p>; 
<table width="100%" border="1">; 
<tr>; 
<td >;学号</td>; 
<td >;姓名</td>; 
<td >;性别</td>; 
<td >;班级</td>; 
</tr>; 
<span jwcid="liststudent">; 
<tr>; 
<td>;<span jwcid="id">;20012400</span>;</td>; 
<td>;<span jwcid="sname">;宗锋</span>;</td>; 
<td>;<span jwcid="gender">;男</span>;</td>; 
<td>;<span jwcid="department">;计算机研一</span>;</td>; 
</tr>; 
</span>; 
<tr jwcid="$remove$">; 
<td>;20011389</td>; 
<td>;桑一珊</td>; 
<td>;男</td>; 
<td>;计算机研一</td>; 
</tr>; 
</table>; 
<a jwcid="add">;添加学生</a>; 
</body>; 
</html>; 

与前面的简单应用不同,我们在这个页面中定义了七个组件,下面看一下部分Home.jwc文件,我们将详细讲述一下怎样描述这些组件。 


<specification class="test.ListStudent">; 
<component id="liststudent" type="Foreach">; 
<binding name="source" property-path="student"/>; 
<binding name="value" property-path="eachstudent"/>; 
</component>; 
<component id="id" type="Insert">; 
<binding name="value" property-path="eachstudent.id"/>; 
</component>; 
<component id="add" type="Page">; 
<static-binding name="page">;EditStudent</static-binding>; 
</component>; 
</specification>; 

在这里,我们的specification的class属性值不再是BasePage,而是其派生类ListStudent。对于每一个组件,id属性指定唯一的标识符,这个值与html文件中的jwcid值相对应,type 指定组件名,binding指定组件怎得到数据,property-path是一系列属性的集合,这些属性一般定义在javabean中,例如上面的property-path="student",则在相应的javabean类ListStudent中应该有个函数getStudent。liststudent是一个Foreach组件,这个组件其实是一个for循环,它从source中读入一个数组,将其一个一个的赋值给value参数指定的属性。id,name,gender,department四个是Insert组件,这个组件用来插入文本数据,参数value指定要插入的值,property-path指定怎样获取这些值,eachstudent.id相当于调用javabean的getEachstudent().getId()。add是一个Page组件,page属性指定页面名(定义在application文件中),static-binding表明要绑定的数据是不可修改的。$remove$组件没有在这个文件中描述,因为Tapestry运行时会自动删除这种组件。 
下面看一下ListStudent类: 

package test; 
import com.primix.tapestry.*; 
import sun.jdbc.odbc.JdbcOdbcDriver ; 


/** 
* 返回每个学生的数据 

*/ 

public class ListStudent extends BasePage 

private Student eachstudent; 
private Student[] student; 
public void detach() 

eachstudent=null; 
student=null; 
super.detach(); 


public Student getEachstudent() 

return eachstudent; 

public void setEachstudent(Student value) 

eachstudent = value; 

public Student[] getStudent() 

try{ 
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
student=StudentFactory.findAllStudents(); 
}catch(Exception e){ 
e.printStackTrace(); 

return student; 






这个类有四个函数,其中detach函数是将页面放入缓冲池时执行的操作,getStudent函数返回所有的学生记录,这是给jwc文件中liststudent组件的source参数赋值,getEachstudent给这个组件的value参数赋值,因为source是一个数组,每次循环需要从中取出一条记录赋值给eachstudent,所以还有一个函数为setEachstudent,你会注意到这个函数很简单,其实是Tapestry帮你做了大部分工作。 
至此,显示学生的部分已经完成,下面看一下EditStudent.html 

<html>; 
<head>; 
<title>;增加学生</title>; 
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">; 
</head>; 
<body>; 
<p>;<img src="student.gif" width="32" height="32"/>; 学生管理系统</p>; 
<form jwcid="form">; 
<span jwcid="ifError">; 
<font size=+2 color=red>;<span jwcid="insertError"/>;</font>; 
</span>; 
<p>;学号: 
<input jwcid="id"/>; 
</p>; 
<p>;姓名: 
<input jwcid="name"/>; 
</p>; 
<span jwcid="gender">; 
<p>;性别: 
<input jwcid="male"/>; 
男 
<input jwcid="female"/>; 
女 
</p>; 
</span>; 
<p>;班级: 
<input jwcid="department"/>; 
</p>; 
<p>; 
<input type="submit" value="确定">; 
</p>; 
</form>; 
</body>; 
</html>; 


在这个文件中,用到了另外一些常用的组件,先看一下EditStudent.jwc中的这些组件的描述: 


<specification class="test.EditStudent">; 
<component id="form" type="Form">; 
<binding name="listener" property-path="listeners.formSubmit"/>; 
</component>; 
<component id="gender" type="RadioGroup">; 
<binding name="selected" property-path="gender"/>; 
</component>; 
<component id="ifError" type="Conditional">; 
<binding name="condition" property-path="error"/>; 
</component>; 
<component id="insertError" type="Insert">; 
<binding name="value" property-path="error"/>; 
</component>; 
<component id="id" type="TextField">; 
<binding name="value" property-path="id"/>; 
</component>; 
<component id="male" type="Radio">; 
<field-binding name="value" field-name="test.EditStudent.MALE"/>; 
</component>; 
</specification>; 


form是一个Form组件,它的参数listener指定submit这个form时有那个函数处理。ifError是一个Conditional组件,这个组件指定当condition满足时才会显示,在本例中,如果error不为空,则condition满足。在这个组件中,有嵌套了一个Insert类型的组件,用于将错误显示。这是Tapestry中经常用到的处理错误的方式。gender是一个RadioGroup组件,它绑定了javabean中的gender属性,selected参数指定那个radio被选中,在这个组件中,又嵌套了两个Radio组件,分别用来表示男,女。Radio的value参数指定当用户选定这个radio时,RadioGroup绑定的属性值将会等于field-name中指定的值(这个值必须是static的),在本例中,gender=test.EditStudent.MALE。id是一个TextField组件,其参数value绑定到javabean中的id属性。 
下面是相应的EditStudent类: 

package test; 
import com.primix.tapestry.*; 

public class EditStudent extends BasePage 

public static final int MALE = 1; 
public static final int FEMALE = 2; 

private int gender; 
private String error; 
private String id; 
private String sname; 
private String department; 

public void detach() 

error = null; 
id=null; 
sname=null; 
gender=0; 
department=null; 
super.detach(); 


public int getGender() 

return gender; 

public String getId() 

return id; 

public String getSname() 

return sname; 

public String getDepartment() 

return department; 



public void setGender(int value) 

gender = value; 
fireObservedChange("gender", value); 

public void setId(String value) 

id = value; 
fireObservedChange("id", value); 

public String getError() 

return error; 

public void setSname(String value) 

sname = value; 
fireObservedChange("sname", value); 

public void setDepartment(String value) 

department = value; 
fireObservedChange("department", value); 

public void formSubmit(IRequestCycle cycle) 

//判断用户是否添完了所有数据 
if (gender== 0||id==null||id.equals("")||sname==null||sname.equals("")|| 
department==null||department.equals("")) 

error = "请填充完所有选项"; 
return; 

//将学生保存 
try{ 
Student student=new Student(); 
student.setId(id); 
student.setName(sname); 
if(gender==1) 
student.setGender("男"); 
else 
student.setGender("女"); 
student.setDepartment(department); 
student.save(null); 
}catch(Exception e){ 
e.printStackTrace(); 

//清空当前的各个属性,以免再次进入此页面时,各属性仍旧保留原来的值 
setSname(null); 
setDepartment(null); 
setId(null); 
setGender(0); 
//重定向到Home页面 
cycle.setPage("Home"); 





在本类的一些设置属性的函数中使用了fireObservedChange这个函数,这个函数激发一个改变事件,通知当前的属性的值已经改变。
其他应用 

Tapestry中自带的例子中的Workbench中的localization例子演示了怎样使用本地化,你只需要创建不同语言的html模板,还有图形等其它一些html中用到的资源。例如创建一个法语版的EditStudent.html,则相应的html文件名为EditStudent_fr.html,而jwc中定义的组件的描述不用有多个版本。这里要介绍一下Tapestry本地化中经常用到的一个概念:assets。assets是一些web应用中用到的资源,如图象,视频。assets有三种:external, internal 和private。External类型的assets来源于任意的URL。Internal类型的assets来源于和Tapestry应用在同一个服务器上的URL。Private 类型的assets允许部署在WAR的WEB-INF/classes目录下(同上面的html模板,jwc文件一样),这个目录对于web服务器来说是不可见的。 
看一下Workbench中localization例子中的localization.jwc文件的片断: 

<component id="changeButton" type="ImageSubmit">; 
<binding name="image" property-path="assets.change-button"/>; 
</component>; 

<private-asset name="change-button" resource-path="/tutorial/workbench/localization/Change.gif"/>; 

在changeButton组件中就使用了private assets,而这些图像文件就放在WAR的WEB-INF/classes下,注意图像跟html一样也有多个语言的版本。 
注意jwc文件中的inputLocale这个组件,其实localization应用就是通过这个组件来实现本地化。具体参数请看其Developer guide。 

<component id="inputLocale" type="PropertySelection">; 
<binding name="value" property-path="page.engine.locale"/>; 
<binding name="model" property-path="localeModel"/>; 
</component>; 

Tapestry还支持创建自己的可重用组件,其自身带了一个这样的例子:Border。同时它还有其它一些例子:Inspector展示了怎样监视你的应用程序。vlib是一个用tapestry作表示层的j2ee应用程序(用jboss作为应用服务器)。 

Tapestry的功能非常强大,本文只是介绍了其一小部分,还有很多方面没有涉及到,例如javascript在Tapestry中的应用。具体可以看其文档,相信如果你用一下这个框架,你就会被它深深吸引。Tapestry的文档做的不是很全,不过经过不断的摸索,相信你会很快掌握它。
posted @ 2006-02-27 17:46 Live-in Java 阅读(270) | 评论 (0)编辑 收藏

osworkflow tutorial - chinese

http://wiki.opensymphony.com/display/WF/Tutorial+-+Chinese
posted @ 2006-02-26 16:16 Live-in Java 阅读(261) | 评论 (0)编辑 收藏

posted @ 2006-02-22 16:27 Live-in Java 阅读(425) | 评论 (0)编辑 收藏

使用java.exe 的-Xmx 參數來設定最大的heap size. 所以啟動時的命令可以如下

java -Xmx512m
	
如果用eclipse.exe 啟動也是可以下達參數
eclipse.exe -vmargs -Xmx512M
posted @ 2006-02-21 18:19 Live-in Java 阅读(443) | 评论 (0)编辑 收藏

Commonclipse can automaticly create these following methods:
public String toString()
public boolean equals(Object object)
public int hashCode()
some of them are used by hibernate.

Eclipse 3.0.1 + Commonclipse 1.2  can work together well.
posted @ 2006-02-20 14:24 Live-in Java 阅读(387) | 评论 (0)编辑 收藏

Valentine's Day 情人节

Date 约会

Bunch 花束

Rose 玫瑰

Candy 糖果

Chocolate 巧克力

Forget-Me-Not 勿忘我

Puppy Love/First Love 初恋

Cute Meet 浪漫的邂逅

Fall In Love 坠入爱河

Love At The First Sight 一见钟情

Propose 求婚

Valentine Cards 情人节卡片

Candlelight Dinner 烛光晚餐

Heart-Shaped/Cordate 心形的

Truelove 真爱

Enamored 倾心的

Saint Valentine\'s Day 情人节

The Chemical Feeling 奇妙的感觉,触电

Sweet Bitterness 甜蜜的痛苦

A Doomed Couple 天生一对

A Happy Ending 大团圆结局

Sweetheart 甜心

Lover 爱人

Cupid 爱神丘比特

Admirer 仰慕者

Romance 浪漫

Heartthrob 激情

Courtship 求爱

Infatuation 醉心

Promise/Pledge/Vow 誓言

Fidelity 忠心

Eternal/Immortal/Everlasting 永恒
posted @ 2006-02-14 23:08 Live-in Java 阅读(219) | 评论 (0)编辑 收藏

I should pay more attention to  following java technologies , focusing on the advantage of these technologies.

  • DWR 1.0
  • Prototype 1.4.0
  • Scriptaculous 1.5.1
  • Acegi Security 1.0
  • pageFlow, Continuation  --> spring WebFlow(http://java.chinaitlab.com/WebServices/33768.html)
  • Loadrunner+JProbe 测试 session导致的内存浪费问题
  • hibernate query cache, Lightor Query Cache.
  • 规则引擎或者脚本引擎
  • posted @ 2006-02-10 15:08 Live-in Java 阅读(235) | 评论 (0)编辑 收藏

    实现两个Web下拉选择框关联
      比如要实现国家Country与城市City的关联:
    动态javascript方法实现如下:
       <!-- 引入js文件-->
       <script src="/scripts/xselect.js"></script>
      <script language="javascript">
      <!--    
     var dsy = new Dsy();
     //countryID是父select控件名称, cityID是子select控件名称.
     var sel = ["countryID","cityID"];
     //定义父与子两个select控件的默认值
     var def = ['<c:out value="${storeForm.countryID}" />','<c:out value="${storeForm.cityID}" />'];
     
     //父select控件内容的定义
     dsy.add("0",[['-------','0']
     <logic:iterate name="CountryList" id="country">
         ,['<bean:write name="country" property="label"/>','<bean:write name="country" property="value"/>']
     </logic:iterate>
     ]);

     //下面定义子select控件的内容
     dsy.add("0_0",[['------','0']]);
     <logic:iterate name="CountryList" id="country" indexId="index">
         dsy.add('0_<%=index.intValue()+1%>',[['------','0']
         <logic:iterate name="Citys" id="city">
          <bean:define id="c" name="city" property="countryID" />
         <bean:define id="c2" name="country" property="value" />
         //由于city.countryID是long类型,而country.value是String类型,所以把long类型转换为String类型
          <%
            String str = c + "";
         %>
            //遍历所有的City List, 如果city的countryID与country id一致,就加入select控件
            <logic:equal name="country" property="value" value="<%=str%>">
      ,['<bean:write name="city" property="name"/>','<c:out value="${city.id}" />']
            </logic:equal>
         </logic:iterate>]);
     </logic:iterate>
     
     attachSelect(dsy,sel,def);

      // -->
    </script>   
    //注意,上述代码写到html form里面

    posted @ 2006-02-05 16:18 Live-in Java 阅读(537) | 评论 (0)编辑 收藏

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