Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
J
jiwei-api
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
马天浩
jiwei-api
Commits
485c1341
Commit
485c1341
authored
Aug 28, 2020
by
matianhao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[审管办接口] <add> 接入审管办接口
parent
68c2ff6f
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
502 additions
and
98 deletions
+502
-98
pom.xml
pom.xml
+27
-13
RequestController.java
...a/com/mth/requestsecret/controller/RequestController.java
+73
-73
SgbController.java
.../java/com/mth/requestsecret/controller/SgbController.java
+295
-0
ZbdController.java
.../java/com/mth/requestsecret/controller/ZbdController.java
+3
-3
RestTemplateService.java
...va/com/mth/requestsecret/service/RestTemplateService.java
+33
-1
AESUtils.java
src/main/java/com/mth/requestsecret/util/AESUtils.java
+71
-8
No files found.
pom.xml
View file @
485c1341
...
...
@@ -80,8 +80,6 @@
<version>
20180813
</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>
org.apache.httpcomponents
</groupId>
...
...
@@ -89,7 +87,23 @@
<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>
...
...
src/main/java/com/mth/requestsecret/controller/RequestController.java
View file @
485c1341
This diff is collapsed.
Click to expand it.
src/main/java/com/mth/requestsecret/controller/SgbController.java
0 → 100644
View file @
485c1341
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>"
);
}
}
src/main/java/com/mth/requestsecret/controller/ZbdController.java
View file @
485c1341
package
com
.
mth
.
requestsecret
.
controller
;
import
com.alibaba.fastjson.JSONObject
;
import
com.mth.requestsecret.service.RestTemlateService
;
import
com.mth.requestsecret.service.RestTem
p
lateService
;
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
restTem
lateService
;
private
RestTemplateService
restTemp
lateService
;
/**
* 2.2 获取标段信息接口
...
...
@@ -142,7 +142,7 @@ public class ZbdController {
log
.
info
(
"{} - 参数:{}"
,
apiMethod
,
requestParam
.
toJSONString
());
try
{
return
restTemlateService
.
zbdSendRequest
(
param
,
apiMethod
);
return
restTem
p
lateService
.
zbdSendRequest
(
param
,
apiMethod
);
}
catch
(
Exception
e
)
{
return
exceptionResponseEntity
();
}
...
...
src/main/java/com/mth/requestsecret/service/RestTemlateService.java
→
src/main/java/com/mth/requestsecret/service/RestTem
p
lateService.java
View file @
485c1341
...
...
@@ -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
RestTem
p
lateService
{
@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
src/main/java/com/mth/requestsecret/util/AESUtils.java
View file @
485c1341
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
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment