JBoss规则引擎与Web Services <o:p></o:p>
作者: Mark Proctor <o:p></o:p>
我最近刚刚完成了一个项目,其中JBoss规则引擎通过Web Services来提供使用。因此我写下其中的一些细节。<o:p></o:p>
在这个特殊的项目中,只有有效负载(payload)中的根对象被设置,整个payload不被分成更小的关联对象设置到Working Memory中,通常这样被认为是最佳实践方式;无论怎样,我们在这里演示给你看怎样有效率的在嵌套的XML有效负载中使用‘from’。
我所理解的步骤可以简单定义如下:<o:p></o:p>
- 为你的模型建立一个XSD<o:p></o:p>
- 使用JAXB's XJC产生类<o:p></o:p>
- 在你的XML有效负载中解包(Unmarshal),并设置root对象<o:p></o:p>
- 在你的规则中使用from对模型导航<o:p></o:p>
- 得到修改后的模型和封包(marshal)<o:p></o:p>
为你的模型建立XSD
<o:p></o:p>
一开始你需要使用XSD来描述你的模式,看起来如下:
xml 代码
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="creditscore" targetNamespace="creditscore"> <xs:complexType name="root"> <xs:sequence> <xs:element name="division" type="xs:string"/> <xs:element name="occupancy" type="xs:string"/> <xs:element name="occupancyAdjustment" type="xs:double"/> <xs:element name="creditScore" type="CreditScore" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="CreditScore"> <xs:sequence> <xs:element name="programGroup" type="xs:string"/> <xs:element name="lienType" type="xs:string"/> <xs:element name="division" type="xs:string"/> <xs:element name="score" type="xs:double"/> </xs:sequence> </xs:complexType> <xs:element name="Root" type="root"/> </xs:schema>
Pojo
从Sun网站https://jaxb.dev.java.net/可获得最新的JAXB参考实现,我使用jaxb<st1:chsdate w:st="on" isrocdate="False" year="1899" day="30" islunardate="False" month="12">2.1.3</st1:chsdate>。从命令行执行下面的命令:<o:p></o:p>
jaxb-ri-20070413\bin\xjc -p org.domain -d c:\folder MyModel.xsd <o:p></o:p>
这建立了三个对象,ObjectFactory和Root、CreditScore两个类。看起来如下:<o:p></o:p>
<o:p> </o:p>
<o:p>
java 代码
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "root", propOrder = {"division", "occupancy", "occupancyAdjustment", "creditScore1", "creditScore2"}) public class Root { @XmlElement(required = true) protected String division; @XmlElement(required = true) protected String occupancy; protected double occupancyAdjustment; protected CreditScore creditScore1; protected List creditScore2; public String getDivision() { return division; } public void setDivision(String value) { this.division = value; } public String getOccupancy() { return occupancy; } public void setOccupancy(String value) { this.occupancy = value; } public double getOccupancyAdjustment() { return occupancyAdjustment; } public void setOccupancyAdjustment(double value) { this.occupancyAdjustment = value; } public CreditScore getCreditScore1() { return creditScore1; } public void setCreditScore1(CreditScore value) { this.creditScore1 = value; } public List getCreditScore2() { if ( creditScore2 == null ) { creditScore2 = new ArrayList(); } return this.creditScore2; } } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "CreditScore", propOrder = {"programGroup", "lienType", "division", "score"}) public class CreditScore { @XmlElement(required = true) protected String programGroup; @XmlElement(required = true) protected String lienType; @XmlElement(required = true) protected String division; protected double score; public String getProgramGroup() { return programGroup; } public void setProgramGroup(String value) { this.programGroup = value; } public String getLienType() { return lienType; } public void setLienType(String value) { this.lienType = value; } public String getDivision() { return division; } public void setDivision(String value) { this.division = value; } public double getScore() { return score; } public void setScore(double value) { this.score = value; } }
在你的XML有效负载中解包(Unmarshal),并设置Root对象
<o:p></o:p>
你现在可以用JAXB解包你的XML负载:<o:p></o:p>
<o:p> </o:p>
<o:p>
java 代码
</o:p><o:p>
JAXBContextImpl jc = (JAXBContextImpl) JAXBContext.newInstance( "org.domain" ); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement element = ( JAXBElement ) unmarshaller.unmarshal( new File( XML_FILE ) ); Root root = ( Root ) element.getValue();
在你的规则中使用from对模型导航<o:p></o:p>
'from' 在Drools4.0中是一个新的元素,它允许规则对working memory以外的数据上进行规则推论。我们可以使用‘from’对模型中的子对象进行导航<o:p></o:p>
<o:p> </o:p>
<o:p></o:p>得到修改后的模型和封包(marshal)<o:p></o:p>
java 代码
package creditscore import creditscore.CreditScore rule "Credit_Score_Adjustments_0" dialect "mvel" no-loop true when r : Root( division=="wholesale", occupancy=="Investors" ) cs : CreditScore( programGroup=="ACMEPowerBuyerGroup", lienType=="FIRST_TD; SECOND_TD", division=="Wholesale", score >= 500, score <= 579) from r.creditscore then cs.score = cs.score + 1; modify(cs); end
<o:p> </o:p>
<o:p>
java 代码
</o:p><o:p>
RuleBase ruleBase = RuleBaseFactory.newRuleBase(); ruleBase.addPackage( pkg ); StatelessSession session = ruleBase.newStatelessSession(); StatelessSessionResult results = session.executeWithResults( new Object[] { root } ); Root returnedRoot = ( Root ) results.iterateObjects().next(); Marshaller marshaller = jc.createMarshaller(); marshaller.marshal( new JAXBElement( new QName("org.domain", "Root"), returnedRoot.getClass(), returnedRoot ), System.out );
</o:p></o:p></o:p>模型现在可以使用JAXB's XJC建立。