smooks数据转换:java to edi

Smooks是一种java的开源框架,可以进行edi to java、java to edi、xml to edi、edi to xml等等转换操作。

milyn-smooks-edi是milyn-smooks-all的一个子模块,处理edi和java之间的转换
 1 <dependency>
 2     <groupId>org.milyn</groupId>
 3     <artifactId>milyn-smooks-all</artifactId>
 4     <version>1.7.0</version>
 5 </dependency>
 6 或者
 7 <dependency>
 8      <groupId>org.milyn</groupId>
 9      <artifactId>milyn-smooks-edi</artifactId>
10      <version>1.7.0</version>
11 </dependency>

在Smooks的官方文档有相关edi to java的案例,但是java to edi的例子非常少,本篇博客主要提供一些java to edi的方法。

EDI,全称 Electronic Data Interchange,译名:电子数据交换。有很多的标准,本文主要转化的是Intrra D99b UN/Edifacrt  类型的国际标准的EDI报文

 1         <dependency>
 2             <groupId>org.milyn.edi.unedifact</groupId>
 3             <artifactId>d99b-mapping</artifactId>
 4             <version>1.7.0</version>
 5         </dependency>
 6         <dependency>
 7             <groupId>org.milyn.edi.unedifact</groupId>
 8             <artifactId>d99b-binding</artifactId>
 9             <version>1.0.2</version>
10         </dependency>

d99b-mapping包解决了edi to java,d99b-binding包解决了java to edi.

https://mvnrepository.com/artifact/org.milyn.edi.unedifact 或者 https://www.pangugle.com/lib/maven/group/org.milyn.edi.unedifact.html 几乎有所有类型的国家标准的edi类型报文和java之间的映射。

  3 import org.apache.commons.io.IOUtils;
  4 import org.milyn.Smooks;
  5 import org.milyn.smooks.edi.unedifact.UNEdifactReaderConfigurator;
  6 import org.milyn.smooks.edi.unedifact.model.UNEdifactInterchange;
  7 import org.milyn.smooks.edi.unedifact.model.UNEdifactInterchangeFactory;
  8 import org.milyn.smooks.edi.unedifact.model.r41.*;
  9 import org.milyn.smooks.edi.unedifact.model.r41.types.DateTime;
 10 import org.milyn.smooks.edi.unedifact.model.r41.types.MessageIdentifier;
 11 import org.milyn.smooks.edi.unedifact.model.r41.types.Party;
 12 import org.milyn.smooks.edi.unedifact.model.r41.types.SyntaxIdentifier;
 13 
 14 import javax.xml.transform.stream.StreamResult;
 15 import javax.xml.transform.stream.StreamSource;
 16 import java.io.*;
 17 import java.text.SimpleDateFormat;
 18 import java.util.ArrayList;
 19 import java.util.Date;
 20 import java.util.List;
 21 
 22 public class UNEdifactUtil {
 23 
 24     private static String dateformat = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
 25 
 26     /**
 27      * 组装Interchange Header 报文交换头部
 28      * @param senderId
 29      * @param recipientId
 30      * @param yymmddStr
 31      * @param hhmmStr
 32      * @param agreementNumber
 33      * @return
 34      */
 35     public static UNB41 assembleUNB(String senderId, String recipientId, String yymmddStr, String hhmmStr, String agreementNumber){
 36         UNB41 interchangeHeader = new UNB41();
 37         SyntaxIdentifier syntaxIdentifier = new SyntaxIdentifier();
 38         syntaxIdentifier.setId("UNOA");
 39         syntaxIdentifier.setVersionNum("2");
 40         interchangeHeader.setSyntaxIdentifier(syntaxIdentifier);
 41 
 42         Party sender = new Party();
 43         sender.setId(senderId);
 44         sender.setCodeQualifier("ZZZ");
 45         interchangeHeader.setSender(sender);
 46 
 47         Party recipient = new Party();
 48         recipient.setId(recipientId);
 49         recipient.setCodeQualifier("ZZZ");
 50         interchangeHeader.setRecipient(recipient);
 51 
 52         DateTime dateTime = new DateTime();
 53         dateTime.setDate(yymmddStr);
 54         dateTime.setTime(hhmmStr);
 55         interchangeHeader.setDate(dateTime);
 56 
 57         interchangeHeader.setControlRef(agreementNumber);
 58         return interchangeHeader;
 59     }
 60 
 61     /**
 62      * 组装 Interchange Trailer 报文交换尾部
 63      * @param agreementNumber
 64      * @return
 65      */
 66     public static UNZ41 assembleUNZ(String agreementNumber){
 67         UNZ41 interchangeTrailer = new UNZ41();
 68         interchangeTrailer.setControlCount(1);
 69         interchangeTrailer.setControlRef(agreementNumber);
 70         return interchangeTrailer;
 71     }
 72 
 73     /**
 74      * 组装Message Header 报文头部
 75      * @param agreementNumber
 76      * @return
 77      */
 78     public static UNH41 assembleUNH(String agreementNumber){
 79         UNH41 messageHeader = new UNH41();
 80         messageHeader.setMessageRefNum(agreementNumber);
 81         MessageIdentifier messageIdentifier = new MessageIdentifier();
 82         messageIdentifier.setId("IFTMIN");
 83         messageIdentifier.setControllingAgencyCode("UN");
 84         messageIdentifier.setVersionNum("D");
 85         messageIdentifier.setReleaseNum("99B");
 86         messageHeader.setMessageIdentifier(messageIdentifier);
 87         return messageHeader;
 88     }
 89 
 90     /**
 91      * 组装Message Trailer 报文尾部
 92      * @param segmentCount
 93      * @param agreementNumber
 94      * @return
 95      */
 96     public static UNT41 assembleUNT(int segmentCount, String agreementNumber){
 97         UNT41 messageTrailer = new UNT41();
 98         messageTrailer.setSegmentCount(segmentCount);
 99         messageTrailer.setMessageRefNum(agreementNumber);
100         return messageTrailer;
101     }
102 
103     /**
104      * java(message)转EDI报文
105      *
106      * @param factory 工厂类型
107      * @param message 报文内容
108      * @return
109      * @throws Exception
110      */
111     public static String toUNEdidact(String senderIdentification, String receiverIdentification, UNEdifactInterchangeFactory factory, Object message) throws IOException{
112         Date date = new Date();
113         String yymmddStr = new SimpleDateFormat("yyMMdd").format(date);
114         String hhmmStr = new SimpleDateFormat("HHmm").format(date);
115         int randomNumber =(int)(Math.random() * 10000);
116         //文件交换号
117         String agreementNumber = yymmddStr + hhmmStr + randomNumber;
118         UNB41 interchangeHeader = assembleUNB(senderIdentification, receiverIdentification, yymmddStr, hhmmStr, agreementNumber);
119         UNZ41 interchangeTrailer = assembleUNZ(agreementNumber);
120         Integer line = 1;
121         UNH41 messageHeader = assembleUNH(agreementNumber);
122         UNT41 beforeMessageTrailer = assembleUNT(line, agreementNumber);
123         String beforeMessage = javaToUNEdifact(factory, message,null, null, messageHeader, beforeMessageTrailer);
124         line = StringUtil.messageLine(beforeMessage);
125         UNT41 afterMessageTrailer = assembleUNT(line, agreementNumber);
126         return javaToUNEdifact(factory,message,interchangeHeader,interchangeTrailer,messageHeader,afterMessageTrailer);
127     }
128 
129 
130     /**
131      *
132      * @param factory 工厂类型
133      * @param message 报文内容
134      * @param interchangeHeader 报文头
135      * @param interchangeTrailer 报文尾
136      * @param messageHeader 消息头
137      * @param messageTrailer 消息尾
138      * @return 国际标准EDI报文
139      * @throws IOException
140      */
141     public static String javaToUNEdifact(UNEdifactInterchangeFactory factory, Object message,
142                                          UNB41 interchangeHeader, UNZ41 interchangeTrailer,
143                                          UNH41 messageHeader, UNT41 messageTrailer) throws IOException {
144         StringWriter ediOutStream = new StringWriter();
145 
146         UNEdifactInterchange41 interchange = new UNEdifactInterchange41();
147         interchange.setInterchangeHeader(interchangeHeader);
148         interchange.setInterchangeTrailer(interchangeTrailer);
149 
150         UNEdifactMessage41 unEdifactMessage41 = new UNEdifactMessage41();
151         unEdifactMessage41.setMessage(message);
152         unEdifactMessage41.setInterchangeHeader(interchangeHeader);
153         unEdifactMessage41.setMessageHeader(messageHeader);
154         unEdifactMessage41.setMessageTrailer(messageTrailer);
155         List<UNEdifactMessage41> unEdifactMessage41List = new ArrayList<>();
156         unEdifactMessage41List.add(unEdifactMessage41);
157         interchange.setMessages(unEdifactMessage41List);
158 
159         factory.toUNEdifact(interchange, ediOutStream);
160         return ediOutStream.toString();
161     }
162 
163     /**
164      * 国际标准的UN/EDIFact 转 xml
165      *
166      * @param mappingType 报文标准类型 例如:d99b-mapping
167      * @param filePath 报文文件路径
168      * @return
169      */
170     public static String ediToXml(String mappingType, String filePath){
171         Smooks smooks = new Smooks();
172         StringWriter writer = new StringWriter();
173         try{
174             smooks.setReaderConfig(new UNEdifactReaderConfigurator("urn:org.milyn.edi.unedifact:"+mappingType+":*"));
175             smooks.filterSource(new StreamSource(new FileInputStream(filePath)), new StreamResult(writer));
176             return writer.toString();
177         }catch (Exception e){
178             e.printStackTrace();
179             return null;
180         }finally {
181             smooks.close();
182             IOUtils.closeQuietly(writer);
183         }
184     }
185 
186 
187     /**
188      * 国际标准的UN/EDIFact 转 Object
189      *
190      * @param factory 工厂类型 例如:D93AInterchangeFactory
191      * @param filePath 报文路径
192      * @return
193      * @throws IOException
194      */
195     public static UNEdifactMessage41 edifactToObject(UNEdifactInterchangeFactory factory, String filePath) throws IOException {
196         InputStream stream = new FileInputStream(filePath);
197         UNEdifactInterchange interchange = factory.fromUNEdifact(stream);
198         if (interchange instanceof UNEdifactInterchange41) {
199             UNEdifactInterchange41 interchange41 = (UNEdifactInterchange41) interchange;
200             List<UNEdifactMessage41> message41List = interchange41.getMessages();
201             if(message41List.size()>0){
202                 return message41List.get(0);
203             }
204         }
205         return null;
206     }
207 }

测试类如下:

 1 import org.junit.Test;
 2 import org.junit.runner.RunWith;
 3 import org.milyn.edi.unedifact.d99b.D99BInterchangeFactory;
 4 import org.milyn.edi.unedifact.d99b.IFTMIN.Iftmin;
 5 import org.milyn.edisax.model.internal.Delimiters;
 6 import org.milyn.smooks.edi.unedifact.model.r41.*;
 7 import org.springframework.boot.test.context.SpringBootTest;
 8 import org.springframework.test.context.junit4.SpringRunner;
 9 
10 import java.io.StringWriter;
11 import java.io.Writer;
12 
13 
14 @RunWith(SpringRunner.class)
15 @SpringBootTest
16 public class UNEdifactUtilTest {
17 
18     @Test
19     public void ediToXml(){
20         String messageOut = UNEdifactUtil.ediToXml("d99b-mapping","iftmin.txt");
21         System.out.println(messageOut);
22     }
23 
24     @Test
25     public void ediToObject() throws Exception{
26         UNEdifactMessage41 result = UNEdifactUtil.edifactToObject(D99BInterchangeFactory.getInstance(),"iftmin.txt");
27         Iftmin iftmin = (Iftmin)result.getMessage();
28     }
29 
30     @Test
31     public void javaToEdi() throws Exception{
32         /**
33          * 本次例子是先把EDI报文转换成java Object再转换成EDI,真是情况java Object应该是由数据库数据组装而成。
34          */
35         UNEdifactMessage41 result = UNEdifactUtil.edifactToObject(D99BInterchangeFactory.getInstance(),"iftmin.txt");
36         Iftmin iftmin = (Iftmin)result.getMessage();
37 
38         Writer writer = new StringWriter();
39         Delimiters delimiters = new Delimiters();
40         delimiters.setSegment("'");
41         delimiters.setField("+");
42         delimiters.setComponent(":");
43         delimiters.setDecimalSeparator(".");
44 
45         //只转换了消息主体
46         iftmin.write(writer,delimiters);
47         String msg = writer.toString();
48         System.out.println(msg);
49 
50         System.out.println("======================================\n");
51         //包含报文的头部尾部
52         System.out.println(UNEdifactUtil.toUNEdidact("发送港","接受港",D99BInterchangeFactory.getInstance(),iftmin));
53         System.out.println("\n======================================");
54     }
55 }

 

2020-06-05补充信息,

1. 所需文件:https://files.cnblogs.com/files/zmngc/IFTMIN.zip

2. 计算报文行数: 

    /**
     * 计算报文有多少行
     *
     * @param message 报文内容
     * @return
     */
    public static Integer messageLine(String message) {
        if (StringUtils.isEmpty(message)) {
            return 0;
        }
        message = message.trim();
        String[] array = message.split("'");
        String[] array2 = message.split("\\?'");
        if (array2.length > 0) {
            return array.length - array2.length + 1;
        } else {
            return array.length;
        }
    }
posted @ 2019-05-29 11:33  鸡犬相闻  阅读(3016)  评论(17编辑  收藏  举报