Skip to content

二、快速入门

FTK edited this page Jun 4, 2024 · 6 revisions

1.maven引入坐标

<dependencies>
    <dependency>
        <groupId>com.alatka</groupId>
        <artifactId>alatka-messages</artifactId>
        <version>[version]</version>
    </dependency>

    <!-- yaml配置方式 -->
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-yaml</artifactId>
        <version>[version]</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-jsr310</artifactId>
      <version>[version]</version>
    </dependency>
    <!-- xml配置方式 -->
    <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-xml</artifactId>
      <version>[version]</version>
    </dependency>
    <!-- annotation配置方式 -->
    <dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>[version]</version>
    </dependency>
    <!-- 数据库配置方式-无强制依赖 -->
</dependencies>

2.报文格式定义

以固定格式9008(客户查询交易)报文为例,YAML配置XML配置注解配置数据库配置四选一。

2.1.YAML配置

2.1.1.YAML文件内容
# YAML固定前缀
alatka.messages:
  # 报文描述/备注
  remark: 客户查询交易
  # 报文类型:fixed/iso
  type: fixed
  # 报文分组,指代机构代码
  group: "0601"
  # 报文代码
  code: 9008
  #报文内容
  message:
    # domainNo:报文域号/索引号,name:报文域名称,length:报文域字节长度,remark:报文域描述,clazz:报文域字段映射java类型
    # 请求体
    request:
      - { "domainNo": 1, "name": "trxType", "length": 4, "remark": "交易代码", "clazz": "java.lang.String" }
      - { "domainNo": 2, "name": "retCode", "length": 6, "remark": "响应码", "clazz": "java.lang.String" }
      - { "domainNo": 3, "name": "bnkNbr", "length": 4, "remark": "银行代号", "clazz": "java.lang.String" }
      - { "domainNo": 4, "name": "source", "length": 2, "remark": "交易来源", "clazz": "java.lang.String" }
      - { "domainNo": 5, "name": "brnNo", "length": 6, "remark": "网点代号", "clazz": "java.lang.String" }
      - { "domainNo": 6, "name": "opeNo", "length": 6, "remark": "操作员号", "clazz": "java.lang.String" }
      - { "domainNo": 7, "name": "seqNo", "length": 6, "remark": "流水号", "clazz": "java.lang.Integer" }
      - { "domainNo": 8, "name": "option", "length": 8, "remark": "标志位", "clazz": "java.lang.String" }
      - { "domainNo": 9, "name": "custNbr", "length": 19, "remark": "证件号码", "clazz": "java.lang.String" }
      - { "domainNo": 10, "name": "cardNbr", "length": 19, "remark": "卡号", "clazz": "java.lang.String" }
      - { "domainNo": 11, "name": "tagType", "length": 5, "remark": "标签类型", "clazz": "java.lang.String" }
      - { "domainNo": 12, "name": "tagCode", "length": 4, "remark": "标签代码", "clazz": "java.lang.String" }
      - { "domainNo": 13, "name": "tagInfo", "length": 20, "remark": "标签内容", "clazz": "java.lang.String" }
      - { "domainNo": 14, "name": "resvd", "length": 200, "remark": "保留域", "clazz": "java.lang.String" }
    # 响应体
    response:
      - { "domainNo": 1, "name": "trxType", "length": 4, "remark": "交易代码", "clazz": "java.lang.String" }
      - { "domainNo": 2, "name": "retCode", "length": 6, "remark": "响应码", "clazz": "java.lang.String" }
      - { "domainNo": 3, "name": "bnkNbr", "length": 4, "remark": "银行代号", "clazz": "java.lang.String" }
      - { "domainNo": 4, "name": "source", "length": 2, "remark": "交易来源", "clazz": "java.lang.String" }
      - { "domainNo": 5, "name": "brnNo", "length": 6, "remark": "网点代号", "clazz": "java.lang.String" }
      - { "domainNo": 6, "name": "opeNo", "length": 6, "remark": "操作员号", "clazz": "java.lang.String" }
      - { "domainNo": 7, "name": "seqNo", "length": 6, "remark": "流水号", "clazz": "java.lang.Integer" }
      - { "domainNo": 8, "name": "option", "length": 8, "remark": "标志位", "clazz": "java.lang.String" }
      - { "domainNo": 9, "name": "custNbr", "length": 19, "remark": "证件号码", "clazz": "java.lang.String" }
      - { "domainNo": 10, "name": "cardNbr", "length": 19, "remark": "卡号", "clazz": "java.lang.String" }
      - { "domainNo": 11, "name": "tagType", "length": 5, "remark": "标签类型", "clazz": "java.lang.String" }
      - { "domainNo": 12, "name": "tagCode", "length": 4, "remark": "标签代码", "clazz": "java.lang.String" }
      - { "domainNo": 13, "name": "tagInfo", "length": 20, "remark": "标签内容", "clazz": "java.lang.String" }
      - { "domainNo": 14, "name": "resvd", "length": 200, "remark": "保留域", "clazz": "java.lang.String" }
2.1.2.YAML文件名
0601.9008.fixed.yml
  • 0601:同alatka.messages.group取值一致
  • 9008:同alatka.messages.code取值一致
  • fixed:同alatka.messages.type取值一致
  • yml:文件后缀,指代YAML文件

注:建议依据以上规则命名YAML文件,方便维护管理,但不强制要求(.fixed.yml后缀除外)。

2.2.XML配置

2.2.1.XML文件内容
<?xml version="1.0" encoding="UTF-8" ?>
<alatka-messages xmlns="http://messages.alatka.com"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://messages.alatka.com alatka-messages.xsd">
    <!-- type同YAML文件 alatka.messages.type -->
    <!-- group同YAML文件 alatka.messages.group -->
    <!-- code同YAML文件 alatka.messages.code -->
    <!-- remark同YAML文件 alatka.messages.remark -->
    <message type="fixed" group="0601" code="9008" remark="客户查询交易">
        <request>
            <field domainNo="1" name="trxType" length="4" remark="交易代码" clazz="java.lang.String"/>
            <field domainNo="2" name="retCode" length="6" remark="响应码" clazz="java.lang.String"/>
            <field domainNo="3" name="bnkNbr" length="4" remark="银行代号" clazz="java.lang.String"/>
            <field domainNo="4" name="source" length="2" remark="交易来源" clazz="java.lang.String"/>
            <field domainNo="5" name="brnNo" length="6" remark="网点代号" clazz="java.lang.String"/>
            <field domainNo="6" name="opeNo" length="6" remark="操作员号" clazz="java.lang.String"/>
            <field domainNo="7" name="seqNo" length="6" remark="流水号" clazz="java.lang.Integer"/>
            <field domainNo="8" name="option" length="8" remark="标志位" clazz="java.lang.String"/>
            <field domainNo="9" name="custNbr" length="19" remark="证件号码" clazz="java.lang.String"/>
            <field domainNo="10" name="cardNbr" length="19" remark="卡号" clazz="java.lang.String"/>
            <field domainNo="11" name="tagType" length="5" remark="标签类型" clazz="java.lang.String"/>
            <field domainNo="12" name="tagCode" length="4" remark="标签代码" clazz="java.lang.String"/>
            <field domainNo="13" name="tagInfo" length="20" remark="标签内容" clazz="java.lang.String"/>
            <field domainNo="14" name="resvd" length="200" remark="保留域" clazz="java.lang.String"/>
        </request>
        <response>
            <field domainNo="1" name="trxType" length="4" remark="交易代码" clazz="java.lang.String"/>
            <field domainNo="2" name="retCode" length="6" remark="响应码" clazz="java.lang.String"/>
            <field domainNo="3" name="bnkNbr" length="4" remark="银行代号" clazz="java.lang.String"/>
            <field domainNo="4" name="source" length="2" remark="交易来源" clazz="java.lang.String"/>
            <field domainNo="5" name="brnNo" length="6" remark="网点代号" clazz="java.lang.String"/>
            <field domainNo="6" name="opeNo" length="6" remark="操作员号" clazz="java.lang.String"/>
            <field domainNo="7" name="seqNo" length="6" remark="流水号" clazz="java.lang.Integer"/>
            <field domainNo="8" name="option" length="8" remark="标志位" clazz="java.lang.String"/>
            <field domainNo="9" name="custNbr" length="19" remark="证件号码" clazz="java.lang.String"/>
            <field domainNo="10" name="cardNbr" length="19" remark="卡号" clazz="java.lang.String"/>
            <field domainNo="11" name="tagType" length="5" remark="标签类型" clazz="java.lang.String"/>
            <field domainNo="12" name="tagCode" length="4" remark="标签代码" clazz="java.lang.String"/>
            <field domainNo="13" name="tagInfo" length="20" remark="标签内容" clazz="java.lang.String"/>
            <field domainNo="14" name="resvd" length="200" remark="保留域" clazz="java.lang.String"/>
        </response>
    </message>
</alatka-messages>
2.2.2.XML文件名
0601.9008.fixed.xml
  • 0601:同message.group取值一致
  • 9008:同message.code取值一致
  • fixed:同message.type取值一致
  • xml:文件后缀,指代XML文件

注:建议依据以上规则命名YAML文件,方便维护管理,但不强制要求(.fixed.xml后缀除外)。

2.3.注解配置

2.3.1.请求体定义
@MessageMeta(
        type = MessageDefinition.Type.fixed,   // 同YAML文件 alatka.messages.type
        group = "0601",                        // 同YAML文件 alatka.messages.group
        code = "9008",                         // 同YAML文件 alatka.messages.code
        kind = MessageDefinition.Kind.request, // 同YAML文件 alatka.messages.message.request
        remark = "客户查询交易")                // 同YAML文件 alatka.messages.remark
public class Fixed9008Req extends FixedHeader {

    @FixedFieldMeta(domainNo = 8, length = 8, remark = "标志位")
    private String option;
    @FixedFieldMeta(domainNo = 9, length = 19, remark = "证件号码")
    private String custNbr;
    @FixedFieldMeta(domainNo = 10, length = 19, remark = "卡号")
    private String cardNbr;
    @FixedFieldMeta(domainNo = 11, length = 5, remark = "标签类型")
    private String tagType;
    @FixedFieldMeta(domainNo = 12, length = 4, remark = "标签代码")
    private String tagCode;
    @FixedFieldMeta(domainNo = 13, length = 20, remark = "标签内容")
    private String tagInfo;
    @FixedFieldMeta(domainNo = 14, length = 200, remark = "保留域")
    private String resvd;

    // getter setter...
}
2.3.2.响应体定义
@MessageMeta(
        type = MessageDefinition.Type.fixed,    // 同YAML文件 alatka.messages.type
        group = "0601",                         // 同YAML文件 alatka.messages.group
        code = "9008",                          // 同YAML文件 alatka.messages.code
        kind = MessageDefinition.Kind.response, // 同YAML文件 alatka.messages.message.response
        remark = "客户查询交易")                 // 同YAML文件 alatka.messages.remark
public class Fixed9008Res extends FixedHeader {

    @FixedFieldMeta(domainNo = 8, length = 8, remark = "标志位")
    private String option;
    @FixedFieldMeta(domainNo = 9, length = 19, remark = "证件号码")
    private String custNbr;
    @FixedFieldMeta(domainNo = 10, length = 19, remark = "卡号")
    private String cardNbr;
    @FixedFieldMeta(domainNo = 11, length = 5, remark = "标签类型")
    private String tagType;
    @FixedFieldMeta(domainNo = 12, length = 4, remark = "标签代码")
    private String tagCode;
    @FixedFieldMeta(domainNo = 13, length = 20, remark = "标签内容")
    private String tagInfo;
    @FixedFieldMeta(domainNo = 14, length = 200, remark = "保留域")
    private String resvd;

    // getter setter...
}
2.3.3.共用字段定义
// 共用字段可单独定义一个类
public class FixedHeader {

    @FixedFieldMeta(domainNo = 1, length = 4, remark = "交易代码")
    private String trxType;
    @FixedFieldMeta(domainNo = 2, length = 6, remark = "响应码")
    private String retCode;
    @FixedFieldMeta(domainNo = 3, length = 4, remark = "银行代号")
    private String bnkNbr;
    @FixedFieldMeta(domainNo = 5, length = 2, remark = "网点代号")
    private String source;
    @FixedFieldMeta(domainNo = 4, length = 6, remark = "交易来源")
    private String brnNo;
    @FixedFieldMeta(domainNo = 6, length = 6, remark = "操作员号")
    private String opeNo;
    @FixedFieldMeta(domainNo = 7, length = 6, remark = "流水号")
    private Integer seqNo;

    // getter setter...
}

2.4.数据库配置

2.4.1.ALK_MESSAGE_DEFINITION
M_ID M_TYPE M_GROUP M_CODE M_KIND M_DOMAIN M_USAGE M_DOMAIN_TYPE M_HOLDER M_CHARSET M_REMARK
1 fixed 0601 9008 request NONE GB18030 客户查询交易请求报文
2 fixed 0601 9008 response NONE GB18030 客户查询交易应答报文
2.4.2.ALK_FIELD_DEFINITION
M_ID F_ID F_DOMAIN_NO F_NAME F_ALIAS_NAME F_FIXED F_LENGTH F_MAX_LENGTH F_CLAZZ F_PATTERN F_REMARK F_STATUS F_PAGE_SIZE_NAME F_PARSE_TYPE F_EXIST_SUBDOMAIN F_SUBDOMAIN_TYPE F_NON_SUBDOMAIN_EXCEPTION
1 1 1 trxType 1 4 4 java.lang.String 交易代码 OPEN ASCII 0
1 2 2 retCode 1 6 6 java.lang.String 响应码 OPEN ASCII 0
1 3 3 bnkNbr 1 4 4 java.lang.String 银行代号 OPEN ASCII 0
1 4 4 source 1 2 2 java.lang.String 交易来源 OPEN ASCII 0
1 5 5 brnNo 1 6 6 java.lang.String 网点代号 OPEN ASCII 0
1 6 6 opeNo 1 6 6 java.lang.String 操作员号 OPEN ASCII 0
1 7 7 seqNo 1 6 6 java.lang.String 流水号 OPEN ASCII 0
1 8 8 option 1 8 8 java.lang.String 标志位 OPEN ASCII 0
1 9 9 custNbr 1 19 19 java.lang.String 证件号码 OPEN ASCII 0
1 10 10 cardNbr 1 19 19 java.lang.String 卡号 OPEN ASCII 0
1 11 11 tagType 1 5 5 java.lang.String 标签类型 OPEN ASCII 0
1 12 12 tagCode 1 4 4 java.lang.String 标签代码 OPEN ASCII 0
1 13 13 tagInfo 1 20 20 java.lang.String 标签内容 OPEN ASCII 0
1 14 14 resvd 1 500 500 java.lang.String 保留域 OPEN ASCII 0
2 15 1 trxType 1 4 4 java.lang.String 交易代码 OPEN ASCII 0
2 16 2 retCode 1 6 6 java.lang.String 响应码 OPEN ASCII 0
2 17 3 bnkNbr 1 4 4 java.lang.String 银行代号 OPEN ASCII 0
2 18 4 source 1 2 2 java.lang.String 交易来源 OPEN ASCII 0
2 19 5 brnNo 1 6 6 java.lang.String 网点代号 OPEN ASCII 0
2 20 6 opeNo 1 6 6 java.lang.String 操作员号 OPEN ASCII 0
2 21 7 seqNo 1 6 6 java.lang.String 流水号 OPEN ASCII 0
2 22 8 option 1 8 8 java.lang.String 标志位 OPEN ASCII 0
2 23 9 custNbr 1 19 19 java.lang.String 证件号码 OPEN ASCII 0
2 24 10 cardNbr 1 19 19 java.lang.String 卡号 OPEN ASCII 0
2 25 11 tagType 1 5 5 java.lang.String 标签类型 OPEN ASCII 0
2 26 12 tagCode 1 4 4 java.lang.String 标签代码 OPEN ASCII 0
2 27 13 tagInfo 1 20 20 java.lang.String 标签内容 OPEN ASCII 0
2 28 14 resvd 1 500 500 java.lang.String 保留域 OPEN ASCII 0

3.报文打包解包

3.1.基于YAML配置方式

import holder.com.alatka.messages.MessageHolder;

public class Test {
  public static void main(String[] args) {
    // 1.加载配置
    String classpath = ""; // 0601.9008.fixed.yml文件classpath
    new FixedYamlMessageDefinitionBuilder(classpath).build();

    // 2.接收处理请求报文
    byte[] reqBytes = ...; // 需要解包的字节数据
    String reqKey = "fixed:0601:9008:request"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
    MessageHolder req = MessageBuilder.init(reqKey).unpack(reqBytes); // 解包为对应MessageHolder实体

    // 3.业务处理...

    // 4.响应实体序列化为字节数组
    MessageHolder res = ...; // 响应实体
    String resKey = "fixed:0601:9008:response"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
    byte[] resBytes = MessageBuilder.init(resKey).pack(res); // 打包响应MessageHolder实体为字节数组

    // 5.响应给客户端...
  }
}

3.2.基于XML配置方式

import holder.com.alatka.messages.MessageHolder;

public class Test {
  public static void main(String[] args) {
    // 1.加载配置
    String classpath = ""; // 0601.9008.fixed.xml文件classpath
    new FixedXmlMessageDefinitionBuilder(classpath).build();

    // 2.接收处理请求报文
    byte[] reqBytes = ...; // 需要解包的字节数据
    String reqKey = "fixed:0601:9008:request"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
    MessageHolder req = MessageBuilder.init(reqKey).unpack(reqBytes); // 解包为对应MessageHolder实体

    // 3.业务处理...

    // 4.响应实体序列化为字节数组
    MessageHolder res = ...; // 响应实体
    String resKey = "fixed:0601:9008:response"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
    byte[] resBytes = MessageBuilder.init(resKey).pack(res); // 打包响应MessageHolder实体为字节数组

    // 5.响应给客户端...
  }
}

3.3.基于注解配置方式

public class Test {
    public static void main(String[] args) {
        // 1.加载配置
        String packagePath = ""; // Fixed9008Req Fixed9008Res FixedHeader 类路径
        new FixedAnnotationMessageDefinitionBuilder(packagePath).build();

        // 2.接收处理请求报文
        byte[] reqBytes = ...; // 需要解包的字节数据
        String reqKey = "fixed:0601:9008:request"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
        Fixed9008Req req = MessageBuilder.init(reqKey).unpack(reqBytes); // 解包为对应实体

        // 3.业务处理...

        // 4.响应实体序列化为字节数组
        Fixed9008Res res = ...; // 响应实体
        String resKey = "fixed:0601:9008:response"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
        byte[] resBytes = MessageBuilder.init(resKey).pack(res); // 打包响应实体为字节数组

        // 5.响应给客户端...
    }
}

3.4.基于数据库配置方式

import holder.com.alatka.messages.MessageHolder;

public class Test {
  public static void main(String[] args) {
    // 1.加载配置
    DataSource dataSource = ....;
    new FixedDatabaseMessageDefinitionBuilder(dataSource).build();

    // 2.接收处理请求报文
    byte[] reqBytes = ...; // 需要解包的字节数据
    String reqKey = "fixed:0601:9008:request"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
    MessageHolder req = MessageBuilder.init(reqKey).unpack(reqBytes); // 解包为对应MessageHolder实体

    // 3.业务处理...

    // 4.响应实体序列化为字节数组
    MessageHolder res = ...; // 响应实体
    String resKey = "fixed:0601:9008:response"; // [type]:[group]:[code]:[kind] 唯一标识一类报文
    byte[] resBytes = MessageBuilder.init(resKey).pack(res); // 打包响应MessageHolder实体为字节数组

    // 5.响应给客户端...
  }
}