背景
最近工作原因,需要对接GAT1400公有协议,网上资源相较缺乏,记录一下踩过的坑
流程概述
- 请求报文和响应报文参见大佬写的文章:
- 话不多说,上代码,一些说明放到代码后面
@Controller
@RequestMapping("/VIID")
public class MyController {
private static final Logger log = LoggerFactory.getLogger(MyController.class);
@PostMapping("/System/Register")
public ResponseEntity<ResponseGAT> register(HttpServletRequest request) {
try {
BufferedReader reader = request.getReader();
String str = reader.readLine();
if (StringUtils.hasLength(str)) {
RegisterDTO registerDTO = JSON.parseObject(str, RegisterDTO.class);
if (!StringUtils.hasLength(request.getHeader("Authorization"))) { // 首次注册,返回401
log.debug("===首次注册===");
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("WWW-Authenticate", "Digest realm=\"myrealm\", nonce=\"abc123321\"");
headers.add("Content-Type", "application/*+JSON");
return new ResponseEntity<>(headers, HttpStatus.UNAUTHORIZED);
} else { // 二次注册
log.debug("===二次注册===");
ResponseGAT response = new ResponseGAT();
response.setId(registerDTO.getRegisterObject().getDeviceId());
response.setLocalTime(new Date());
response.setRequestURL("/VIID/System/Register");
response.setStatusCode("O");
response.setStatusString("成功注册");
LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/*+JSON");
return new ResponseEntity<>(response, headers, HttpStatus.OK);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@PostMapping("/System/Keepalive")
public ResponseEntity<ResponseGAT> keepalive(HttpServletRequest request) {
log.debug("===设备保活===");
try {
BufferedReader reader = request.getReader();
String str = reader.readLine();
if (StringUtils.hasLength(str)) {
KeepaliveDTO keepaliveDTO = JSON.parseObject(str, KeepaliveDTO.class);
ResponseGAT response = new ResponseGAT();
response.setId(keepaliveDTO.getKeepaliveObject().getDeviceId());
response.setLocalTime(new Date());
response.setRequestURL("/VIID/System/Keepalive");
response.setStatusCode("O");
response.setStatusString("成功响应");
LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Content-Type", "application/*+JSON");
return new ResponseEntity<>(response, headers, HttpStatus.OK);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
- 代码说明
- 由于需要自定义返回的响应码,所以用
@Controller
,返回ResponseEntity - SpringMVC只能转换通用的Content-Type(例如application/json等),GAT1400协议使用的是自定义的Content-Type,所以无法自动转换为bean对象,这里使用的方式是通过request对象,以字符流的方式获取请求体中的数据,再利用fastJSON转为bean对象使用
- 需要注意的是,响应的请求体应该每次都设置为application/*+JSON
- 在注册时会涉及到Digest加密,WWW-Authenticate的内容,以及第二次注册请求的Authentication字段可能根据设备的不同而有所不同,具体的加密方式请自行搜索
- 由于需要自定义返回的响应码,所以用
结语
该demo只提供了对接注册和保活的接口的思路,具体代码并不完善,也可能根据设备的不同出现问题,如有问题,请多指正!