作者 朱兆平

部分报文格式生成及验证

package com.sunyo.wlpt.base.model.efreight;
import org.springframework.util.StringUtils;
public class BASE {
public boolean hasText(String var){
return StringUtils.hasText(var);
}
}
... ...
package com.sunyo.wlpt.base.model.efreight.fwb;
import com.sunyo.wlpt.base.model.efreight.BASE;
import com.sunyo.wlpt.base.model.efreight.fwb.exception.FWBException;
import com.sunyo.wlpt.base.model.efreight.fwb.exception.FWBExceptionType;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 电子运单主运单
* @author mrz
* @date 2023-05-30
*
*/
public class FWB {
public class FWB extends BASE implements FWB_BASE {
/**
* 版本号
* 默认16
... ... @@ -14,35 +21,36 @@ public class FWB {
public String ver = "16";
/**
* 主运单格式
* [0-9]{3}-[0-9]{8}
*/
private String waybillNum;
private String waybillNum = "";
/**
* 运单起始站
*/
private String origin;
private String origin = "";
/**
* 运单目的站
*/
private String destination;
private String destination = "";
/**
* 运单总件数
* number of pieces
*/
private String quantity_picecs;
private String quantity_picecs = "";
/**
* 运单毛重,运单的实际称重
*/
private String quantity_weight;
private String quantity_weight = "";
/**
* 计重单位,
* K 代表KG 公斤
* L 代表公升
*/
private String quantity_weight_code;
private String quantity_weight_code = "";
/**
* 体积
*/
private String quantity_volume;
private String quantity_volume = "";
/**
* 体积单位
* MC 代表 立方米 Cubic Metres
... ... @@ -50,19 +58,199 @@ public class FWB {
* CF 代表 立方英尺 Cubic Feet
* CI 代表 立方英寸 Cubic Inches
*/
private String quantity_volume_code;
private String quantity_volume_code = "";
/**
* 密度
* 可选节点
*/
private String quantity_density ;
private String quantity_density = "";
/**
* 密度
* 可选节点
*/
private String quantity_density_code = "DG";
public String getWaybillNum() throws FWBException {
String patternStr = "^[0-9]{3}-[0-9]{8}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(waybillNum);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_ERR);
}
String serialNumber = waybillNum.split("-")[1];
Integer serialNumber7 = Integer.valueOf(serialNumber.substring(0,7)) ;
Integer serialNumberEnd = Integer.valueOf(serialNumber.substring(7));
//模七校验
if ((serialNumber7%7) != serialNumberEnd){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_REGX_ERR);
}
return waybillNum;
}
public void setWaybillNum(String waybillNum) {
this.waybillNum = waybillNum;
}
public String getOrigin() throws FWBException {
String patternStr = "^[A-Z]{3}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(origin);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_ORGN_ERR);
}
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getDestination() throws FWBException {
String patternStr = "^[A-Z]{3}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(origin);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_DES_ERR);
}
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getQuantity_picecs() throws FWBException {
String patternStr = "^[0-9]{1,4}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(quantity_picecs);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_PCE_ERR);
}
return quantity_picecs;
}
public void setQuantity_picecs(String quantity_picecs) {
this.quantity_picecs = quantity_picecs;
}
public String getQuantity_weight() throws FWBException {
String patternStr = "^[1-9][0-9\\.]{1,6}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(quantity_weight);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_WGT_ERR);
}
return quantity_weight;
}
public void setQuantity_weight(String quantity_weight) {
this.quantity_weight = quantity_weight;
}
public String getQuantity_weight_code() throws FWBException {
String patternStr = "^[KL]$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(quantity_weight_code);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_WGT_CODE_ERR);
}
return quantity_weight_code;
}
public void setQuantity_weight_code(String quantity_weight_code) {
this.quantity_weight_code = quantity_weight_code;
}
public String getQuantity_volume() throws FWBException {
if (hasText(quantity_volume)){
String patternStr = "^[1-9][0-9\\.]{0,8}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(quantity_volume);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_VOL_ERR);
}
}
return quantity_volume;
}
public void setQuantity_volume(String quantity_volume) {
this.quantity_volume = quantity_volume;
}
public String getQuantity_volume_code() throws FWBException {
String patternStr = "^MC|CC|CI|CF$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(quantity_volume_code);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_VOL_CODE_ERR);
}
return quantity_volume_code;
}
public void setQuantity_volume_code(String quantity_volume_code) {
this.quantity_volume_code = quantity_volume_code;
}
public String getQuantity_density() throws FWBException {
String patternStr = "^[1-9]?[0-9]?$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(quantity_density);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_WAYBILL_DG_ERR);
}
return quantity_density;
}
public void setQuantity_density(String quantity_density) {
this.quantity_density = quantity_density;
}
public String getQuantity_density_code() {
return quantity_density_code;
}
public void setQuantity_density_code(String quantity_density_code) {
this.quantity_density_code = quantity_density_code;
}
@Override
public String getFWBNodeText() throws FWBException {
String SPLIT_CODE = "/";
String CRLF = "\n";
StringBuilder sb = new StringBuilder("");
sb.append(getWaybillNum()).append(getOrigin()).append(getDestination())
.append(SPLIT_CODE).append("T").append(getQuantity_picecs())
.append(getQuantity_weight_code()).append(getQuantity_weight());
if (hasText(getQuantity_volume())){
sb.append(getQuantity_volume_code()).append(getQuantity_volume());
}
if (hasText(getQuantity_density())){
sb.append(getQuantity_density_code()).append(getQuantity_density());
}
sb.append(CRLF);
return sb.toString();
}
@Override
public String getNodeName() {
return "FWB/"+ver+"\n";
}
}
... ...
package com.sunyo.wlpt.base.model.efreight.fwb;
import com.sunyo.wlpt.base.model.efreight.BASE;
import com.sunyo.wlpt.base.model.efreight.fwb.exception.FWBException;
import com.sunyo.wlpt.base.model.efreight.fwb.exception.FWBExceptionType;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Flight Bookings
* FLT
* 运单航程航班
* O 可选节点
* 可重复最多两次
*/
public class FWB_FLT {
public class FWB_FLT extends BASE implements FWB_BASE {
/**
* 承运人代码 mm
* [A-Z]{2}
* [A-Z0-9]{2}
*/
private String cariier;
private String cariier = "";
/**
* 航班号 nnn(n)(a)
* [0-9]{3}\d?[A-Z0-9]?
*/
private String flightNumber;
private String flightNumber = "";
/**
* 航班日期 - 按日标识
* [0-9]{2}
*/
private String day;
private String day = "";
public String getCariier() throws FWBException {
String patternStr = "^[A-Z0-9]{0,2}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(cariier);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_FLT_CARRIER_ERR);
}
return cariier;
}
public void setCariier(String cariier) {
this.cariier = cariier;
}
public String getFlightNumber() throws FWBException {
String patternStr = "^[0-9]{3}\\d?[A-Z0-9]?$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(flightNumber);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_FLT_NUMBER_ERR);
}
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
}
public String getDay() throws FWBException {
String patternStr = "^[0-9]{2}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(day);
if (!matcher.find() || Integer.parseInt(day) > 31){
throw new FWBException(FWBExceptionType.FWB_FLT_DAY_ERR);
}
return day;
}
public void setDay(String day) {
this.day = day;
}
@Override
public String getFWBNodeText() throws FWBException {
String SPLIT_CODE = "/";
String CRLF = "\n";
StringBuilder sb = new StringBuilder("");
if (hasText(cariier) || hasText(flightNumber) || hasText(day)){
sb.append(SPLIT_CODE).append(getCariier()).append(getFlightNumber()).append(SPLIT_CODE).append(getDay());
}
//todo:此节点循环的报文内容获取方式
// sb.append(CRLF);
return sb.toString();
}
@Override
public String getNodeName() {
return "FLT";
}
}
... ...
package com.sunyo.wlpt.base.model.efreight.fwb;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.sunyo.wlpt.base.model.efreight.BASE;
import com.sunyo.wlpt.base.model.efreight.fwb.exception.FWBException;
import com.sunyo.wlpt.base.model.efreight.fwb.exception.FWBExceptionType;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Flight Bookings
* Routing
* RTG
* 运单航程目的地承运人
*/
public class FWB_RTG {
public class FWB_RTG extends BASE implements FWB_BASE {
/**
* 首程目的站
* [A-Z]{3}
... ... @@ -22,10 +30,98 @@ public class FWB_RTG {
* 下一航程起始航站
* 可选节点
* 下一航程节点最多可重复两次,结合首程一共三个航程
* Onward 部分最多可以出现2次
*/
private String onwardAirport;
/**
* 下一航程起始航站承运人
*/
private String onwardCarrier;
public String getDestinationAirport() throws FWBException {
String patternStr = "^[A-Z]{3}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(destinationAirport);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_RTG_AIRPORT_ERR);
}
return destinationAirport;
}
public void setDestinationAirport(String destinationAirport) {
this.destinationAirport = destinationAirport;
}
public String getDestinationCarrier() throws FWBException {
String patternStr = "^[A-Z0-9]{0,2}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(destinationCarrier);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_RTG_CARRIER_ERR);
}
return destinationCarrier;
}
public void setDestinationCarrier(String destinationCarrier) {
this.destinationCarrier = destinationCarrier;
}
public String getOnwardAirport() throws FWBException {
String patternStr = "^[A-Z]{3}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(onwardAirport);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_RTG_AIRPORT_ERR);
}
return onwardAirport;
}
public void setOnwardAirport(String onwardAirport) {
this.onwardAirport = onwardAirport;
}
public String getOnwardCarrier() throws FWBException {
String patternStr = "^[A-Z0-9]{0,2}$";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(onwardCarrier);
if (!matcher.find()){
throw new FWBException(FWBExceptionType.FWB_RTG_CARRIER_ERR);
}
return onwardCarrier;
}
public void setOnwardCarrier(String onwardCarrier) {
this.onwardCarrier = onwardCarrier;
}
@Override
public String getFWBNodeText() throws FWBException {
String SPLIT_CODE = "/";
String CRLF = "\n";
StringBuilder sb = new StringBuilder("");
sb.append(SPLIT_CODE);
if (hasText(destinationAirport)) {
sb.append(getDestinationAirport());
}
sb.append(getDestinationCarrier());
if (hasText(onwardAirport)) {
sb.append(SPLIT_CODE).append(getOnwardAirport());
}
if (hasText(onwardCarrier) ){
sb.append(getOnwardCarrier());
}
//todo:此节点循环的报文内容获取方式
// sb.append(CRLF);
return sb.toString();
}
@Override
public String getNodeName() {
return "RTG";
}
}
... ...
... ... @@ -7,6 +7,32 @@ package com.sunyo.wlpt.base.model.efreight.fwb.exception;
*/
public enum FWBExceptionType {
/**
* 运单号格式验证错误
*/
FWB_WAYBILL_ERR("21","运单格式错误,格式须为 [0-9]{3}-[0-9]{8}"),
/**
* 运单号模七验证错误
*/
FWB_WAYBILL_REGX_ERR("211","运单不符合模七校验"),
FWB_WAYBILL_ORGN_ERR("221","运单起始地格式错误"),
FWB_WAYBILL_DES_ERR("222","运单目的地格式错误"),
FWB_WAYBILL_PCE_ERR("233","运单件数信息错误"),
FWB_WAYBILL_WGT_CODE_ERR("234","运单重量单位信息错误"),
FWB_WAYBILL_WGT_ERR("235","运单重量信息错误"),
FWB_WAYBILL_VOL_CODE_ERR("241","运单体积单位信息错误"),
FWB_WAYBILL_VOL_ERR("242","运单体积 信息错误"),
FWB_WAYBILL_DG_ERR("252","运单密度信息错误"),
FWB_FLT_CARRIER_ERR("322","承运人信息错误"),
FWB_FLT_NUMBER_ERR("323","航班号信息错误"),
FWB_FLT_DAY_ERR("325","航班日期信息错误,格式为应为[0-9]{2}"),
FWB_RTG_AIRPORT_ERR("422","涉及航站信息有误"),
FWB_RTG_CARRIER_ERR("422","涉及承运人信息有误"),
REF_ERROR("203", "缺少 REF Sender Reference - Sender Office Message Address"),
REF_SOMA_REGEX_FAILD("2031", "REF- Sender Office Message Address RegEx Faild"),
REF_SPID_REGEX_FAILD("206", "REF- Sender Participant Idenfitication RegEx Faild,缺少关联节点信息"),
... ... @@ -14,11 +40,12 @@ public enum FWBExceptionType {
OCI_CSRC_ERROR("297", "缺少 Other Customs,Security And Regulatory Control Information Identifier");
/**
* 响应业务状态
* 参照字典FWB节点位置
* 如21 为 第二章 第一部分 211 为 第二章 第一部分 第一节
*/
private String code;
/**
* 响应消息
* 错误信息描述
*/
private String msg;
... ...
import com.sunyo.wlpt.base.model.efreight.fwb.FWB_OCI;
import com.sunyo.wlpt.base.model.efreight.fwb.FWB_REF;
import com.sunyo.wlpt.base.model.efreight.fwb.*;
import com.sunyo.wlpt.base.model.efreight.fwb.exception.FWBException;
public class FWBTest {
public static void main(String[] args) {
FWB_WAYBILL_TEST();
// FWB_FLT_TEST();
FWB_RTG_TEST();
REF_TEST();
// OCI_TEST();
... ... @@ -36,10 +38,61 @@ public class FWBTest {
fwb_ref.setRef_participant_airport("CGO");
try {
String oci = fwb_ref.getFWBNodeText();
String oci = fwb_ref.getNodeName() + fwb_ref.getFWBNodeText();
System.out.println(oci);
} catch (FWBException e) {
e.printStackTrace();
}
}
static String FWB_WAYBILL_TEST(){
FWB fwb = new FWB();
fwb.setWaybillNum("804-31118393");
fwb.setOrigin("CGO");
fwb.setDestination("ICN");
fwb.setQuantity_picecs("1");
fwb.setQuantity_weight("102.22");
fwb.setQuantity_weight_code("L");
fwb.setQuantity_volume("20.22");
fwb.setQuantity_volume_code("MC");
fwb.setQuantity_density("22");
try {
fwb.getWaybillNum();
String nodeText = fwb.getNodeName() + fwb.getFWBNodeText();
// System.out.println(nodeText);
return nodeText;
} catch (FWBException e) {
e.printStackTrace();
}
return "";
}
static void FWB_FLT_TEST(){
FWB_FLT flt = new FWB_FLT();
flt.setCariier("CV");
flt.setFlightNumber("732");
flt.setDay("29");
try {
String nodeText = flt.getNodeName() + flt.getFWBNodeText() + "\n";
System.out.println(FWB_WAYBILL_TEST()+nodeText);
} catch (FWBException e) {
e.printStackTrace();
}
}
static void FWB_RTG_TEST(){
FWB_RTG var = new FWB_RTG();
// var.setDestinationAirport("ICN");
var.setDestinationCarrier("F5");
var.setOnwardAirport("SIN");
// var.setOnwardCarrier("K9");
try {
String nodeText = var.getNodeName() + var.getFWBNodeText() + "\n";
System.out.println(FWB_WAYBILL_TEST()+nodeText);
} catch (FWBException e) {
e.printStackTrace();
}
}
}
... ...