java to edi 动态/静态映射

本文详细介绍了如何使用Java进行EDI报文的处理,包括静态映射和动态映射两种方法。静态映射需要手动实现`EDIWritable`接口,而动态映射则通过Smooks库自动生成Java类,减少了编码工作。文章提供了具体的代码示例和项目结构,帮助读者理解这两种方法的优缺点及应用场景。

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="&#10;" 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内容,拷贝到自己的对象去。

这样就成为了静态映射,也简化了创建的繁琐。

 

三,网上的工具

这个大家直接看  https://www.cnblogs.com/zmngc/p/10942835.html

下载代码方式:https://pan.quark.cn/s/28492da20c79 依据所提供的文件资料,本资源将系统地探讨FPGA(即现场可编程门阵列)的核心概念、其在视频图像技术领域的入门及进阶知识要点,以及图像处理算法的实现方法。此外,还将对VIPBoardBig这一特定FPGA开发板的详细资料和使用途径进行深入剖析。 FPGA的入门与进阶学习主要涉及以下核心内容: 1. FPGA的基础概念:FPGA是一种能够通过编程进行配置的集成电路,主要目的是达成硬件逻辑的可重构特性。该类芯片由大量的可配置逻辑模块(CLB)、输入输出模块(IOB)以及可编程互连资源共同构成。 2. FPGA开发板与相关套件:FPGA开发板是一种用于FPGA芯片学习和测试的硬件平台,通常配备有基础的外设设备,例如LED指示灯、按键开关、LCD显示屏、串口通信接口等。套件则通常包含硬件板卡、技术文档、相关资源,以及可能的软件工具和示例代码集。VIPBoardBig即为本教程选用的FPGA开发板,拥有特定的硬件配置和功能特性。 3. FPGA的开发流程:FPGA开发一般涉及硬件描述语言(HDL)的设计与仿真阶段,常用语言为Verilog或VHDL。随后,借助综合工具将设计蓝图转化为FPGA内部的逻辑网络,最终通过编程设备将配置文件传输至FPGA芯片中,从而实现设计的预期功能。 4. 外设开发与设计工作:涵盖LED显示控制、键盘驱动、LCD显示驱动、UART串口设计等基础外设的开发任务。这部分知识将引导学习者掌握如何在FPGA平台上管理和运用这些基础外设。 5. VGA驱动显示与字符显示测试:VGA(Video Graphics Array)是一种视频传输接口标准,能够支持640x480...
内容概要:本文系统阐述了企业在搭建官方知识库后如何通过“7步锚定法”实现GEO(生成式引擎优化)的落地,重点在于从知识库走向内容矩阵的战略升级。文章指出知识库仅为起点,真正的核心是让大模型“信任并推荐”企业内容。为此提出“一个主战场+多个品牌布局”的策略,强调需根据行业特性选择高商业流量的大模型(如豆包、文心一言、通义千问等),而非工具性模型(如ChatGPT、Claude)。通过业务场景画像、大模型流量测绘、采信逻辑拆解、内容架构设计、语义关键词埋点、信源建设与效果迭代七步法,构建高质量、高可信度的内容体系,并警惕“全模型覆盖、内容堆砌、一套内容通用、忽视第三方平台”四大误区。最终指出GEO本质是一场认知战,比拼的是对大模型逻辑与客户需求的理解深度及长期主义投入。; 适合人群:已完成官方知识库搭建、希望提升AI引用率与获客效率的企业市场负责人、品牌运营、数字营销从业者及SEO/GEO优化相关人员。; 使用场景及目标:①指导企业科学选择主攻大模型并制定差异化内容策略;②构建符合大模型采信逻辑的高质量内容矩阵;③避免常见GEO落地误区,提升AI搜索下的品牌曝光与转化效果;④建立可持续优化的数据反馈闭环。; 阅读建议:建议结合自身行业特征与客户决策路径,逐步实践“7步法”,优先聚焦单一主战场打透,注重内容质量与第三方权威信源建设,坚持3-6个月持续投入以观察真实效果。
内容概要:本文针对考虑需求响应的微电网优化调度问题,提出了一种基于改进多目标灰狼算法(GWO)的优化方法,并通过Matlab代码实现了完整的仿真验证。研究在传统灰狼算法基础上引入改进机制,有效提升了算法的收敛速度、全局搜索能力和Pareto前沿分布质量,用于求解包含经济运行成本、碳排放水平、可再生能源利用率等多重目标的微电网调度模型。模型充分融合用户侧需求响应机制,利用分时电价等激励手段引导负荷转移与削峰填谷,从而增强系统对光伏、风电等间歇性能源的消纳能力,降低综合运行成本与环境影响。文中系统阐述了多目标优化建模过程、算法改进策略、约束处理方法及仿真结果对比分析,验证了该方法在获取高质量非劣解集和辅助决策方面的优越性。; 适合人群:适用于电力系统、能源互联网、自动化控制、智能优化算法等相关领域的硕士/博士研究生、科研人员,以及从事微电网能量管理、综合能源系统优化、低碳调度等工作的工程技术人员。; 使用场景及目标:①应用于微电网能量管理系统(EMS)中实现多目标协同优化调度;②为基于电价激励的需求响应项目提供负荷调控策略与量化分析工具;③作为智能计算算法在能源系统优化中应用的教学案例与科研参考,支持进一步拓展至多能互补、多微网互联等复杂场景的研究。; 阅读建议:建议读者结合提供的Matlab代码深入理解算法实现细节,重点关注目标函数构造、约束条件处理、多目标适应度评估及决策者偏好选择机制;可尝试将该框架迁移至含氢能储能、电动汽车集群等新型设备的综合能源系统中进行性能测试与算法改进。
内容概要:本文深入分析了洞察时空在2026年世界人工智能大会上提出的“数算一体AI星座”项目,该星座由576颗低轨及超低轨卫星构成,旨在实现“一天一次全球扫描”的高频对地观测能力,为AI Agent提供标准化的“地球真值”数据,弥补大模型在物理世界认知中的预测偏差。项目创新性地提出“数算一体”范式,通过天地一体算力协同、星上边缘计算与多模态数据融合,构建以“地球状态变量”为核心的智能认知系统,推动天基基础设施从数据采集向智能服务跃迁。报告系统梳理了当前研究现状,指出现有遥感系统在时效性、一致性与AI适配性上的不足,提出涵盖星座组网、星上AI推理、数据标准化等关键技术路径,并剖析了星上算力限制、数据一致性保障、物理可解释性等核心挑战,给出了芯片研发、开放标准、跨学科协作等未来发展方向。洞察时空作为主导企业,具备航天与AI复合背景,已获政策与资本支持,计划2030年完成全星座部署。; 适合人群:从事商业航天、人工智能、遥感技术、地球系统科学及相关交叉领域的科研人员、技术研发人员、政策制定者与产业投资者。; 使用场景及目标:①理解AI与天基系统融合的前沿趋势与技术架构;②探索“数算一体”在星地协同计算、多模态数据产品标准化中的实现路径;③评估高频地球观测数据对AI Agent、气候建模、灾害预警等应用的支撑潜力; 阅读建议:本报告兼具战略高度与技术深度,建议结合商业航天发展动态与AI在科学发现中的应用案例进行延伸阅读,重点关注天地算力调度机制与“地球状态变量”的定义演化,以把握下一代天基智能基础设施的发展方向。
内容概要:本文围绕综合能源系统与模型预测控制(MPC)滚动优化展开深入研究,重点利用Matlab代码实现对包含光伏、储能、风电等多种能源形式的综合能源系统进行建模与多时间尺度优化调度。通过MPC滚动优化方法,结合系统的动态数学模型与对未来负荷、可再生能源出力的预测信息,实现对能源生产、存储、转换与消费的协同优化控制,旨在提升系统运行的经济性、能源利用效率、低碳水平及供电可靠性。研究详细阐述了MPC的核心原理、预测模型构建、目标函数设计(如运行成本最小化)、系统约束(如功率平衡、设备容量、储能荷电状态)处理以及优化求解过程,并提供了完整的Matlab仿真代码框架,便于读者复现和二次开发。; 适合人群:具备一定电力系统、自动化、能源系统工程或控制理论基础,熟悉Matlab编程环境,从事相关领域科研、工程应用的研发人员、高校研究生及高年级本科生。; 使用场景及目标:①掌握模型预测控制(MPC)在综合能源系统、微电网、智慧园区等场景中的优化调度应用方法;②学习如何构建多能互补系统的精细化数学模型并实现滚动优化求解;③为能源互联网、新型电力系统背景下的能量管理与决策提供技术参考、算法支持与代码实例。; 阅读建议:建议读者结合文中提供的Matlab代码进行动手实践,重点关注MPC控制器的设计逻辑、预测模型与优化器的耦合机制,以及约束条件的代码实现方式。同时,鼓励在现有模型基础上,拓展至不同的能源设备配置、负荷场景或优化目标(如碳排放最小化),以深化对MPC在能源领域应用的理解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值