Smooks是一种java的开源框架,可以进行edi to java、java to edi、xml to edi、edi to xml等等转换操作。
milyn-smooks-edi是milyn-smooks-all的一个子模块,处理edi和java之间的转换
12 6 或者 7org.milyn 3milyn-smooks-all 41.7.0 58 org.milyn 9milyn-smooks-edi 101.7.0 11
在Smooks的官方文档有相关edi to java的案例,但是java to edi的例子非常少,本篇博客主要提供一些java to edi的方法。
EDI,全称 Electronic Data Interchange,译名:电子数据交换。有很多的标准,本文主要转化的是Intrra D99b UN/Edifacrt 类型的国际标准的EDI报文
12 6com.yqn.unedifact 3d99b-mapping 41.7.0 57 com.yqn.unedifact 8d99b-binding 91.0.2 10
d99b-mapping包解决了edi to java,d99b-binding包解决了java to edi.
https://mvnrepository.com/artifact/org.milyn.edi.unedifact 几乎有所有类型的国家标准的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 ListunEdifactMessage41List = 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 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 }