最近需要对接 东方国际 edi 报文
下面,就简单描述一下过程。
首先,放上参考资料:都很有帮助
参考链接:
1 有嵌套对象的例子,而且很有帮助
2 smooks example :
一,项目结构
1 MainDongFang是测试类
2 model.modelEDI.dongfang 是 java bean
3 resources.testDongFang 存放
① input-message.edi 测试edi数据
② smooks-config.xml 配置文件
③ edi-to-java-order-mapping.xml 映射文件
二,引入smooks
org.milyn
milyn-smooks-all
1.7.0
三,
1 数据 input-message.edi
这里为了简洁,我只映射 00,03,47 的字段
00:IFTMBF:BOOKING:9:QYHD::201912261722'02:FLEX923423:DMDFR191217001:CY-CY::::::::::::OIT1234'03:EXP::::1'11::::ONE:OCEAN NETWORK EXPRESS:::20200109'12:CNSHA:SHANGHAI:CNSHA:SHANGHAI:CAVAN:VANCOUVER,BC:::CAMTR:MONTREAL,QC:CAMTR:MONTREAL,QC'14::FREIGHT PREPAID'15:::P'17:it@oitco.com'20::SHANGHAI OIT:HONGKOU CHANG YANG ROAD NO 8:TEL 6100000:MAIL IT@OITCO.COM'21::USA OIT:ADDRESS?:NEW YORK:LOCAL NO.4:BILL BUILDING:TEL ?: 00121-1234567'22::USA OIT:ADDRESS?:NEW YORK:LOCAL NO.4:BILL BUILDING:TEL ?: 00121-1234567'41:1:::30:PACKAGE(S):PACKAGE(S):6000.0:21.73::::::6000.0'44:N/M::'47:VEHICLE DOOR FORGING'47:ACCEPT LONG-TERM LEASED & '47:CARRIER OWNED CNTR ONLY'48:20GP:1:F:::::N'48:40HC:1:F:::::N'99:18'
2 配置smooks-config.xml
jb:wiring :代表引用类型
jb:value :代表基本类型
xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"xmlns:edi="http://www.milyn.org/xsd/smooks/edi-1.4.xsd"xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.4.xsd">
yyyyMMddHHmm
3 edi-to-java-order-mapping.xml
---- medi:description
segment:换行符
field:字段分隔符
component:根据某一列的分隔符再次分割。
escape:转义符
----medi:segment
segcode:行指令
xmltag:我看下来,是smooks-config.xml 中的createOnElement
truncatable : 可空(注意segment和field都要加!)
----medi:segmentGroup 代表循环
maxOccurs : 最大循环次数,-1代表多个。
minOccurs:最小循环次数,0代表可能没有。
----medi:segment segcode=99
这个是海关要求,需要一个总行数。可以没有对应实体。
四,实体类
1,DongFangOrder
@Datapublic classDongFangOrder {privateHEAD_00 head_00;privateBL_03 bl_03;private Listcargo_description_47s;
}
2,Head_00
@Datapublic classHEAD_00 {private String messageType; //报文类型
private String fileDescription; //文件说明
private String fileFunction; //文件功能
private String sendCode; //发送方代码
private String receiverCode; //接收方代码
private Date fileCreateTime; //文件建立时间
}
3,BL_03
@Datapublic classBL_03 {private String typeOfBLFrom; //提单类型
private String placeOfBLIssueCode; //提单签发地代码
private String placeOfBLIssue; //提单签发地
private String dateOfIssue; //签发日期
private Integer numberOfOriginalBL; //正本提单份数
private String prepaidAt; //预付地点
private String payableAt; //到付地点
}
4,Cargo_Description_47
@Datapublic classCARGO_DESCRIPTION_47 {private String cargoDescription; //货物描述
}
五,测试
直接调用 smooks的example中例子就可以了。
packagecom.kintech.webEDI;importorg.milyn.Smooks;importorg.milyn.SmooksException;importorg.milyn.container.ExecutionContext;importorg.milyn.event.report.HtmlReportGenerator;importorg.milyn.io.StreamUtils;importorg.milyn.payload.JavaResult;importorg.xml.sax.SAXException;importjavax.xml.transform.stream.StreamSource;import java.io.*;/*** Simple example main class.
*
*@authortom.fennelly@gmail.com*/
public classMainDongFang {private static byte[] messageIn =readInputMessage();private finalSmooks smooks;protected MainDongFang() throwsIOException, SAXException {//Instantiate Smooks with the config...
smooks = new Smooks("testDongFang/smooks-config.xml");
}protected JavaResult runSmooksTransform(ExecutionContext executionContext) throwsIOException, SAXException, SmooksException {try{//java bean
JavaResult javaResult = newJavaResult();
smooks.filterSource(new StreamSource(newByteArrayInputStream(messageIn)), javaResult);//xml//StringResult result=new StringResult();//smooks.filterSource(new StreamSource(new ByteArrayInputStream(messageIn)), result);//System.out.println(result.getResult());
returnjavaResult;
}finally{
smooks.close();
}
}public static void main(String[] args) throwsIOException, SAXException, SmooksException {
System.out.println("\n\n==============Message In==============");
System.out.println(newString(messageIn));
System.out.println("======================================\n");
pause("The EDI input stream can be seen above. Press 'enter' to see how this stream is transformed into an Order Object graph...");
MainDongFang smooksMain= newMainDongFang();
ExecutionContext executionContext=smooksMain.smooks.createExecutionContext();
JavaResult result=smooksMain.runSmooksTransform(executionContext);
System.out.println("\n==============EDI as Java Object Graph=============");
System.out.println(result.getBean("order"));
System.out.println("======================================\n\n");
pause("And that's it! Press 'enter' to finish...");
}private static byte[] readInputMessage() {try{return StreamUtils.readStream(Main.class.getResourceAsStream("../../../testDongFang/input-message.edi"));
}catch(IOException e) {
e.printStackTrace();return "".getBytes();
}
}private static voidpause(String message) {try{
BufferedReader in= new BufferedReader(newInputStreamReader(System.in));
System.out.print("> " +message);
in.readLine();
}catch(IOException e) {
}
System.out.println("\n");
}public JavaResult runSmooksTransform() throwsIOException, SAXException {
ExecutionContext executionContext=smooks.createExecutionContext();returnrunSmooksTransform(executionContext);
}
}
需要注意的是:runSmooksTransform 方法中,使用了工厂模式,
底层会通过 TransformFactory工厂接收你传入的 JavaResult / StringResult等等,来产生不同的结果。
JavaResult返回java bean
StringResult 返回 xml String
其他类型,暂时我没有研究。
六,结果