OpenAS2对接Wal-Mart EDI

时间:2022-08-17 01:07:55

一、OpenAS2下载安装

1.下载

从官方网站https://sourceforge.net/projects/openas2下载OpenAS2Server-2.13.0.zip。

2.直接进行解压

解压目录中不能包含空格等特殊字符。

3.安装JAVA

环境必须配置JAVA_HOME。

CLASSPATH:  .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
PATH: %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

不然会出现奇怪的错误。

4.启动

在命令行中直接运行解压目录bin下的start-openas2.bat,能够启动成功说明安装完成。

OpenAS2对接Wal-Mart EDI

二、配置文件修改

秘钥生成之后,下面需要修改配置文件,才能满足实际需求。

1.生成密钥

在bin目录下执行命令

gen_p12_key_par.bat gwinsunp gwinsunc SHA256 "CN=gwinsunc,OU=gwinsunu,o=gwinsuno,L=wuhu,S=anhui,c=CN"

回车后输入密码,继续回车,会在bin目录下生成密钥库文件gwinsunp.p12 gwinsunc.cer

OpenAS2对接Wal-Mart EDI

2.config.xml配置

使用 notepad++ 打开或者其他便利的工具。此处的密钥库为自己生成的密钥库名称gwinsunp密码为自己输入的密码

<?xml version="1.0" encoding="UTF-8"?>
<openas2>
   <properties storageBaseDir="%home%/../data"
               log_date_format="yyyy-MM-dd HH:mm:ss.SSS"
               sql_timestamp_format="yyyy-MM-dd HH:mm:ss.SSS"
               as2_message_id_format="OPENAS2-$date.ddMMyyyyHHmmssZ$-$rand.UUID$@$msg.sender.as2_id$_$msg.receiver.as2_id$"
               as2_async_mdn_url="http://localhost:19001"
               as2_receive_message_filename_fallback="$rand.shortUUID$"
               console.logger.enabled="true"
               file.logger.enabled="true"
               socket.logger.enabled="false"
               email.logger.enabled="false"
               console.command.processor.enabled="true"
               socket.command.processor.enabled="false"
               restapi.command.processor.enabled="false"
               module.AS2SenderModule.enabled="true"
               module.MDNSenderModule.enabled="true"
               module.DbTrackingModule.enabled="true"
               module.MDNFileModule.enabled="true"
               module.MessageFileModule.enabled="true"
               module.DirectoryResenderModule.enabled="true"
               module.AS2ReceiverModule.http.enabled="true"
               module.AS2MDNReceiverModule.http.enabled="true"
               module.AS2ReceiverModule.https.enabled="false"
               module.AS2MDNReceiverModule.https.enabled="false"
               module.HealthCheckModule.enabled="false"
               />
    <!-- 此处需配置证书的存放位置及密码 -->
   <certificates classname="org.openas2.cert.PKCS12CertificateFactory"
                 filename="%home%/../bin/gwinsun.p12"
                 password="123456"
                 interval="300"/>
   <!-- 关联到partnerships.xml配置文件,配置伙伴信息 -->
   <partnerships classname="org.openas2.partner.XMLPartnershipFactory"
                 filename="%home%/partnerships.xml"
                 interval="120"/>
   <loggers>
      <logger classname="org.openas2.logging.ConsoleLogger"
              enabled="$properties.console.logger.enabled$"/>
      <logger classname="org.openas2.logging.EmailLogger"
              enabled="$properties.email.logger.enabled$"
              only_active_msg_transfer_errors="false"
              log_exception_trace="false"
              javax.mail.properties.file="%home%/java.mail.properties"
              from="openas2"
              to="your email address"
              smtpserver="your smtp server"
              smtpport="your smtp server port"
              smtpauth="true"
              smtpuser="mySmtpUserId"
              smtppwd="mySmtpPwd"
              subject="$exception.name$: $exception.message$"
              bodytemplate="%home%/emailtemplate.txt"/>
      <logger classname="org.openas2.logging.FileLogger"
              enabled="$properties.file.logger.enabled$"
              filename="%home%/../logs/log-$date.yyyyMMdd$.txt"/>
      <logger classname="org.openas2.logging.SocketLogger"
              enabled="$properties.socket.logger.enabled$"
              ipaddr="127.0.0.1"
              port/>
   </loggers>
   <commands classname="org.openas2.cmd.XMLCommandRegistry"
             filename="%home%/commands.xml"/>
   <commandProcessors>
      <commandProcessor classname="org.openas2.cmd.processor.StreamCommandProcessor"
                        enabled="$properties.console.command.processor.enabled$"/>
      <commandProcessor classname="org.openas2.cmd.processor.SocketCommandProcessor"
                        enabled="$properties.socket.command.processor.enabled$"
                        portId="14321"
                        user
                        password="pWd"
                        response_format="xml"/>
      <commandProcessor classname="org.openas2.cmd.processor.RestCommandProcessor" 
                        enabled="$properties.restapi.command.processor.enabled$"
                        baseuri="https://localhost:8443" 
                        ssl_protocol="TLS"
                        ssl_keystore="%home%/ssl_certs.jks"
                        ssl_keystore_password="testas2"
                        user 
                        password="pWd" />
   </commandProcessors>
   <processor classname="org.openas2.processor.DefaultProcessor"
              pendingMDN="$properties.storageBaseDir$/pendingMDN3"
              pendingMDNinfo="$properties.storageBaseDir$/pendinginfoMDN3"
              resend_max_retries="5">
      <module enabled="$properties.module.AS2SenderModule.enabled$"
              classname="org.openas2.processor.sender.AS2SenderModule"/>
      <module enabled="$properties.module.MDNSenderModule.enabled$"
              classname="org.openas2.processor.sender.MDNSenderModule"/>
      <!--这个目录轮询模块将解析文件名,以获得要发送给合作伙伴的发送方、接收方和文件名。sender与receiver都是partner主要还是配置partner直接的关系-->
      <module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
              outboxdir="$properties.storageBaseDir$/toAny" errordir="$properties.storageBaseDir$/toAny/error/$msg.sender.as2_id$-$msg.receiver.as2_id$"
              interval="5"
              delimiters="-"
              mergeextratokens="true"
              sendfilename="true"
              format="sender.as2_id, receiver.as2_id, attributes.filename"
              mimetype="application/EDI-X12"/>
      <!-- 此处defaults需配置发送方的id及接收方的id -->
      <module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
              outboxdir="$properties.storageBaseDir$/toPartnerA/"
              errordir="$properties.storageBaseDir$/toPartnerA/error/$date.YYYY$/$date.MM$"
              stored_error_filename="$msg.attributes.filename$-$date.YYYY$-$date.MM$-$msg.headers.message-id$"
              sentdir="$properties.storageBaseDir$/$msg.sender.as2_id$-$msg.receiver.as2_id$/sent/$date.YYYY$/$date.MM$"
              stored_sent_filename="$msg.attributes.filename$-$msg.headers.message-id$"
              interval="5"
              defaults="sender.as2_id=gwinsun, receiver.as2_id=146907777000001"
              sendfilename="true"
              mimetype="application/EDI-X12"/>
      <!-- This directory polling module will is dedicated to sending to partner PartnerB_OID -->
      <module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
              outboxdir="$properties.storageBaseDir$/toPartnerB"
              errordir="$properties.storageBaseDir$/toPartnerB/error"
              interval="5"
              defaults="sender.as2_id=MyCompany_OID, receiver.as2_id=PartnerB_OID"
              sendfilename="true"
              mimetype="application/EDI-X12"/>
	<module classname="org.openas2.processor.msgtracking.DbTrackingModule" 
		use_embedded_db="false"
		force_load_jdbc_driver="false"
		db_user="openas2"
		db_pwd="eoM2ssoYRSsSfPw6"
		db_name="openas2"
		db_directory="%home%/DB"
		jdbc_driver="com.mysql.cj.jdbc.Driver" jdbc_connect_string="jdbc:mysql://localhost:3306/$component.db_name$"
		sql_escape_character="'" />
      <module enabled="$properties.module.MDNFileModule.enabled$"
              classname="org.openas2.processor.storage.MDNFileModule" filename="$properties.storageBaseDir$/$mdn.msg.sender.as2_id$-$mdn.msg.receiver.as2_id$/mdn/$date.yyyy-MM-dd$/$mdn.msg.content-disposition.filename$-$mdn.msg.headers.message-id$"
              protocol="as2"
              tempdir="$properties.storageBaseDir$/temp"/>
      <module enabled="$properties.module.MessageFileModule.enabled$"
              classname="org.openas2.processor.storage.MessageFileModule"
              filename="$properties.storageBaseDir$/$msg.sender.as2_id$-$msg.receiver.as2_id$/inbox/$msg.content-disposition.filename$-$msg.headers.message-id$"
              header="$properties.storageBaseDir$/$msg.sender.as2_id$-$msg.receiver.as2_id$/msgheaders/$date.yyyy-MM-dd$/$msg.content-disposition.filename$-$msg.headers.message-id$"
              protocol="as2"
              tempdir="$properties.storageBaseDir$/temp"/>
      <module enabled="$properties.module.AS2ReceiverModule.http.enabled$"
              classname="org.openas2.processor.receiver.AS2ReceiverModule"
              port="19000"
              errordir="$properties.storageBaseDir$/inbox/error"
              errorformat="sender.as2_id, receiver.as2_id, headers.message-id"/>
      <module enabled="$properties.module.AS2ReceiverModule.https.enabled$"
              classname="org.openas2.processor.receiver.AS2ReceiverModule"
              port="10443"
              protocol="https"
              ssl_protocol="TLS"
              ssl_keystore="%home%/ssl_certs.jks"
              ssl_keystore_password="testas2"
              errordir="$properties.storageBaseDir$/inbox/error"
              errorformat="sender.as2_id, receiver.as2_id, headers.message-id"/>
      <module enabled="$properties.module.AS2MDNReceiverModule.http.enabled$"
              classname="org.openas2.processor.receiver.AS2MDNReceiverModule"
              port="19001"/>
      <module enabled="$properties.module.AS2MDNReceiverModule.https.enabled$"
              classname="org.openas2.processor.receiver.AS2MDNReceiverModule"
              port="10444"
              protocol="https"
              ssl_protocol="TLS"
              ssl_keystore="%home%/ssl_certs.jks"
              ssl_keystore_password="testas2"/>
      <module enabled="$properties.module.DirectoryResenderModule.enabled$"
              classname="org.openas2.processor.resender.DirectoryResenderModule"
              resenddir="$properties.storageBaseDir$/resend"
              errordir="$properties.storageBaseDir$/resend/error"
              resenddelay="60"/>
      <module enabled="$properties.module.HealthCheckModule.enabled$"
              classname="org.openas2.processor.receiver.HealthCheckModule"
              port="10099"/>
   </processor>
</openas2>

OpenAS2对接Wal-Mart EDI

3.发送文件路径的配置

sender.as2_id,receriver.as2_id 的配置,关联到partnerships.xml.interval=5, 每5秒进程自动扫描文件夹下是否有文件需要发送。

4.其它数据库配置,消息配置

4.1 发送文件配置

OPEN AS2会轮询扫描指定的目录,寻找发送给伙伴的文件。目录扫描器会在两个连续周期检查发现的文件大小是否发生变化,如果没有变化则会将此文件加入发送队列中。 用于存放发送文件的目录可以是一个伙伴的专有目录,也可以是一个通用目录。如果使用通用目录,则通过解析文件名确定伙伴的身份。 以下是发送文件相关的关键属性: outboxdir - 发送文件的扫描目录 errordir - 发送文件出错后存放文件的目录 interval - 扫描目录的周期(秒) sendfilename - 发送给远程伙伴的消息是否必须包含文件名 mimetype - 指定发送消息中文件的扩展类型

通用发送目录配置

<!-- 这个目录轮询模块将解析文件名,以获得要发送给合作伙伴的发送方、接收方和文件名。例如,名为MyComapny_OID-PartnerB_OID-OrderID-745634的文件。edi将从MyCompany发送到PartnerB。发送给合作伙伴的文件的名称将是“OrderID-745634.edi”-->
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
        outboxdir="$properties.storageBaseDir$/toAny"
        errordir="$properties.storageBaseDir$/toAny/error"
        interval="5"
        delimiters="-"
        mergeextratokens="true"
        sendfilename="true"
        format="sender.as2_id, receiver.as2_id, attributes.filename"
        mimetype="application/EDI-X12" />

专有发送目录配置

<!-- This directory polling module will is dedicated to sending to partner PartnerA_OID -->
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
        outboxdir="$properties.storageBaseDir$/toPartnerA/"
        errordir="$properties.storageBaseDir$/toPartnerA/error"
        interval="5"
        defaults="sender.as2_id=MyCompany_OID, receiver.as2_id=PartnerA_OID"
        sendfilename="true"
        mimetype="application/EDI-X12"/>
<!-- This directory polling module will is dedicated to sending to partner PartnerB_OID -->
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
        outboxdir="$properties.storageBaseDir$/toPartnerB"
        errordir="$properties.storageBaseDir$/toPartnerB/error"
        interval="5"
        defaults="sender.as2_id=MyCompany_OID, receiver.as2_id=PartnerB_OID"
        sendfilename="true"
        mimetype="application/EDI-X12"/>

复制代码其中,“defaults”属性指定了目录中所有文件的发送方和接收方的AS2 ID。此外,还可以限制发送文件的扩展名,fileextensionfilter指定了通过的文件扩展名,fileextensionexcludefilter指定了忽略的文件扩展名。 fileextensionfilter="doc, docx, txt, edi" fileextensionexcludefilter="tmp"

4.2 partnerships.xml 配置文件的修改。

<partnerships>
  <partner as2_
           name="walmart"
           email="XXXX@wal-mart.com"
           x509_alias="walmart"/>
  <partner as2_
           name="gwinsun"
           email="gwinsun01@gwinsun.com.cn"
           x509_alias="gwinsun"/>
  <partnership name="gwinsun-to-walmart">
    <sender name="gwinsun"/>
    <receiver name="walmart"/>
    <attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, SHA256"/>
    <attribute name="subject" value="File $attributes.filename$ sent from $sender.name$ to $receiver.name$"/>
    <attribute name="compression_type" value="ZLIB"/>
    <attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
    <attribute name="sign" value="SHA256"/>
    <attribute name="prevent_canonicalization_for_mic" value="false"/>
    <attribute name="resend_max_retries" value="3"/>
    <attribute name="content_transfer_encoding" value="binary"/>
    <attribute name="protocol" value="as2"/>
    <attribute name="as2_mdn_to" value="http://gem.wal-mart.com:5080"/>
    <attribute name="encrypt" value="3DES"/>
    <attribute name="as2_url" value="http://gem.wal-mart.com:5080"/>
    <attribute name="rename_digest_to_old_name" value="false"/>
  </partnership>
  <!-- 配置沃尔玛发送给我们的地址 -->
  <partnership name="walmart-to-gwinsun">
    <sender name="walmart"/>
    <receiver name="gwinsun"/>
    <attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, SHA256"/>
	<attribute name="as2_receipt_option" value="http://140.249.197.197:19001"/> 
    <attribute name="as2_mdn_to" value="http://140.249.197.197:19001"/>

	<attribute name="subject" value="File $attributes.filename$ sent from $sender.name$ to $receiver.name$"/>
    <attribute name="encrypt" value="3DES"/>
    <attribute name="as2_url" value="http://140.249.197.197:19000"/>
    <attribute name="sign" value="SHA256"/>
    <attribute name="protocol " value="as2"/>
  </partnership>
</partnerships>

如果有多个合作伙伴,可以增加多个,partner.

4.3 发送端、接收端 的配置

as2_mdn_to 需要设置成自己使用的邮箱。交换密钥,互相将公钥发送给对方,并导入到密钥库。 导入公钥的命令如下

cert import <alias> <path+filename> <keystore password>

OPEN AS2也提供了快捷的脚本import_public_cert.sh,使用方法如下

import_public_cert.sh <cer文件路径及地址> <自己的密钥库.p12> <对方密钥别名>

import_public_cert.bat 47269_WM.cer gwinsun.p12 walmart

OpenAS2对接Wal-Mart EDI

三、基本命令

1 启动报错问题

打开openas2 \bin ,运行 start-openas2.bat,以windows 为例, linux 请运行 .sh 的文件。通过管理员身份进行。

  1. 如果JDK 安装、配置没有问题。会出现如下界面
  2. OpenAS2对接Wal-Mart EDI

  3. 如果,窗口一闪而过,或出现其他错误信息,
  4.   1.请排查 JDK 安装,jdk环境变量问题。   2.或者 cmd--cd ..openas2\bin --- start-openas2.bat ,留住窗口查看信息。   如下图,是config 文件路径错误,具体错误请自己分析,仅举个栗子。
  5. OpenAS2对接Wal-Mart EDI

2 命令查看

5.2 在成功启动之后,按 enter , 输入? openas2 有提供了几个命令查看服务器信息

      

OpenAS2对接Wal-Mart EDI

exit --退出 , cert ...正常的查看,导入,删除,清楚。

      

OpenAS2对接Wal-Mart EDI

partner

OpenAS2对接Wal-Mart EDI

partnership

      

OpenAS2对接Wal-Mart EDI

四、使用及测试发送文件

打开 openas2\data\ ... 在data 目录下有刚才修改配置文件,启动服务,自动生成的文件夹 niubi2 .

 在niubi2的文件夹下  a、 新建 1.txt 文件,并在文件下,随便写入 123--保存。  b、大约 5秒之后,文件发出。 cmd 框中出现如下信息,表示文件发送成功。接受端的窗口中,亦会出现类似信息。       

OpenAS2对接Wal-Mart EDI

如果对方发送文件过来,请在data 目录下,生成一个以 *_OID-_OID 命名的文件夹中。 ***配置文件中的patner 名。

      

OpenAS2对接Wal-Mart EDI

五、代码开发

1. pom中引入smooks解析工具

<!-- smooks解析工具-->
		<dependency>
			<groupId>org.milyn</groupId>
			<artifactId>milyn-smooks-edi</artifactId>
			<version>1.7.1</version>
		</dependency>
		<dependency>
			<groupId>org.milyn</groupId>
			<artifactId>milyn-smooks-javabean</artifactId>
			<version>1.7.1</version>
		</dependency>

2.配置文件purchaseorder-config.xml

首先创建响应的实体类,与配置文件中的字段进行对应。此处的字段可以做相应的转化,例如日期的转换。

<?xml version="1.0"?>
<smooks-resource-list
	xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
	xmlns:edi="http://www.milyn.org/xsd/smooks/edi-1.1.xsd"
	xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd">

    <!--
    Configure the EDI Reader to parse the message stream into a stream of SAX events.
    -->
    <edi:reader mappingModel="purchaseorder-mapping.xml" />

    <jb:bean beanId="messagePurchaseOrder" class="org.jeecg.modules.edi.PurchaseOrder.MessagePurchaseOrder"
             createOnElement="MessagePurchaseOrder">
        <jb:wiring property="isa" beanIdRef="isa" />
        <jb:wiring property="gs" beanIdRef="gs" />
        <jb:wiring property="purchaseOrders" beanIdRef="purchaseOrderList" />
        <jb:wiring property="ge" beanIdRef="ge" />
        <jb:wiring property="iea" beanIdRef="iea" />
    </jb:bean>

    <jb:bean beanId="isa" class="org.jeecg.modules.edi.PurchaseOrder.ISA" createOnElement="${messagePurchaseOrder}/isa" >
        <jb:value property="code1" data="#/code1" />
        <jb:value property="code2" data="#/code2" />
        <jb:value property="code3" data="#/code3" />
        <jb:value property="code4" data="#/code4" />
        <jb:value property="code5" data="#/code5" />
        <jb:value property="code6" data="#/code6" />
        <jb:value property="code7" data="#/code7" />
        <jb:value property="code8" data="#/code8" />
        <jb:value property="code9" data="#/code9" />
        <jb:value property="code10" data="#/code10" />
        <jb:value property="code11" data="#/code11" />
        <jb:value property="code12" data="#/code12" />
        <jb:value property="code13" data="#/code13" />
        <jb:value property="code14" data="#/code14" />
        <jb:value property="code15" data="#/code15" />
        <jb:value property="code16" data="#/code16" />
    </jb:bean>

    <jb:bean beanId="gs" class="org.jeecg.modules.edi.PurchaseOrder.GS" createOnElement="${messagePurchaseOrder}/gs" >
        <jb:value property="code1" data="#/code1" />
        <jb:value property="code2" data="#/code2" />
        <jb:value property="code3" data="#/code3" />
        <jb:value property="code4" data="#/code4" />
        <jb:value property="code5" data="#/code5" />
        <jb:value property="code6" data="#/code6" />
        <jb:value property="code7" data="#/code7" />
        <jb:value property="code8" data="#/code8" />
    </jb:bean>

    <jb:bean beanId="purchaseOrderList" class="java.util.ArrayList" createOnElement="MessagePurchaseOrder">
        <jb:wiring beanIdRef="purchaseorder" />
    </jb:bean>

    <jb:bean beanId="ge" class="org.jeecg.modules.edi.PurchaseOrder.GE" createOnElement="${messagePurchaseOrder}/ge" >
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>

    <jb:bean beanId="iea" class="org.jeecg.modules.edi.PurchaseOrder.IEA" createOnElement="${messagePurchaseOrder}/iea" >
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>


    <jb:bean beanId="purchaseorder" class="org.jeecg.modules.edi.PurchaseOrder.PurchaseOrder"
             createOnElement="PurchaseOrder">
        <jb:value property="code1" decoder="String" data="#/code1" />
        <jb:value property="code2" decoder="String" data="#/code2" />
        <jb:wiring property="beginning" beanIdRef="beginning" />
        <jb:wiring property="orderCurrency" beanIdRef="orderCurrency" />
        <jb:wiring property="refList" beanIdRef="refList" />
        <jb:wiring property="fobList" beanIdRef="fobList" />
        <jb:wiring property="serviceAllowanceChargeList" beanIdRef="serviceAllowanceChargeList" />
        <jb:wiring property="itdList" beanIdRef="itdList" />
        <jb:wiring property="dateTimeReferenceList" beanIdRef="dateTimeReferenceList" />
        <jb:wiring property="TD5List" beanIdRef="TD5List" />
        <jb:wiring property="n9LoopList" beanIdRef="n9LoopList" />
        <jb:wiring property="n1LoopList" beanIdRef="n1LoopList" />
        <jb:wiring property="baselineItemDatas" beanIdRef="baselineItemDatas" />
        <jb:wiring property="summary" beanIdRef="summary" />
    </jb:bean>

    <jb:bean beanId="beginning" class="org.jeecg.modules.edi.PurchaseOrder.Beginning" createOnElement="Beginning">
        <jb:value property="purposeCode" decoder="String" data="#/purpose-code" />
        <jb:value property="orderType" decoder="String" data="#/order-type" />
        <jb:value property="orderNumber" decoder="String" data="#/order-number" />
        <jb:value property="releaseNumber" decoder="String" data="#/release-number" />
        <jb:value property="date" decoder="Date" data="#/date">
            <jb:decodeParam name="format">yyyyMMdd</jb:decodeParam>
            <jb:decodeParam name="locale">en_IE</jb:decodeParam>
        </jb:value>
    </jb:bean>
    <jb:bean beanId="orderCurrency" class="org.jeecg.modules.edi.PurchaseOrder.OrderCurrency" createOnElement="OrderCurrency">
        <!-- Customer bindings... -->
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>

    <jb:bean beanId="refList" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <jb:wiring beanIdRef="ref" />
    </jb:bean>
    <jb:bean beanId="ref" class="org.jeecg.modules.edi.PurchaseOrder.REF" createOnElement="REF">
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>

    <jb:bean beanId="fobList" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="fob" />
    </jb:bean>
    <jb:bean beanId="fob" class="org.jeecg.modules.edi.PurchaseOrder.FOB" createOnElement="FOB">
        <!-- Customer bindings... -->
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
        <jb:value property="value1" data="#/value1" />
    </jb:bean>

    <jb:bean beanId="serviceAllowanceChargeList" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="serviceAllowanceCharge" />
    </jb:bean>

    <jb:bean beanId="serviceAllowanceCharge" class="org.jeecg.modules.edi.PurchaseOrder.ServiceAllowanceCharge" createOnElement="ServiceAllowanceCharge">
        <!-- Customer bindings... -->
        <jb:value property="ACcode" data="#/ACcode" />
        <jb:value property="SCCode" data="#/SCCode" />
        <jb:value property="remark1" data="#/remark1" />
        <jb:value property="remark2" data="#/remark2" />
        <jb:value property="amount" decoder="BigDecimal" data="#/amount" />
        <jb:value property="percent" data="#/percent" />
        <jb:value property="rate" decoder="BigDecimal"  data="#/rate" />
        <jb:value property="percentDecimalFormat" data="#/percentDecimalFormat" />
        <jb:value property="measurementUnit" data="#/measurementUnit" />
        <jb:value property="quantity" data="#/quantity" />
        <jb:value property="remark3" data="#/remark3" />
        <jb:value property="handlingCode" data="#/handlingCode" />
    </jb:bean>

    <jb:bean beanId="itdList" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="itd" />
    </jb:bean>

    <jb:bean beanId="itd" class="org.jeecg.modules.edi.PurchaseOrder.ITD" createOnElement="ITD">
        <!-- Customer bindings... -->
        <jb:value property="code1" data="#/code1" />
        <jb:value property="code2" data="#/code2" />
        <jb:value property="code3" data="#/code3" />
        <jb:value property="code4" data="#/code4" />
        <jb:value property="code5" data="#/code5" />
        <jb:value property="code6" data="#/code6" />
        <jb:value property="code7" data="#/code7" />
    </jb:bean>

    <jb:bean beanId="dateTimeReferenceList" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="dateTimeReference" />
    </jb:bean>

    <jb:bean beanId="dateTimeReference" class="org.jeecg.modules.edi.PurchaseOrder.DateTimeReference" createOnElement="DateTimeReference">
        <!-- Customer bindings... -->
        <jb:value property="code" data="#/code" />
        <jb:value property="date" decoder="Date" data="#/date">
            <jb:decodeParam name="format">yyyyMMdd</jb:decodeParam>
            <jb:decodeParam name="locale">en_IE</jb:decodeParam>
        </jb:value>
    </jb:bean>

    <jb:bean beanId="TD5List" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="td5" />
    </jb:bean>
    <jb:bean beanId="td5" class="org.jeecg.modules.edi.PurchaseOrder.TD5" createOnElement="TD5">
        <jb:value property="value1" data="#/value1" />
        <jb:value property="value2" data="#/value2" />
        <jb:value property="value3" data="#/value3" />
        <jb:value property="value4" data="#/value4" />
        <jb:value property="value5" data="#/value5" />
    </jb:bean>

    <jb:bean beanId="n9LoopList" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <jb:wiring beanIdRef="n9Loop" />
    </jb:bean>
    <jb:bean beanId="n9Loop" class="org.jeecg.modules.edi.PurchaseOrder.N9Loop" createOnElement="N9Loop">
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
        <jb:wiring property="mtxList"  beanIdRef="mtxList" />
    </jb:bean>

    <jb:bean beanId="mtxList" class="java.util.ArrayList" createOnElement="N9Loop">
        <jb:wiring beanIdRef="mtx" />
    </jb:bean>
    <jb:bean beanId="mtx" class="org.jeecg.modules.edi.PurchaseOrder.MTX" createOnElement="MTX">
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>

    <jb:bean beanId="n1LoopList" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <jb:wiring beanIdRef="n1Loop" />
    </jb:bean>
    <jb:bean beanId="n1Loop" class="org.jeecg.modules.edi.PurchaseOrder.N1Loop" createOnElement="N1Loop">
        <jb:value property="identifierCode" data="#/identifier-code" />
        <jb:value property="freeFormName" data="#/free-form-name" />
        <jb:value property="codeQualifier" data="#/code-qualifier" />
        <jb:value property="partyCode" data="#/party-code" />

        <jb:wiring property="supplier" beanIdRef="supplier" />
        <jb:wiring property="n3List" beanIdRef="n3List" />
        <jb:wiring property="n4List" beanIdRef="n4List" />
        <jb:wiring property="supplier" beanIdRef="supplier" />
    </jb:bean>

    <jb:bean beanId="supplier" class="org.jeecg.modules.edi.PurchaseOrder.Supplier" createOnElement="Supplier">
        <!-- Customer bindings... -->
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>
    <jb:bean beanId="n3List" class="java.util.ArrayList" createOnElement="N1Loop">
        <jb:wiring beanIdRef="n3" />
    </jb:bean>
    <jb:bean beanId="n3" class="org.jeecg.modules.edi.PurchaseOrder.N3" createOnElement="N3">
        <!-- Customer bindings... -->
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>
    <jb:bean beanId="n4List" class="java.util.ArrayList" createOnElement="N1Loop">
        <jb:wiring beanIdRef="n4" />
    </jb:bean>
    <jb:bean beanId="n4" class="org.jeecg.modules.edi.PurchaseOrder.N4" createOnElement="N4">
        <!-- Customer bindings... -->
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
        <jb:value property="value1" data="#/value1" />
        <jb:value property="value2" data="#/value2" />
    </jb:bean>



    <jb:bean beanId="baselineItemDatas" class="java.util.ArrayList" createOnElement="PurchaseOrder">
        <jb:wiring beanIdRef="baselineItemData" />
    </jb:bean>
    <jb:bean beanId="baselineItemData" class="org.jeecg.modules.edi.PurchaseOrder.BaselineItemData" createOnElement="BaselineItemData">
        <!-- Customer bindings... -->
        <jb:value property="lineNumber" data="#/line-number" />
        <jb:value property="quantity" decoder="Integer" data="#/quantity" />
        <jb:value property="unit" data="#/unit" />
        <jb:value property="unitPrice" decoder="BigDecimal" data="#/unit-price" />
        <jb:value property="basisOfUnitPriceCode" data="#/basis-of-unit-price-code" />
        <jb:value property="in" data="#/in" />
        <jb:value property="itemNumber" data="#/item-number" />
        <jb:value property="en" data="#/en" />
        <jb:value property="GTIN" data="#/GTIN" />
        <jb:value property="vn" data="#/vn" />
        <jb:value property="vendorin" data="#/vendorin" />
        <jb:value property="bo" data="#/bo" />
        <jb:value property="color" data="#/color" />
        <jb:value property="iz" data="#/iz" />
        <jb:value property="size" data="#/size" />
        <jb:value property="p8" data="#/p8" />
        <jb:value property="pricelookup" data="#/price-look-up" />
        <jb:value property="ua" data="#/ua" />
        <jb:value property="caseCode" data="#/case-code" />
        <jb:value property="up" data="#/up" />
        <jb:value property="universalProduct" data="#/universal-product" />
        <jb:value property="uk" data="#/uk" />
        <jb:value property="ukCode" data="#/uk-code" />
        <jb:wiring property="pricingInformationList" beanIdRef="pricingInformationList" />
        <jb:wiring property="productItemDescriptionList" beanIdRef="productItemDescriptionList" />
        <jb:wiring property="po4" beanIdRef="PO4" />
        <jb:wiring property="detailSACList" beanIdRef="detailSACList" />
        <jb:wiring property="detailSDQList" beanIdRef="detailSDQList" />
        <jb:wiring property="n9LoopList" beanIdRef="n9LoopList" />
        <jb:wiring property="sublineItemDetailList" beanIdRef="sublineItemDetailList" />
        <jb:wiring property="monetaryAmountDetailList" beanIdRef="monetaryAmountDetailList" />
    </jb:bean>
    <jb:bean beanId="pricingInformationList" class="java.util.ArrayList" createOnElement="BaselineItemData">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="pricingInformation" />
    </jb:bean>
    <jb:bean beanId="pricingInformation" class="org.jeecg.modules.edi.PurchaseOrder.PricingInformation" createOnElement="PricingInformation">
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
        <jb:value property="value1" data="#/value1" />
    </jb:bean>

    <jb:bean beanId="productItemDescriptionList" class="java.util.ArrayList" createOnElement="BaselineItemData">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="productItemDescription" />
    </jb:bean>

    <jb:bean beanId="productItemDescription" class="org.jeecg.modules.edi.PurchaseOrder.ProductItemDescription" createOnElement="ProductItemDescription">
        <jb:value property="itemType" data="#/item-type" />
        <jb:value property="itemCode" data="#/item-code" />
        <jb:value property="agencyQualifierCode" data="#/agency-qualifier-code" />
        <jb:value property="productdescriptioncode" data="#/product-description-code" />
        <jb:value property="productdescription" data="#/product-description" />
    </jb:bean>

    <jb:bean beanId="PO4" class="org.jeecg.modules.edi.PurchaseOrder.PO4" createOnElement="PO4">
        <jb:value property="value" data="#/value" />
        <jb:value property="code2" data="#/code2" />
        <jb:value property="code3" data="#/code3" />
        <jb:value property="code4" data="#/code4" />
        <jb:value property="code5" data="#/code5" />
        <jb:value property="code6" data="#/code6" />
        <jb:value property="code7" data="#/code7" />
        <jb:value property="code8" data="#/code8" />
        <jb:value property="code9" data="#/code9" />
        <jb:value property="code10" data="#code10" />
        <jb:value property="code11" data="#code11" />
        <jb:value property="code12" data="#code12" />
        <jb:value property="code13" data="#code13" />
        <jb:value property="code14" data="#code14" />
    </jb:bean>

    <jb:bean beanId="detailSACList" class="java.util.ArrayList" createOnElement="BaselineItemData">
        <jb:wiring beanIdRef="detailSAC" />
    </jb:bean>
    <jb:bean beanId="detailSAC" class="org.jeecg.modules.edi.PurchaseOrder.DetailSAC" createOnElement="DetailSAC">
        <jb:value property="code1" data="#/code1" />
        <jb:value property="code2" data="#/code2" />
        <jb:value property="code3" data="#/code3" />
        <jb:value property="code4" data="#/code4" />
        <jb:value property="code5" data="#/code5" />
        <jb:value property="code6" data="#/code6" />
        <jb:value property="code7" decoder="BigDecimal" data="#/code7" />
    </jb:bean>


    <jb:bean beanId="detailSDQList" class="java.util.ArrayList" createOnElement="BaselineItemData">
        <jb:wiring beanIdRef="detailSDQ" />
    </jb:bean>
    <jb:bean beanId="detailSDQ" class="org.jeecg.modules.edi.PurchaseOrder.DetailSDQ" createOnElement="DetailSDQ">
        <jb:value property="code1" data="#/code1" />
        <jb:value property="code2" data="#/code2" />
        <jb:value property="code3" data="#/code3" />
        <jb:value property="code4" data="#/code4" />
        <jb:value property="code5" data="#/code5" />
        <jb:value property="code6" data="#/code6" />
        <jb:value property="code7" data="#/code7" />
        <jb:value property="code8" data="#/code8" />
        <jb:value property="code9" data="#/code9" />
        <jb:value property="code10" data="#code10" />
        <jb:value property="code11" data="#code11" />
        <jb:value property="code12" data="#code12" />
        <jb:value property="code13" data="#code13" />
        <jb:value property="code14" data="#code14" />
        <jb:value property="code15" data="#code15" />
        <jb:value property="code16" data="#code16" />
        <jb:value property="code17" data="#code17" />
        <jb:value property="code18" data="#code18" />
        <jb:value property="code19" data="#code19" />
        <jb:value property="code20" data="#code20" />
        <jb:value property="code21" data="#code21" />
        <jb:value property="code22" data="#code22" />
    </jb:bean>
    <jb:bean beanId="sublineItemDetailList" class="java.util.ArrayList" createOnElement="BaselineItemData">
        <jb:wiring beanIdRef="sublineItemDetail" />
    </jb:bean>
    <jb:bean beanId="sublineItemDetail" class="org.jeecg.modules.edi.PurchaseOrder.SublineItemDetail" createOnElement="SublineItemDetail">
        <jb:value property="value1" data="#/value1" />
        <jb:value property="value2" data="#/value2" />
        <jb:value property="value3" data="#/value3" />
        <jb:value property="value4" data="#/value4" />
        <jb:value property="value5" data="#/value5" />
        <jb:value property="value6" data="#/value6" />
        <jb:value property="value7" data="#/value7" />
        <jb:value property="value8" data="#/value8" />
        <jb:value property="value9" data="#/value9" />
        <jb:value property="value10" data="#/value10" />
        <jb:value property="value11" data="#/value11" />
        <jb:value property="value12" data="#/value12" />
        <jb:value property="value13" data="#/value13" />
        <jb:value property="value14" data="#/value14" />
        <jb:value property="value15" data="#/value15" />
        <jb:value property="value16" data="#/value16" />
        <jb:value property="value17" data="#/value17" />
        <jb:value property="value18" data="#/value18" />
        <jb:value property="value19" data="#/value19" />
        <jb:value property="value20" data="#/value20" />
        <jb:value property="value21" data="#/value21" />
        <jb:value property="value22" data="#/value22" />
        <jb:value property="value23" data="#/value23" />
        <jb:value property="value24" data="#/value24" />
        <jb:value property="value25" data="#/value25" />
        <jb:value property="value26" data="#/value26" />
        <jb:value property="value27" data="#/value27" />
        <jb:value property="value28" data="#/value28" />

    </jb:bean>
    <jb:bean beanId="monetaryAmountDetailList" class="java.util.ArrayList" createOnElement="BaselineItemData">
        <jb:wiring beanIdRef="monetaryAmountDetail" />
    </jb:bean>
    <jb:bean beanId="monetaryAmountDetail" class="org.jeecg.modules.edi.PurchaseOrder.MonetaryAmountDetail" createOnElement="MonetaryAmountDetail">
        <jb:value property="code" data="#/code" />
        <jb:value property="monetaryAmountDetail" decoder="BigDecimal" data="#/monetary-amount"/>
    </jb:bean>

    <jb:bean beanId="summary" class="org.jeecg.modules.edi.PurchaseOrder.Summary" createOnElement="Summary">
        <jb:wiring property="transactionTotalList" beanIdRef="transactionTotalList" />
        <jb:wiring property="monetaryAmountList" beanIdRef="monetaryAmountList" />
        <jb:value property="code" data="#/code" />
        <jb:value property="value" data="#/value" />
    </jb:bean>

    <jb:bean beanId="transactionTotalList" class="java.util.ArrayList" createOnElement="Summary">
        <jb:wiring beanIdRef="transactionTotals" />
    </jb:bean>

    <jb:bean beanId="transactionTotals" class="org.jeecg.modules.edi.PurchaseOrder.TransactionTotals" createOnElement="TransactionTotals">
        <!-- Customer bindings... -->
        <jb:value property="totalNumber" data="#/total-number" />
    </jb:bean>

    <jb:bean beanId="monetaryAmountList" class="java.util.ArrayList" createOnElement="Summary">
        <!-- Customer bindings... -->
        <jb:wiring beanIdRef="monetaryAmount" />
    </jb:bean>

    <jb:bean beanId="monetaryAmount" class="org.jeecg.modules.edi.PurchaseOrder.MonetaryAmount" createOnElement="MonetaryAmount">
        <!-- Customer bindings... -->
        <jb:value property="code" data="#/code" />
        <jb:value property="monetaryAmount" data="#/monetary-amount" />
    </jb:bean>

</smooks-resource-list>

3.配置文件purchaseorder-mapping.xml

如果此配置文件中mapping与文件字段数量不一致会发生报错,此时需要添加truncatable="true"对数据进行截断。segcode匹配的设置可以使用正则表达式的方式如:segcode="N1\(BY|FR|SN)."

<?xml version="1.0" encoding="UTF-8"?>
<medi:edimap xmlns:medi="http://www.milyn.org/schema/edi-message-mapping-1.3.xsd">

    <medi:description name="Purchase Order" version="1.0"/>

    <medi:delimiters segment=">" field="*" component="^" sub-component="~"/>

    <medi:segments xmltag="MessagePurchaseOrder">
        <medi:segment segcode="ISA" xmltag="isa" minOccurs="0" maxOccurs="1">
            <medi:field xmltag="code1"/>
            <medi:field xmltag="code2"/>
            <medi:field xmltag="code3"/>
            <medi:field xmltag="code4"/>
            <medi:field xmltag="code5"/>
            <medi:field xmltag="code6"/>
            <medi:field xmltag="code7"/>
            <medi:field xmltag="code8"/>
            <medi:field xmltag="code9"/>
            <medi:field xmltag="code10"/>
            <medi:field xmltag="code11"/>
            <medi:field xmltag="code12"/>
            <medi:field xmltag="code13"/>
            <medi:field xmltag="code14"/>
            <medi:field xmltag="code15"/>
            <medi:field xmltag="code16"/>
        </medi:segment>
        <medi:segment segcode="GS" xmltag="gs" minOccurs="0" maxOccurs="1">
            <medi:field xmltag="code1"/>
            <medi:field xmltag="code2"/>
            <medi:field xmltag="code3"/>
            <medi:field xmltag="code4"/>
            <medi:field xmltag="code5"/>
            <medi:field xmltag="code6"/>
            <medi:field xmltag="code7"/>
            <medi:field xmltag="code8"/>
        </medi:segment>
        <medi:segmentGroup maxOccurs="-1" minOccurs="0">
            <medi:segment segcode="ST" xmltag="PurchaseOrder" maxOccurs="1">
                <medi:field xmltag="code1"/>
                <medi:field xmltag="code2"/>
            </medi:segment>

            <medi:segment segcode="BEG" xmltag="Beginning" maxOccurs="1">
                <medi:field xmltag="purpose-code"/>
                <medi:field xmltag="order-type"/>
                <medi:field xmltag="order-number"/>
                <medi:field xmltag="release-number"/>
                <medi:field xmltag="date"/>
            </medi:segment>

            <medi:segment segcode="CUR" xmltag="OrderCurrency" maxOccurs="1">
                <medi:field xmltag="code"/>
                <medi:field xmltag="value"/>
            </medi:segment>
            <medi:segment segcode="REF" xmltag="REF" maxOccurs="-1">
                <medi:field xmltag="code"/>
                <medi:field xmltag="value"/>
            </medi:segment>
            <medi:segment segcode="FOB" xmltag="FOB" maxOccurs="-1">
                <medi:field xmltag="code"/>
                <medi:field xmltag="value"/>
                <medi:field xmltag="value1"/>
            </medi:segment>
            <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                <medi:segment segcode="SAC" xmltag="ServiceAllowanceCharge" maxOccurs="1" truncatable="true">
                    <medi:field xmltag="ACcode"/>
                    <medi:field xmltag="SCCode"/>
                    <medi:field xmltag="remark1"/>
                    <medi:field xmltag="remark2"/>
                    <medi:field xmltag="amount"/>
                    <medi:field xmltag="percent"/>
                    <medi:field xmltag="rate"/>
                    <medi:field xmltag="percentDecimalFormat"/>
                    <medi:field xmltag="measurementUnit"/>
                    <medi:field xmltag="quantity"/>
                    <medi:field xmltag="remark3"/>
                    <medi:field xmltag="handlingCode"/>
                </medi:segment>
            </medi:segmentGroup>
            <medi:segment segcode="ITD" xmltag="ITD" minOccurs="0" maxOccurs="10">
                <medi:field xmltag="code1"/>
                <medi:field xmltag="code2"/>
                <medi:field xmltag="code3"/>
                <medi:field xmltag="code4"/>
                <medi:field xmltag="code5"/>
                <medi:field xmltag="code6"/>
                <medi:field xmltag="code7"/>
            </medi:segment>
            <medi:segment segcode="DTM" xmltag="DateTimeReference" minOccurs="0" maxOccurs="10">
                <medi:field xmltag="code"/>
                <medi:field xmltag="date"/>
            </medi:segment>
            <medi:segment segcode="TD5" xmltag="TD5" maxOccurs="-1" minOccurs="0">
                <medi:field xmltag="value1"/>
                <medi:field xmltag="value2"/>
                <medi:field xmltag="value3"/>
                <medi:field xmltag="value4"/>
                <medi:field xmltag="value5"/>
            </medi:segment>
            <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                <medi:segment segcode="N9" xmltag="N9Loop" maxOccurs="1">
                    <medi:field xmltag="code"/>
                    <medi:field xmltag="value"/>
                </medi:segment>
                <medi:segment segcode="MTX" xmltag="MTX" maxOccurs="-1">
                    <medi:field xmltag="code"/>
                    <medi:field xmltag="value"/>
                </medi:segment>
            </medi:segmentGroup>
            <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                <medi:segment segcode="N1\*(BY|FR|SN).*" xmltag="N1Loop" minOccurs="0" maxOccurs="-1">
                    <medi:field xmltag="identifier-code"/>
                    <medi:field xmltag="free-form-name"/>
                    <medi:field xmltag="code-qualifier"/>
                    <medi:field xmltag="party-code"/>
                </medi:segment>

                <medi:segment segcode="N3" xmltag="N3" minOccurs="0" maxOccurs="1" truncatable="true">
                    <medi:field xmltag="code"/>
                    <medi:field xmltag="value"/>
                </medi:segment>
                <medi:segment segcode="N4" xmltag="N4" minOccurs="0" maxOccurs="1">
                    <medi:field xmltag="code"/>
                    <medi:field xmltag="value"/>
                    <medi:field xmltag="value1"/>
                    <medi:field xmltag="value2"/>
                </medi:segment>
                <medi:segment segcode="N1\*SU.*" xmltag="Supplier" minOccurs="0" maxOccurs="-1">
                    <medi:field xmltag="code"/>
                    <medi:field xmltag="value"/>
                </medi:segment>
            </medi:segmentGroup>
            <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                <medi:segment segcode="PO1" xmltag="BaselineItemData" minOccurs="0" maxOccurs="1">
                    <medi:field xmltag="line-number"/>
                    <medi:field xmltag="quantity"/>
                    <medi:field xmltag="unit"/>
                    <medi:field xmltag="unit-price"/>
                    <medi:field xmltag="basis-of-unit-price-code"/>
                    <medi:field xmltag="in"/>
                    <medi:field xmltag="item-number"/>
                    <medi:field xmltag="en"/>
                    <medi:field xmltag="GTIN"/>
                    <medi:field xmltag="vn"/>
                    <medi:field xmltag="vendorin"/>
                    <medi:field xmltag="bo"/>
                    <medi:field xmltag="color"/>
                    <medi:field xmltag="iz"/>
                    <medi:field xmltag="size"/>
                    <medi:field xmltag="p8"/>
                    <medi:field xmltag="price-look-up"/>
                    <medi:field xmltag="ua"/>
                    <medi:field xmltag="case-code"/>
                    <medi:field xmltag="up"/>
                    <medi:field xmltag="universal-product"/>
                    <medi:field xmltag="uk"/>
                    <medi:field xmltag="uk-code"/>
                </medi:segment>
                <medi:segment segcode="PID" xmltag="ProductItemDescription" minOccurs="0" maxOccurs="200">
                    <medi:field xmltag="item-type"/>
                    <medi:field xmltag="item-code"/>
                    <medi:field xmltag="agency-qualifier-code"/>
                    <medi:field xmltag="product-description-code"/>
                    <medi:field xmltag="product-description"/>
                </medi:segment>
                <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                    <medi:segment segcode="CTP" xmltag="PricingInformation" minOccurs="0" maxOccurs="1">
                        <medi:field xmltag="code"/>
                        <medi:field xmltag="value"/>
                        <medi:field xmltag="value1"/>
                    </medi:segment>
                </medi:segmentGroup>

                <medi:segment segcode="PO4" xmltag="PO4" minOccurs="0" maxOccurs="1" truncatable="true">
                    <medi:field xmltag="value"/>
                    <medi:field xmltag="code2" truncatable="true"/>
                    <medi:field xmltag="code3" truncatable="true"/>
                    <medi:field xmltag="code4" truncatable="true"/>
                    <medi:field xmltag="code5" truncatable="true"/>
                    <medi:field xmltag="code6" truncatable="true"/>
                    <medi:field xmltag="code7" truncatable="true"/>
                    <medi:field xmltag="code8" truncatable="true"/>
                    <medi:field xmltag="code9" truncatable="true"/>
                    <medi:field xmltag="code10" truncatable="true"/>
                    <medi:field xmltag="code11" truncatable="true"/>
                    <medi:field xmltag="code12" truncatable="true"/>
                    <medi:field xmltag="code13" truncatable="true"/>
                    <medi:field xmltag="code14" truncatable="true"/>

                </medi:segment>
                <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                    <medi:segment segcode="SAC" xmltag="DetailSAC" maxOccurs="1" truncatable="true">
                        <medi:field xmltag="code1"/>
                        <medi:field xmltag="code2"/>
                        <medi:field xmltag="code3"/>
                        <medi:field xmltag="code4"/>
                        <medi:field xmltag="code5"/>
                        <medi:field xmltag="code6"/>
                        <medi:field xmltag="code7"/>
                        <medi:field xmltag="code8"/>
                        <medi:field xmltag="code9"/>
                        <medi:field xmltag="code10"/>
                        <medi:field xmltag="code11"/>
                        <medi:field xmltag="code12"/>
                    </medi:segment>
                </medi:segmentGroup>
                <medi:segment segcode="SDQ" xmltag="DetailSDQ" minOccurs="0" maxOccurs="500" truncatable="true">
                    <medi:field xmltag="code1"/>
                    <medi:field xmltag="code2"/>
                    <medi:field xmltag="code3"/>
                    <medi:field xmltag="code4"/>
                    <medi:field xmltag="code5" required="false" truncatable="true"/>
                    <medi:field xmltag="code6" required="false" truncatable="true"/>
                    <medi:field xmltag="code7" required="false" truncatable="true"/>
                    <medi:field xmltag="code8" required="false" truncatable="true"/>
                    <medi:field xmltag="code9" required="false" truncatable="true"/>
                    <medi:field xmltag="code10" required="false" truncatable="true"/>
                    <medi:field xmltag="code11" required="false" truncatable="true"/>
                    <medi:field xmltag="code12" required="false" truncatable="true"/>
                    <medi:field xmltag="code13" required="false" truncatable="true"/>
                    <medi:field xmltag="code14" required="false" truncatable="true"/>
                    <medi:field xmltag="code15" required="false" truncatable="true"/>
                    <medi:field xmltag="code16" required="false" truncatable="true"/>
                    <medi:field xmltag="code17" required="false" truncatable="true"/>
                    <medi:field xmltag="code18" required="false" truncatable="true"/>
                    <medi:field xmltag="code19" required="false" truncatable="true"/>
                    <medi:field xmltag="code20" required="false" truncatable="true"/>
                    <medi:field xmltag="code21" required="false" truncatable="true"/>
                    <medi:field xmltag="code22" required="false" truncatable="true"/>
                </medi:segment>
                <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                    <medi:segment segcode="N9" xmltag="N9" maxOccurs="1">
                        <medi:field xmltag="code"/>
                        <medi:field xmltag="value"/>
                    </medi:segment>
                    <medi:segment segcode="MTX" xmltag="MTX" minOccurs="0" maxOccurs="1">
                        <medi:field xmltag="code"/>
                        <medi:field xmltag="value"/>
                    </medi:segment>
                </medi:segmentGroup>
                <medi:segmentGroup maxOccurs="-1" minOccurs="0">
                    <medi:segment segcode="SLN" xmltag="SublineItemDetail" maxOccurs="-1">
                        <medi:field xmltag="value1"/>
                        <medi:field xmltag="value2"/>
                        <medi:field xmltag="value3"/>
                        <medi:field xmltag="value4"/>
                        <medi:field xmltag="value5"/>
                        <medi:field xmltag="value6"/>
                        <medi:field xmltag="value7"/>
                        <medi:field xmltag="value8"/>
                        <medi:field xmltag="value9"/>
                        <medi:field xmltag="value10"/>
                        <medi:field xmltag="value11"/>
                        <medi:field xmltag="value12"/>
                        <medi:field xmltag="value13"/>
                        <medi:field xmltag="value14"/>
                        <medi:field xmltag="value15"/>
                        <medi:field xmltag="value16"/>
                        <medi:field xmltag="value17"/>
                        <medi:field xmltag="value18"/>
                        <medi:field xmltag="value19"/>
                        <medi:field xmltag="value20"/>
                        <medi:field xmltag="value21"/>
                        <medi:field xmltag="value22"/>
                        <medi:field xmltag="value23"/>
                        <medi:field xmltag="value24"/>
                        <medi:field xmltag="value25"/>
                        <medi:field xmltag="value26"/>
                        <medi:field xmltag="value27"/>
                        <medi:field xmltag="value28"/>
                    </medi:segment>
                </medi:segmentGroup>
                <medi:segmentGroup minOccurs="0" maxOccurs="-1">
                    <medi:segment segcode="AMT" xmltag="MonetaryAmountDetail" minOccurs="0" maxOccurs="1">
                        <medi:field xmltag="code"/>
                        <medi:field xmltag="monetary-amount"/>
                    </medi:segment>
                </medi:segmentGroup>
            </medi:segmentGroup>
            <medi:segmentGroup minOccurs="0" maxOccurs="-1">
                <medi:segment segcode="CTT" xmltag="TransactionTotals" minOccurs="0" maxOccurs="1">
                    <medi:field xmltag="total-number"/>
                </medi:segment>
                <medi:segment segcode="AMT" xmltag="MonetaryAmount" minOccurs="0" maxOccurs="1">
                    <medi:field xmltag="code"/>
                    <medi:field xmltag="monetary-amount"/>
                </medi:segment>
            </medi:segmentGroup>
            <medi:segment segcode="SE" xmltag="Summary" minOccurs="0" maxOccurs="1">
                <medi:field xmltag="code"/>
                <medi:field xmltag="value"/>
            </medi:segment>
        </medi:segmentGroup>

        <medi:segment segcode="GE" xmltag="ge" minOccurs="0" maxOccurs="1">
            <medi:field xmltag="code"/>
            <medi:field xmltag="value"/>
        </medi:segment>
        <medi:segment segcode="IEA" xmltag="iea" minOccurs="0" maxOccurs="1">
            <medi:field xmltag="code"/>
            <medi:field xmltag="value"/>
        </medi:segment>
    </medi:segments>

</medi:edimap>

4.服务注册

package org.jeecg.modules.edi.service;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.edi.PurchaseOrder.*;
import org.jeecg.modules.order.entity.ZwxWalmartOrderItem;
import org.jeecg.modules.order.entity.ZwxWalmartOrders;
import org.jeecg.modules.order.vo.ZwxWalmartOrdersPage;
import org.milyn.Smooks;
import org.milyn.container.ExecutionContext;
import org.milyn.payload.JavaResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liujb
 * @创建时间 2021-11-21
 * @描述
 */
@Service
@Slf4j
public class WalmartPurchaseOrderService{
    /**
     * 验证码类型
      */
    @Value("${jeecg.path.edifilepath}")
    private String edifilepath;

    public Result<Map<File,List<ZwxWalmartOrdersPage>>> updateFromWalmart(){
        Map<File,List<ZwxWalmartOrdersPage>> result = new HashMap<>();
        Smooks smooks = null;
        try {
            smooks = new Smooks("purchaseorder-config.xml");
            ExecutionContext executionContext = smooks.createExecutionContext();
            JavaResult javaResult = new JavaResult();
            File files = new File(edifilepath);

            File[] tempList = files.listFiles();
            if(tempList.length > 0){
                for (File file : tempList) {
                    //返回结果
                    List<ZwxWalmartOrdersPage> zwxWalmartOrdersList = new ArrayList<>();
                    InputStreamReader reader = new InputStreamReader(new FileInputStream(file), Charset.forName("gb2312"));
                    smooks.filterSource(executionContext, new StreamSource(reader), javaResult);
                    MessagePurchaseOrder messagePurchaseOrder = (MessagePurchaseOrder) javaResult.getBean("messagePurchaseOrder");
                    log.info(messagePurchaseOrder.toString());
                    List<PurchaseOrder> purchaseOrders = messagePurchaseOrder.getPurchaseOrders();
                    for (PurchaseOrder order:purchaseOrders) {
                        ZwxWalmartOrdersPage zwxWalmartOrdersPage = new ZwxWalmartOrdersPage();
                        ZwxWalmartOrders zwxOrders = new ZwxWalmartOrders();
                        zwxOrders.setDeptId(112);
                        zwxOrders.setPurchaseOrderNo(order.getBeginning().getOrderNumber());
                        zwxOrders.setOrderDate(order.getBeginning().getDate());

                        for (ServiceAllowanceCharge sac:order.getServiceAllowanceChargeList()) {
                            zwxOrders.setAllowance(BigDecimal.valueOf(0.01).multiply(sac.getAmount()));
                            zwxOrders.setAllowanceRate(BigDecimal.valueOf(0.01).multiply(sac.getRate()));
                        }
                        List<REF> refList = order.getRefList();
                        for (REF ref:refList) {
                            switch (ref.getCode()){
                                case "PD":
                                    zwxOrders.setPromotionalEvent(ref.getValue());
                                    break;
                                case "MR":
                                    zwxOrders.setOrderType(ref.getValue());
                                    break;
                                default:
                            }
                        }

                        List<DateTimeReference> dateTimeReferenceList = order.getDateTimeReferenceList();
                        for (DateTimeReference dateTimeReference:dateTimeReferenceList) {
                            /**
                             * 001 Cancel After
                             * 002 Delivery Requested
                             * 037 Ship Not Before
                             * 038 Ship No Later
                             * 063 Do Not Deliver After
                             */
                            switch (dateTimeReference.getCode()){
                                case "001":
                                    zwxOrders.setMustArriveBy(dateTimeReference.getDate());
                                    break;
                                case "010":
                                    zwxOrders.setShipNoLaterThan(dateTimeReference.getDate());
                                    break;
                                case "037":
                                    zwxOrders.setShipNotBefore(dateTimeReference.getDate());
                                    break;
                                case "038":
                                    zwxOrders.setShipNoLaterThan(dateTimeReference.getDate());
                                    break;
                                case "063":
                                    zwxOrders.setMustArriveBy(dateTimeReference.getDate());
                                    break;
                                default:

                            }
                        }
                        zwxOrders.setCurrency(order.getOrderCurrency().getValue());
                        List<N1Loop> n1LoopList = order.getN1LoopList();
                        for (N1Loop n1Loop:n1LoopList) {
                            String[] splitFormName = n1Loop.getFreeFormName().split(" ");
                            if (splitFormName.length>1){
                                if("BY".equals(n1Loop.getIdentifierCode())){
                                    String shopNo = splitFormName[splitFormName.length - 1];
                                    zwxOrders.setShopNo(shopNo);
                                    zwxOrders.setShopName(n1Loop.getFreeFormName().replace(shopNo,""));
                                }
                            }else{
                                zwxOrders.setShopName(n1Loop.getFreeFormName());
                            }
                            if(null != n1Loop.getSupplier()){
                                zwxOrders.setSupplierName(n1Loop.getSupplier().getValue());
                            }
                        }
                        List<TransactionTotals> transactionTotalList = order.getSummary().getTransactionTotalList();
                        for (TransactionTotals transactionTotals:transactionTotalList) {
                            zwxOrders.setTotalLineItems(transactionTotals.getTotalNumber());
                        }
                        List<MonetaryAmount> monetaryAmountList = order.getSummary().getMonetaryAmountList();
                        for (MonetaryAmount amount:monetaryAmountList) {
                            if("TT".equals(amount.getCode())){
                                zwxOrders.setTotalAmount(amount.getMonetaryAmount());
                            }
                        }

                        List<ZwxWalmartOrderItem> zwxOrderItemList = new ArrayList<>();
                        for (BaselineItemData baselineItemData:order.getBaselineItemDatas()) {
                            ZwxWalmartOrderItem zwxOrderItem = new ZwxWalmartOrderItem();
                            zwxOrderItem.setColor(baselineItemData.getColor());
                            zwxOrderItem.setQuantity(baselineItemData.getQuantity());
                            zwxOrderItem.setSize(baselineItemData.getSize());
                            zwxOrderItem.setPack(baselineItemData.getPo4().getValue());
//                            StringBuilder productDescription = new StringBuilder();
//                            for (ProductItemDescription productItemDescription:baselineItemData.getProductItemDescriptionList()) {
//                                productDescription.append(productItemDescription.getProductdescription());
//                            }
                            zwxOrderItem.setProductName(baselineItemData.getProductItemDescriptionList().get(0).getProductdescription());
                            zwxOrderItem.setItemNo(baselineItemData.getItemNumber().toString());
                            zwxOrderItem.setLineNumber(Integer.parseInt(baselineItemData.getLineNumber()));
                            zwxOrderItem.setUnitPrice(baselineItemData.getUnitPrice());
                            for (MonetaryAmountDetail monetaryAmountDetail:baselineItemData.getMonetaryAmountDetailList()) {
                                zwxOrderItem.setTotalPrice(monetaryAmountDetail.getMonetaryAmountDetail());
                            }

                            for (DetailSAC sac:baselineItemData.getDetailSACList()) {
                                if("N".equals(sac.getCode1())){
                                    zwxOrderItem.setTaxRate(BigDecimal.valueOf(0.01).multiply(sac.getCode7()));
                                }
                            }
//                            String errorMessage = zwxOrdersService.matchSapMaterial(zwxOrders, zwxOrderItem);
//                            content.append(errorMessage);
                            zwxOrderItemList.add(zwxOrderItem);
                        }

                        BeanUtils.copyProperties(zwxOrders,zwxWalmartOrdersPage);
                        zwxWalmartOrdersPage.setZwxWalmartOrderItemList(zwxOrderItemList);
                        zwxWalmartOrdersList.add(zwxWalmartOrdersPage);
                    }
                    result.put(file,zwxWalmartOrdersList);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        } finally {
            log.info("获取沃尔玛采购订单执行结束!");
            smooks.close();
        }
        return Result.OK(result);
    }
}