Spring boot 开发 GA/T1400 协议之注册、保活、注销、校时功能
开发GA/T 1400协议之前 需要了解整个1400协议的流程及基础架构,各位准备进行开发的同学应该基本上都有文档了,我就不多阐述,直接开始:
===》 GA/T 1400 注册模块接口
controller代码:
/**
* @description: 注册功能
* @create: 2020-10-13 14:00
**/
@RestController
@RequestMapping("/VIID/System")
@Slf4j
public class Ga1400RegisterController {
@Autowired
Ga1400RegisterService ga1400RegisterService;
/**
* @param register
* @description: 采集设备注册接口
* @create: 2020-10-13 14:00
**/
@ApiOperation(value = "Register", notes = "GA/T1400注册")
@PostMapping(value = "Register")
public String register(@RequestBody JSONObject register, HttpServletRequest request, HttpServletResponse response) throws IOException {
String deviceId = register.getJSONObject("RegisterObject").getString("DeviceID");
return ga1400RegisterService.register(deviceId, response).toJSONString();
}
/**
* @param keepalive
* @description: 采集设备保活接口
* @create: 2020-10-13 14:00
**/
@ApiOperation(value = "Keepalive", notes = "GA/T1400保活")
@PostMapping(value = "Keepalive")
public String keepalive(@RequestBody JSONObject keepalive, HttpServletResponse response) {
log.info(" keepalive --->");
String deviceId = keepalive.getJSONObject("KeepaliveObject").getString("DeviceID");
log.info("Device keepAlive deviceIdInfo :",deviceId);
return ga1400RegisterService.keepAlive(deviceId).toJSONString();
}
/**
* @param unRegister,request,response
* @description: 采集设备注销接口
* @create: 2020-10-13 14:00
**/
@ApiOperation(value = "UnRegister", notes = "GA/T1400注销")
@PostMapping(value = "UnRegister")
public String unRegister(@RequestBody JSONObject unRegister, HttpServletRequest request, HttpServletResponse response) {
return ga1400RegisterService.unRegister(unRegister,response).toJSONString();
}
/**
* @param request,response
* @description: 采集设备校时接口
* @create: 2020-10-13 14:00
**/
@ApiOperation(value = "Time", notes = "GA/T1400校时")
@GetMapping(value = "Time")
public String time(HttpServletRequest request, HttpServletResponse response) {
return ga1400RegisterService.time(request, response).toJSONString();
}
}
service代码:
/**
* @description: 公安1400协议注册服务
* @create: 2020-10-16 10:56
**/
public interface Ga1400RegisterService {
JSONObject register(String deviceId , HttpServletResponse response);
JSONObject unRegister(JSONObject jsonpObject ,HttpServletResponse response);
JSONObject keepAlive(String deviceId );
JSONObject time(HttpServletRequest request,HttpServletResponse response);
}
service 实现类方法:
@Service
@Slf4j
public class Ga1400RegisterServiceImpl implements Ga1400RegisterService {
@Value("${spring.ga1400.key}")
private String key;
@Value("${spring.ga1400.userName}")
private String userName;
@Autowired
GaDeviceInfoService gaDeviceInfoService;
@Autowired
private RedisTemplateUtils redisTemplateUtils;
@Override
public JSONObject register(String deviceId, HttpServletResponse response) {
log.info("Device register deviceIdInfo :",deviceId);
//todo
//视图库设备上线
int num = gaDeviceInfoService.count(new QueryWrapper<GaDeviceEntity>().lambda().eq(GaDeviceEntity::getDeviceId,deviceId));
GaDeviceEntity gaDeviceEntity = new GaDeviceEntity();
gaDeviceEntity.setDeviceId(deviceId);
gaDeviceEntity.setIsDelete(0);
gaDeviceEntity.setIsOnline(1);
//进行入库
if(num > 0 ){
gaDeviceEntity.setUpdateTime(LocalDateTime.now());
gaDeviceInfoService.update(gaDeviceEntity,new UpdateWrapper<GaDeviceEntity>().lambda().eq(GaDeviceEntity::getDeviceId,deviceId));
}else{
gaDeviceEntity.setCreateTime(LocalDateTime.now());
gaDeviceInfoService.save(gaDeviceEntity);
}
redisTemplateUtils.hset(Ga1400Constant.GA1400_DEVICELIST_KEY,deviceId, JSON.toJSONString(gaDeviceEntity));
response.setStatus(HttpServletResponse.SC_OK);
return InfoUtils.responseStatus(GaResponse.ok(Ga1400Constant.GA1400_REGISTER_URL,deviceId));
}
@Override
public JSONObject unRegister(JSONObject jsonObject, HttpServletResponse response) {
String deviceId = jsonObject.getJSONObject("UnRegisterObject").getString("DeviceID");
log.info("Device UnRegister deviceIdInfo :",deviceId);
if(redisTemplateUtils.hHasKey(Ga1400Constant.GA1400_DEVICELIST_KEY,deviceId) ){
//视图库删除
redisTemplateUtils.hdel(Ga1400Constant.GA1400_DEVICELIST_KEY,deviceId);
redisTemplateUtils.hdel(Ga1400Constant.GA1400_DEVICE_KEEPALIVE_KEY,deviceId);
//todo
//是否需要进行入库操作
GaDeviceEntity gaDeviceEntity = new GaDeviceEntity();
gaDeviceEntity.setDeviceId(deviceId);
gaDeviceEntity.setIsDelete(1);
gaDeviceEntity.setIsOnline(0);
gaDeviceEntity.setUpdateTime(LocalDateTime.now());
gaDeviceInfoService.update(gaDeviceEntity,new UpdateWrapper<GaDeviceEntity>().lambda().eq(GaDeviceEntity::getDeviceId,deviceId));
response.setStatus(HttpServletResponse.SC_OK);
return InfoUtils.responseStatus(GaResponse.ok( Ga1400Constant.GA1400_UNREGISTER_URL,deviceId));
}else{
return InfoUtils.responseStatus(GaResponse.failed(HttpServletResponse.SC_NOT_FOUND,"device can't find",Ga1400Constant.GA1400_UNREGISTER_URL,deviceId));
}
}
@Override
public JSONObject keepAlive(String deviceId) {
log.info("Device keepAlive deviceIdInfo :",deviceId);
System.out.println("Device keepAlive deviceIdInfo");
//todo
//1、验证deviceid是否在已经注册的列表中
if(redisTemplateUtils.hHasKey(Ga1400Constant.GA1400_DEVICELIST_KEY,deviceId)){
//2、设置保活的deviceid的key
redisTemplateUtils.hset(Ga1400Constant.GA1400_DEVICE_KEEPALIVE_KEY,deviceId,deviceId,180);
return InfoUtils.responseStatus(GaResponse.ok(Ga1400Constant.GA1400_KEEPALIVE_URL,deviceId));
}else {
return InfoUtils.responseStatus(GaResponse.failed(HttpServletResponse.SC_NOT_FOUND,"device can't find",Ga1400Constant.GA1400_KEEPALIVE_URL,deviceId));
}
}
@Override
public JSONObject time(HttpServletRequest request, HttpServletResponse response) {
String deviceId = request.getHeader("User-Identify");
JSONObject backJson = new JSONObject();
SystemTime systemTime = new SystemTime();
log.info("Device Time deviceIdInfo :",deviceId);
System.out.println("Device Time deviceIdInfo :"+deviceId);
//todo
//1、验证deviceid是否在已经注册的列表中
if(redisTemplateUtils.hHasKey(Ga1400Constant.GA1400_DEVICELIST_KEY,deviceId)){
systemTime.setTimeMode("1");
systemTime.setLocalTime(DateUtil.format(new Date(),"YYYYMMDDhhmmssMMM"));
systemTime.setViidServerId(deviceId);
systemTime.setTimeZone(Ga1400Constant.TIME_ZONE);
response.setStatus(HttpServletResponse.SC_OK);
backJson.put("SystemTime",systemTime);
}else {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return null;
}
return backJson;
}
代码只提供借鉴,很多地方也未考虑充分,业界也没有公开的代码。
其中关于digist校验得代码如下:
1、首先需要自定义 HandlerInterceptorAdapter:
/**
* 签名验证
*/
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
@Value("${spring.ga1400.key}")
private String key;
@Value("${spring.ga1400.userName}")
private String userName;
@Autowired
private RedisTemplateUtils redisTemplateUtils;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//从header中获取auth
String auth = request.getHeader("Authorization");
String deviceId = request.getHeader("User-Identify");
if(redisTemplateUtils.sHasKey(Ga1400Constant.GA1400_DEVICELIST_KEY+deviceId,deviceId)){
return true;
}
if(StringUtils.isNotBlank(auth) && RegisterDigestAuthUtils.verifyAuthorization(auth,key,request.getMethod())){
return true;
}else{
response.setHeader("WWW-Authenticate", RegisterDigestAuthUtils.register401Str(userName));
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
return false;
}
}
2、需要在自定义得webmvcConfigurer中添加适配器:
/**
* MVC配置
* @date 2020-10-20 22:30
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AuthorizationInterceptor authorizationInterceptor;
@Autowired
private AccessLogInterceptor accessLogInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authorizationInterceptor).addPathPatterns("/VIID/**");
registry.addInterceptor(accessLogInterceptor).addPathPatterns("/**");
}
}
代码中有针对 基于redis的保活策略, 通过设置统一的key 来 监听 设备的保活状态,由哪些设备已经完成注册 、注销时 删除redis中数据 等等代码,懂得同学可以自己 进行开发设计。
后续还有针对人脸、人体、机动性、非机动车得代码分享,遇到很多坑,各种相机 视图库版本问题及如何配置相机进行数据得上报,都会在后续进行分享,避免入坑。
代码不规范 ,不喜勿喷。