edi to java的已经介绍过了:https://blog.csdn.net/hanjun0612/article/details/113182931
参考相关链接:
官方文档(细节上有点缺失):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=" " 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.getResource("/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内容,拷贝到自己的对象去。
这样就成为了静态映射,也简化了创建的繁琐。
三,网上的工具