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

原文地址:https://www.cnblogs.com/hanjun0612/p/14339954.html