服务的定义

Moqui框架的主要逻辑单元是服务。这是一个面向服务的架构,小粒度的逻辑单元,又被用作外部的、大粒度的逻辑聚合。Moqui服务支持:

  • 事务
  • 安全(身份鉴定和鉴权,加上流量限制的Tarpit)
  • 验证(数据类型和多种输入参数的约束)
  • 用包括脚本语言、Java方法甚至一个Apache Camel终端的多种语言和工具实现
  • 在本地或远程调用运行
  • 同步、异步或按计划运行
  • 在执行的多个阶段的事件触发源,以使用服务事件条件动作(ServiceECA)来运行其他服务
  • 可选地用一个数据库信号量(semaphore)约束为单运行实例

服务 用 service 元素定义在一个服务XML文件中。服务的名字由路径、动词和名词以${路径.动词#名词}的结构组成。注意在服务定义中名词是可选的,在服务名中动词和名词间的井号(#)也是可选的。这是一个例子,mantle.party.PartyServices.create#Person 服务(来自Mantle业务构件):

<service verb="create" noun="Person">
        <in-parameters>
            <auto-parameters entity-name="mantle.party.Party"/>
            <auto-parameters entity-name="mantle.party.Person" include="nonpk"/>
            <parameter name="firstName" required="true"/>
            <parameter name="lastName" required="true"/>
            <parameter name="roleTypeId"/>
        </in-parameters>
        <out-parameters><parameter name="partyId"/></out-parameters>
        <actions>
            <service-call name="create#mantle.party.Party" in-map="context + [partyTypeEnumId:'PtyPerson']" out-map="context"/>
            <service-call name="create#mantle.party.Person" in-map="context"/>
            <if condition="roleTypeId"><service-call name="create#mantle.party.PartyRole" in-map="[partyId:partyId, roleTypeId:roleTypeId]"/></if>
        </actions>
</service>

一个服务唯一的必需属性是动词,尽管一般推荐要使用一个名词。type属性是常用的,但是默认是为“inline”,就像上面的服务由一个actions元素包含服务的实现。对其他类型的服务,即实现服务的其他方式,location和可选的method属性被用来指定运行什么。

上例中有in-parameters,它包括有parameter元素和带入mantle.party.Person实体上的所有非主键字段的auto-parameters元素。它也有一个out-parameter,此例中的partyId,在没有作为入参传入时会生成,或直接使用传入的值。

actions元素有服务的实现,包含一个XML Actions脚本。在此例中,它调用两个服务,然后如果有传入roleTypeId则调用第三个。注意没有明确地对partyId出参(在结果Map中)进行设置,因为Service Facade在服务的实现被运行后为每个声明了的出参自动提取上下文中的值填充到输出/结果Map。

service元素上可用的属性有:

  • verb: 可以是任意动词,通常是 create, update, store, delete 或 find 其中之一。服务的全名将是 "${path}.${verb}#${noun}"。动词是必须的,名词是可选的,如果没有名词,服务名将只有动词。
  • noun: 对于entity-auto服务,这应当是一个有效的实体名。在许多其他场景中,一个实体名是描述动作目的的最好方式,但实际可以是任意值。
  • type: 服务类型指定服务是如何实现的。默认可用的选项有:inline, entity-auto, script, java, interface, remote-xml-rpc, remote-json-rpc和camel。额外的类型可以通过实现 org.moqui.impl.service.ServiceRunner 接口并加一个 service-facade.service-type 元素到 Moqui配置XML文件中来添加。
  • location: 服务的位置。对于脚本是文件的 Resource Facade 位置。对于Java类方法是类的全名。对一个远程服务,是远程服务的URL。除了一个实际的位置,也可以是指Moqui配置XML文件中的service-facade.service-location元素预先定义的位置。这对于远程服务URL特别有用。
  • method: 位置内的方法,如果能适用于服务类型。
  • authenticate:
    • 如果没有设置为 false(默认为true),用户必须登录才能运行此服务。如果服务运行在一个有用户登录的 ExecutionContext 中,将是可以运行的。如果没有,那么要么指定一个"authUserAccount"参数,要么指定"authUsername"和"authPassword"参数,并且必须包含有效的系统用户信息。如果指定了,将作为上下文租户被用来运行服务。
    • 也能被设置为 anonymous-all 或 anonymous-view,不仅不需要身份鉴定,此服务将作为已授权(使用NA用户)为所有动作或只读动作运行。
  • allow-remote: 默认为false,表示此服务不能被通过类似JSON-RPC和XML-RPC的远程接口调用。如果设置为true则可以。在设置为true之前确保服务足够安全(对于身份鉴定和鉴权)。
  • validate: 默认为true。设置为false,则不校验输入参数,也不会自动移除未指定的参数。
  • transaction:
    • ignore:不管事务的事(如果已经有就用,如果没有也不开始一个)
    • use-or-begin: 使用当前活跃的事务,如果没有活跃事务则开始一个。这是默认的。
    • force-new: 总是开始一个新事务,如果已经有一个,则暂停/恢复已有的。
    • cache: 就像use-or-begin,但是每个事务准备一个write-through的缓存(甚至有TX时也有)。详情请看 TransactionCache 类的 JavaDoc 注释中的注意和警告。
    • force-cache: 像 force-new,也像 cache 选项有一个事务缓存。
  • transaction-timeout:事务超时时间,单位为秒。此值只用在服务开始一个事务时(force-new, force-cache或还没有缓存时的use-or-begin、cache)。
  • semaphore: 用于运行时间很长(通常是计划)的服务。用数据库中的一条记录来锁定服务,这样任意时间对于一个给定的数据库,只有一个实例能运行。选项包括 none(默认的)、fail和wait。
  • semaphore-timeout: 超时前等待多长时间,单位为秒。默认为120秒。
  • semaphore-sleep: 对信号量做检查之间等待多长时间,单位为秒。默认为5秒。
  • semaphore-ignore: 超过这么多时间后则忽略现在的信号量,单位为秒。默认为 3600秒(1小时)

服务的输入和输出每个都是有name/value条目的Map。用in-parameters元素指定入参,out-parameters元素指定出参。在这些元素下使用parameter元素来定义单个参数,auto-parameter元素基于实体的主键(pk)、非主键(nonpk)或所有字段来自动定义参数。

定义parameter元素的属性有:

  • name: 参数名,与传入的或从服务返回的参数Map中的条目的键匹配。
  • type: 属性的类型,一个Java全类名或共有的Java API类之一(包括String, Timestamp, Time, Date, Integer, Long, Float, Double, BigDecimal, BigInteger, Boolean, Object, Blob, Clob, Collection, List, Map, Set, Node)。
  • required: 默认为false,设置为true表示参数是必需的。也能设置为disabled,表现得就像没有这个参数一样,在覆盖一个之前定义的参数时有用。
  • allow-html: 只应用到 String 字段。只检查输入参数(意味着校验来自用户、其他系统等的输入)。
    • 默认为none, 意思是不允许HTML(将导致一个错误信息)。
    • 如果期望某些HTML,则使用safe,将遵循antisamy-esapi.xml文件中的规则。这将对内部和公开用户都安全。
    • 在很少的场景,当用户被信任或者不是一个敏感字段时,any选项可以被用来不对HTML内容做任何检查。
  • format: 只用在当参数被作为字符串传入,但类型并不是String时,被用来转换成对应的类型。对于date/time,使用标准的Java SimpleDateFormat 字符串。
  • default: 被指定的字段或表达式将被用于没有值传入的参数(只用在required=false时)。像default-value,但是是一个字段名或者表达式,而不是一个文本值。如果同时指定了default和default-value,将先使用default,只在default为空时使用default-value。
  • default-value: 指定的文本值将被用于没有传入值的参数(只用在required=false时)。如果同时指定了default和default-value,将先使用default,只在default为空时使用default-value。
  • entity-name: 可选属性,当此参数与某个实体的一个字段有关时,该实体的名字。
  • field-name: 可选属性,在命名实体内,此参数关联的字段名。对于从服务参数自动定义的表单字段有用。当参数时用auto-parameters元素自动定义时,将会被自动填值。

对于包含其他对象的参数对象类型(例如List, Map和Node),parameter元素能被嵌套以指定(并且如果可用、有效)在parameter对象内有什么。

除了 required 属性,还能用这些子元素为每个参数指定校验:

  • matches: 用在 regexp 属性中指定的正则表达式来校验当前的参数
  • number-range: 校验参数是在minmax范围内的数字
  • number-integer: 校验参数是一个整数
  • number-decimal: 校验参数是一个十进制数
  • text-length: 校验文本长度在minmax范围内
  • text-email: 校验文本是一个有效的email地址
  • text-url: 校验文本时一个有效的URL
  • text-letters: 校验文本只包含字母
  • text-digits: 校验文本只包含数字
  • time-range: 校验日期/时间在beforeafter范围内,使用指定的格式format
  • credit-card: 使用Luhn MOD-10标准校验文本是一个有效的信用卡号码,并且(如果指定了)是指定的类型types

校验元素可以用 val-orval-and 元素组合,或用 val-not 元素取反。

当一个XML表单字段是基于一个带校验的服务参数时,校验会自动在浏览器中用JavaScript校验,包括required, matches, number-integer, number-decimal, text-email, text-urltext-digits

现在你的服务定义好了,基本上配置好了当服务被调用时Service Facade的行为。是时候实现它了。

results matching ""

    No results matching ""