zoukankan      html  css  js  c++  java
  • java to edi 动态/静态映射

    edi to java的已经介绍过了:https://www.cnblogs.com/hanjun0612/p/14333668.html

    参考相关链接:

    官方文档(细节上有点缺失):https://www.smooks.org/documentation/#ejc---edifact-java-compiler

    github地址(推荐下载看看):https://github.com/smooks/smooks/tree/v1.7.1/smooks-examples

    静态映射(下面也会说):https://stackoverflow.com/questions/35740207/from-java-object-prepare-the-edi-data

    下面,我介绍一下 java to edi。

    首先,java to edi 有 3种方式

    1 代码映射

    2 动态映射(重点)

    3 网上的工具:https://www.cnblogs.com/zmngc/p/10942835.html

    一, 静态映射

    参考:https://stackoverflow.com/questions/35740207/from-java-object-prepare-the-edi-data

    我们简单看一下,其实比较简单。

    1 CustomOrder 实现EDIWritable

    主要实现write方法。

    public class CustomOrder implements Serializable, EDIWritable{
    private int number;
    private IntegerDecoder numberDecoder;
    private String sender;
    private String message;
    private int price;
    private IntegerDecoder priceDecoder;
    public CustomOrder() {
        numberDecoder = new IntegerDecoder();
        priceDecoder = new IntegerDecoder();
    }
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
    public void setSender(String sender) {
        this.sender = sender;
    }
    public String getSender() {
        return sender;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public  void write(Writer writer, Delimiters delimiters) throws IOException {
        // TODO Auto-generated method stub
         Writer nodeWriter = writer;
     
            if(number != 0) {
                nodeWriter.write(delimiters.escape(numberDecoder.encode(number)));
            }
            nodeWriter.write(delimiters.getField());
     
            if(sender != null) {
                nodeWriter.write(delimiters.escape(sender.toString()));
            }
            nodeWriter.write(delimiters.getField());
     
            if(message != null) {
                nodeWriter.write(delimiters.escape(message.toString()));
            }
            nodeWriter.write(delimiters.getField());
            if(price != 0) {
                nodeWriter.write(delimiters.escape(priceDecoder.encode(price)));
            }
            //nodeWriter.write(delimiters.getField());
     
            writer.write(delimiters.getSegmentDelimiter());
            writer.flush();
     
    }
    }

    2 实现工厂CustomOrderFactory

    public class CustomOrderFactory {
     private Smooks smooks;
     private Delimiters delimiters;
     public static CustomOrderFactory getInstance() throws IOException, SAXException {
            return new CustomOrderFactory();
        }
        public void addConfigurations(InputStream resourceConfigStream) throws SAXException, IOException {
            smooks.addConfigurations(resourceConfigStream);
        }
        public void toEDI(CustomOrder instance, Writer writer) throws IOException {
            instance.write(writer, delimiters);
        }
     
        private CustomOrderFactory() throws IOException, SAXException {
            smooks = new Smooks(CustomOrderFactory.class.getResourceAsStream("smooks-config.xml"));
            System.out.println("smooks is prepared");
            try {   
                Edimap edimap = EDIConfigDigester.digestConfig(CustomOrderFactory.class.getResourceAsStream("custom-order-mapping.xml"));
                System.out.println("ediMap is prepared");
                delimiters = edimap.getDelimiters();
                System.out.println("delimeter is prepared");
            } catch(EDIConfigurationException e) {
                IOException ioException = new IOException("Exception reading EDI Mapping model.");
                ioException.initCause(e);
                throw ioException;
            }
        }
    }

    3 测试

    Main smooksMain = new Main();
    ExecutionContext executionContext = smooksMain.smooks.createExecutionContext();
    org.milyn.payload.JavaResult result = smooksMain.runSmooksTransform(executionContext);
    CustomOrder custOrder = (CustomOrder) result.getBean("customer");
    // Prepare edi data from java object custOrder
    CustomOrderFactory customOrderFactory = CustomOrderFactory.getInstance();
    OutputStream os = new FileOutputStream("createdEDIFile.edi");
    customOrderFactory.toEDI(custOrder, new OutputStreamWriter(os));    
    System.out.println("Edi file is created from java object");

    二, 动态映射(重点)

    我们发现,静态映射还是比较麻烦。

    例如我对接东方国际的edi报文,可能有20个class。。。。。

    每个都需要实现write,想想吧就烦。

    但是,动态映射也有缺点。编译不通过。只能mvn clean install后调试,而且对代码阅读也不友好。

    所以两相结合,我们通过动态映射,生成的class,然后拷贝到项目中。

    变相的成为了静态映射,这样至少节省大把时间,代码至少可读性要强。

    下面看一下例子:

    项目结构

    1 POM文件

    dependencies:添加4个包

    plugins:添加打包时的动态映射工具

    <dependencies>
          <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>
        <dependency>
          <groupId>org.milyn</groupId>
          <artifactId>milyn-smooks-all</artifactId>
          <version>1.7.0</version>
        </dependency>
        <dependency>
          <groupId>org.milyn</groupId>
          <artifactId>milyn-smooks-ejc</artifactId>
          <version>1.7.1</version>
        </dependency>
      </dependencies>
     
      <build>
        <resources>
          <resource>
            <directory>src/main/java</directory>
            <excludes>
              <exclude>**/*.java</exclude>
            </excludes>
          </resource>
          <resource>
            <directory>src/main/resources</directory>
            <includes>
              <include>**/*.*</include>
            </includes>
          </resource>
        </resources>
     
        <plugins>
          <plugin>
            <groupId>org.milyn</groupId>
            <artifactId>ejc-maven-plugin</artifactId>
            <version>1.7.1</version>
            <configuration>
              <ediMappingFile>src/main/resources/test/edi-to-java-order-mapping.xml</ediMappingFile>
              <packageName>com.acme.order.model</packageName>
            </configuration>
            <executions>
              <execution>
                <phase>generate-sources</phase>
                <goals>
                  <goal>generate</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
     
      </build>
    </project>

    2 文件内容

    ①  input-message.edi 测试edi数据 

    HDR*1*0*59.97*64.92*4.95*Wed Nov 15 13:45:28 EST 2006
    CUS*user1*Harry^Fletcher*SD
    ORD*1*1*364*The 40-Year-Old Virgin*29.98
    ORD*2*1*299*Pulp Fiction*29.99

    ②  smooks-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">
     
        <edi:reader mappingModel="edi-to-java-order-mapping.xml" />
     
        <jb:bean beanId="order" class="com.kintech.webEDI.model.modelEDI.test.Order" createOnElement="Order">
            <jb:wiring property="header" beanIdRef="header" />
            <jb:wiring property="orderItems" beanIdRef="orderItemList" />
        </jb:bean>
     
        <jb:bean beanId="header" class="com.kintech.webEDI.model.modelEDI.test.Header" createOnElement="${order}/header">
            <jb:wiring property="customer" beanIdRef="customer" />
            <jb:value property="orderId" data="#/order-id" />
            <jb:value property="orderStatus" decoder="Long" data="#/status-code" />
            <jb:value property="netAmount" decoder="BigDecimal" data="#/net-amount" />
            <jb:value property="totalAmount" decoder="BigDecimal" data="#/total-amount" />
            <jb:value property="tax" decoder="BigDecimal" data="#/tax" />
            <jb:value property="date" decoder="Date" data="#/date">
                <jb:decodeParam name="format">EEE MMM dd HH:mm:ss z yyyy</jb:decodeParam>
                <jb:decodeParam name="locale">en_IE</jb:decodeParam>
            </jb:value>
        </jb:bean>
     
        <jb:bean beanId="customer" class="com.kintech.webEDI.model.modelEDI.test.Customer" createOnElement="customer-details">
            <!-- Customer bindings... -->
            <jb:value property="userName" data="#/username" />
            <jb:value property="firstName" data="#/name/firstname" />
            <jb:value property="lastName" data="#/name/lastname" />
            <jb:value property="state" data="#/state" />
        </jb:bean>
     
     
        <jb:bean beanId="orderItemList" class="java.util.ArrayList" createOnElement="Order">
            <jb:wiring beanIdRef="orderItem" />
        </jb:bean>
     
        <jb:bean beanId="orderItem" class="com.kintech.webEDI.model.modelEDI.test.OrderItem" createOnElement="order-item">
            <!-- OrderItem bindings... -->
            <jb:value property="quantity" decoder="Integer" data="#/quantity" />
            <jb:value property="productId" decoder="String" data="#/product-id" />
            <jb:value property="price" decoder="BigDecimal" data="#/price" />
            <jb:value property="title" data="#/title" />
        </jb:bean>
     
    </smooks-resource-list>

    ③  edi-to-java-order-mapping.xml 映射文件

    <?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="DVD Order" version="1.0" />
     
        <medi:delimiters segment="&#10;" field="*" component="^" sub-component="~" />
     
        <medi:segments xmltag="Order">
     
            <medi:segment segcode="HDR" xmltag="header">
                <medi:field xmltag="order-id" />
                <medi:field xmltag="status-code" />
                <medi:field xmltag="net-amount" />
                <medi:field xmltag="total-amount" />
                <medi:field xmltag="tax" />
                <medi:field xmltag="date" />
            </medi:segment>
     
            <medi:segment segcode="CUS" xmltag="customer-details">
                <medi:field xmltag="username" />
                <medi:field xmltag="name">
                    <medi:component xmltag="firstname" />
                    <medi:component xmltag="lastname" />
                </medi:field>
                <medi:field xmltag="state" />
            </medi:segment>
     
            <medi:segment segcode="ORD" xmltag="order-item" maxOccurs="-1">
                <medi:field xmltag="position" />
                <medi:field xmltag="quantity" />
                <medi:field xmltag="product-id" />
                <medi:field xmltag="title" />
                <medi:field xmltag="price" />
            </medi:segment>
     
        </medi:segments>
        
    </medi:edimap>

    3 测试类(第4步完成,才可执行)

    package com.kintech.webEDI;
    
    import com.acme.order.model.*;
    import com.acme.order.model.field.Name;
    
    import java.io.IOException;
    import java.io.File;
    import java.io.PrintWriter;
    import java.io.StringReader;
    import java.math.BigDecimal;
    import java.util.List;
    
    import org.xml.sax.SAXException;
    import org.milyn.io.FileUtils;
    /**
     * @author Tyler
     * @date 2021/1/27
     */
    
    public class MainEJC {
        public static void main(String[] args) throws IOException, SAXException {
            String ediMessage = new String(FileUtils.readFile(new File(MainEJC.class.getResourcec("/test/input-message.edi").toURI())));
            StringReader ediStream = new StringReader(ediMessage);
    
            OrderFactory orderFactory = OrderFactory.getInstance();
    
            //edi to java
            Order order = orderFactory.fromEDI(ediStream);
            Header header=order.getHeader();
    
            //java to edi
            orderFactory.toEDI(order, new PrintWriter(System.out));
    
            System.out.println();
        }
    }

    4 打包

    maven打开终端,执行 mvn clean install

    我们在target目录下,会看到动态生成的model

    然后就可以  Debug / Run 上面的Main了

    如果你觉得动态映射,太过抽象,维护也困难。

    那么,你可以把生成的class内容,拷贝到自己的对象去。

    这样就成为了静态映射,也简化了创建的繁琐。

    三,网上的工具

    这个大家直接看  https://www.cnblogs.com/zmngc/p/10942835.html

  • 相关阅读:
    某开源ERP最新版SQL与RCE的审计过程
    QEMU固件模拟技术-stm32仿真分析及IRQ仿真实践
    QEMU固件模拟技术分析-luaqemu实现分析
    C/C++源码扫描系列- Fortify 篇
    C/C++源码扫描系列- Joern 篇
    C/C++源码扫描系列- codeql 篇
    bluetooth_stack开源蓝牙协议栈源码分析与漏洞挖掘
    DA14531芯片固件逆向系列(4)- L2CAP及ATT层收包再分析
    DA14531芯片固件逆向系列(3)- BLE收包流程分析及漏洞挖掘思路分享
    微服务架构简单搭建——Spring Cloud Eureka、Ribbon实现服务治理与服务消费
  • 原文地址:https://www.cnblogs.com/hanjun0612/p/14339954.html
Copyright © 2011-2022 走看看