下面是本人总结的一些WLI81的使用经验,写出来,与大家共享
从开发环境发布应用到生产环境...
改变process的会话周期...
LOG 处理...
如何创建一个XMLBean.
Process的Exception Handle.
采用Xquery操作XML.
取得Process中变量的值...
从开发环境发布应用到生产环境
在WORKSHOP中把整个应用编译成一个EAR文件,把该EAR文件直接放到DOMAIN的applications目录下,该APPLICATION中的每个Project都要创建两个JMS Queue. 如该applications有一个名为AccountSyn的Project。就要创建两个JMS QUEUE。JNDI如下。
AccountSyn.queue.AsyncDispatcher
AccountSyn.queue.AsyncDispatcher_error
在创建时,可同时打开开发环境与生产环境的CONSOLE,进行比较。对照创建生产环境上的JMS QUEUE。创建完毕后,要重新启动WLI才能生效。
改变process的会话周期
process缺省的会话周期为1天,即流程实例1天有效。如果超过1天,还没有完成的process实例都会自动消失掉。有很多流程不可能在一天之内完成。可通过下面的方法改变process的会话周期,在WORKSHOP中点击Source View,然后在Property Editor ->conversation-lifetime-> max-age设定相应的会话周期。
LOG 处理
一种不好的做法是在Process的代码中通过System.out.println()直接打印调试信息。比较好的做法是通过context.getLogger()来打印LOG信息.
context.getLogger("vartest.jpd").info("vartest.jpd启动");
将在WLI81的启动窗口上打印出:
<2004-4-4 下午14时16分26秒 CST> <Info> <WLW> <000000> <vartest.jpd启动>
当然,还可以利用context.getLogger("vartest.jpd"). error()等打印出其他级别的LOG.
可以写一个LOG函数,在其他地方直接调用就可以了
public void log (String message) throws java.lang.Exception
{
Logger logger=this.context.getLogger("vartest.jpd ");
logger.info(message);
}
更好的方法是通过LOG4J等来统一处理整个APPLICATION的LOG.
注意: 要在CONSOLE中把该SERVER的LOG级别设置为INFO,才能打印出info级别的LOG.如下图所示.
如何创建一个XMLBean
一般一个PROCESS INTANCE 在启动时接收一个XMLBean当输入参数, 在WLI81中,通常采用PageFlow来开发Processs的客户端,在PageFlow中可通过FormBean提取Form中各个字段的值。然后拼成一个长的XML字符串,再用XmlObject.Factory.parse(str) 转化为一个XML Object 或一个 XMLBean. 然后当启动流程的参数或在其他地方使用。如下所示:
StringBuffer sb = new StringBuffer(10000);
sb.append("<settleQueryResult>");
sb.append("<seqNumber>");
sb.append(this.seqNumber);
sb.append("</seqNumber>");
sb.append("<sender>");
sb.append(settleOrderObj.sender);
sb.append("</sender>");
sb.append("</settleQueryResult>");
SettleQueryResultDocument doc;
SettleQueryResultDocument.SettleQueryResult qr;
doc= SettleQueryResultDocument.Factory.parse(sb.toString());
qr=doc.get SettleQueryResult();
更简单的方式是直接采用XMLBean的SET方法把值传入。如下所示:
try
{
ShipOrderDocument sod;
sod = ShipOrderDocument.Factory.newInstance();
ShipOrder so=sod.addNewShipOrder();
so.setBeginDate(form.getBeginDate());
so.setCargoName(form.getCargoName());
so.setOriginAddress(form.getOriginAddress());
so.setQuantity(form.getQuantity());
Context ctx = new InitialContext();
RemoteWorklistManagerHome
pwmh=(RemoteWorklistManagerHome)ctx.lookup("RemoteWorklistManagerBean");
RemoteWorklistManager rwmb=(RemoteWorklistManager)pwmh.create();
com.bea.xml.XmlObject[] newOrder={sod};
String s=rwmb.startProcess("/postPortal/shipOrder/shipOrder.jpd","clientRequest",
newOrder);
}
catch(Exception e)
{
e.printStackTrace();
}
Process的Exception Handle
“接收Partner发来的ebXML数据” 节点的代码如下:
try
{
newOrder = SettleOrderDocument.Factory.parse(this.payload.toString());
settleOrder = newOrder.getSettleOrder();
}
catch(Exception e)
{
e.printStackTrace();
}
seqNumber=settleOrder.getSeqNumber();
sumAmount=settleOrder.getSumAmount();
System.out.println(“seqNumber=”+ seqNumber);
如果没有上面的OnException。当settleOrder=NULL时。流程将继续往后走到System.out.println(“seqNumber=”+ seqNumber);
如果有了上面的OnException,当settleOrder=NULL,流程将只走到seqNumber=settleOrder.getSeqNumber(); 然后进入ProcessException()。
如果 “接收Partner发来的ebXML数据” 节点的代码如下:
try
{
newOrder = SettleOrderDocument.Factory.parse(this.payload.toString());
settleOrder = newOrder.getSettleOrder();
seqNumber=settleOrder.getSeqNumber();
sumAmount=settleOrder.getSumAmount();
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(“seqNumber=”+ seqNumber);
那么不管有没有OnException, 流程将继续往后走到System.out.println(“seqNumber=”+ seqNumber);
采用Xquery操作XML
以下是XMLBean的Schema,和通过Schema转换和取得节点的方法:
Schema:
<?xml version="1.0" encoding="gb2312"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Demo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Node" minOccurs="1">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="value" type="xsd:string"/>
<xsd:element name="type" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
从文件或者字符串中取得XMLBean,然后查询节点的例子:
DemoDocument dd=
DemoDocument.Factory.parse(new File("D:\stepdoc.xml"));
String s="/Demo/Node"; //查询节点的XQuery
Node[] sarr=(Node[])dd.selectPath(s);
for(int i=0;i<sarr.length;i++){
System.out.println(sarr[i].getName()+":"+sarr[i].getValue());
}
System.out.println(dd.getDemo().getNode().getName());
其他具体例子,可以参照Workshop帮助。
取得Process中变量的值
可以通过MBEAN来取得Process中变量的值。代码如下:先用RemoteWorklistManager的startProcess()启动流程,并返回该流程实例的ID,再通过ProcessRuntimeMBean的getProcessVariable()方法和ProcessVariableValue的getValueRepresentation()方法取到变量的值. 该流程实例必须还没有结束才能取到变量的值.如果该流程实例已经结束,会抛异常:
<2004-4-4 下午16时57分30秒 CST> <Error> <WLW> <000000> <Conversation not found.ServiceURI:/jpd0404Web/processes/vartest.jpd InstanceId:127.0.0.1-1531aca.fbb421
c0ee.-7fb2
java.lang.NullPointerException
at com.bea.wli.management.adminhelper.AdminHelperBean.getProcessContaine
rBean(AdminHelperBean.java:412)
try
{
String fd[] = new String[1];
fd[0]="***test***";
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, "t3://127.0.0.1");
p.put(Context.SECURITY_PRINCIPAL,"weblogic");
p.put(Context.SECURITY_CREDENTIALS,"weblogic");
Context ctx = new InitialContext(p);
RemoteWorklistManagerHome pwmh=(RemoteWorklistManagerHome)ctx.lookup("RemoteWorklistManagerBean");
RemoteWorklistManager rwmb=(RemoteWorklistManager)pwmh.create();
String s=rwmb.startProcess("/jpd0404Web/processes/vartest.jpd","clientRequest", fd);
ProcessRuntimeMBean prmb=MBeanHelper.getProcessRuntimeMBean();
ProcessVariableValue pvv=prmb.getProcessVariable("/jpd0404Web/processes/vartest.jpd",s,"str1");
String ss= (String)pvv.getValueRepresentation();
System.out.println("ss= " + ss) ;
}
catch(Exception e)
{
e.printStackTrace();
}
采用这种方式,Client端必须和Process在同一个Project中才可以.
还可以通过设置流程的启动方式为”Invoked synchronously via a client Request with Return”, 在其他地方通过JPD PROXY方式启动该流程,并把变量当返回值.
PROXY的start()方法的返回值就是Process实例的返回的变量值.
.
另一种方式是把变量当返回值. 在客户端以HTTP方式调用该Process. 在客户端通过取HTTP连接的输出得到该Process的返回值.
| 作者简介 |
|
徐春金(dev2dev ID: xcjing)BEA 技术顾问 |
|