1.在JSP文件中加上:
<%@ page contentType="text/html; charset=utf-8" %>
<html:html lang="true"></html:html>
2.使用以下形式输出字符:
<bean:message bundle="index" key="Anonymous"/>
3.建立类似以下形式的文件(放在classses目录下):
application_en_US.properties
application_zh_TW.properties
application_zh_CN.properties
其中可能用到这样的命令:
native2ascii application_cn.properties application_zh_CN.properties
posted @
2006-06-07 14:44 崛起的程序员 阅读(245) |
评论 (0) |
编辑 收藏
以下所说的struts-config.xml和ApplicationResources.properties等文件名是缺省时使用的,如果你使用了多模块,或指定了不同的资源文件名称,这些名字要做相应的修改。
1、“No bean found under attribute key XXX”
在struts-config.xml里定义了一个ActionForm,但type属性指定的类不存在,type属性的值应该是Form类的全名。或者是,在Action的定义中,name或attribute属性指定的ActionForm不存在。
2、“Cannot find bean XXX in any scope”
在Action里一般会request.setAttribute()一些对象,然后在转向的jsp文件里(用tag或request.getAttribute()方法)得到这些对象并显示出来。这个异常是说jsp要得到一个对象,但前面的Action里并没有将对象设置到request(也可以是session、servletContext)里。
可能是名字错了,请检查jsp里的tag的一般是name属性,或getAttribute()方法的参数值;或者是Action逻辑有问题没有执行setAttribute()方法就先转向了。
还有另外一个可能,纯粹是jsp文件的问题,例如<logic:iterate>会指定一个id值,然后在循环里<bean:write>使用这个值作为name的值,如果这两个值不同,也会出现此异常。(都是一个道理,request里没有对应的对象。)
3、“Missing message for key "XXX"”
缺少所需的资源,检查ApplicationResources.properties文件里是否有jsp文件里需要的资源,例如:
<bean:message key="msg.name.prompt"/>
这行代码会找msg.name.prompt资源,如果AppliationResources.properties里没有这个资源就会出现本异常。在使用多模块时,要注意在模块的struts-config-xxx.xml里指定要使用的资源文件名称,否则当然什么资源也找不到,这也是一个很容易犯的错误。
4、“No getter method for property XXX of bean teacher”
这条异常信息说得很明白,jsp里要取一个bean的属性出来,但这个bean并没有这个属性。你应该检查jsp中某个标签的property属性的值。例如下面代码中的cade应该改为code才对:
<bean:write name="teacher" property="cade" filter="true"/>
5、“Cannot find ActionMappings or ActionFormBeans collection”
待解决。
6、“Cannot retrieve mapping for action XXX”
在.jsp的<form>标签里指定action='/XXX',但这个Action并未在struts-config.xml里设置过。
7、HTTP Status 404 - /xxx/xxx.jsp
Forward的path属性指向的jsp页面不存在,请检查路径和模块,对于同一模块中的Action转向,path中不应包含模块名;模块间转向,记住使用contextRelative="true"。
8、没有任何异常信息,显示空白页面
可能是Action里使用的forward与struts-config.xml里定义的forward名称不匹配。
9、“The element type "XXX" must be terminated by the matching end-tag "XXX".”
这个是struts-config.xml文件的格式错误,仔细检查它是否是良构的xml文件,关于xml文件的格式这里就不赘述了。
10、“Servlet.init() for servlet action threw exception”
一般出现这种异常在后面会显示一个关于ActionServlet的异常堆栈信息,其中指出了异常具体出现在代码的哪一行。我曾经遇到的一次提示如下:
java.lang.NullPointerException
at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1003)
at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:955)
为解决问题,先下载struts的源码包,然后在ActionServlet.java的第1003行插入断点,并对各变量进行监视。很丢人,我竟然把struts-config.xml文件弄丢了,因此出现了上面的异常,应该是和CVS同步时不小心删除的。
11、“Resources not defined for Validator”
这个是利用Validator插件做验证时可能出现的异常,这时你要检查validation.xml文件,看里面使用的资源是否确实有定义,form的名称是否正确,等等。
posted @
2006-06-07 14:43 崛起的程序员 阅读(245) |
评论 (0) |
编辑 收藏
这只小猫玩了它差不多也有一年多了,还没仔细瞅瞅长个什么样。当它耍性子的时候,常常弄的我手足无措,因为不懂它说出的一大堆乱七八糟的洋话。为了能让它说start就start,说down就down,下面要开始一段我训兽师的经历 ^_^。
宠物简介
Jakarta Tomcat服务器是一种Servlet/JSP容器,经历了3.x到4.0.x到4.1.x的变迁,现在最新的版本为5.0.x,支持Servlet2.4和JSP2.0规范,从apache网站上下载Tomcat 5,在环境变量中配置一下JAVA_HOME,小猫就能生灵活现的跑起来了。若小猫启动失败,DOS窗口会自动关闭,若运行catalina run命令DOS窗口是不会自动关闭的。
tomcat中有三个放置java库的地方,分别是/server/lib、/shared/lib和/common/lib。
区别:/server/lib - 其中的jar文件只能被tomcat服务器访问。
/shared/lib - 其中的jar文件可以被所有的Web应用访问,但不能被tomcat服务器访问到。
/common/lib - Web服务和tomcat服务器都可以访问的到。
server.xml文件解析 - 文件位置是<%CATALINA_HOME%>/conf/server.xml
配置虚拟主机
Host元素代表虚拟主机,在同一个Engine元素下可以配置多个虚拟主机。打开server.xml文件可以发现Engine元素下已经有一个名为localhost的Host元素了,可以在它后面加入下列代码:
<
Host
name
="www.myname.com"
debug
="0"
appBase
="c:\myname"
unpackWar
="true"
autoDeploy
="true"
>
<
alias
>
www.myname1.com
</
alias
>
<
alias
>
www.myname2.com
</
alias
>
<
Context
pathh
="/helloapp"
docBase
="helloapp"
debug
="0"
reloadable
="true"
/>
</
Host
>
Session的使用
Session是一种用来跟踪用户状态的机制,那它是怎么实现的呢?Servlet容器通过在客户端浏览器中保存一个Session ID来跟踪Session,调用session.getID()可以看到你的Session ID是多少。如果客户端支持Cookie,就把Session ID作为Cookie保持在浏览器中,现在绝大多数浏览器都会把Cookie功能打开,但如果用户禁止了Cookie呢?Java Servlet API中提出了另外一种机制,Servlet容器可以重写客户requst的URL,把Session ID添加到URL信息中,HttpServletResponse接口提供了这样的方法:public String encodeURL(String url)-先判断如果没有启用Session,例如jsp中<%@ page session="false"%>或执行了session.invalideate(),那么直接返回url,在判断客户端师父支持Cookie,如果不支持,就在url中加入Session ID的信息,然后返回修改后的url。
Session的管理
当一个sesson开始时,Servlet容器会创建一个HttpSession对象,在某些情况下把这些Httpsession对象从内存中转移到文件系统中或数据库中,需要访问的时候在把它们载入到内存中来。这样做的好处有两点:节约了内存的消耗,当web服务器产生故障时,还可以从文件系统或数据库中恢复Session的数据。
对于Session的管理,小猫提供了两个实现类:org.apache.catalina.session.StandardManager和org.apache.catalina.session.PersistentManager。
StandardManager -是默认的方法,当Tomcat服务器重启或重载的时候,会把Session对象保存到
<%CATALINA_HOME%>/work/Catalina/honstname/applicatonname/SESSIONS.ser(默认值)文件中,每个对象对应一个文件,以Session ID为文件名,例如:
<
Context
path
="/helloapp"
docBase
="helloapp"
debug
="0"
reloadable
="true"
>
<
Manager
className
="org.apache.catalina.session.StandardManager"
debug
="0"
maxActiveSessions="-1" checkInterval="60"
/
>
</
Context
>
参数说明:checkInterval-检查session是否过期的时间间隔,以秒为单位,缺省值是60秒;
maxActiveSessions-可处于活动状态的session数。
PersistentManager -提供了更加灵活的管理方式,具有容错能力,可以及时把Session备份到Session Store中,可以控制内存中Session的数量。
小猫还提供了实现持久化Session Store的接口,org.apache.catalina.Store,目前提供了两个具体实现类:org.apache.catalina.FileStore和org.apache.catalina.JDBCStore。
server.xml中的配置File Store -
<
Context
path
="/helloapp"
docBase
="helloapp"
debug
="0"
reloadable
="true"
>
<
Manager
className
="org.apache.catalina.session.PersistentManager"
debug
="0"
saveOnRestart
="true"
maxActiveSessions
="-1"
minIdleSwap
="-1"
maxIdleSwap
="-1"
maxIdleBackup
="-1"
>
<
Store
className
="org.apache.catalina.session.FileStore"
directory
="mydir"
/>
</
Manager
>
</
Context
>
参数说明:saveOnRestart-服务器关闭时,是否将所有的session保存到文件中;
maxActiveSessions-可处于活动状态的session数;
minIdleSwap/maxIdleSwap-session处于不活动状态最短/长时间(s),sesson对象转移到File Store中;
maxIdleBackup-超过这一时间,将session备份。(-1表示没有限制)
JDBCStore配置的区别:
<
Store
calssName
="org.apache.catalina.JDBCStore"
driverName
="com.mysql.jdbc.Driver"
connectionURL
="jdbc:mysql://localhost/tomsessionDB?user=root&password="
sessionTable
="tomcat_session"
sessionIdCol
="session_id"
sessionDataCol
="session_data"
sessionValidCol
="session_valid"
sessionMaxInactiveCol
="max_inactive"
sessionLastAccessedCol
="last_access"
sessionAppCol
="app_name"
checkInterval
="60"
debug
="99"
/>
Session失效时间的设定
在web.xml文件中,位于<servlet-mapping>和<welcome-file-list>元素之间加入如下代码,单位为分钟:
<
session-config
>
<
session-timeout
>
60
</
session-timeout
>
</
session-config
>
Tomcat的admin平台和manager平台
这是Tomcat中自带的两个Web应用,位于<%CATALINA_HOME%>/server/webapps/admin(manager),访问地址是http://localhsot:8080/admin(manager)。要访问这两个Web应用,需要在
<%CATALINA_HOME%>/conf/tomcat-users.xml中添加如下内容:
<user username="admin" password="1234" role="admin"/> //对应admin Web应用
<user username="manager" password="1234" role="manager"/> //对应manager Web应用
admin平台把所有可配置的信息分为三类:Tomcat Server、Resources、User Definition。
Tomcat Server-相当于server.xml中的<Server>元素及其子元素,<Service>、<Host>、<Context>、<Resources>、<Date Source>。
Resources-相当于server.xml中的<GlobalNamingResources>,共有四种资源:Date Source(JNDI数据源)、Mail Sessioin(JNDI Mail Session资源)、Environment Entry(环境变量)、User Database(安全域中的用户数据库)。
User Definition-与tomcat-users.xml相对应。
manager平台-列出来所有Web应用和状态,并提供了Start、Stop、Reload、 Undeploy命令,还可以发布
<%CATALINA_HOME%>/webapps目录下的Web应用或系统文件任意位置的WAR文件。
posted @
2006-06-07 14:41 崛起的程序员 阅读(241) |
评论 (0) |
编辑 收藏
解决思路:
配置web工程web.xml加上
<mime-mapping>
<extension>doc</extension>
<mime-type>application/msword</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xls</extension>
<mime-type>application/vnd.ms-excel</mime-type>
</mime-mapping>
修改后非常注意的要清空缓存这样才会弹出保存还是打开的窗口否则打开还是乱码.
posted @
2006-06-02 12:32 崛起的程序员 阅读(1080) |
评论 (0) |
编辑 收藏
在weblogic下面增加虚拟目录
修改weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="
http://www.bea.com/ns/weblogic/80
" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
" xsi:schemaLocation="
http://www.bea.com/ns/weblogic/80
http://www.bea.com/ns/weblogic/80/weblogic-web-app.xsd
http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
">
<context-root>webdoc</context-root>
<virtual-directory-mapping>
<local-path>c:/word/doc</local-path>
<url-pattern>/*</url-pattern>
</virtual-directory-mapping>
</weblogic-web-app>
posted @
2006-06-01 15:49 崛起的程序员 阅读(2495) |
评论 (3) |
编辑 收藏
使用Spring来创建一个简单的工作流引擎
spring是支持控制反转编程机制的一个相对新的框架。本文把spring作为简单工作流引擎,将它用在了更加通用的地方。在对工作流简单介绍之后,将要介绍在基本工作流场景中基于Spring的工作流API的使用。
许多J2EE应用程序要求在一个和主机分离的上下文中执行处理过程。在许多情况下,这些后台的进程执行多个任务,一些任务依赖于以前任务的状态。由于这些处理任务之间存在相互依赖的关系,使用一套基于过程的方法调用常常不能满足要求。开发人员能够利用Spring来容易地将后台进程分离成活动的集合。Spring容器连接这些活动,并将它们组织成简单的工作流。
在本文中,简单工作流被定义成不需要用户干预,以一定顺序执行的任意活动的集合。然而,我们并不建议将这种方式代替存在的工作流框架。在一些场景中,需要更多的用户交互,例如基于用户输入而进行的转向,连接或传输,这时,比较好的方法是配用一个单独的开源或者商业的工作流引擎。一个开源项目已经成功地将更复杂的工作流设计集成到spring中。
如果你手上的工作流任务是简单的,那么,与功能完备的独立工作流框架相比,简单工作流的策略就会变得有意义,特别地,如果已经使用了spring,这种快速实现可以保证时间不会变得更加漫长。此外,考虑到spring轻量级的控制反转容器的特点,spring在资源负载上减少了资源负载。
这篇文章简短地从编程主题的角度介绍工作流。通过使用工作流的概念,spring被用来作为驱动工作流引擎的框架。然后,讨论了生产部署选项。现在,让我们从工作流的设计模式和相关背景信息来介绍简单工作流的思想吧。
简单工作流
工作流模型是一个早在70年代就有人开始研究的主题,许多开发者都试图创建工作流模型规范。W.H.M. van der Aalst等人写了《工作流模型》白皮书(2003年7月),它成功地提炼出一组设计模式,这些设计模式准确地将大多数通用的工作流场景建模。当中,最普通的工作流模式是顺序模式 (Sequence pattern)。顺序工作流模式满足了简单工作流的设计原则,并且由一组顺序执行的活动组成。
UML(统一建模语言)活动图通常被用来作为一个机制对工作流建模。图1显示了一个基本的使用标准UML活动图对顺序工作流过程的建模过程。
图 1顺序工作流模式
顺序工作流是一个在J2EE中流行的标准工作流模式。J2EE应用程序在后台线程中,通常需要一些顺序发生的事件或者异步事件。图2中的活动图描述了一个简单的工作流,用来通知感兴趣的旅行者,他们感兴趣的目的地的机票价格已经下降的事件。
图 2.机票价格下降的简单工作流
图1中的航线工作流负责创建和发送动态的email通知。过程中的每一步表示了一个活动(activity)。在工作流处于活动之前,一些额外事件必须发生。在这个例子中,事件是飞行路线费率的减少。
让我们来简要的看一下航线工作流的业务逻辑。如果第一个活动找不到对费率减少通知感兴趣的用户,那么整个工作流就被取消。如果发现了感兴趣的用户,那么接下来的活动继续执行。随后,一个XSL(扩展样式表)转换生成消息内容,之后,记录审计信息 (audit information)。最后,工作流试图通过SMTP服务器发送这个消息。如果这个任务没有错误地完成,便在日志中记录成功的信息,进程结束。但是,如果在和SMTP服务器通讯时发生了错误,一个特别的错误处理例程将要管理这些错误。错误处理代码将会试着去重新发送消息。
考虑这个航线的例子,一个明显的问题是:你怎么样有效地将顺序处理过程分解为单独的活动?这个问题被spring巧妙的处理了。下面,让我们快速地讨论spring的反转控制框架。
控制反转
Spring通过使用spring容器来负责控制对象之间的依赖关系,使得我们不再对对象之间的依赖负责。 这种依赖关系的实现就是大家所知道的控制反转(IoC)或依赖注射。参见Martin Fowler's "Inversion of Control Containers and the Dependency Injection Pattern"(martinfowler.com, 2004年2月)得到关于控制反转和依赖注射的更加深入的讨论。通过管理对象之间的依赖关系,spring就不需要那些只是为了使类能够相互协作,而将对象粘合的代码。
作为spring beans的工作流组件
在进一步讨论之前,现在是简要介绍spring中主要概念的恰当时候。接口ApplicationContext是从接口BeanFactory继承的,它被用来作为在spring容器内实际的控制实体和容器。
ApplicationContext负责对一组作为spring beans的一组bean的初始化,配置和生命期管理。我们通过装配在一个基于XML的配置文件中的spring beans来配置ApplicationContext。这个配置文件说明了spring beans互相协作的本质特点。这样,用spring的术语来说,与其他spring beans交互的spring beans就被叫着协作者(collaborators)。缺省情况下,spring beans是作为单例存在于ApplicationContext中的,但是,单例的属性能够被设置为false,从而有效地改变他们在spring中调用原型模式时的行为。
回到我们的例子,在飞机票价下降的时候,一个SMTP发送例程的抽象就被装配在工作流过程例子中的最后的活动(例子代码可以在 Resources中得到)。由于是第5个活动,我们命名它为activity5。要发送消息,activity5就要求一个代理协作者和一个错位处理句柄。
class="org.iocworkflow.test.sequence.ratedrop.SendMessage">
BR>
/FONT>
将工作流组件实施成spring beans产生了两个令人喜悦的结果,就是容易进行单元测试和很大程度上可重用能力。IoC容器的特点明显地提供了有效的单元测试。使用像spring这样的Ioc容器,在测试期间,协作者之间的依赖能够容易的用假的替代者替代。在这个航线的例子中,能够容易地从唯一的测试ApplicationContext中检索出像activity5活动这样的spring bean。用一个假的SMTP代理SMTP服务器,就有可能单独地测试activity5。
第二个意外的结果,可重用能力是通过像XSL转换这样的工作流活动实现的。一个被抽象成工作流活动的XSL转换现在能够被任何处理XSL转换的工作流所重用。
装配工作流
在提供的API中(从Resources下载),spring控制了一些操作者以一种工作流的方式交互。关键接口如下:
Activity: 封装了工作流中一个单步业务逻辑
ProcessContext:在工作流活动之间传递具有ProcessContext类型的对象。实现了这个接口的对象负责维护对象在工作流转换中从一个活动转换到另一个活动的状态。
ErrorHandler: 提供错误处理的回调方法。
Processor: 描述一个作为主工作流线程的执行者的bean。
下面从例子源码中摘录的代码是将航线例子装配为简单工作流过程的spring bean的配置。
BR>
BR> /property>
org.iocworkflow.test.sequence.ratedrop.RateDropContextBR>
/property>
SequenceProcessor类是一个对顺序模式建模的具体子类。有5个活动被连接到工作流处理器,工作流处理器将顺序执行这5个活动。
与大多数过程式后台进程相比,工作流的解决方案真正的突出了高度强壮的错误处理。错误处理句柄可以单独地处理每个活动。这种类型的句柄在单一活动级别提供了细致的错误处理。如果没有单独处理单个活动的错误处理句柄,那么全局工作流处理器的错误处理句柄将会处理出现的问题。例如,如果在工作流处理过程中的任意时刻,一个没有被处理的错误出现了,那么它将会向外传播,被使用defaultErrorHandler属性装配的ErrorHandler Bean处理。
更复杂的工作流框架将工作流转换之间的状态持久化存储到数据库中。在这篇文章中,我们仅仅对状态转换是自动完成的工作流感兴趣。状态信息仅仅在实际工作流运行时在ProcessContext中得到。在ProcessContext中,你仅仅能看到ProcessContext的接口的两个方法:
public interface ProcessContext extends Serializable {
public boolean stopProcess();
public void setSeedData(Object seedObject);
}
用于航线例子工作流的具体的ProcessContext类是RateDropContext类。RateDropContext类封装了用于执行航线费率降低工作流必须的数据。
到现在为止,经由缺省的ApplicationContext的作用,所有bean实例都已经成了单例。但是,对于每一个航线工作流的调用,我们必须创建一个新的RateDropContext类的实例。为了处理这种需求,需要配置SequenceProcessor,采用全限定类名作为processContextClass属性的值。对于每个工作流的执行,SequenceProcessor使用指定的类名从spring检索ProcessorContext类的一个新的实例。为了使这种机制能够起作用,非单件的spring bean或者类型org.iocworkflow.test.sequence.simple.SimpleContext的原型必须存在于ApplicationContext中(完整的列表,参见rateDrop.xml)。
播种工作流
既然我们知道怎样使用spring来组装一个简单的工作流,就让我们集中精力使用种子数据(seed data)示例工作流的过程。要明白怎样开始工作流,看一看在实际接口Processor上表现的方法:
public interface Processor {
public boolean supports(Activity activity);
public void doActivities();
public void doActivities(Object seedData);
public void setActivities(List activities);
public void setDefaultErrorHandler(ErrorHandler defaultErrorHandler);
}
大多数情况下,工作流需要一些初始化激活才能开始。开始一个处理过程有两个选项:doActivities(ObjectseedData)方法或者无参数的doActivities()。下面的代码列表是包含在样例代码中为SequenceProcessor而实现的doActivities():
public void doActivities(Object seedData) {
//Retrieve injected by Spring
List activities = getActivities();
//Retrieve a new instance of the Workflow ProcessContext
ProcessContext context = createContext();
if (seedData != null)
context.setSeedData(seedData);
//Execute each activity in sequential order
for (Iterator it = activities.iterator(); it.hasNext();) {
Activity activity = (Activity) it.next();
try {
context = activity.execute(context);
} catch (Throwable th) {
//Determine if an error handler is available at the activity level
ErrorHandler errorHandler = activity.getErrorHandler();
if (errorHandler == null) {
getDefaultErrorHandler().handleError(context, th);
break;
} else {
//Handle error using default handler
errorHandler.handleError(context, th);
}
}
//Ensure it's ok to continue the process
if (processShouldStop(context, activity))
break;
}
}
在这个航空费用减少的例子中,工作流过程的种子数据包括航线信息和费率减少的信息。使用容易测试的航线工作流例子,通过doActivities(Object seedData)方法发出种子数据并激活一个单一的工作流过程是简单的:
BaseProcessor processor = (BaseProcessor)context.getBean("rateDropProcessor");
processor.doActivities(createSeedData());
这些代码是从包含在这篇文章中的测试例子中摘录的。rateDropProcessor Bean是从ApplicationContext中检索来的。rateDropProcessor实际上是装配成SequenceProcessor的实例来处理顺序执行。createSeedData()方法实例化一个对象,这个对象封装了初始化航线工作流所需要的所有种子数据。
Processor选项
虽然包含在源代码中的Processor具体的子类仅仅是SequenceProcessor,但是,许多Processor接口的实现也是可以想象得到的。可以开发其他工作流处理过程子类来控制不同的工作流类型,例如,另一种像并行切割模式那样有着变化的执行路径的工作流。对于简单工作流来说,因为活动的顺序是预先决定了的,所以SequenceProcessor是好的选择。尽管没有被包括进来,对于使用基于spring的简单工作流的实现来说,排他选择模式是另一个好的选择。当使用排他选择模式时,在每个活动执行之后,Processor具体类就会讯问ProcessorContext,接下来将要执行哪一个活动。
注:有关并行切割,排他选择和其他工作流模式的更多信息,请参看W.M.P. van der Aalst等人写的《工作流模式》一书。
启动工作流
考虑到工作流过程常常需要异步执行的特点,使用分离的执行线程来启动工作流就变得有意义了。对于工作流的异步启动而言,有好几个选项;我们主要集中在其中的两个:积极地检测(actively polling)一个队列来启动工作流,或者使用通过ESB(enterprise service bus, 企业服务总线)的事件驱动方式来启动工作流,而Mule就是ESB的一个开源项目(关于Mule的更多信息,请参加"Event-Driven Services in SOA"(JavaWorld, 2005年1月)。
图3和图4描绘了两种启动策略。图3中,积极检测在工作流中第一个活动经常检查资源的情形下发生,比如数据源或POP3邮件帐户。如果图3中的积极检测发现有任务等待处理,那么启动就会开始。
图 3. 通过积极检测来启动工作流
另一方面,图4表示了使用JMS(JAVA消息服务)的J2EE应用程序把事件放到队列上的情形。一个通过ESB配置的事件监听器收到图4中的事件,并且开始工作流,这样,启动工作流过程。
图 4. 通过ESB事件来启动工作流
http://searchwebservices.techtarget.com.cn/tips/110/2127110.shtml
使用所提供样例的代码,让我们更详细的看看主动选择启动方式与事件驱动的启动方式。
积极检测
积极检测是一种花费较少的启动工作流过程的方案。SequenceProcessor足够灵活,以使得能够通过平滑的选择工作来进行启动过程。尽管并不令人满意,在没有时间进行事件驱动子系统的配置和部署的许多情景中,积极检测是明智的选择。
使用Spring的ScheduledTimerTask,检测模式就能够容易地装配。缺点就是必须创建额外的活动来进行检测。这个检测活动必须被设计来讯问某些实体,如数据库表,pop邮件帐户,或者Web服务,然后决定新的工作是否等待参与到工作流中。
在所提供的例子中,PollingTestCase类实例化一个基于检测的工作流过程。使用一个有着积极检测处理过程与事件驱动的启动过程的不同之处在于,spring支持doActivities()方法的无参数版本。相反地,在事件驱动的启动中,启动处理过程的实体通过doActivities(Object seedData)方法提供了种子数据来启动工作流。检测方法的另一个缺点是:资源不一定能够被重复地使用。依赖于应用程序环境,这种资源的消耗是不可接受的。
下面代码例子演示了使用积极检测来控制工作流启动的一个活动:
public class PollForWork implements Activity
{
public ProcessContext execute(ProcessContext context) throws Exception {
//First check if work needs to be done
boolean workIsReady = lookIntoDatabaseForWork();
if (workIsReady) {
//The Polling Action must also load any seed data
((MyContext) context).setSeedData(createSeedData());
} else {
//Nothing to do, terminate the workflow process for this iteration
((MyContext) context).setStopEntireProcess(true);
}
return context;
}
}
此外,包含在例子代码的单元测试中的PollRates类提供了一个主动选举启动的可以运行的例子。PollRates模拟了对于航线费率下降的重复检查。
通过ESB的事件驱动启动工作流
理想地,一个包含了适当的种子数据的线程能够异步地启动工作流。这种情况的一个例子是收到从JAVA消息服务队列的消息。一个监听JMS队列或者主题的客户会收到通知,这个通知告知处理应该在onMessage()方法中开始工作流。然后,通过使用Spring和doActivities(Object seedData)方法就能够获得工作流处理器Bean。
使用ESB,实际用于发送启动事件的机制能够恰当地从工作流处理器中分离出来。开源项目Mule ESB有紧凑地和Spring相集成的好处。任意传送机制,比如JMS,JVM,或者POP3邮箱都能够发起事件的传播。
工作流的连续运行
工作流引擎后台进程应该能够没有干扰地连续运行。对于正在运行的基于spring的工作流单一进程来说好,有几个选项。一个有着main()方法的简单Java类就足够演示与这篇文章伴随着的单元测试中的例子了。一个更加可靠的用于部署的机制是嵌入工作流到某种形式的J2EE组件中。Spring很好地支持和J2EE兼容的web应用程序归档或者war文件的集成。基于Java管理附件(JMX)服务归档和JBoss应用服务器(更多信息,参见JBoss homepage)支持的sar文件是更加合适的可部署组件,这种更合适的可部署组件也能够被用来将部署归档。在JBoss 4.0中,sar文件已经被大家所知道的deployer的格式所取代了。
例子代码
打包成zip格式的例程代码最好是用Apache Maven来使用它们。你能够在主源代码目录src/java找到API。src/java目录中有三个单元测试,包括:SimpleSequenceTestCase,RateDropTestCase和PoolingTestCase。要运行所有这些测试,在命令行shell中键入maven test,然后在编译和运行之前,Maven将会下载所有必需的jar文件。实际的XSL转换将会发生在两个测试中,它们的结果被管道输出到控制台。键入maven test:ui来拉出图形化的测试运行器,然后选择你想要运行的测试,并且观察控制台的结果。
结论
在这篇文章中你已经通过设计模式看到了工作流过程种类,在这些模式中,我们主要集中介绍了顺序模式。通过使用接口,我们来对基本工作流组件建模。通过装配多个接口实现到Spring,实现一个顺序工作流。最后还讨论了启动和部署工作流的不同选项。
这里所提出的简单工作流技术肯定不是最终的和革命性的。但是,使用Spring来实现像工作流这样的通用任务是一个通过使用IoC容器而获得的效率的好的示例。由于减少了粘合性代码的需要,Spring在保持面向对象的约束同时,减少面向对象操作麻烦的程度。
http://macrochen.blogdriver.com/macrochen/1088243.html
什么是工作流引擎(Workflow Engine )- -
所谓工作流引擎是指workflow作为应用系统的一部分,并为之提供对各应用系统有决定作用的根据角色、分工和条件的不同决定信息传递路由、内容等级等核心解决方案。例如开发一个系统最关键的部分不是系统的界面,也不是和数据库之间的信息交换,而是如何根据业务逻辑开发出符合实际需要的程序逻辑并确保其稳定性、易维护性(模块化和结构化)和弹性(容易根据实际业务逻辑的变化作出程序上的变动,例如决策权的改变、组织结构的变动和由于业务方向的变化产生的全新业务逻辑等等)。 Workflow 引擎解决的就是这个问题:如果应用程序缺乏强大的逻辑层,势必变得容易出错(信息的路由错误、死循环等等)。
就好比一辆汽车,外表做得再漂亮,如果发动机有问题就只是一个摆设。应用系统的弹性就好比引擎转速方面的性能,加速到100 公里需要1 个小时(业务流程发生变动需要进行半年的程序修改)还能叫好车吗?引擎动不动就熄火(程序因为逻辑的问题陷入死循环)的车还敢开吗?
工作流解决方案与传统管理软件的关系传统的管理软件注重解决企业应用层现存的问题(例如提高企业的资源配置率或提高单一员工的生产效率)。例如:EXCEL 可以提高员工画表格的效率、财务软件可以规范财务人员的工作并提高帐目查询的效率、CRM 可以规范客户管理从而使客户资源掌握在公司手中而不是被一部分业务人员把持并提高客户响应时间、ERP 解决的是如何配置企业资源:使企业的人力资源、财力资源和物资资源能够根据业务的需求实现最大化配置。 workflow 关注的是如何缩短流程闲置时间,从而提高企业的业务处理能力并使企业能够关注于真正对企业有意义的增值业务上。从建立企业神经系统的角度也许更能理解两者的区别。传统软件不能解决工作流的问题,例如ERP 关注的是企业的资源配置,但不可能解决资源传输过程中的损耗和降低传输(流程)的成本;同样workflow也不能完全解决传统管理软件所能解决的问题,例如对生产管理的MRP 系统所能解决的生产过程控制通过workflow很难实现。但一个好的传统软件如果希望能自动化地在整个企业中应用起来,必须有一个强大的逻辑层,用以解决信息传递的逻辑判断和自动流转,这个时候就需要workflow的平台。所以说: 1.workflow 和传统管理软件不是同一种软件,不具可比性; 2.workflow 对于已经有传统管理软件的企业的作用非常明显,可以籍此平台整合企业的各种应用系统,使之成为一个完整的企业级应用,也就是通常所说的EAI. 3. 具备workflow功能的管理软件(workflow与传统管理软件的结合)对于传统管理软件有绝对的优势;4.workflow可以根据企业的需要开发解决信息传递问题的流程以及帮助企业开发与现有应用系统的接口
工作流自动化并不复杂因为下述几个原因,工作流自动化业界有" 适合处理复杂业务流程" 的名声。
1.常规工作流自动化软件包及其部署相当昂贵。通常,伴随产品的是长时期的咨询关系。所以为了非常简单的业务流程购买和部署软件是被不被采纳的。这些软件通常只被用于复杂、关键和控制成本相对较高而工作流自动化带来的效益明显的量产型工作流应用。因此经销商和用户都会不自觉地关注于将复杂的业务问题自动化。 2. 处于类似原因,工作流研究人士首先会关注解决了哪些复杂的业务流程问题。
而对于大多数案例而言,为解决简单工作流程问题部署自动化软件的成本显然是不经济的。这里遵循一条简单的道理:走之前必须先会爬,跑之前必须先会走。 3. 最后一条原因,也是"IT 业的尴尬".总经理对IT部门经理工作衡量的标准就是:能够解决复杂问题的能力。自然,IT经理就会不遗余力地解决那些复杂的问题,他们的方案通常也就复杂而且昂贵。
所有这些目前都在改变。针对桌面电脑的应用方案快速发展以及工作流解决方案的发展使解决日常工作流程问题成为可能。费用不再昂贵,部署更为简便。事实上,企业越来越意识到工作流的重要性,同时在部署复杂关键的流程自动化之前,愿意从一些简单的流程入手积累经验。
工作流会成为操作系统的一部分吗?
有人认为工作流会成为操作系统平台(例如WINDOWS 平台)的一部分。我们的观点是,基于下述几个原因,在可预见的未来,工作流不会成为操作系统的一部分: 1. 扩展表格、文字处理程序和数据库存在了20多年,成了家喻户晓的名词。这些技术被广泛理解和应用,也相应形成了各自的标准和相关术语。然而因为很多原因,直到今天这些技术也没有成为操作系统的一部分。最重要的原因之一是用户需要差异和选择的自由。相比较而言,工作流自动化软件是较新的技术,也更有差异性、不易被广泛理解并且比这些技术更为先进。因为工作流程的差异性和复杂性,工作流自动化的用户需要更多的选择空间。
2.财务软件包从电脑发明后就迅速普及了。这是实施、术语和规则被普遍接受的另一个领域。然而至今也没有哪种操作系统吹嘘集成了多少财务软件的功能。而工作流自动化软件比财务软件更为复杂和有差异性。 3. 操作系统提供商,例如微软和Sun ,不会为了使其系统具备工作流自动化的功能而大量改变他们现有的系统。他们有什么必要为工作流自动化软件投入开发和支持的成本呢? 4. 操作系统是为常规条件设计并使之最优化。正因如此,目前操作系统的开发成本几乎都要上亿美元。业务流程十分复杂并充满了例外情况,如在操作系统中内嵌工作流自动化程序会极大地增加开发成本和难度。因此,即便操作系统提供商决定做工作流软件,也会是巨额投入开发一套新的操作系统,而不是将工作流嵌入。
事实上,今天的很多优秀的工作流解决方案集成了短信息、页面服务、目标管理、文件管理和其他一些操作系统才提供的服务。
工作流自动化的主要成分工作流自动化如今成了管理的一句时髦话。市面上也有很多号称能激活工作流的自动化产品。只要他们的应用程序支持基本的E-mail功能,卖主就会随意地把" 激活工作流" 作为标签贴在产品上。然而,这类产品和真正工作流自动化软件之间的差别就如同写字版和Word之间的差别。我们相信,应用程序只有具备了下列主要特征,才能称其为工作流自动化解决方案:
能够画出工作流程图,当然以图形化界面设计的为佳;能为每个步骤设计电子表格;能将外部应用程序结合为工作流自动化的一部分;能与电子表格及企业数据库相连接;能设计基于复杂业务规则的条件型路由的工作流程图,最好无须编程;能根据功能、用户名称或上下级关系按规则传递信息;能够监控工作流执行状况;能够对工作流进行调节;能够模拟并测试工作流的行为;工作流的应用必须支持多用户并具高度可靠性;工作流的应用必须支持内部网或英特网及跨多种平台。
网友讨论工作流应该是一个中间件而不应该是一个完整的系统。工作流应该整合到其他系统中而不是单独使用。
工作流要完成的核心功能有流程设计,流程执行,流程和线程的调度,任务的分派与通知,集成已有信息系统(很多人忘了)。
工作流应该提供对组织机构,用户,权限管理,流程,任务的管理能力,但是对这些管理能力最基本实现方式是提供API ,而不是一个管理系统,即使把这些管理作为一个管理系统来实现(A ),也主要是用于演示,因为当工作流用于其它系统(B ),因为B 需要一个统一的管理界面,所以通常不会直接使用A.而表单设计,报表之类根本就是外围功能,是二次开发商的任务。
我基本赞同wangtaoyy 的说法,再补充一点。我觉得工作流与其说是中间件,还不如说是一个应用整合和集成的框架。类似在j2ee规范下各产商开发的应用服务器,工作流也应当是在wfmc标准下开发出来的" 容器" ,只要是满足了标准的应用程序或组件都能够在这个" 容器" 中按照预定的规则被调度和执行。我认为理想情况下工作流系统不应该提供API 作二次开发,工作流的内部对基于工作流的应用程序应当是完全不透明的,工作流应当提供给开发者的是一个类似于J2EE那样的标准,一套编程模型和接口模型。开发者在这个模型下去实现那些接口,开发出应用组件,再利用工作流提供的管理器进行" 注册".总而言之,对开发者而言,工作流是黑箱,他需要做的事情是开发标准组件,在工作流提供的UI管理工具中配置业务流程,包括业务过程、资源、权限、时间、规则等等。
1. j2ee 应用服务器也是中间件的一种。
2. 工作流要做成j2ee哪样的标准还是比较困难的, j2ee 重点在于提供开发全新系统的能力,所以可以制定比较好的容器- 组件标准,而工作流的重点是整合已经存在的系统,要在这些各式各样的老系统上强加标准是不现实的。
3.工作流应该提供api ,因为其他系统中的一些事件可能会启动一个流程,或者触发其他与流程相关的东西
工作流分为两种类型,一种是嵌入式的,另一种是非嵌入式的。这在WFMC的文档中已经有所介绍,大家可以找找看一下。按照工作流管理联盟的文档,大家说的都没有什么错误,只是侧重点不同。wangtaoyy 的观点倾向于前者,而coffeewoo 的观点倾向于后者。
我的看法并不是趋向于嵌入式工作流。我理解的工作流提供的api 并不是一般软件包的API ,而是一种服务方式的API ,类似于操作系统中的系统调用。
我们在软件中大量使用了操作系统提供的系统调用API ,但是操作系统并不是嵌入到我们软件系统中的。我认为工作流系统与操作系统有很强的可比性,只是工作流层次更高。比如流程设计相当于编程,模型相当于程序,流程实例相当于进程,流程分支相当于线程,操作系统要对进程和线程进行调度,工作流引擎要对流程实例和分支进行调度,操作系统和工作流系统都应该对内存进行管理避免耗尽系统内存,操作系统提供系统调用API 而工作流引擎提供工作流API.何其相似。
从功能的角度看:工作流系统的本职工作就是管理和控制业务流程,例如:流程实例的启动、停止;环节实例的启动、结束;任务的分配等等。从工作流系统的组成看:工作流系统应该包括流程引擎、流程定义工具、运行管理工具、api 系统。工作流系统应该该不包括表单定义、组织机构定义及其管理、权限管理、数据流管理等等。
工作流系统虽然不包括上述功能,但是工作流系统一定会和上述功能发生交互关系,所以好的工作流产品并不是一个包办上述功能的产品,而是一个设计良好的能够和上述功能交互的系统。从和其他系统的关系看待工作流:如果站在基础业务平台的角度,那么,工作流系统、组织机构管理系统、表单自定义系统、权限管理系统、数据流管理系统、报表系统都是这个基础业务平台的服务。业务功能系统在运行的过程中会调用这些服务,这些服务之间本身也可能互相调用。例如:工作流服务和组织机构管理服务之间的关系就非常密切,尽管如此,如果认为工作流系统一定包含组织机构管理系统应该是不正确的。在oa系统中,表单自定义好像比较重要,而且流程常常需要引用表单上的数据,但是表单自定义绝对不是工作流系统的组成部分。流程在运行的过程中可能跨多个数据库系统,任务在流转的过程中需要“携带”大量的业务数据,但是这些也不是工作流要做的事情,完成这些工作的系统我称之为“数据流管理系统”。总之:从功能的角度,所有的功能都是必要的,但是从技术的角度,这些功能不可以做到一个“铁板一块”的所谓的“工作流”里面去。从技术发展的趋势看:工作流系统很可能发展成为一个类似关系型数据库管理系统的专职的系统。我那个工作流东东还在改进中,希望作出一个设计合理的(决对不是强行coding出来的),工程实用的东西出来
posted @
2006-06-01 14:12 崛起的程序员 阅读(1976) |
评论 (0) |
编辑 收藏
Note for Eclipse 3.1 Update Manager users: you can use special Eclipse update site for most plugins presented here. Go to "Help -> Software Updates -> Find and Install... -> Search for new features to install -> Next -> New Remote Site..." and use the http://andrei.gmxhome.de/eclipse/ as url.
Extended VS Presentation plugin for Eclipse: examples
Enable/disable Extended VS Presentation here
Set custom properties here (this settings will override current theme settings)
Change selected theme properties here (this settings will override current theme settings)
posted @
2006-05-31 15:50 崛起的程序员 阅读(298) |
评论 (0) |
编辑 收藏
凡是接触过
Java
的人都知道
JRE
的概念,即
Java
运行时环境(
Java Runtime Environment
),因为它是运行
Java
程序必不可少的(除非程序用
GCJ
等编译,但我怀疑这样处理后还能不能称之为“
Java
程序”了)。
Java
喊出的带有标志性的口号“
Write Once
,
Run Anywhere
(一次编写,到处运行)”(记得某老师给俺们上课讲到这里时还不忘幽一默:到处运行?没有计算机就运行不了……),正是建立在
JRE
的基础之上。何以实现?就是在
Java
应用程序和操作系统之间增加了一虚拟层——
JRE
。程序源代码不是直接编译、链接成机器代码,而是先转化到字节码(
bytecode
)这种特殊的中间形式,字节码再转换成机器码或系统调用。前者是传统的编译方法,生成的机器代码就不可避免地跟特殊的操作系统和特殊的机器结构相关,很多装双系统的用户无法在
Linux
运行
Windows
下的大型游戏,心里那个郁闷(于是很多虚拟软件和模拟程序应运而生)。而
Java
程序的字节码文件可以放到任意装有
JRE
的计算机运行,再由不同
JRE
的将它们转化成相应的机器代码,这就实现了
Java
程序的可移植性。这样程序员也不用去关心程序运行的具体环境,而可以专心编写软件。这种分层抽象、隐藏细节的思想在计算机科学中处处可见,比如机器组织结构的设计、网络协议的实现等。
Pascal
语言的发明者
Niklaus Wirth
,就富有预见性地指出应该有这样一种可移植的语言,其生成的中间代码可以在一台假想的机器(
a hypothetical machine
)上运行。而
Java
虚拟机(
Java virtual machine
或
JVM
)就是这样的一台机器,它模拟实际处理器的结构,解释字节码。怎么一会说是
JRE
,一会儿又成了
JVM
,两者是否同物不同名?
回答是否定的。
JVM
是
Java
平台的基础,和实际的机器一样,它也有自己的指令集,并且在运行时操作不同的内存区域。
JVM
通过抽象操作系统和
CPU
结构,提供了一种与平台无关的代码执行方法,即与特殊的实现方法、主机硬件、主机操作系统无关。但是在一些小的方面,
JVM
的实现也是互不相同的,比如垃圾回收算法,线程调度算法(可能不同
OS
有不同的实现)。
JVM
的主要工作是解释自己的指令集(即字节码)到
CPU
的指令集或
OS
的系统调用,保护用户免被恶意程序骚扰。
JVM
对上层的
Java
源文件是不关心的,它关注的只是由源文件生成的类文件(
class file
)。类文件的组成包括
JVM
指令集,符号表以及一些补助信息。
而
JRE
是
Sun
公司发布的一个更大的系统,它里面就有一个
JVM
。
JRE
就与具体的
CPU
结构和操作系统有关,我们从
Sun
下载
JRE
的时候就看到了不同的各种版本。同
JVM
一起组成
JRE
的还有一些
API
(如
awt
,
swing
等)。
JRE
是运行
Java
程序必不可少的。
Over
posted @
2006-05-22 22:30 崛起的程序员 阅读(710) |
评论 (1) |
编辑 收藏
一、读大学,究竟读什么?
大学生和非大学生最主要的区别绝对不在于是否掌握了一门专业技能,一个经过独立思考而坚持错误观点的人比一个不假思索而接受正确观点的人更值得肯定,草木可以在校园年复一年地生长,而我们却注定要很快被另外一群人替代,尽管每次网到鱼的不过是一个网眼,但要想捕到鱼,就必须要编织一张网。
二、人生规划:三岔路口的抉择
不走弯路就是捷径,仕途,商界,学术。在这人生的三岔路口,你将何去何从,与其跟一百个人去竞争五个职位,不如跟一个人去竞争一个职位,学术精神天然的应当与尘嚣和喧哗保持足够的距离,商场不忌讳任何神话。你也完全可能成为下一个传奇。
三、专业无冷热,学校无高低
没有哪个用人单位会认为你代表了你的学校或者你的专业,既然是概率,就存在不止一种可能性,如果是选择学术,冷门专业比热门专业更容易获得成就,跨专业几乎早已成为一种流行一种时尚,大学之间的实力之争到了考研考场和人才市场原来是那样的微不足道。
四、不可一业不专,不可只专一业
千招会,不如一招熟,十个百分之十并不是百分之百,而是零,在这个现实的社会,真正实现个人价值才是最体面最有面子最有尊严的事情,要想知道需要学什么,最好的方式就是留意招聘信息,很多专业因为不具备专长的有效性,所以成为了屠龙之术,为什么不将“买一送一”的促销思维运用到求职应聘的过程中来呢。
五、不逃课的学生不是好学生
什么课都不逃,跟什么课都逃掉没什么两样,读大学,关键是学会思考问题的方法,逃课没有错,但是不要逃错课,英语角绝对不是学英语的地方,为了英语丢了专业,那就舍本逐末了,招聘单位是用人才的地方,而不是培养人才的地方,既要逃课,又要让老师给高分。
六、勤工俭学的辩证法
对于贫困生来说,首先要做的不是挣钱,而是省钱,大部分女生将电脑当成了影碟机,大部分男生将电脑当成了游戏机,在这个处女膜都可以随意伪造的年代,还有什么值得轻易相信,态度决定一切,当学习下降到次要的地位,大学生就只能说是兼职的学生了。
七、做事不如做人,人脉决定成败
学问好不如做事好,做事好不如做人好,会说话,就能减少奋斗三十年,一个人有多少钱并不是指他拥有多少钱的所有权,而是指他拥有多少钱的使用权,一个人赚的钱,12.5%是靠自身的知识,87.5%则来自人脉关系,三十岁以前靠专业赚钱,三十岁以后拿人脉赚钱,你和世界上的任何一个人之间只隔着四个人。
八、互联网:倚天剑与达摩克利斯之剑
花两个小时就写出一篇天衣无缝的优秀毕业论文,在互联网领域创业的技术门槛并不高,关键的是市场眼光和营销能力,轻舞飞扬已经红颜薄命了,而痞子蔡却继续跟别的女孩发生着一次又一次的亲密接触,很多大学生的网友遍布祖国大江南北,可他们却从未主动向周围的人说一声:你好,我们可以聊聊吗。
九、恋爱:花开堪折方须折
爱情是不期而至的,可以期待,但不可以制造,越是寂寞,越要警惕爱情,既然单身是可耻的,那西门庆是不是应该被评为宋朝十大杰出青年,花开堪折方须折,莫让鲜花败残枝,一个有一万块钱的人为你花掉一百元,你只占了他的百分之一;而一个只有十块钱的人为你花掉十块,你就成了他的全部。
十、性:上帝死了,众神在堕落
爱要说,爱要做,我只有在肉体一下一下的撞击中才感到快乐。经过之后,将是更大的寂寞更大的空虚,为何要让别人的虚荣成为对自己的伤害,当她机械地躺在床上张开双腿,她的父母正在憧憬着女儿的未来,一朝春尽红颜老,花落人亡两不知。
十一、考研:痛苦的安乐死
没有比浪费青春更失败的事情了,研究生扩招的速度是30%,也就意味着硕士学历贬值的速度是30%,同样是付出三年的努力,你可以让E1的值增加1,也可以让E2的值增加2甚至增加3,读完硕士或博士并不等于工作能力更强,面对13.54万的成本,你还会毫不犹豫地投资读研究生吗,努力就会有结果,但不一定是好结果。
十二、留学:“海龟”变“海带”
月薪2500元的工作,居然引得三个“海归”硕士争相竞聘,对于某些专业而言,去美国留学和去埃塞俄比亚留学没什么两样,既然全世界的公司都想到中国的市场上来瓜分蛋糕,为什么中国人还要一门心思到国外去留学然后给外国人打工。
十三、非统招:养卑照样处优
她在中国信息产业界创下了几项纪录。她被称为中国的“打工皇后”。而她不过是一名自考大专生,要想把曾经输掉的东西赢回来,就必须把自己比别人少付出的努力补上来,非统招生不但要有一定的实力,而且必须掌握一定的技巧,做到扬长避短出奇制胜,路在脚下。好走,走好。
十四、毕业:十面埋伏的陷阱
母校不把自己当母亲,你又何必把自己当儿女,听辅导班不过是花钱买踏实,人才市场就是一个地雷阵,通过多种方式求职固然没有错,但是千万不要饥不择食,只要用人单位一说要你交钱,你掉头就走便是了,这年头立字尚且不足以为据,更何况一个口头约定。
十五、求职:做人不要太厚道
求职简历必须突出自己的核心竞争力,求职的时候大可不必像严守一那样“有一说一”,一个人说假话并不难,难的是把假话说到底,并且不露一丝破绽,在填写自己的特长时,一定要尽可能详细,一份求职简历只要用一张A4纸做个表格就足够了,面试其实是有规律的,每次面试的时候只要背标准答案就行了。
十六、骑一头能找千里马的驴
美国铁路两条铁轨之间的标准距离是4英尺8.5英寸,为什么呢?因为两匹马臀部之间的宽度是4英尺8.5英寸,垃圾是放错位置的人才,世界上最大的悲剧莫过于有太多的年轻人从来没有发现自己真正想做什么,中小型企业或许能够让你得到更充分的锻炼,从基层做起并不意味着可以从基层的每一个职位做起,要“钱途”,更要前途。
十七、写字楼政治:白领必修课
大公司是做人,小公司是做事,职员能否得到提升,很大程度不在于是否努力,而在于老板对你的赏识程度,公司的事情和秘密永远比你想象的还要复杂和深奥,在适当的时候装糊涂不但是必要的,而且是睿智的,就把你的同事当成一群你可以叫得出名字的陌生人好了。
十八、创业:29岁以前做富翁
瘦死的骆驼比马大,撑死胆大的,饿死胆小的,不再是“大鱼吃小鱼”,而是“快鱼吃慢鱼”,对于趋势的把握是一个创业者最重要的能力,高科技行业留给毕业生的空间已经很小,欲速则不达。在创业以前通过给别人打工而积累经验是非常必要的,市场永远比产品更重要,钱不够花,怎么办?第一,看菜吃饭;第二,借鸡生蛋。
posted @
2006-05-19 15:30 崛起的程序员 阅读(199) |
评论 (0) |
编辑 收藏
关于李煜
李煜(937-978),初名从嘉,字重光,号钟隐,又号钟峰白莲居士,即位后改名煜。南唐中主第六子。徐州人。宋建隆二年(961年)在金陵即位,在位十五年,世称李后主。他嗣位的时候,南唐已奉宋正朔,苟安于江南一隅。宋开宝七年(974年),宋太祖屡次遣人诏其北上,均辞不去。同年十月,宋兵南下攻金陵。明年十一月城破,后主肉袒出降,被俘到汴京,封违命侯。太宗即位,进封陇西郡公。太平兴国三年(978)七夕是他四十二岁生日,宋太宗恨他 有“故国不堪回首月明中”之词,命人在宴会上下牵机药将他毒死。追封吴王,葬洛阳邙山。 后主前期词作风格绮丽柔靡,还不脱“花间”习气。国亡后在“日夕只以眼泪洗面”的软禁生涯中,以一首首泣尽以血的绝唱,使亡国之君成为千古词坛的“南面王”(清沈雄《古今词话》语),正是“国家不幸诗家幸, 话到沧桑语始工”。这些后期词作,凄凉悲壮,意境深远,已为苏辛所谓的 “豪放”派打下了伏笔,为词史上承前启后的大宗师,如王国维《人间词话 》所言:“词至李后主而眼界始大,感慨遂深。”至于其语句的清丽,音韵 的和谐,更是空前绝后的了。 后主本有集,已失传。现存词四十四首,其中几首前期作品或为他人所作,可以确定者仅三十八首。
李煜李煜是多才多艺身,又是多福多苦命。
说他是多才多艺身,是因为他工书善画,能诗擅词,又精通音乐。他玩什么,都能玩出名堂。他的书法,自成一家,创造出了“聚针钉”、“金错刀”、“撮襟”等体式。他作画,“远过常流,高出意外”(郭若虚《图画见闻志》)。他创作的乐曲,也很“奇绝”,亡国前创作的《念家山》、《念家山破》等乐曲,流行很广,“宫中民间日夜奏之,未及两月,传满江南”(邵思《雁门野说》”。他还会点武艺,像李璟,弧矢箭术都不赖。多才多艺、精通音律的李煜,写起小词来,自然是驾轻就熟。他能创造出《虞美人》之类的绝妙好词,一点也不奇怪。
说他多福,首先是因为他原本无缘也无心做世子、当国主,却一不小心,当上了世子,做上了国主。他是李璟的第六子,当世子、做国主原本没有他的份儿。可憨人有憨福。他的长兄弘冀早就被立为世子,可弘冀莫名其妙地暴死,其他四位兄长又都早夭,这样李煜就成了“老大”,于是在建隆二年(961),顺利地被立为世子。同年,李璟病逝,李煜在金陵登上国主的宝,拥有了至高无上的地位。
后主登基的时候,宋太祖赵匡胤已建言了宋王朝,统一了北方。只是大宋要一个个地收拾其他小国,一时还顾不上平定南唐。于是李后主有李会苟延残喘,做了十五年的小国之君。宋太祖曾说:“卧榻之下,岂容他人酣睡。”李煜居然在宋太祖的卧榻之下,小心翼翼地睡了十五年。这也算是有福气吧。
他的福气,还不止这些。事业、爱情都美满,才是真正圆满的人生、幸福的人生。李煜的爱情,也挺幸福的。先后两个王后,都是天姿国色,而且多才多艺,跟他又情投意合。大周后,小字娥皇,精通书史,善解间律,特别擅长演奏琵琶。既会谱曲,又能填词,可惜没有词作流传下来。她还是一位时装和发型设计师,曾设计“高髻纤裳及首翘鬃朵之妆”,人人仿效。有这样一位可人儿作伴侣,叫后主片不心满意足?小周后,是娥皇的妹妹,也是“警敏有才思,神彩端静”,风情万种。后主与小周后婚前的爱情,更具有刺激性,更令他心荡神怡。如果说大周后要是引发了后主对音乐的兴趣爱好,间接促进了后主词的创作,那么小周后与后主婚前的频频幽会,则是直接为后主的词作提供了素材。后主词中的“刬袜步香阶,手提金缕鞋”,就是写与小周后的恋爱经历。
菩萨蛮
花明月黯笼轻雾,今霄好向郎边去!
刬袜步香阶,手提金缕鞋。
画堂南畔见,一向偎人颤。
奴为出来难,教君恣意怜。
李后主算不上好国主,却是一个优秀的词人,有着艺术家的天真和坦诚。身为国主,连自己的恋爱故事也不隐瞒,公开写到词里让人传唱,这是多么坦率多情!也许是他觉得这场恋爱太惬意太美满,以致于情不自禁,跟情人约会之后就把约会的情景用词记录下来,作为刻骨铬心的永恒纪念。
据马令《南唐书》记载,在大周后病重期间,后主就与她的小妹相恋。娥皇死后,后主娶她小妹为继室,世称小周后。这首词就是写他与小周后婚前的一次约会。
词以第一人称的口吻,让小周后自述约会的过程,表现她的多情与主动。后主真诚坦率之中,也有狭义狯的一面。他不说自己相约对方,而是说她如何主动大胆。在这场不太合乎当时伦理规范的恋爱中,他似乎是被动的。当然,他们爱得非常意愿。名人的恋爱故事本来就吸引人,风流帝王的恋爱故事更有魅力。这首词的魅力,倒不仅仅是因为名人效应,艺术上也相当成功。几个细节和动作,就把人物写得活灵活现。手提绣鞋,刬袜潜来,见出女子的谨慎心细,生怕被别人发现。“偎人颤”,传神地写出她与情郎见面时既紧张又惊喜的神态。词是专门抒情的诗体,但有些词抒情时隐含着故事,或者说是因事言情,在讲故事时表达情思。词中这种因事言情的物法,韦庄是最先使用的。他的《荷叶杯》上片回忆当年与情人约会的故事:“记得那年花下。深夜。初识谢娘时。水堂西面画帘垂。携手暗相期。”把约会的时间、地点、过程交代得一清二楚。词中这类故事到底是讲词人的经历,还是别人的事情,虽然很难判断,但总有一种逼真感、现场感。这种像是亲身经历的感情故事更能引起读者听众的兴趣。到了宋代,欧阳修和柳永的词也常常使用这种手法,在浓浓的情思中隐含着模糊的故事。
浪淘沙
往事只堪哀,对景难排。
秋风庭院藓侵阶。
一任珠帘闲不卷,终日谁来?
金剑已沉埋,壮气蒿莱。
晚凉天净月华开。
想得玉楼瑶殿影,空照秦淮!
此词为入宋后抒写幽闭时心情。
“往事只堪哀”,是说想起往事就悲哀,而不是说想起悲哀的往事。后主被俘入宋后,总是难忘故国的“往事”。《虞美人》词说“往事知多少”;《菩萨蛮》词说“往事已成空”,可见他的“往事”是指过去欢乐“往事”。如今触目皆悲,所以想起欢乐的往事,更倍增伤感。开篇流露的是幸福的失落感,接下来表现的是沉重的孤独感。庭院长满了苔藓,可见环境的极度荒凉冷清。室内也是死气沉沉。珠帘不卷,既是无人卷,也是无心卷帘。户外荒凉,触目肠断,不如呆在室内消磨时光。可长期龟缩幽闭一室,内心的孤独还是不能排解。他在期盼人来,期盼着与人交流、倾诉,可等待“终日”,不见人来,也无人敢来。据宋人王铚《默记》记载,后主在汴京开封的住处,每天都有“一老卒守门”,并“有旨不得与外人接”。李煜在汴京,实质是被软禁的囚徒。他明明知道没有人愿意来看望,也没有人敢来看望,却偏偏说“终日”有“谁来 ”。他是在失望中期盼,在期盼中绝望。这就是李后主的心态。
在极度孤独中度日的李煜,打发时光、排遣苦闷的最好方式是回忆往事。金剑沉埋于废墟,壮气消沉于荒草,复国的机会与可能是一点儿也没有了,只好任命吧!就这样过一天算一天吧!
上片写的是白天,下片写晚上,晚凉天静,月华普照,全词的境界闪出一丝亮色,主人公的心情也为之开朗。可这月亮已非故乡之月,就像建安时期王粲《登楼赋》所说的“虽信美而吾土”。于是他由月亮想到当年月光照耀下的秦淮河畔的故国宫殿。但玉楼瑶殿已非我有,明月照得再亮,也只能徒增伤感。后主总是这么执着地留恋过去,故国成了他解不开的情结。故国情结是他后期词作的一大主题,也是他打发孤独寂寞时光的一副强心剂。但故国情结并不能解脱心中的屈辱与痛苦。他靠回忆过去打发时光。可是一旦从过去的往事中回到现实,又痛苦不堪。这样周而复始,后主深深地陷入了无法解开的心理怪圈。
由王子、君主到臣虏,李后主的人生经历了巨大的反差。正如唐圭璋在《李后主》评传》中所说:“他身为国王,富贵繁华到了极点,而身经亡国,繁华消竭,不堪回首,悲哀也到了极点。正因为他经历过这种极端的悲乐,遂使他在文学上的收成也格外光荣而伟大。在欢乐的词里,我们看见一朵朵美丽之花;在悲哀的词里,我们看见一缕缕的血痕泪痕。”
然而富贵繁华也好,悲哀血泪也好,这些都违背了李煜的本愿。他的最初理想是做一个远离尘寰逍遥山林的隐逸之士。在《即位上宋太祖表》中,李后主说的很明白:臣本于诸子,实愧非才。自出胶庠,心疏利禄。……思追巢、许之余尘,远慕夷、齐之高义。意思是说:当君主并不符合自己本来的志愿。自己的理想只是追步巢父、许由的后尘,做一个像伯夷、叔齐式的隐士。他为自己取了许多别号,自称“钟山隐士”、“钟锋隐者”、“钟锋隐居”、“莲峰居士”,省称曰“钟隐”。可知他心神向往的,完完全全是超越尘俗的山林生活啊!
正是:林花谢了春红, 太匆匆。无奈朝来寒雨,晚来风!
posted @
2006-05-19 15:23 崛起的程序员 阅读(195) |
评论 (0) |
编辑 收藏