GA/T 1400协议 - 通知消息流程

需求:订阅成功后,当有新的数据时,下级平台可以向上级平台发送通知消息推送数据。

目录

  • 一、通知接口
    • 1.接口文档
    • 2.入参对象
      • (1)通知对象
      • (2)设备对象
      • (3)卡口对象
      • (4)人脸对象
      • (5)机动车对象
      • (6)子图像对象
    • 3.请求头示例
    • 4.请求方法体示例
      • (1)通知消息对象
      • (2)设备对象
      • (3)卡口对象
      • (4)人脸对象
      • (4)机动车对象
      • (6)子图像对象
  • 二、通知消息代码示例
    • 请求结果示例
  • 三、RestTemplate请求配置
  • 附录
    • 1.图像类型
  • 参考资料

一、通知接口

1.接口文档

GA/T 1400协议 - 通知消息流程_第1张图片

2.入参对象

(1)通知对象

通过通知消息,可推送采集设备、卡口信息、人脸信息、机动车信息等数据。

GA/T 1400协议 - 通知消息流程_第2张图片

(2)设备对象

设备ID(20位数字):1-6位行政区划码;11-13位119

GA/T 1400协议 - 通知消息流程_第3张图片

(3)卡口对象

卡口ID规则同设备ID
GA/T 1400协议 - 通知消息流程_第4张图片

(4)人脸对象

详见协议GA/T 1400.3-A.9 人脸对象,此处仅列举必选字段。R为必选/O为可选。
设备编码必填,否则无法挂到对应设备下。
GA/T 1400协议 - 通知消息流程_第5张图片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(5)机动车对象

详见协议GA/T 1400.3-A.10 机动车对象,此处仅列举必选字段。R为必选/O为可选。
卡口编号为必填,否则无法挂到对应卡口下。
GA/T 1400协议 - 通知消息流程_第6张图片
坐标值没有可以填0。
在这里插入图片描述
GA/T 1400协议 - 通知消息流程_第7张图片
在这里插入图片描述
在这里插入图片描述

(6)子图像对象

Data:图片base64码。
Type:图像类型。如果类型不对会导致图片无法解析。
GA/T 1400协议 - 通知消息流程_第8张图片

3.请求头示例

User-Identify20位数字平台编码(本平台)

4.请求方法体示例

(1)通知消息对象

@Data
public class SubscribeNotificationRequestObject {

    private SubscribeNotificationListObject SubscribeNotificationListObject;
    @Data
    public static class SubscribeNotificationListObject {
        private List<SubscribeNotification> SubscribeNotificationObject;
    }
    @Data
    public static class SubscribeNotification {
        private String NotificationID;	// 通知消息id 33位
        private String SubscribeID;
        private String Title;
        private String TriggerTime;
        private String InfoIDs;
        private Integer ExecuteOperation;   // 更新项目:1添加;2修改;3删除
		// 设备数据 集合
        private DeviceRequestObject.APEListObject DeviceList;
        // 卡口目录 集合
        private TollgateRequestObject.TollgateListObject TollgateObjectList;
		// 人脸数据 集合
        private FaceRequestObject.FaceListObject FaceObjectList;
        // 机动车数据 集合
        private MotorVehicleRequestObject.MotorVehicleListObject MotorVehicleObjectList;
    }
}

========================================================================================

Json格式:
{
	"SubscribeNotificationListObject": {
		"SubscribeNotificationObject": [{
			"NotificationID": "xxxx",
			"InfoIDs": "xxxx",
			"Title": "xx数据通知",
			"SubscribeID": "xxxx",
			"TriggerTime": "20230412145514",
			"ExecuteOperation":1,
			"DeviceList":{},
			"FaceObjectList":{},
			"MotorVehicleObjectList":{},
			"TollgateObjectList":{}
		}]
	}
}

(2)设备对象

@Data
public class DeviceRequestObject {
    private APEListObject APEList;
    @Data
    public static class APEListObject {
        private List<ApeObject> APEObject;
    }
    @Data
    public static class ApeObject {
        private String ApeID;	// 设备ID
        private String Name;
        private String Model;
        private String IPAddr;
        private String IPV6Addr;
        private String Port;
        private String Longitude;
        private String Latitude;
        private String PlaceCode;
        private String Place;
        private String OrgCode;
        private String MonitorDirection;
        private String MonitorAreaDesc;
        private String IsOnline;
        private String OwnerApsID;
        private String UserId;
        private String Password;
        private String FunctionType;
    }
}

========================================================================================

Json格式:
"DeviceList": 
{
	"APEObject": [{
		"IPAddr": "xx.xx.xx.xx",
		"Port": "xx",
		"FunctionType": "x",
		"PlaceCode": "行政区划码",
		"Latitude": "xx.xxxx",
		"Longitude": "xx.xxxx",
		"Name": " 设备名称",
		"IsOnline": "1",
		"Model": "xxxx",
		"ApeID": "xxxx"
	}]
}

(3)卡口对象

@Data
public class TollgateRequestObject {
    private TollgateListObject TollgateListObject;
    @Data
    public static class TollgateListObject {
        private List<Tollgate> TollgateObject;
    }
    @Data
    public static class Tollgate {
        private String TollgateID;
        private String Name;
        private String Longitude;
        private String Latitude;
        private String PlaceCode;
        private String Place;
        private String Status;
        private String TollgateCat;
        private String TollgateUsage;
        private String LaneNum;
        private String OrgCode;
        private String OrgIndex;
    }
}

========================================================================================

Json格式:
"TollgateObjectList":
{
	"TollgateObject": [{
		"Status": "x",
		"PlaceCode": "行政区划码",
		"TollgateCat": "xx",
		"Latitude": "xxx.xx",
		"Longitude": "xx.xx",
		"Name": "卡口名称",
		"TollgateID": "xxx",
		"TollgateUsage": "xx"
	}]
}

(4)人脸对象

@Data
public class FaceRequestObject {
    private FaceListObject FaceListObject;
    @Data
    public static class FaceListObject {
        private List<Face> FaceObject;
    }
    @Data
    public static class Face {
        private String FaceID;	// 48位
        private Integer InfoKind;
        private String SourceID;	// faceId的前41位,与子图像对象中底图类型的ImageID相等
        private String DeviceID;
        private Integer LeftTopX;
        private Integer LeftTopY;
        private Integer RightBtmX;
        private Integer RightBtmY;
        private Integer IsDriver;
        private Integer IsForeigner;
        private Integer IsSuspectedTerrorist;
        private Integer IsCriminalInvolved;
        private Integer IsDetainees;
        private Integer IsVictim;
        private Integer IsSuspiciousPerson;
        private SubImageList SubImageList;
    }
    @Data
    public static class SubImageList {
        private List<SubImageInfo> SubImageInfoObject;
    }
}

========================================================================================

Json格式:
"FaceObjectList": 
{
	"FaceObject": [{
		"FaceID": "xxxx",
		"DeviceID": "xxxx",
		"SourceID": "xxxx",
		"IsVictim": 0,
		"SubImageList": {
			"SubImageInfoObject": [{
				"DeviceID": "xxxx",
				"EventSort": 2,
				"FileFormat": "Jpeg",
				"Type": "14",	// 底图
				"ImageID": "xxxx",
				"ShotTime": "20220412145208",
				"Height": 1440,
				"Width": 2560
			}, {
				"DeviceID": "xxx",
				"EventSort": 2,
				"FileFormat": "Jpeg",
				"Type": "11",	// 人脸图
				"ImageID": "xxx",
				"ShotTime": "20220412145208",
				"Height": 512,
				"Width": 512
			}]
		},
		"IsSuspectedTerrorist": 0,
		"IsForeigner": 0,
		"InfoKind": 0,
		"IsCriminalInvolved": 0,
		"IsDetainees": 0,
		"IsSuspiciousPerson": 0
	}]
}

(4)机动车对象

@Data
public class MotorVehicleRequestObject {
    private MotorVehicleListObject MotorVehicleListObject;
    @Data
    public static class MotorVehicleListObject {
        private List<MotorVehicle> MotorVehicleObject;
    }
    @Data
    public static class MotorVehicle {
        private String MotorVehicleID;	// 48位
        private Integer InfoKind;
        private String SourceID;		// motorVehicleID的前41位
        private String TollgateID;
        private String DeviceID;
        private String StorageUrl1;
        private Integer LeftTopX;
        private Integer LeftTopY;
        private Integer RightBtmX;
        private Integer RightBtmY;
        private String HasPlate;
        private String PlateClass;
        private String PlateColor;
        private String PlateNo;
        private String VehicleColor;
        private SubImageList SubImageList;
    }
    @Data
    public static class SubImageList {
        private List<SubImageInfo> SubImageInfoObject;
    }
}

========================================================================================

Json格式:
"MotorVehicleObjectList": 
{
	"MotorVehicleObject": [{
		"MotorVehicleID": "xxxxx",
		"DeviceID": "xxxxx",
		"SourceID": "xxxxxx",
		"StorageUrl1": "https://图片路径.jpg",
		"SubImageList": {
			"SubImageInfoObject": [{
				"DeviceID": "xxxx",
				"EventSort": 1,
				"FileFormat": "xx",
				"Type": "01",	// 车辆大图
				"StoragePath": "https://车辆大图路径.jpg",
				"ImageID": "xxxxxx",
				"ShotTime": "20210412151437",
				"Height": 1440,
				"Width": 2560
			}]
		},
		"PlateClass": "xx",
		"InfoKind": 0,
		"HasPlate": true,
		"VehicleColor": "x",
		"PlateColor": "x",
		"PlateNo": "xxxxx"
	}]
}

(6)子图像对象

@Data
public class SubImageInfo {
    private String ImageID;
    private Integer EventSort;
    private String DeviceID;
    private String StoragePath;
    private String ImageType;
    private String FileFormat;
    private String ShotTime;	// 拍摄时间
    private Integer  Width;
    private Integer Height;
    private String Data;	// 图片base64码
    private String Type;
}

二、通知消息代码示例

public class Gat1400NotificationDemo {
	
	public void notification() {
        try {

            /** 根据保存的订阅详情,获得
            *(1)订阅ID
            *(2)订阅类型
            *(3)发送通知消息地址(或写死)
            *(4)图像类型
            */
            String SubscribeID = "SubscribeID";
            String SubscribeType = "SubscribeType";
            String receiveAddr = "receiveAddr";
            String ResultImageDeclare = "ResultImageDeclare";

            // 构造通知消息
            SubscribeNotificationRequestObject subscribeNotificationRequestObject = new SubscribeNotificationRequestObject();
            SubscribeNotificationRequestObject.SubscribeNotificationListObject subscribeNotificationListObject = new SubscribeNotificationRequestObject.SubscribeNotificationListObject();
            subscribeNotificationRequestObject.setSubscribeNotificationListObject(subscribeNotificationListObject);
            List<SubscribeNotificationRequestObject.SubscribeNotification> subscribeNotificationList = new ArrayList();

            // 公安机关机构代码 + 子类型编码(04-订阅通知)+ 时间编码(YYYYMMDDhhmmss) + 流水序号(00001)
            String time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
            String NotificationIDStr = "xx0000000000" + "04" + time;    // 需要补上5位流水号

            int count = 1;
            SubscribeNotificationRequestObject.SubscribeNotification subscribeNotification = new SubscribeNotificationRequestObject.SubscribeNotification();
            subscribeNotification.setSubscribeID(SubscribeID);
            subscribeNotification.setNotificationID(NotificationIDStr + String.format("%05d",count));
            subscribeNotification.setTriggerTime(time);
            subscribeNotification.setInfoIDs("MotorVehicleObjectList");
            subscribeNotification.setTitle(SubscribeTitle);   // 订阅标识

			// 数据查询条件:时间区间、地区等
            SearchParam param = new SearchParam();
                    
            switch (SubscribeType) {
                case "13":   // 机动车数据
                    MotorVehicleRequestObject vehicleRequestObject = new MotorVehicleRequestObject();
                    MotorVehicleRequestObject.MotorVehicleListObject vehicleListObject = new MotorVehicleRequestObject.MotorVehicleListObject();
                    vehicleRequestObject.setMotorVehicleListObject(vehicleListObject);
                    List<MotorVehicleRequestObject.MotorVehicle> vehicleList = new ArrayList<>();
                    
                    // 填充车辆方法 vehicleList
                    makeVehicleList(vehicleList, param);
                    
                    vehicleListObject.setMotorVehicleObject(vehicleList);
                    subscribeNotification.setMotorVehicleObjectList(vehicleListObject);
                    break;
                    
                case "12":	// 人脸数据
                	FaceRequestObject faceRequestObject = new FaceRequestObject();
                    FaceRequestObject.FaceListObject faceListObject = new FaceRequestObject.FaceListObject();
                    faceRequestObject.setFaceListObject(faceListObject);
                	List<FaceRequestObject.Face> faceList = new ArrayList<>();
					
					// 填充人脸数据方法
					makeFaceList(faceList, param);
					
					faceListObject.setFaceObject(faceList);
                    subscribeNotification.setFaceObjectList(faceListObject);
                    break;
                    
                case "3":	// 采集设备
                	DeviceRequestObject deviceRequestObject = new DeviceRequestObject();
                    DeviceRequestObject.APEListObject apeList = new DeviceRequestObject.APEListObject();
                    deviceRequestObject.setAPEList(apeList);
 					List<DeviceRequestObject.ApeObject> apeObjectList = new ArrayList<>();
 					
 					// 填充采集设备方法
					makeDeviceList(apeObjectList, param);
					
					apeList.setAPEObject(apeObjectList);
                    subscribeNotification.setDeviceList(apeList);
                   	break;
                   
                case "7":	// 卡口
					TollgateRequestObject tollgateRequestObject = new TollgateRequestObject();
                    TollgateRequestObject.TollgateListObject tollgateListObject = new TollgateRequestObject.TollgateListObject();
                    tollgateRequestObject.setTollgateListObject(tollgateListObject);
                    List<TollgateRequestObject.Tollgate> tollgateList = new ArrayList<>();
					
					// 填充卡口方法
					makeDeviceList(tollgateList, param);
					
					tollgateListObject.setTollgateObject(tollgateList);
                    subscribeNotification.setTollgateObjectList(tollgateListObject);
                    break;
                    
                default:
                    break;
            }

            subscribeNotificationList.add(subscribeNotification);
           	subscribeNotificationListObject.setSubscribeNotificationObject(subscribeNotificationList);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/json;charset=utf-8"));
            headers.set("User-Identify", "本级平台编码");
            HttpEntity<String> httpEntity = new HttpEntity<>(JSONUtil.toJsonStr(subscribeNotificationRequestObject), headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(receiveAddr, HttpMethod.POST, httpEntity, String.class);

        } catch (Exception e) {
            log.error("异常:", e);
        }
    }	
}

/**
 * 根据查询条件,查询对应的车辆信息,再构造成通知数据对象加入列表中。
 */
private void makeVehicleList(List<MotorVehicleRequestObject.MotorVehicle> vehicleList, SearchParam param) {
		
		// 根据param查询车辆数据..
	
        MotorVehicleRequestObject.MotorVehicle motorVehicle = new MotorVehicleRequestObject.MotorVehicle();
        motorVehicle.setMotorVehicleID("xxxx");
        ...
        // 子图片对象信息
        MotorVehicleRequestObject.SubImageList subImageList = new MotorVehicleRequestObject.SubImageList();
        SubImageInfo subImageInfo = new SubImageInfo();
        subImageInfo.setData("base64码");
        subImageInfo.setShotTime("拍摄时间");
        ...
        List<SubImageInfo> subImageInfoList = new ArrayList<>();
        subImageInfoList.add(subImageInfo);
        subImageList.setSubImageInfoObject(subImageInfoList);
        motorVehicle.setSubImageList(subImageList);
		...
        vehicleList.add(motorVehicle);
}

请求结果示例

{
	"ResponseStatusListObject": {
		"ResponseStatusObject": [{
			"RequestURL": "/VIID/SubscribeNotifications",
			"StatusCode": 0,
			"StatusString": "操作成功",
			"Id": "通知id",
			"LocalTime": "20220412161015"
		}]
	}
}

三、RestTemplate请求配置

需要限制请求响应时长不超过5秒,数据应该少量多次推送。

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        HttpClient httpclient = HttpClientBuilder.create().build();
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpclient);
        httpRequestFactory.setConnectTimeout(5000);
        httpRequestFactory.setConnectionRequestTimeout(5000);
        httpRequestFactory.setReadTimeout(5000);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                if (response.getRawStatusCode() != 401) {
                    super.handleError(response);
                }
            }
        });

        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        return restTemplate;
    }

}

附录

1.图像类型

GA/T 1400协议 - 通知消息流程_第9张图片

参考资料

GA-T1400协议–人脸数据
hxrui/gat1400

你可能感兴趣的:(工作日常,GA/T,1400,java,http,spring)