自定义创建服务
createTutorial transition使用了隐含的 entity-auto 服务 create#tutorial.Tutorial。下面我们看看手工定义和实习一个服务要怎么做。
首先定义一个服务并使用自动实体 CRUD 实现:
runtime/component/tutorial/service/tutorial/TutorialServices.xml
<?xml version="1.0" encoding="UTF-8"?>
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-definition-2.1.xsd">
<service verb="create" noun="Tutorial" type="entity-auto">
<in-parameters>
<auto-parameters include="all"/>
</in-parameters>
<out-parameters>
<auto-parameters include="pk" required="true"/>
</out-parameters>
</service>
</services>
这里允许传入Tutorial实体的所有字段,包括主键字段 tutorialId(可选),如果没有指定主键字段的值,那么会生成一个序列ID。 它(总会)返回主键字段(tutorialId)。注意 auto-parameters 元素,我们是基于实体定义的服务,如果我们加了字段到实体,加了的字段会自动表达到服务。
service.@type 设置为"entity-auto"的一个奇怪的地方是它使用 service.@noun 作为实体名。名字里不需要实体的包名也能行,是因为框架允许使用没有包名的实体名,尽管在不同的包里有同样名字的实体时会导致不一致的结果。
现在更改服务定义为增加一个内联(inline)的实现。注意有修改service.@type属性,有添加actions元素。
相关改动
改动后的tutorialServices.xml
<?xml version="1.0" encoding="UTF-8"?> <services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-definition-2.1.xsd"> <service verb="create" noun="Tutorial" type="inline"> <in-parameters> <auto-parameters include="all"/> </in-parameters> <out-parameters> <auto-parameters include="pk" required="true"/> </out-parameters> <actions> <entity-make-value entity-name="tutorial.Tutorial" value-field="tutorial"/> <entity-set value-field="tutorial" include="all"/> <if condition="!tutorial.tutorialId"> <entity-sequenced-id-primary value-field="tutorial"/> </if> <entity-create value-field="tutorial"/> </actions> </service> </services>
调用此服务而不是隐含的entity-auto,只要更改 transition 为指向此服务:
<transition name="createTutorial">
<service-call name="tutorial.TutorialServices.create#Tutorial"/>
<default-response url="."/>
</transition>
注意像这样定义的服务的名字像一个全限定Java类名。有一个“包”("tutorial"),它是component/service目录下的目录(也可能是有点号分隔的多个目录的路径)。然后是一个点号和等效的类名("TutorialServices"),它是服务所在的XML文件名,但没有.xml后缀。后面跟着另一个点号,然后是有动词和由#号分隔的名词的服务名。