Commit 485c1341 authored by matianhao's avatar matianhao

[审管办接口] <add> 接入审管办接口

parent 68c2ff6f
......@@ -73,23 +73,37 @@
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
</dependencies>
......
package com.mth.requestsecret.controller;
import com.mth.requestsecret.service.RestTemplateService;
import com.mth.requestsecret.util.AESUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.json.JSONObject;
import org.json.XML;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
/**
* 审管办接口
*
* @author MaTianHao
* @date 2020/8/27
*/
@RestController
@Slf4j
public class SgbController {
@Autowired
private RestTemplateService restTemplateService;
private static final String TOKEN = "cd5202f4-df21-40d6-8205-db4e326c6521";
/**
* 2.1 索引接口
*
* @param startTime
* @param endTime
* @return
* @throws Exception
*/
@PostMapping("/readTenderNoData")
public ResponseEntity readTenderNoData(String startTime, String endTime) throws Exception {
String apiMethod = "ReadTenderNoData";
// 1. 设置参数
StringBuilder soapRequestData = new StringBuilder();
appendStartPart(soapRequestData);
soapRequestData.append("<").append(apiMethod).append(" xmlns=\"http://tempuri.org/\">");
soapRequestData.append("<userToken>{0}</userToken>");
soapRequestData.append("<startTime>{1}</startTime>");
soapRequestData.append("<endTime>{2}</endTime>");
soapRequestData.append("</").append(apiMethod).append(">");
appendEndPart(soapRequestData);
log.info("接收参数 - startTime:{};endTime:{}", startTime, endTime);
// 2. 参数加密,替换占位符
String paramData = MessageFormat.format(soapRequestData.toString(),
TOKEN, AESUtils.desEncrypt(startTime), AESUtils.desEncrypt(endTime));
// 3. 发送请求
String resultStr = restTemplateService.sgbSendRequest(paramData, apiMethod);
return getParseResponseXmlAndConvertToJson(apiMethod, resultStr);
}
/**
* 2.2 项目基本信息表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readTenderData")
public ResponseEntity readTenderData(String tenderNo) throws Exception {
String apiMethod = "ReadTenderData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.3 开评标安排表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readProjectArrangementData")
public ResponseEntity readProjectArrangementData(String tenderNo) throws Exception {
String apiMethod = "ReadProjectArrangementData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.4 开标记录信息表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readOpenBidRecordData")
public ResponseEntity readOpenBidRecordData(String tenderNo) throws Exception {
String apiMethod = "ReadOpenBidRecordData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.5 评标委员会基本信息表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readProjectBidEvalCommitteeData")
public ResponseEntity readProjectBidEvalCommitteeData(String tenderNo) throws Exception {
String apiMethod = "ReadProjectBidEvalCommitteeData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.6 专家抽取组信息表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readProjectCommitteeSelectGroupData")
public ResponseEntity readProjectCommitteeSelectGroupData(String tenderNo) throws Exception {
String apiMethod = "ReadProjectCommitteeSelectGroupData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.7 专家抽取信息表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readProjectSelectJudgeData")
public ResponseEntity readProjectSelectJudgeData(String tenderNo) throws Exception {
String apiMethod = "ReadProjectSelectJudgeData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.8 甲方评委信息表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readProjectOwnerJudgeData")
public ResponseEntity readProjectOwnerJudgeData(String tenderNo) throws Exception {
String apiMethod = "ReadProjectOwnerJudgeData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.9 中标信息表
*
* @param tenderNo
* @return
* @throws Exception
*/
@PostMapping("/readTenderWinData")
public ResponseEntity readTenderWinData(String tenderNo) throws Exception {
String apiMethod = "ReadTenderWinData";
return getResponseEntityByTenderNo(tenderNo, apiMethod);
}
/**
* 2.2~2.9接口参数都为 tenderNo 项目编号,这里提取复用
*
* @param tenderNo
* @param apiMethod
* @return
* @throws Exception
*/
private ResponseEntity getResponseEntityByTenderNo(String tenderNo, String apiMethod) throws Exception {
// 1. 设置参数
StringBuilder soapRequestData = new StringBuilder();
appendStartPart(soapRequestData);
soapRequestData.append("<").append(apiMethod).append(" xmlns=\"http://tempuri.org/\">");
soapRequestData.append("<userToken>{0}</userToken>");
soapRequestData.append("<TenderNo>{1}</TenderNo>");
soapRequestData.append("</").append(apiMethod).append(">");
appendEndPart(soapRequestData);
log.info("接收参数 - tenderNo:{}", tenderNo);
// 2. 参数加密,替换占位符
String paramData = MessageFormat.format(soapRequestData.toString(),
TOKEN, AESUtils.desEncrypt(tenderNo));
// 3. 发送请求
String resultStr = restTemplateService.sgbSendRequest(paramData, apiMethod);
// 4. 解析响应并返回
return getParseResponseXmlAndConvertToJson(apiMethod, resultStr);
}
/**
* 解析接口响应xml,处理异常信息,结果转为json格式返回
*
* @param apiMethod
* @param resultStr
* @return
* @throws DocumentException
*/
private ResponseEntity getParseResponseXmlAndConvertToJson(String apiMethod, String resultStr) throws DocumentException {
// 标签节点
String elementResponse = apiMethod + "Response";
String elementResult = apiMethod + "Result";
// 1. 解析xml,获取标签数据
SAXReader read = new SAXReader();
Document doc = read.read(new ByteArrayInputStream(resultStr.getBytes(StandardCharsets.UTF_8)));
Element resultElement = doc.getRootElement()
.element("Body")
.element(elementResponse)
.element(elementResult);
String encryptDataResult = resultElement.getText();
// 2. 节点数据非加密后的字符串数据时,将接口异常信息返回
if (StringUtils.isBlank(encryptDataResult)) {
String dataResult = resultElement.getStringValue();
return exceptionResponseEntity(dataResult);
}
// 3. 解密标签数据(xml形式)
String decryptDataResult = AESUtils.desDecrypt(encryptDataResult);
if (StringUtils.isBlank(decryptDataResult)) {
return exceptionResponseEntity("未获取到数据");
}
// 4. 解密后xml结果转为json并返回
JSONObject jsonResult = XML.toJSONObject(decryptDataResult);
log.info("节点数据解密转json后:{}", jsonResult);
// 节点数据非xml,将解密后信息返回
if (jsonResult.isEmpty()) {
log.info("节点数据解密后:{}", decryptDataResult);
return exceptionResponseEntity(decryptDataResult);
}
// 返回json信息
jsonResult.put("success", true);
return ResponseEntity.status(HttpStatus.OK).body(jsonResult.toString());
}
/**
* 异常响应体
*/
private ResponseEntity exceptionResponseEntity(String errMsg) {
Map<String, Object> resultBody = new HashMap<>(2);
resultBody.put("success", false);
resultBody.put("error", errMsg);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(resultBody);
}
/**
* 拼接xml参数开始部分
*/
private void appendStartPart(StringBuilder soapRequestData) {
soapRequestData.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
soapRequestData.append("<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">");
soapRequestData.append("<soap12:Body>");
}
/**
* 拼接xml参数结束部分
*/
private void appendEndPart(StringBuilder soapRequestData) {
soapRequestData.append("</soap12:Body>");
soapRequestData.append("</soap12:Envelope>");
}
}
package com.mth.requestsecret.controller;
import com.alibaba.fastjson.JSONObject;
import com.mth.requestsecret.service.RestTemlateService;
import com.mth.requestsecret.service.RestTemplateService;
import com.mth.requestsecret.util.AESUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RestController;
public class ZbdController {
@Autowired
RestTemlateService restTemlateService;
private RestTemplateService restTemplateService;
/**
* 2.2 获取标段信息接口
......@@ -142,7 +142,7 @@ public class ZbdController {
log.info("{} - 参数:{}", apiMethod, requestParam.toJSONString());
try {
return restTemlateService.zbdSendRequest(param, apiMethod);
return restTemplateService.zbdSendRequest(param, apiMethod);
} catch (Exception e) {
return exceptionResponseEntity();
}
......
......@@ -7,6 +7,7 @@ import com.mth.requestsecret.util.DSLUtils;
import com.mth.requestsecret.util.MD5Utils;
import com.mth.requestsecret.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
......@@ -29,7 +30,7 @@ import static com.mth.requestsecret.constant.Constants.SJJ_REQUEST_SECRET_PREFIX
*/
@Component
@Slf4j
public class RestTemlateService {
public class RestTemplateService {
@Autowired
private RestTemplate restTemplate;
......@@ -57,6 +58,9 @@ public class RestTemlateService {
@Value("${zbd.address}")
private String zbdAddress;
@Value("${sgb.address}")
private String sgbAddress;
/**
* 瑞成平台接口发送请求
*
......@@ -168,4 +172,32 @@ public class RestTemlateService {
return AESUtils.decrypt(encryptTimestamp);
}
/**
* 审管办接口发送请求(webService)
*
* @param soapRequestData
* @param apiMethod
* @return
*/
public String sgbSendRequest(String soapRequestData, String apiMethod) throws Exception {
// 1. 构造http请求头
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
headers.setContentType(type);
HttpEntity<String> formEntity = new HttpEntity<String>(soapRequestData, headers);
// 2. 返回结果
String resultStr = restTemplate.postForObject(sgbAddress, formEntity, String.class);
// 3. 日志记录
log.info("审管办api:{}", apiMethod);
log.info("api url:{}", sgbAddress);
log.info("api params:{}", soapRequestData);
log.info("api response:{}", resultStr);
// 转换返回结果中的特殊字符,返回的结果中会将xml转义,此处需要反转移
return StringEscapeUtils.unescapeXml(resultStr);
}
}
\ No newline at end of file
package com.mth.requestsecret.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;
/**
......@@ -15,25 +18,41 @@ import java.util.Base64;
@Slf4j
public class AESUtils {
// 招必得加密参数
/**
* AES/CBC协定密钥key(256位)
*/
private final static String KEY = "LaKEXJRbiocF1iYOssFgj5Tdq1m0kFVO";
private final static String ZBD_KEY = "LaKEXJRbiocF1iYOssFgj5Tdq1m0kFVO";
/**
* AES/CBC协定向量iv(128位)
*/
private final static String IV = "LaKEXJRbiocF1iYO";
private final static String ZBD_IV = "LaKEXJRbiocF1iYO";
// 审管办加密参数
/**
* key
*/
private final static String SGB_KEY = "SAD68C6X";
/**
* 加密
* 偏移向量iv
*/
private final static byte[] SGB_IV = {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x90, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF};
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 招必得:aes加密
*/
public static String encrypt(String sstr) throws Exception {
byte[] keyByte = KEY.getBytes("utf-8");
byte[] keyByte = ZBD_KEY.getBytes("utf-8");
SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
// 算法/模式/补码方式
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] ivByte = IV.getBytes(StandardCharsets.UTF_8);
byte[] ivByte = ZBD_IV.getBytes(StandardCharsets.UTF_8);
// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
IvParameterSpec iv = new IvParameterSpec(ivByte);
......@@ -45,17 +64,17 @@ public class AESUtils {
}
/**
* 解密
* 招必得:aes解密
*/
public static String decrypt(String sstr) {
try {
byte[] keyByte = KEY.getBytes("utf-8");
byte[] keyByte = ZBD_KEY.getBytes("utf-8");
SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
// 算法/模式/补码方式
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes());
IvParameterSpec ivParameterSpec = new IvParameterSpec(ZBD_IV.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
byte[] encrype = Base64.getDecoder().decode(sstr);
byte[] origin = cipher.doFinal(encrype);
......@@ -64,6 +83,50 @@ public class AESUtils {
} catch (Exception e) {
return null;
}
}
/**
* 审管办接口:des加密
*/
public static String desEncrypt(String sstr) throws Exception {
// 算法/模式/补码方式
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS7Padding");
// key
SecretKeySpec keySpec = new SecretKeySpec(SGB_KEY.getBytes("utf-8"), "AES");
// iv
IvParameterSpec iv = new IvParameterSpec(SGB_IV);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
if (StringUtils.isEmpty(sstr)) {
return null;
}
byte[] encrype = cipher.doFinal(sstr.getBytes());
// 此处使用BASE64做转码功能,同时能起到2次加密的作用。
return Base64.getEncoder().encodeToString(encrype);
}
/**
* 审管办接口:des解密
*/
public static String desDecrypt(String sstr) {
try {
// 算法/模式/补码方式
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS7Padding");
// key
SecretKeySpec keySpec = new SecretKeySpec(SGB_KEY.getBytes("utf-8"), "AES");
// iv
IvParameterSpec iv = new IvParameterSpec(SGB_IV);
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
byte[] encrype = Base64.getDecoder().decode(sstr);
byte[] origin = cipher.doFinal(encrype);
return new String(origin);
} catch (Exception e) {
return null;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment