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=" " 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内容,拷贝到自己的对象去。
这样就成为了静态映射,也简化了创建的繁琐。
三,网上的工具