gb28181 MANSCDP+xml 编解码
This commit is contained in:
parent
2550500fb9
commit
4e62e90c0c
@ -0,0 +1,18 @@
|
||||
package cn.skcks.docking.gb28181.constant;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class CmdType {
|
||||
public static final String KEEPALIVE = "Keepalive";
|
||||
public static final String DEVICE_CONFIG = "DeviceConfig";
|
||||
public static final String DEVICE_CONTROL = "DeviceControl";
|
||||
public static final String DEVICE_STATUS = "DeviceStatus";
|
||||
public static final String CATALOG = "Catalog";
|
||||
public static final String ALARM = "Alarm";
|
||||
public static final String MOBILE_POSITION = "MobilePosition";
|
||||
public static final String BROADCAST = "Broadcast";
|
||||
public static final String DEVICE_INFO = "DeviceInfo";
|
||||
public static final String RECORD_INFO = "RecordInfo";
|
||||
public static final String MEDIA_STATUS = "MediaStatus";
|
||||
public static final String CONFIG_DOWNLOAD = "ConfigDownload";
|
||||
public static final String PRESET_QUERY = "PresetQuery";
|
||||
}
|
@ -7,6 +7,8 @@ public class GB28181Constant {
|
||||
public static final String CHARSET = "GB2312";
|
||||
public static final String GEO_COORD_SYS = "WGS84";
|
||||
|
||||
public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
|
||||
|
||||
public static class TransPort {
|
||||
public static final String UDP = ListeningPoint.UDP;
|
||||
public static final String TCP = ListeningPoint.TCP;
|
||||
|
@ -0,0 +1,22 @@
|
||||
package cn.skcks.docking.gb28181.sip.manscdp.catalog;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JacksonXmlRootElement(localName = "DeviceList")
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class CatalogDeviceListDTO {
|
||||
@JacksonXmlProperty(isAttribute = true)
|
||||
private Integer num;
|
||||
@JacksonXmlProperty(localName = "Item")
|
||||
@JacksonXmlElementWrapper(useWrapping = false)
|
||||
private List<CatalogItemDTO> deviceList;
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package cn.skcks.docking.gb28181.sip.manscdp.catalog;
|
||||
|
||||
|
||||
import cn.skcks.docking.gb28181.constant.GB28181Constant;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@JacksonXmlRootElement(localName = "Item")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class CatalogItemDTO {
|
||||
/**
|
||||
* 设备/区域/系统编码(必选)
|
||||
*/
|
||||
@JacksonXmlProperty(localName = "DeviceID")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 设备/区域/系统名称(必选)
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 当为设备时,设备厂商(必选)
|
||||
*/
|
||||
private String manufacturer;
|
||||
|
||||
/**
|
||||
* 当为设备时,设备型号(必选)
|
||||
*/
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* 当为设备时,设备归属(必选)
|
||||
*/
|
||||
private String owner;
|
||||
|
||||
/**
|
||||
* 行政区域(必选)
|
||||
*/
|
||||
@JacksonXmlProperty(localName = "CivilCode")
|
||||
private String civilCode;
|
||||
|
||||
/**
|
||||
* 警区(可选)
|
||||
*/
|
||||
private String block;
|
||||
|
||||
/**
|
||||
* 当为设备时,安装地址(必选)
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 当为设备时,是否有子设备(必选)1有, 0没有
|
||||
*/
|
||||
@Builder.Default
|
||||
private Integer parental = 0;
|
||||
|
||||
/**
|
||||
* 父设备/区域/系统ID(必选)
|
||||
*/
|
||||
@JacksonXmlProperty(localName = "ParentID")
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 信令安全模式(可选)缺省为0; 0:不采用;2:S/MIME 签名方式;3:S/ MIME加密签名同时采用方式;4:数字摘要方式
|
||||
*/
|
||||
@Builder.Default
|
||||
private Integer safetyWay = 0;
|
||||
|
||||
/**
|
||||
* 注册方式(必选)缺省为1;1:符合IETF RFC3261标准的认证注册模 式;2:基于口令的双向认证注册模式;3:基于数字证书的双向认证注册模式
|
||||
*/
|
||||
@Builder.Default
|
||||
private Integer registerWay = 1;
|
||||
|
||||
/**
|
||||
* 证书序列号(有证书的设备必选)
|
||||
*/
|
||||
private String certNum;
|
||||
|
||||
/**
|
||||
* 证书有效标识(有证书的设备必选)缺省为0;证书有效标识:0:无效 1: 有效
|
||||
*/
|
||||
@Builder.Default
|
||||
private Integer certifiable = 0;
|
||||
|
||||
/**
|
||||
* 无效原因码(有证书且证书无效的设备必选)
|
||||
*/
|
||||
@Builder.Default
|
||||
private Integer errCode = 0;
|
||||
|
||||
/**
|
||||
* 证书终止有效期(有证书的设备必选)
|
||||
*/
|
||||
@JsonFormat(pattern = GB28181Constant.DATETIME_FORMAT, timezone = GB28181Constant.TIME_ZONE)
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 保密属性(必选)缺省为0;0:不涉密,1:涉密
|
||||
*/
|
||||
@Builder.Default
|
||||
private Integer secrecy = 0;
|
||||
|
||||
/**
|
||||
* 设备/区域/系统IP地址(可选)
|
||||
*/
|
||||
@JacksonXmlProperty(localName = "IPAddress")
|
||||
private String ipAddress;
|
||||
|
||||
/**
|
||||
* 设备/区域/系统端口(可选)
|
||||
*/
|
||||
private Integer port;
|
||||
|
||||
/**
|
||||
* 设备口令(可选)
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 设备状态(必选)
|
||||
*/
|
||||
@Builder.Default
|
||||
private String status = "ON";
|
||||
|
||||
/**
|
||||
* 经度(可选)
|
||||
*/
|
||||
@Builder.Default
|
||||
private String longitude = "0.0";
|
||||
|
||||
/**
|
||||
* 纬度(可选)
|
||||
*/
|
||||
@Builder.Default
|
||||
private String latitude = "0.0";
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.skcks.docking.gb28181.sip.manscdp.catalog;
|
||||
|
||||
|
||||
import cn.skcks.docking.gb28181.constant.CmdType;
|
||||
import com.fasterxml.jackson.annotation.JsonRootName;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@JacksonXmlRootElement(localName = "Query")
|
||||
@JsonRootName("Query")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class CatalogQueryDTO {
|
||||
@Builder.Default
|
||||
private String cmdType = CmdType.CATALOG;
|
||||
@JacksonXmlProperty(localName = "SN")
|
||||
private String sn;
|
||||
|
||||
/**
|
||||
* 目标设备的设备编码(必选)
|
||||
*/
|
||||
@JacksonXmlProperty(localName = "DeviceID")
|
||||
private String deviceId;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package cn.skcks.docking.gb28181.sip.manscdp.catalog;
|
||||
|
||||
import cn.skcks.docking.gb28181.constant.CmdType;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@JacksonXmlRootElement(localName = "Response")
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Data
|
||||
public class CatalogResponseDTO {
|
||||
@Builder.Default
|
||||
private String cmdType = CmdType.CATALOG;
|
||||
@JacksonXmlProperty(localName = "SN")
|
||||
private String sn;
|
||||
|
||||
/**
|
||||
* 目标设备的设备编码(必选)
|
||||
*/
|
||||
@JacksonXmlProperty(localName = "DeviceID")
|
||||
private String deviceId;
|
||||
|
||||
private Long sumNum;
|
||||
|
||||
private CatalogDeviceListDTO deviceList;
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
package cn.skcks.docking.gb28181.sip.utils;
|
||||
|
||||
import cn.skcks.docking.gb28181.constant.GB28181Constant;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.json.JsonReadFeature;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
|
||||
import lombok.*;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Objects;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class MANSCDPUtils {
|
||||
private static final XmlMapper mapper = new XmlMapper();
|
||||
static {
|
||||
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||
// 如果json中有新增的字段并且是实体类类中不存在的,不报错
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
|
||||
// 允许出现特殊字符和转义符
|
||||
mapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
|
||||
// 允许出现单引号
|
||||
mapper.configure(JsonReadFeature.ALLOW_SINGLE_QUOTES.mappedFeature(), true);
|
||||
// 大驼峰 (首字母大写)
|
||||
mapper.setPropertyNamingStrategy(new PropertyNamingStrategies.UpperCamelCaseStrategy());
|
||||
// 添加 xml 头部声明
|
||||
mapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, false);
|
||||
mapper.configure(ToXmlGenerator.Feature.UNWRAP_ROOT_OBJECT_NODE, true);
|
||||
}
|
||||
|
||||
@JacksonXmlRootElement(localName = "xml")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public static class XMLWrapper<T> {
|
||||
@Builder.Default
|
||||
@JacksonXmlProperty(isAttribute = true, localName = "encoding")
|
||||
private String encoding = GB28181Constant.CHARSET;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private T query;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private T response;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private T notify;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private T control;
|
||||
}
|
||||
|
||||
|
||||
public static String toXml(Object obj, String inputCharset,String outputCharset) {
|
||||
try {
|
||||
return new String(Objects.requireNonNull(toByteXml(obj, inputCharset)), Charset.forName(outputCharset));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String toXml(Object obj, String charset) {
|
||||
if(obj == null){
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new String(toByteXml(obj, GB28181Constant.CHARSET), Charset.forName(charset));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String toXml(Object obj) {
|
||||
if(obj == null){
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new String(toByteXml(obj, GB28181Constant.CHARSET), GB28181Constant.CHARSET);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteXml(Object obj) {
|
||||
try {
|
||||
return toByteXml(obj, GB28181Constant.CHARSET);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteXml(Object obj, Charset charset) {
|
||||
try {
|
||||
return mapper.writeValueAsString(obj).getBytes(charset);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteXml(Object obj, String charset) {
|
||||
if(obj == null){
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return mapper.writeValueAsString(obj).getBytes(Charset.forName(charset));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static <T> T parse(byte[] xml, Class<T> clazz) {
|
||||
return parse(xml, clazz, GB28181Constant.CHARSET);
|
||||
}
|
||||
|
||||
public static <T> T parse(byte[] xml, Class<T> clazz, String charset) {
|
||||
return parse(xml, clazz, Charset.forName(charset));
|
||||
}
|
||||
|
||||
public static <T> T parse(byte[] xml, Class<T> clazz, Charset charset) {
|
||||
return parse(new String(xml, charset), clazz);
|
||||
}
|
||||
|
||||
public static <T> T parse(String xml, Class<T> clazz) {
|
||||
try {
|
||||
return mapper.readValue(xml, clazz);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static <T> T parse(byte[] xml, TypeReference<T> clazz) {
|
||||
return parse(xml, clazz, GB28181Constant.CHARSET);
|
||||
}
|
||||
|
||||
public static <T> T parse(byte[] xml, TypeReference<T> clazz, String charset) {
|
||||
return parse(xml, clazz, Charset.forName(charset));
|
||||
}
|
||||
|
||||
public static <T> T parse(byte[] xml, TypeReference<T> clazz, Charset charset) {
|
||||
return parse(new String(xml, charset), clazz);
|
||||
}
|
||||
|
||||
public static <T> T parse(String xml, TypeReference<T> clazz) {
|
||||
try {
|
||||
return mapper.readValue(xml, clazz);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T convert(Object object, Class<T> clazz) {
|
||||
return MANSCDPUtils.convert(object, clazz, GB28181Constant.CHARSET);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static <T> T convert(Object object, Class<T> clazz, String charset) {
|
||||
return MANSCDPUtils.convert(object, clazz, Charset.forName(charset));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static <T> T convert(Object object, Class<T> clazz, Charset charset) {
|
||||
if(object == null){
|
||||
return null;
|
||||
}
|
||||
return MANSCDPUtils.parse(MANSCDPUtils.toXml(object).getBytes(charset), clazz, charset);
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package cn.skcks.docking.gb28181.sip.manscdp;
|
||||
|
||||
import cn.skcks.docking.gb28181.sip.manscdp.catalog.CatalogDeviceListDTO;
|
||||
import cn.skcks.docking.gb28181.sip.manscdp.catalog.CatalogItemDTO;
|
||||
import cn.skcks.docking.gb28181.sip.manscdp.catalog.CatalogQueryDTO;
|
||||
import cn.skcks.docking.gb28181.sip.manscdp.catalog.CatalogResponseDTO;
|
||||
import cn.skcks.docking.gb28181.sip.utils.MANSCDPUtils;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@Slf4j
|
||||
public class MANSCDPTest {
|
||||
public static final String deviceId = "44050100001110000010";
|
||||
public static final String channelId = "44050100001310000010";
|
||||
public static final String deviceName = "模拟设备名称";
|
||||
|
||||
@Test
|
||||
public void catalog(){
|
||||
String sn = String.valueOf(1);
|
||||
// 创建 目录查询 请求
|
||||
CatalogQueryDTO catalogQueryDTO = CatalogQueryDTO.builder()
|
||||
.deviceId("时空旅行者")
|
||||
.sn(sn)
|
||||
.build();
|
||||
log.info("\n{}", MANSCDPUtils.toXml(catalogQueryDTO));
|
||||
|
||||
MANSCDPUtils.XMLWrapper<CatalogQueryDTO> query = MANSCDPUtils.XMLWrapper.<CatalogQueryDTO>builder()
|
||||
.query(catalogQueryDTO)
|
||||
.build();
|
||||
String serialize = MANSCDPUtils.toXml(query);
|
||||
log.info("\n{}", serialize);
|
||||
|
||||
MANSCDPUtils.XMLWrapper<CatalogQueryDTO> deserializeCatalogQueryDTO = MANSCDPUtils.parse(serialize, new TypeReference<>(){});
|
||||
log.info("\n{}",deserializeCatalogQueryDTO);
|
||||
if (deserializeCatalogQueryDTO == null) {
|
||||
return;
|
||||
}
|
||||
CatalogQueryDTO queryDTO = deserializeCatalogQueryDTO.getQuery();
|
||||
log.info("{}",queryDTO);
|
||||
|
||||
// 创建 目录 查询响应
|
||||
CatalogItemDTO catalogItemDTO = CatalogItemDTO.builder()
|
||||
.deviceId(channelId)
|
||||
.name(deviceName)
|
||||
.manufacturer("gb28181-docking-platform")
|
||||
.build();
|
||||
CatalogResponseDTO catalogResponseDTO = CatalogResponseDTO.builder()
|
||||
.deviceId(deviceId)
|
||||
.sn(sn)
|
||||
.deviceList(new CatalogDeviceListDTO(1,Collections.singletonList(catalogItemDTO)))
|
||||
.sumNum(0L)
|
||||
.build();
|
||||
MANSCDPUtils.XMLWrapper<CatalogResponseDTO> response = MANSCDPUtils.XMLWrapper.<CatalogResponseDTO>builder()
|
||||
.response(catalogResponseDTO)
|
||||
.build();
|
||||
serialize = MANSCDPUtils.toXml(response);
|
||||
log.info("\n{}", serialize);
|
||||
MANSCDPUtils.XMLWrapper<CatalogResponseDTO> deserializeCatalogResponseDTO = MANSCDPUtils.parse(serialize, new TypeReference<>(){});
|
||||
if (deserializeCatalogResponseDTO == null) {
|
||||
return;
|
||||
}
|
||||
CatalogResponseDTO responseDTO = deserializeCatalogResponseDTO.getResponse();
|
||||
log.info("{}",responseDTO);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user