zhaoyiran
7 months ago
12 changed files with 396 additions and 494 deletions
@ -0,0 +1,32 @@ |
|||
package com.win.bank.enums; |
|||
|
|||
public enum PaymentStatusEnum { |
|||
|
|||
UNPROCESSED("0", "未处理"), PAYING("1", "支付中"), SUCCESS("2", "支付成功"), FAILED("3", "支付失败"); |
|||
|
|||
private final String code; |
|||
private final String description; |
|||
|
|||
PaymentStatusEnum(String code, String description) { |
|||
this.code = code; |
|||
this.description = description; |
|||
} |
|||
|
|||
public String getCode() { |
|||
return code; |
|||
} |
|||
|
|||
public String getDescription() { |
|||
return description; |
|||
} |
|||
|
|||
public static PaymentStatusEnum getByCode(String code) { |
|||
for (PaymentStatusEnum status : PaymentStatusEnum.values()) { |
|||
if (status.getCode().equals(code)) { |
|||
return status; |
|||
} |
|||
} |
|||
throw new IllegalArgumentException("Invalid PaymentStatus code: " + code); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,21 @@ |
|||
package com.win.bank.service; |
|||
|
|||
import com.win.bank.domain.BankDO; |
|||
|
|||
public interface BaseBankService { |
|||
/** |
|||
* 支付 |
|||
* |
|||
* @param bankDO |
|||
* @return |
|||
*/ |
|||
BankDO payment(BankDO bankDO); |
|||
|
|||
/** |
|||
* 查询支付结果 |
|||
* |
|||
* @param bankDO |
|||
* @return |
|||
*/ |
|||
BankDO queryPaymentResult(BankDO bankDO); |
|||
} |
@ -0,0 +1,28 @@ |
|||
package com.win.bank.service.bocom; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import com.win.bank.domain.BankDO; |
|||
import com.win.bank.service.BaseBankService; |
|||
|
|||
/** |
|||
* 交通银行 |
|||
*/ |
|||
@Service |
|||
public class BocomServiceImpl implements BaseBankService { |
|||
private static final Logger logger = LoggerFactory.getLogger(BocomServiceImpl.class); |
|||
|
|||
@Override |
|||
public BankDO payment(BankDO bankDO) { |
|||
logger.debug("交通银行 payment"); |
|||
return bankDO; |
|||
} |
|||
|
|||
@Override |
|||
public BankDO queryPaymentResult(BankDO bankDO) { |
|||
logger.debug("交通银行 queryPaymentResult"); |
|||
return bankDO; |
|||
} |
|||
} |
@ -1,73 +0,0 @@ |
|||
package com.win.bank.service.cmb; |
|||
|
|||
import java.io.IOException; |
|||
import java.security.GeneralSecurityException; |
|||
import java.security.Security; |
|||
import java.text.SimpleDateFormat; |
|||
import java.util.Date; |
|||
import java.util.Random; |
|||
|
|||
import org.bouncycastle.crypto.CryptoException; |
|||
import org.bouncycastle.jce.provider.BouncyCastleProvider; |
|||
|
|||
/** |
|||
* 招商银行银企直联国密免前置/SaaS对接示例,本示例仅供参考,不保证各种异常场景运行,请勿直接使用,如有错漏请联系对接人员。运行时,请使用所获取的测试资源替换 用户编号、公私钥、对称密钥、服务商编号等信息。 |
|||
* |
|||
* @author cmb.firmbank |
|||
* @date 2023/7/20 |
|||
*/ |
|||
public class ApiDemo { |
|||
|
|||
private static final int BOUND_START = 1000000; |
|||
private static final int BOUND_END = 9000000; |
|||
// 测试地址,生产需要替换
|
|||
private static String url = "http://192.168.0.142:8080/cdcserver/api/v2"; |
|||
// private static String url = "http://cdctest.cmburl.cn:80/cdcserver/api/v2";
|
|||
// 生产地址
|
|||
// private static String url = "https://cdc.cmbchina.com/cdcserver/api/v2";
|
|||
// 银行公钥,生产需要替换
|
|||
private static String publicKey = "BNsIe9U0x8IeSe4h/dxUzVEz9pie0hDSfMRINRXc7s1UIXfkExnYECF4QqJ2SnHxLv3z/99gsfDQrQ6dzN5lZj0="; |
|||
// 生产环境银行公钥
|
|||
// private static String publicKey =
|
|||
// "BEynMEZOjNpwZIiD9jXtZSGr3Ecpwn7r+m+wtafXHb6VIZTnugfuxhcKASq3hX+KX9JlHODDl9/RDKQv4XLOFak=";
|
|||
// 客户私钥,生产需要替换
|
|||
private static String privateKey = "NBtl7WnuUtA2v5FaebEkU0/Jj1IodLGT6lQqwkzmd2E="; |
|||
// 对称密钥,生产需要替换
|
|||
private static String symKey = "VuAzSWQhsoNqzn0K"; |
|||
|
|||
// 企业网银用户号,生产需要替换
|
|||
private static String uid = "N002986522"; |
|||
|
|||
private static Random random = new Random(); |
|||
|
|||
private ApiDemo() {} |
|||
|
|||
public static void main(String[] args) throws GeneralSecurityException, IOException, CryptoException { |
|||
// 装载BC库,必须在应用的启动类中调用此函数
|
|||
Security.addProvider(new BouncyCastleProvider()); |
|||
System.setProperty("sun.net.http.retryPost", "false"); |
|||
|
|||
// 业务接口名,这里是查询业务模式接口,生产请替换为对应接口名
|
|||
String funcode = "BB1PAYQR"; |
|||
// 准备接口数据,生产请替换为具体接口请求报文,包含所需的请求字段
|
|||
String currentDatetime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); |
|||
String reqid = new SimpleDateFormat("yyyyMMddHHmmssSSSS").format(new Date()) + (BOUND_START + random.nextInt(BOUND_END)); |
|||
String data = |
|||
"{\"request\":{\"body\":{\"bb1paybmx1\":[{\"busCod\":\"N02030\",\"busMod\":\"00002\"}],\"bb1payopx1\":[{\"ccyNbr\":\"10\",\"crtAcc\":\"6214831150131511\",\"crtNam\":\"吴极客\",\"dbtAcc\":\"755936045010501\",\"nusAge\":\"用途\",\"bnkFlg\":\"Y\",\"trsAmt\":\"1.05\",\"yurRef\":\"2024041709400601\"}]},\"head\":{\"funcode\":\"BB1PAYOP\",\"userid\":\"N002986522\"}}}"; |
|||
|
|||
// String data =
|
|||
// "{\"request\":{\"body\":{\"bb1payqrx1\":[{\"busCod\":\"N02030\",\"yurRef\":\"2024041709400602\"}]},\"head\":{\"funcode\":\"BB1PAYQR\",\"userid\":\"N002986522\"}}}";
|
|||
System.out.println(data); |
|||
DcHelper dchelper = new DcHelper(url, uid, privateKey, publicKey, symKey); |
|||
// 添加设备信息,请根据文档指引填写真实的信息,参数按顺序分别为:出口IP(无需)、MAC地址、CPU-ID、计算机名、主板ID、主板厂商
|
|||
// DeviceInfo deviceInfo = new DeviceInfo(null, "9822EFF12C6B", "AABBCCDDEEFFGGHH", "XXX", "XXX", "XXX");
|
|||
// String response = dchelper.sendRequest(data, funcode);
|
|||
// process("Api请求1成功,响应报文:\r\n" + response);
|
|||
// String response2 = dchelper.sendRequest(data, funcode, deviceInfo);
|
|||
// process("Api请求2成功,响应报文:\r\n" + response2);
|
|||
} |
|||
|
|||
private static void process(String response) { |
|||
|
|||
} |
|||
} |
@ -1,369 +0,0 @@ |
|||
package com.win.bank.service.cmb; |
|||
|
|||
import java.io.*; |
|||
import java.math.BigInteger; |
|||
import java.net.HttpURLConnection; |
|||
import java.net.URL; |
|||
import java.net.URLEncoder; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.security.GeneralSecurityException; |
|||
import java.security.KeyStore; |
|||
import java.util.*; |
|||
|
|||
import javax.crypto.Cipher; |
|||
import javax.crypto.spec.IvParameterSpec; |
|||
import javax.crypto.spec.SecretKeySpec; |
|||
import javax.net.ssl.*; |
|||
|
|||
import org.bouncycastle.asn1.*; |
|||
import org.bouncycastle.crypto.CryptoException; |
|||
import org.bouncycastle.crypto.params.ECDomainParameters; |
|||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; |
|||
import org.bouncycastle.crypto.params.ECPublicKeyParameters; |
|||
import org.bouncycastle.crypto.params.ParametersWithID; |
|||
import org.bouncycastle.crypto.signers.SM2Signer; |
|||
import org.bouncycastle.jce.ECNamedCurveTable; |
|||
import org.bouncycastle.jce.provider.BouncyCastleProvider; |
|||
import org.bouncycastle.jce.spec.ECParameterSpec; |
|||
import org.bouncycastle.math.ec.ECPoint; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.fasterxml.jackson.databind.SerializationFeature; |
|||
import com.google.gson.Gson; |
|||
import com.google.gson.JsonArray; |
|||
import com.google.gson.JsonObject; |
|||
|
|||
/** |
|||
* 招商银行银企直联国密免前置/SaaS对接示例,本示例仅供参考,不保证各种异常场景运行,请勿直接使用,如有错漏请联系对接人员。运行时,请使用所获取的测试资源替换 用户编号、公私钥、对称密钥、服务商编号等信息。 |
|||
* |
|||
* @author cmb.firmbank |
|||
* @date 2023/7/20 |
|||
*/ |
|||
public class DcHelper { |
|||
|
|||
private static final int LENGTH_32 = 32; |
|||
private static final int USERID_LEN = 16; |
|||
private static final int CONNECT_TIMEOUT = 15000; |
|||
private static final int READ_TIMEOUT = 60000; |
|||
private static final int STATUS_OK = 200; |
|||
private static Base64.Encoder encoder = Base64.getEncoder(); |
|||
private static Base64.Decoder decoder = Base64.getDecoder(); |
|||
|
|||
// 请求URL
|
|||
private final String url; |
|||
// 企业网银用户号
|
|||
private final String uid; |
|||
// 国密算法向量,根据用户号生成
|
|||
private final byte[] userId; |
|||
// 算法,固定为国密算法
|
|||
private final String alg; |
|||
// 客户私钥
|
|||
private final byte[] privateKey; |
|||
// 银行公钥
|
|||
private final byte[] publicKey; |
|||
// 协商的对称密钥
|
|||
private final byte[] symKey; |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(DcHelper.class); |
|||
|
|||
public DcHelper(String url, String uid, String privateKey, String publicKey, String symKey) { |
|||
this.url = url; |
|||
this.uid = uid; |
|||
this.userId = getUserId(uid); |
|||
this.alg = "SM"; |
|||
this.privateKey = decoder.decode(privateKey); |
|||
this.publicKey = decoder.decode(publicKey); |
|||
this.symKey = symKey.getBytes(StandardCharsets.UTF_8); |
|||
} |
|||
|
|||
public String sendRequest(String data, String funcode) throws IOException, CryptoException, GeneralSecurityException { |
|||
// 增加设备信息
|
|||
JsonObject requestJson = new Gson().fromJson(data, JsonObject.class); |
|||
// requestJson.getAsJsonObject("request").add("exthdr", deviceInfo.toJson());
|
|||
// 对请求报文做排序
|
|||
String source = recursiveKeySort(requestJson); |
|||
// 生成签名
|
|||
// byte[] signature = cmbSM2SignWithSM3(userId, privateKey, source.getBytes(StandardCharsets.UTF_8));
|
|||
// 替换签名字段
|
|||
// requestJson.getAsJsonObject("signature").addProperty("sigdat", new String(encoder.encode(signature),
|
|||
// StandardCharsets.UTF_8));
|
|||
|
|||
// 对数据进行对称加密
|
|||
// String request = requestJson.toString();
|
|||
// byte[] encryptRequest = cmbSM4Crypt(symKey, userId, request.getBytes(StandardCharsets.UTF_8), 1);
|
|||
// String encryptedRequest = new String(encoder.encode(encryptRequest), StandardCharsets.UTF_8);
|
|||
logger.debug(data); |
|||
// 发送请求
|
|||
HashMap<String, String> map = new HashMap<>(); |
|||
map.put("UID", uid); |
|||
map.put("ALG", alg); |
|||
map.put("DATA", URLEncoder.encode(data, StandardCharsets.UTF_8.displayName())); |
|||
// map.put("DATA", URLEncoder.encode(encryptedRequest, StandardCharsets.UTF_8.displayName()));
|
|||
map.put("FUNCODE", funcode); |
|||
String response = httpPost(url, map); |
|||
// logger.debug(response);
|
|||
printJson(data); |
|||
if (response.startsWith("CDCServer:")) { |
|||
throw new IOException("访问目标地址 " + url + " 失败:" + response); |
|||
} |
|||
|
|||
// 返回结果解密
|
|||
// response = new String((cmbSM4Crypt(symKey, userId, decoder.decode(response), 2)), StandardCharsets.UTF_8);
|
|||
|
|||
// 验证签名是否正确
|
|||
// JsonObject responseJson = new Gson().fromJson(response, JsonObject.class);
|
|||
// JsonObject signatureJson = responseJson.getAsJsonObject("signature");
|
|||
// String responseSignature = signatureJson.get("sigdat").getAsString();
|
|||
// signatureJson.addProperty("sigdat", "__signature_sigdat__");
|
|||
// responseJson.add("signature", signatureJson);
|
|||
// String responseSorted = recursiveKeySort(responseJson);
|
|||
// boolean verify = cmbSM2VerifyWithSM3(userId, publicKey, responseSorted.getBytes(StandardCharsets.UTF_8),
|
|||
// decoder.decode(responseSignature));
|
|||
// if (!verify) {
|
|||
// throw new IOException("响应报文的签名无效");
|
|||
// }
|
|||
printJson(response); |
|||
return response; |
|||
} |
|||
|
|||
private static String recursiveKeySort(JsonObject json) { |
|||
StringBuilder appender = new StringBuilder(); |
|||
appender.append("{"); |
|||
Iterator<String> keys = new TreeSet<>(json.keySet()).iterator(); |
|||
boolean isFirstEle = true; |
|||
while (keys.hasNext()) { |
|||
if (!isFirstEle) { |
|||
appender.append(","); |
|||
} |
|||
String key = keys.next(); |
|||
Object val = json.get(key); |
|||
if (val instanceof JsonObject) { |
|||
appender.append("\"").append(key).append("\":"); |
|||
appender.append(recursiveKeySort((JsonObject)val)); |
|||
} else if (val instanceof JsonArray) { |
|||
JsonArray jarray = (JsonArray)val; |
|||
appender.append("\"").append(key).append("\":["); |
|||
boolean isFirstArrEle = true; |
|||
for (int i = 0; i < jarray.size(); i++) { |
|||
if (!isFirstArrEle) { |
|||
appender.append(","); |
|||
} |
|||
Object obj = jarray.get(i); |
|||
if (obj instanceof JsonObject) { |
|||
appender.append(recursiveKeySort((JsonObject)obj)); |
|||
} else { |
|||
appender.append(obj.toString()); |
|||
} |
|||
isFirstArrEle = false; |
|||
} |
|||
appender.append("]"); |
|||
} else { |
|||
String value = val.toString(); |
|||
appender.append("\"").append(key).append("\":").append(value); |
|||
} |
|||
isFirstEle = false; |
|||
} |
|||
appender.append("}"); |
|||
return appender.toString(); |
|||
} |
|||
|
|||
private static byte[] getUserId(String uid) { |
|||
return (uid + "0000000000000000").substring(0, USERID_LEN).getBytes(); |
|||
} |
|||
|
|||
private static String httpPost(String httpUrl, Map<String, String> param) throws IOException, GeneralSecurityException { |
|||
HttpURLConnection connection = null; |
|||
String result; |
|||
try { |
|||
URL url = new URL(httpUrl); |
|||
SSLContext sslcontext; |
|||
sslcontext = SSLContext.getInstance("SSL"); |
|||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
|||
tmf.init((KeyStore)null); |
|||
X509TrustManager defaultTm = null; |
|||
for (TrustManager tm : tmf.getTrustManagers()) { |
|||
if (tm instanceof X509TrustManager) { |
|||
defaultTm = (X509TrustManager)tm; |
|||
break; |
|||
} |
|||
} |
|||
sslcontext.init(null, new TrustManager[] {defaultTm}, new java.security.SecureRandom()); |
|||
HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory()); |
|||
|
|||
connection = (HttpURLConnection)url.openConnection(); |
|||
connection.setRequestMethod("POST"); |
|||
connection.setConnectTimeout(CONNECT_TIMEOUT); |
|||
connection.setReadTimeout(READ_TIMEOUT); |
|||
connection.setInstanceFollowRedirects(true); |
|||
|
|||
connection.setDoOutput(true); |
|||
connection.setDoInput(true); |
|||
|
|||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); |
|||
try (OutputStream os = connection.getOutputStream()) { |
|||
os.write(createLinkString(param).getBytes()); |
|||
if (connection.getResponseCode() != STATUS_OK) { |
|||
InputStream is = connection.getErrorStream(); |
|||
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); |
|||
StringBuilder sbf = new StringBuilder(); |
|||
String temp; |
|||
while ((temp = br.readLine()) != null) { |
|||
sbf.append(temp); |
|||
sbf.append("\r\n"); |
|||
} |
|||
|
|||
result = sbf.toString(); |
|||
br.close(); |
|||
is.close(); |
|||
} else { |
|||
InputStream is = connection.getInputStream(); |
|||
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); |
|||
StringBuilder sbf = new StringBuilder(); |
|||
String temp; |
|||
while ((temp = br.readLine()) != null) { |
|||
sbf.append(temp); |
|||
} |
|||
result = sbf.toString(); |
|||
br.close(); |
|||
is.close(); |
|||
} |
|||
} |
|||
} finally { |
|||
if (connection != null) { |
|||
connection.disconnect(); |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
private static String createLinkString(Map<String, String> params) { |
|||
ArrayList<String> keys = new ArrayList<>(params.keySet()); |
|||
Collections.sort(keys); |
|||
|
|||
StringBuilder prestr = new StringBuilder(); |
|||
for (int i = 0; i < keys.size(); i++) { |
|||
String key = keys.get(i); |
|||
String value = params.get(key); |
|||
if (i == keys.size() - 1) { |
|||
prestr.append(key).append("=").append(value); |
|||
} else { |
|||
prestr.append(key).append("=").append(value).append("&"); |
|||
} |
|||
} |
|||
return prestr.toString(); |
|||
} |
|||
|
|||
// 以下是加解密相关的函数
|
|||
|
|||
private static byte[] cmbSM2SignWithSM3(byte[] id, byte[] privkey, byte[] msg) throws IOException, CryptoException { |
|||
if (privkey == null || msg == null) { |
|||
throw new CryptoException("CMBSM2SignWithSM3 input error"); |
|||
} |
|||
ECPrivateKeyParameters privateKey = encodePrivateKey(privkey); |
|||
SM2Signer signer = new SM2Signer(); |
|||
ParametersWithID parameters = new ParametersWithID(privateKey, id); |
|||
signer.init(true, parameters); |
|||
signer.update(msg, 0, msg.length); |
|||
return decodeDERSignature(signer.generateSignature()); |
|||
} |
|||
|
|||
private static ECPrivateKeyParameters encodePrivateKey(byte[] value) { |
|||
BigInteger d = new BigInteger(1, value); |
|||
ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); |
|||
ECDomainParameters ecParameters = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(), spec.getH(), spec.getSeed()); |
|||
return new ECPrivateKeyParameters(d, ecParameters); |
|||
} |
|||
|
|||
private static byte[] decodeDERSignature(byte[] signature) throws IOException { |
|||
ASN1InputStream stream = new ASN1InputStream(new ByteArrayInputStream(signature)); |
|||
ASN1Sequence primitive = (ASN1Sequence)stream.readObject(); |
|||
Enumeration<ASN1Integer> enumeration = primitive.getObjects(); |
|||
BigInteger intR = enumeration.nextElement().getValue(); |
|||
BigInteger intS = enumeration.nextElement().getValue(); |
|||
byte[] bytes = new byte[LENGTH_32 * 2]; |
|||
byte[] r = format(intR.toByteArray()); |
|||
byte[] s = format(intS.toByteArray()); |
|||
System.arraycopy(r, 0, bytes, 0, LENGTH_32); |
|||
System.arraycopy(s, 0, bytes, LENGTH_32, LENGTH_32); |
|||
return bytes; |
|||
} |
|||
|
|||
private static byte[] format(byte[] value) { |
|||
if (value.length == LENGTH_32) { |
|||
return value; |
|||
} else { |
|||
byte[] bytes = new byte[LENGTH_32]; |
|||
if (value.length > LENGTH_32) { |
|||
System.arraycopy(value, value.length - LENGTH_32, bytes, 0, LENGTH_32); |
|||
} else { |
|||
System.arraycopy(value, 0, bytes, LENGTH_32 - value.length, value.length); |
|||
} |
|||
return bytes; |
|||
} |
|||
} |
|||
|
|||
private static byte[] cmbSM4Crypt(byte[] key, byte[] iv, byte[] input, int mode) throws GeneralSecurityException { |
|||
SecretKeySpec spec = new SecretKeySpec(key, "SM4"); |
|||
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); |
|||
Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS7Padding", BouncyCastleProvider.PROVIDER_NAME); |
|||
cipher.init(mode, spec, ivParameterSpec); |
|||
return cipher.doFinal(input); |
|||
} |
|||
|
|||
private static boolean cmbSM2VerifyWithSM3(byte[] id, byte[] pubkey, byte[] msg, byte[] signature) throws IOException { |
|||
|
|||
if (pubkey == null || msg == null || signature == null) { |
|||
throw new IllegalArgumentException("CMBSM2VerifyWithSM3 input error"); |
|||
} |
|||
ECPublicKeyParameters publicKey = encodePublicKey(pubkey); |
|||
SM2Signer signer = new SM2Signer(); |
|||
ParametersWithID parameters = new ParametersWithID(publicKey, id); |
|||
signer.init(false, parameters); |
|||
signer.update(msg, 0, msg.length); |
|||
return signer.verifySignature(encodeDERSignature(signature)); |
|||
} |
|||
|
|||
private static ECPublicKeyParameters encodePublicKey(byte[] value) { |
|||
byte[] x = new byte[LENGTH_32]; |
|||
byte[] y = new byte[LENGTH_32]; |
|||
System.arraycopy(value, 1, x, 0, LENGTH_32); |
|||
System.arraycopy(value, LENGTH_32 + 1, y, 0, LENGTH_32); |
|||
BigInteger intX = new BigInteger(1, x); |
|||
BigInteger intY = new BigInteger(1, y); |
|||
ECParameterSpec spec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); |
|||
ECPoint intQ = spec.getCurve().createPoint(intX, intY); |
|||
ECDomainParameters ecParameters = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN(), spec.getH(), spec.getSeed()); |
|||
return new ECPublicKeyParameters(intQ, ecParameters); |
|||
} |
|||
|
|||
private static byte[] encodeDERSignature(byte[] signature) throws IOException { |
|||
byte[] r = new byte[LENGTH_32]; |
|||
byte[] s = new byte[LENGTH_32]; |
|||
System.arraycopy(signature, 0, r, 0, LENGTH_32); |
|||
System.arraycopy(signature, LENGTH_32, s, 0, LENGTH_32); |
|||
ASN1EncodableVector vector = new ASN1EncodableVector(); |
|||
vector.add(new ASN1Integer(new BigInteger(1, r))); |
|||
vector.add(new ASN1Integer(new BigInteger(1, s))); |
|||
return (new DERSequence(vector)).getEncoded(); |
|||
} |
|||
|
|||
private void printJson(String jsonStr) { |
|||
ObjectMapper mapper = new ObjectMapper(); |
|||
mapper.enable(SerializationFeature.INDENT_OUTPUT); |
|||
|
|||
try { |
|||
// 原始的JSON字符串
|
|||
// String jsonStr = "{\"name\": \"Alice\", \"age\": 30, \"city\": \"Beijing\"}";
|
|||
|
|||
// 格式化打印JSON字符串
|
|||
Object json = mapper.readValue(jsonStr, Object.class); |
|||
String formattedJsonStr = mapper.writeValueAsString(json); |
|||
// System.out.println(formattedJsonStr);
|
|||
logger.debug(formattedJsonStr); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
@ -1,39 +0,0 @@ |
|||
package com.win.bank.service.cmb; |
|||
|
|||
import com.google.gson.JsonObject; |
|||
|
|||
/** |
|||
* 设备信息 |
|||
*/ |
|||
public class DeviceInfo { |
|||
|
|||
private String ipVal; |
|||
private String macVal; |
|||
private String cpuInfo; |
|||
private String computerName; |
|||
private String mainBoardId; |
|||
private String mainBoardName; |
|||
|
|||
public DeviceInfo(String ipVal, String macVal, String cpuInfo, String computerName, String mainBoardId, String mainBoardName) { |
|||
this.ipVal = ipVal; |
|||
this.macVal = macVal; |
|||
this.cpuInfo = cpuInfo; |
|||
this.computerName = computerName; |
|||
this.mainBoardId = mainBoardId; |
|||
this.mainBoardName = mainBoardName; |
|||
} |
|||
|
|||
public JsonObject toJson() { |
|||
JsonObject deviceInfo = new JsonObject(); |
|||
if (ipVal != null) { |
|||
deviceInfo.addProperty("ipType", ipVal.indexOf(':') != -1 ? "6" : "4"); |
|||
deviceInfo.addProperty("ipVal", ipVal); |
|||
} |
|||
deviceInfo.addProperty("macVal", macVal); |
|||
deviceInfo.addProperty("cpuInfo", cpuInfo); |
|||
deviceInfo.addProperty("cmpName", computerName); |
|||
deviceInfo.addProperty("mbId", mainBoardId); |
|||
deviceInfo.addProperty("mbMf", mainBoardName); |
|||
return deviceInfo; |
|||
} |
|||
} |
@ -0,0 +1,54 @@ |
|||
package com.win.bank.utils; |
|||
|
|||
import java.lang.reflect.Modifier; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
import java.util.Set; |
|||
|
|||
import javax.annotation.PostConstruct; |
|||
|
|||
import org.reflections.Reflections; |
|||
import org.springframework.beans.BeansException; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.context.ApplicationContextAware; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import com.win.bank.service.BaseBankService; |
|||
|
|||
@Component |
|||
public class BaseBankServiceUtil implements ApplicationContextAware { |
|||
|
|||
ApplicationContext context; |
|||
|
|||
@Override |
|||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
|||
this.context = applicationContext; |
|||
} |
|||
|
|||
private static Map<String, BaseBankService> map = new HashMap<>(); |
|||
|
|||
public static BaseBankService get(String code) { |
|||
return map.get(code); |
|||
} |
|||
|
|||
@PostConstruct |
|||
public void init() { |
|||
String packageName = "com.win.bank.service"; |
|||
Reflections reflections = new Reflections(packageName); |
|||
Set<Class<? extends BaseBankService>> subTypes = reflections.getSubTypesOf(BaseBankService.class); |
|||
|
|||
for (Class<?> clazz : subTypes) { |
|||
if (!Modifier.isAbstract(clazz.getModifiers()) && !clazz.isInterface()) { |
|||
String key = clazz.getPackageName().substring(clazz.getPackageName().lastIndexOf(".") + 1).toUpperCase(); |
|||
BaseBankService instance = null; |
|||
try { |
|||
instance = (BaseBankService)context.getBean(Class.forName(clazz.getName())); |
|||
map.put(key, instance); |
|||
} catch (ClassNotFoundException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,20 @@ |
|||
package com.win.bank.utils; |
|||
|
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.fasterxml.jackson.databind.ObjectWriter; |
|||
|
|||
public class JsonUtil { |
|||
|
|||
public static String formatJson(String jsonStr) { |
|||
try { |
|||
ObjectMapper mapper = new ObjectMapper(); |
|||
Object json = mapper.readValue(jsonStr, Object.class); |
|||
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter(); |
|||
String prettyJson = '\n' + writer.writeValueAsString(json); |
|||
return prettyJson; |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue