supervision-edh/src/main/java/com/supervision/edh/controller/SupervisionEdhServerControl...

185 lines
8.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.supervision.edh.controller;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.supervision.edh.common.AjaxResult;
import com.supervision.edh.domain.EdhReceiveDataLog;
import com.supervision.edh.enums.BuzStatusEnum;
import com.supervision.edh.enums.EventTypeEnum;
import com.supervision.edh.enums.SubTypeEnum;
import com.supervision.edh.service.IEdhReceiveDataLogService;
import com.supervision.edh.service.IEventProcessingService;
import com.supervision.edh.service.impl.EventProcessingServiceImpl;
import com.supervision.edh.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* @ClassName SupervisionEdhServerController
* @Desc 省局对接示例代码 服务端 接收端
* @Author houduo.wk
* @Date 2020/3/13
**/
@RestController
@RequestMapping("/supervision/edh")
public class SupervisionEdhServerController {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private CertManager certManager;
@Autowired
private IEdhReceiveDataLogService receiveDataLogService;
@Autowired
private EventProcessingServiceImpl processingService;
@PostMapping("/receive")
public String receive(HttpServletRequest request) throws IOException {
RequestWrapper requestWrapper = new RequestWrapper(request);
String body = requestWrapper.getBodyString();
System.out.println(body);
Map<String, Object> paramsTemp = JSON.parseObject(body);
System.out.println(paramsTemp);
Map<String, Object> params = JSON.parseObject(paramsTemp.get("req").toString());
// logger.info("接收到请求参数:{}", params);
// 检查参数,并获取校验结果
String checkResult = checkRequestParam(params);
if (!ResponseBuilder.reqPass().equals(checkResult)) {
return checkResult; // 如果校验失败,直接返回错误信息
}
try {
//传输流水号
String processId = String.valueOf(params.get("process_id"));
//事件编号
String eventId = String.valueOf(params.get("event_id"));
//主数据类型
String eventType = String.valueOf(params.get("event_type"));
//主数据 包含子类型sub_type和数据data
String event = String.valueOf(params.get("event"));
//时间戳 YYMMddHHmmssSSS
String timeStamp = String.valueOf(params.get("timestamp"));
//版本号
String ver = String.valueOf(params.get("ver"));
//企业统一社会信用代码
String tyshxydm = String.valueOf(params.get("tyshxydm"));
/* logger.info("processId:{}|eventId:{}|eventType:{}|event:{}|timeStamp:{}|ver:{}"
, processId, eventId, eventType, event, timeStamp, ver);*/
EventPojo eventPojo = JSON.parseObject(event, EventPojo.class);
//获取私钥
String privateKey = certManager.getPrivateKey();
logger.info("privateKey:{}", privateKey);
String de = certManager.keyDecrypt(privateKey, eventPojo.getData());
String data = StreamUtil.getUnStreamContent(de);
//logger.info("解密之后的文件内容:{}", data);
//保存数据日志
EdhReceiveDataLog dataLog = new EdhReceiveDataLog();
dataLog.setEventId(eventId);
dataLog.setTyshxydm(tyshxydm);
dataLog.setProcessId(processId);
dataLog.setEventType(eventType);
dataLog.setEventTypeName(EventTypeEnum.getNameByType(eventType));
dataLog.setSubType(eventPojo.getSubType());
dataLog.setSubTypeName(SubTypeEnum.getNameByType(eventPojo.getSubType()));
dataLog.setData(eventPojo.getData());
dataLog.setVer(ver);
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS");
dataLog.setEventTime(sdf.parse(timeStamp));//事件上报时间
receiveDataLogService.save(dataLog);
//解析并处理数据
//processingService.asyncProcessEvent(eventPojo, data, eventId);
CompletableFuture<Void> future = processingService.asyncProcessEvent(eventPojo, data, eventId);
future.get(); // 阻塞等待任务完成(如果任务抛出异常,会抛出 ExecutionException
return ResponseBuilder.success();
} catch (BadPaddingException e) {
// RSA 解密失败,可能是密钥不匹配或数据被篡改
logger.error("解密失败:密钥不匹配或数据无效,错误信息:{}", e.getMessage());
return ResponseBuilder.failMsg("解密失败:请检查加密公钥是否匹配或数据是否被篡改");
} catch (IllegalBlockSizeException e) {
// 数据块大小错误(如 RSA 加密数据长度超限)
logger.error("解密失败:数据块大小错误,错误信息:{}", e.getMessage());
return ResponseBuilder.failMsg("解密失败:数据格式错误");
} catch (InvalidKeyException e) {
// 无效的私钥
logger.error("解密失败:提供的私钥无效,错误信息:{}", e.getMessage());
return ResponseBuilder.failMsg("解密失败:私钥无效");
} catch (JsonProcessingException e) {
logger.error("数据解析异常:上报数据格式有误,错误信息:{}", e.getMessage());
return ResponseBuilder.failMsg("数据解析异常:上报数据格式有误");
} catch (ExecutionException e) {
// 捕获异步任务抛出的异常
Throwable cause = e.getCause();
logger.error("异步任务执行失败 - event_id={},错误信息={}",params.get("event_id"),cause.getMessage());
return ResponseBuilder.failMsg("异步任务失败: " + cause.getMessage());
} catch (Exception e) {
logger.error("出错了,错误信息:{}", e.getMessage());
return ResponseBuilder.failMsg(e.getMessage());
}
}
/**
* 检测校验接收参数
* @param params
*/
private String checkRequestParam(Map<String, Object> params) {
if (params == null || params.isEmpty()) {
return ResponseBuilder.failMsg("请求参数不能为空");
}
// 必填参数列表
List<String> requiredParams = Arrays.asList("process_id","event_id","tyshxydm","event_type","event","timestamp","ver");
// 统一校验必填参数
for (String paramName : requiredParams) {
if (!params.containsKey(paramName)) {
return ResponseBuilder.failMsg("缺少必填参数: " + paramName);
}
Object value = params.get(paramName);
if (value == null) {
return ResponseBuilder.failMsg("参数'" + paramName + "'不能为null");
}
if (value instanceof String && StringUtils.isEmpty(value)) {
return ResponseBuilder.failMsg("参数'" + paramName + "'不能为空字符串");
}
// 可以添加其他类型检查,如集合是否为空等
if (value instanceof Collection && ((Collection<?>) value).isEmpty()) {
return ResponseBuilder.failMsg("参数'" + paramName + "'集合不能为空");
}
}
return ResponseBuilder.reqPass();
}
}