CFCA の関連インターフェースを呼び出して、安心して署名できます。非常に詳細です。

1. CFCA 安全署名ドッキング資料を入手する

まず、CFCA の安全な署名ドッキング担当者から、インターフェイス ドキュメントを含む関連情報を見つけます。
ここに画像の説明を挿入

ケースコードは次のとおりです。
ここに画像の説明を挿入
また、テストに必要な関連ドキュメントは通常一緒に提供されます。

2. 通話インターフェース

1.安心して署名できるドッキング担当者を見つけて、IPホワイトリストを追加します

ここで言及したいのは、ホワイトリストを安全な署名に追加する速度は比較的遅く、少なくとも1日であり、IPネットワークセグメントを追加できない.IPが固定されていない場合、テストするのがより不快になる.安全な署名を調整したい場合は、彼らに適切なホワイトリストを追加さ​​せることを忘れないでください.

2. クエリ インターフェイス ドキュメント

たとえば、txCode 3001 (個人口座開設インターフェイス) を呼び出して、
ここに画像の説明を挿入
パラメーターの受け渡し方法を確認したい

3. 対応するテスト ケースを表示する

Anxin Sign のドッキング スタッフが提供するデモで、対応するテスト ケースを見つけます。
ここに画像の説明を挿入

詳細は次のとおりです。

package cfca.trustsign.demo.test;

import cfca.sadk.algorithm.common.PKIException;
import cfca.trustsign.common.vo.cs.HeadVO;
import cfca.trustsign.common.vo.cs.PersonVO;
import cfca.trustsign.common.vo.request.tx3.Tx3001ReqVO;
import cfca.trustsign.demo.connector.HttpConnector;
import cfca.trustsign.demo.constant.Request;
import cfca.trustsign.demo.converter.JsonObjectMapper;
import cfca.trustsign.demo.util.SecurityUtil;
import cfca.trustsign.demo.util.TimeUtil;

public class Test3001 {
    
    
    public static void main(String[] args) throws PKIException {
    
    
        HttpConnector httpConnector = new HttpConnector();
        httpConnector.init();

        PersonVO person = PersonVO.builder().personName("刘三十jiu").identTypeCode("1").identNo("110102200001071156").mobilePhone("95010117774")
                .email("[email protected]").authenticationMode("公安部").build();
        // 监管平台注意:用户首次开户时会签发五年有效期证书,五年后如果证书过期会导致用户签名时交易失败,所以平台要注意证书的有效期。
        // 若五年到期后交易失败,平台可再次对用户进行实名认证并调用此接口完成证书更新操作。
        // 平台亦可自行记录开户时间,五年到期前90天内(安心签默认到期前90天内可更新证书),平台可再次对用户进行实名认证并调用此接口提前完成证书的展期操作,避免用户签章操作的不连续。
        person.setAuthenticationTime(TimeUtil.getCurrentTime(TimeUtil.FORMAT_14));

        Tx3001ReqVO tx3001ReqVO = new Tx3001ReqVO();
        tx3001ReqVO.setHead(HeadVO.builder().txTime(TimeUtil.getCurrentTime(TimeUtil.FORMAT_14)).build());
        tx3001ReqVO.setPerson(person);

        String req = new JsonObjectMapper().writeValueAsString(tx3001ReqVO);
        System.out.println("req:" + req);

        String txCode = "3001", signature = SecurityUtil.p7SignMessageDetach(HttpConnector.JKS_PATH, HttpConnector.JKS_PWD, HttpConnector.ALIAS, req);
        // String txCode = "3001", signature = SecurityUtil.p7SignMessageDetachSm2(HttpConnector.SCER_PATH, HttpConnector.SCER_PASS, HttpConnector.ALIAS, req);
        String res = httpConnector.post("platId/" + Request.PLAT_ID + "/txCode/" + txCode + "/transaction", req, signature);
        System.out.println("res:" + res);
    }
}

4. Anxin Sign に関連する jar パッケージをインポートします

安心して署名するための対応する maven 依存関係はありません. 例のデモの jar パッケージをプロジェクトに追加する必要があります. ドッキング スタッフから複数のデモを要求された場合は、古い jar があるため、最新の jar パッケージをインポートします.パッケージに欠けがある場合がございます。

これはデモの jar パッケージです。すべてをインポートする必要はありません。呼び出しインターフェイスで使用されるものだけをインポートする必要があります。
ここに画像の説明を挿入

主にこちらを使用

5. 通話インターフェースのテスト

public void testTxCode3001() throws Exception {
    
    
    AnxinqianConfig anxinqianConfig = new AnxinqianConfig();
    anxinqianConfig.setJKS_PATH("你的JKS通讯证书文件绝对路径");
    anxinqianConfig.setJKS_PWD("你的通讯证书密码");
    anxinqianConfig.setALIAS("你制作通讯证书时的设置");
    anxinqianConfig.setPLAT_ID("你的安心签平台id");
    anxinqianConfig.setUrl("https://安心签ip:443/FEP/");

    anxinqianConfig.setTxCode(InterfCodeEnum.CODE_3001.getCode());

    Tx3001ReqVO tx3001ReqVO = new Tx3001ReqVO();

    HeadVO headVO = new HeadVO();
    headVO.setTxTime(DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN));  //格式为yyyyMMddHHmmss

    PersonVO personVO = new PersonVO();
    personVO.setPersonName("你的名字");  //个人名称
    personVO.setIdentNo("你的身份证号码");  //证件号码
    personVO.setMobilePhone("你的手机号码");  //手机号码
    personVO.setAuthenticationMode("居民身份证");  //认证方式
    personVO.setIsOpenSM2(0); //是否开通国密证书,0:不开通;1:开通;默认为0

    tx3001ReqVO.setHead(headVO);
    tx3001ReqVO.setPerson(personVO);

    JSONObject responseJSONObject = AnxinqianUtil.sendRequest(anxinqianConfig, tx3001ReqVO);

    log.info("测试3001接口,返回结果:{}", responseJSONObject);
}

説明:

Tx3001ReqVO クラスの完全修飾クラス名 cfca.trustsign.common.vo.request.tx3.Tx3001ReqVO
HeadVO クラスの完全修飾クラス名 cfca.trustsign.common.vo.cs.HeadVO
PersonVO クラスの完全修飾クラス名 cfca.trustsign.common .vo.cs.PersonVO
時間関連のクラスは hutool ツールキットから来ています

呼び出しが成功すると、コンソールの出力は次のようになります。
ここに画像の説明を挿入

返される結果は次のようにフォーマットされます。
ここに画像の説明を挿入

ホワイトリストがない場合、インターフェイスを呼び出すとタイムアウト エラーが報告されます。
ここに画像の説明を挿入
適切なインターフェイスを呼び出すと、このエラーが報告されます。

6. ダウンロード コントラクト インターフェイスを呼び出します (これは特殊です)。

ダウンロード コントラクト インターフェイスは txCode で始まる他のインターフェイスとは異なります. このインターフェイスはバイト配列のみを返します. ここではそれを個別に取り出し, コントラクトをダウンロードするための特別なメソッドも記述します. 以下はテスト コードです.

public void testDownload() throws Exception {
    
    
    AnxinqianConfig anxinqianConfig = new AnxinqianConfig();
    anxinqianConfig.setJKS_PATH("你的JKS通讯证书文件绝对路径");
    anxinqianConfig.setJKS_PWD("你的通讯证书密码");
    anxinqianConfig.setALIAS("你制作通讯证书时的设置");
    anxinqianConfig.setPLAT_ID("你的安心签平台id");
    anxinqianConfig.setUrl("https://安心签ip:443/FEP/");

    anxinqianConfig.setDownloadUrl("/opt/jeecg-boot/upload/hetong"); //安心签保存合同公共地址
    anxinqianConfig.setHetongUrl("你配置访问下载安心签合同的公共域名");  //访问安心签下载合同公共域名,就是文件访问域名,配置Nginx解析到安心签保存合同公共地址

    String contractNo = "CL20230406000010002"; //合同号

    //获取安心签下载合同接口的部分路径,用于拼接到公共路径中
    String uri = AnxinqianUtil.getDownloadContractUri(anxinqianConfig, contractNo);

    byte[] fileByte = AnxinqianUtil.getFile(anxinqianConfig, uri);

    //===============================下面这些是服务器创建合同文件的逻辑,可以自定义===============================

    //合同不存在,直接结束方法
    if (CommonUtil.isEmpty(fileByte))
        throw new RuntimeException("合同不存在!");

    String commonUploadUrl = anxinqianConfig.getDownloadUrl().endsWith("/") ? anxinqianConfig.getDownloadUrl() : anxinqianConfig.getDownloadUrl() + "/";
    String uploadUrl = commonUploadUrl + contractNo + "/";

    Path uploadPath = Paths.get(uploadUrl);

    //创建文件夹及其父文件夹如果被创建文件夹的父文件夹不存在,就创建它如果被创建的文件夹已经存在,就是用已经存在的文件夹,不会重复创建,没有异常抛出
    Files.createDirectories(uploadPath);

    Files.write(Paths.get(uploadUrl + contractNo + ".pdf"), fileByte);

    String contractUrl = (anxinqianConfig.getHetongUrl().endsWith("/") ? anxinqianConfig.getHetongUrl() : anxinqianConfig.getHetongUrl() + "/") + contractNo + "/" + contractNo + ".pdf";

    log.info("合同路径:{}", contractUrl);
}

返される結果:
ここに画像の説明を挿入
保存されたコントラクトに対応するパスを表示します。
ここに画像の説明を挿入

契約書がダウンロードされたことがわかります。ドメイン名を使用してアクセスする
ここに画像の説明を挿入

3. ツール

1. CFCA 安全署名インターフェース列挙型クラス

/**
 * 安心签接口码枚举类
 *
 * @author:user
 * @date: 2022-08-26 11:01
 */
public enum InterfCodeEnum {
    
    

    CODE_3911("3911", "签署合同"),  //废弃
    CODE_3913("3913", "单一用户多合同H5签署"),
    CODE_3001("3001", "个人信息验证"),
    CODE_3101("3101", "发送验证码"),
    CODE_3102("3102", "确认验证码"),
    CODE_3201("3201", "创建合同"),
    CODE_3210("3210", "合同查询");

    private String code;
    private String desc;

    InterfCodeEnum(String code, String desc) {
    
    
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
    
    
        return code;
    }

    public void setCode(String code) {
    
    
        this.code = code;
    }

    public static String getDesc(String code) {
    
    
        for (InterfCodeEnum value : values()) {
    
    
            if (value.code.equals(code))
                return value.desc;
        }
        throw new RuntimeException("未知接口码:" + code);
    }

    public String getDesc() {
    
    
        return desc;
    }

    public void setDesc(String desc) {
    
    
        this.desc = desc;
    }
}

2. CFCA 安全標識構成クラス

import lombok.Data;

/**
 * 安心签配置dto
 *
 * @author:user
 * @date: 2022-08-22 16:53
 */
@Data
public class AnxinqianConfig {
    
    
    //JKS通讯证书文件绝对路径
    private String JKS_PATH;

    //通讯证书密码
    private String JKS_PWD;

    //制作通讯证书时设置,若直接用AnXinSign_CertTool转换,则为anxinsign
    private String ALIAS;

    //账号注册成功时生成的,可登陆安心签测试页面查看或联系技术人员获取
    private String PLAT_ID;

    //公共接口地址
    private String url;

    //===============================上面的是公共的,不能为空的===============================

    //具体哪个接口
    private String uri;

    //合同下载到本地的公共地址
    private String downloadUrl;

    //设置到合同表的公共域名
    private String hetongUrl;

    //授权地点,客户平台将采集到的用户IP或所在地发送给安心签
    private String location;

    //签名域的标签值,创建合同接口的createContract参数下的signLocation
    private String signLocation;

    //安心签项目编号,创建合同接口(3201)的createContract参数下的signInfos中的projectCode
    private String projectCode3201;

    //签名域的标签值,创建合同接口的createContract参数下的signInfos中的signLocation
    private String signLocationBelow;

    //安心签项目编号,发送验证码接口(3101)的proxySign参数下的projectCode
    private String projectCode3101;

    //安心签项目编号,发送验证码接口(3102)的proxySign参数下的projectCode
    private String projectCode3102;

    //===============================3913接口相关 start===============================

    //签名域的标签值,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的signLocation
    private String signLocationBelow3913;

    //关键字,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的keywordInfo的keyword
    private String keyword3913;

    //关键字所在页,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的keywordInfo的pageNo
    private String pageNo3913;

    //关键字所在page页的索引,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的keywordInfo的indexInPage
    private String indexInPage3913;

    //X轴偏移坐标,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的keywordInfo的offsetX
    //单位为:磅,最大偏移量为200
    private String offsetX3913;

    //Y轴偏移坐标,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的keywordInfo的offsetY
    //单位为:磅,最大偏移量为200
    private String offsetY3913;

    //签章图片宽度,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的keywordInfo的width
    //最大为400px
    private String width3913;

    //签章图片高度,单一用户多合同H5签署接口的sendShortUrl参数下的contractInfos中的keywordInfo的height
    //最大为400px
    private String height3913;

    //===============================3913接口相关 end===============================

    //接口码
    private String txCode;
}

3. CFCAセーフサインリターンリザルトコード列挙型クラス

これは主に呼び出しインタフェースが成功したかどうかを判断するために使用され、失敗した場合は直接エラーをスローします。

/**
 * 安心签接口返回结果码
 *
 * @author:gan
 * @date: 2023-04-03 17:49
 */
public enum RetCodeEnum {
    
    
    CODE_60000000("60000000", "成功"),
    CODE_60030401("60030401", "已经开通代签权限");

    private String code;
    private String desc;

    RetCodeEnum(String code, String desc) {
    
    
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
    
    
        return code;
    }

    public void setCode(String code) {
    
    
        this.code = code;
    }

    public static String getDesc(String code) {
    
    
        for (RetCodeEnum value : values()) {
    
    
            if (value.getCode().equals(code)) {
    
    
                return value.desc;
            }
        }
        throw new RuntimeException("未知安心签返回结果码:" + code);
    }

    public String getDesc() {
    
    
        return desc;
    }

    public void setDesc(String desc) {
    
    
        this.desc = desc;
    }
}

4.インターフェースツールクラスを呼び出します(キーはこれです)

package org.jeecg.modules.anxinqian.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.VerifyUtil;
import org.jeecg.modules.anxinqian.constant.MIMEType;
import org.jeecg.modules.anxinqian.constant.Request;
import org.jeecg.modules.anxinqian.constant.SystemConst;
import org.jeecg.modules.anxinqian.dto.AnxinqianConfig;
import org.jeecg.modules.anxinqian.enums.RetCodeEnum;
import org.jeecg.modules.anxinqian.mapper.JsonObjectMapper;
import org.springframework.web.bind.annotation.RequestMethod;

import java.io.File;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 安心签工具类
 *
 * @author:user
 * @date: 2022-08-22 17:35
 */
@Slf4j
public class AnxinqianUtil {
    
    
    public static String JKS_PATH = "./jks/admin.jks";
    public static String JKS_PWD = "11111111";

    public static String url = "https://localhost:8443/FEP/";
    public static String channel = "Test";
    public static String keyStorePath = JKS_PATH;
    public static String keyStorePassword = JKS_PWD;

    private final static HttpClient httpClient = new HttpClient();

//    public void init() {
    
    
//        httpClient = new HttpClient();
//        httpClient.config.connectTimeout = connectTimeout;
//        httpClient.config.readTimeout = readTimeout;
//        httpClient.httpConfig.userAgent = "TrustSign FEP";
//        httpClient.httpConfig.contentType = MIMEType.FORM;
//        httpClient.httpConfig.accept = MIMEType.JSON;
//        try {
    
    
//            if (isSSL) {
    
    
//                httpClient.initSSL(keyStorePath, keyStorePassword.toCharArray(), trustStorePath, trustStorePassword.toCharArray());
//            }
//        } catch (Exception e) {
    
    
//            e.printStackTrace();
//        }
//        if (!url.endsWith("/")) {
    
    
//            url += "/";
//        }
//    }

    /**
     * 初始化方法
     * @param config
     */
    public static void init(AnxinqianConfig config) {
    
    
        httpClient.config.connectTimeout = 30000;
        httpClient.config.readTimeout = 10000;
        httpClient.httpConfig.userAgent = "TrustSign FEP";
        httpClient.httpConfig.contentType = MIMEType.FORM;
        httpClient.httpConfig.accept = MIMEType.JSON;
        try {
    
    
            getInterfUri(config);
            keyStorePath = config.getJKS_PATH();
            keyStorePassword = config.getJKS_PWD();
            httpClient.initSSL(keyStorePath, keyStorePassword.toCharArray(), keyStorePath, keyStorePassword.toCharArray());
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        url = config.getUrl();
        if (!url.endsWith("/")) {
    
    
            url += "/";
        }
    }

    /**
     * 发送安心签请求
     * @param config 安心签配置
     * @param requestParam  请求参数
     * @param map  其他参数
     */
    public static JSONObject sendRequest(AnxinqianConfig config, Object requestParam, Map<String, String> map) throws Exception {
    
    
        init(config);

        //处理请求参数
        JsonObjectMapper requestJsonObjectMapper = new JsonObjectMapper();
        String requestParamStr = requestJsonObjectMapper.writeValueAsString(requestParam);

        log.info("处理后请求参数:{}", JSON.toJSONString(requestParam, SerializerFeature.WriteNullStringAsEmpty));

        //这个应该是类似加密参数的操作
        String signature = SecurityUtil.p7SignMessageDetach(config.getJKS_PATH(), config.getJKS_PWD(), config.getALIAS(), requestParamStr);

        log.info("加密请求参数:{}", signature);

        return deal(config.getUri(), RequestMethod.POST.toString(), prepare(requestParamStr, signature, map));
    }

    /**
     * 发送安心签请求
     * @param config 安心签配置
     * @param requestParam  请求参数
     */
    public static JSONObject sendRequest(AnxinqianConfig config, Object requestParam) throws Exception {
    
    
        return sendRequest(config, requestParam, null);
    }

    /**
     * 发送安心签请求
     * @param config 安心签配置
     * @param data  请求参数
     * @param signature  环境参数加密
     * @param file  文件
     */
    public static void sendRequest(AnxinqianConfig config, String data, String signature, File file) throws Exception {
    
    
        init(config);

        deal(config.getUri(), RequestMethod.POST.toString(), data, file, signature);
    }

    /**
     * 获取请求路径uri
     * @param config 安心签配置
     */
    public static void getInterfUri(AnxinqianConfig config) {
    
    
        config.setUri("platId/" + config.getPLAT_ID() + "/txCode/" + config.getTxCode() + "/transaction");
    }

    /**
     * 获取下载合同uri
     * @param config 安心签配置
     * @param contractNo  合同号
     * @return
     */
    public static String getDownloadContractUri(AnxinqianConfig config, String contractNo) {
    
    
        return "platId/" + config.getPLAT_ID() + "/contractNo/" + contractNo.trim() + "/downloading";
    }

    public JSONObject post(String uri, String data, String signature) throws Exception {
    
    
        return deal(uri, "POST", prepare(data, signature, null));
    }

    public JSONObject post(String uri, String data, String signature, Map<String, String> map) throws Exception {
    
    
        return deal(uri, "POST", prepare(data, signature, map));
    }

    public String post(String uri, String data, String signature, File file) throws Exception {
    
    
        return deal(uri, "POST", data, file, signature);
    }

    //这是原来的getFile
//    public byte[] getFile(String uri) {
    
    
//        HttpURLConnection connection = null;
//        try {
    
    
//            connection = httpClient.connect(url + uri, "GET");
//            int responseCode = httpClient.send(connection, null);
//            System.out.println("responseCode:" + responseCode);
//            if (responseCode != 200) {
    
    
//                System.out.println(CommonUtil.getString(httpClient.receive(connection)));
//                return null;
//            }
//            return httpClient.receive(connection);
//        } catch (Exception e) {
    
    
//            e.printStackTrace();
//            return null;
//        } finally {
    
    
//            httpClient.disconnect(connection);
//        }
//    }

    //这是改造过的,下载合同用到
    public static byte[] getFile(AnxinqianConfig config, String uri) throws Exception{
    
    
        init(config);

        HttpURLConnection connection = httpClient.connect(url + uri, RequestMethod.GET.toString());

        int responseCode = httpClient.send(connection, null);
        log.info("响应码:{}", responseCode);

        return httpClient.receive(connection);
    }

    //这是原来的prepare方法
//    private String prepare(String data, String signature, Map<String, String> map) {
    
    
//        try {
    
    
//            StringBuilder request = new StringBuilder();
//            request.append(Request.CHANNEL).append("=").append(URLEncoder.encode(channel, SystemConst.DEFAULT_CHARSET));
//            if (CommonUtil.isNotEmpty(data)) {
    
    
//                request.append("&").append(Request.DATA).append("=").append(URLEncoder.encode(data, SystemConst.DEFAULT_CHARSET));
//            }
//            if (CommonUtil.isNotEmpty(signature)) {
    
    
//                request.append("&").append(Request.SIGNATURE).append("=").append(URLEncoder.encode(signature, SystemConst.DEFAULT_CHARSET));
//            }
//            if (CommonUtil.isNotEmpty(map)) {
    
    
//                for (Map.Entry<String, String> pair : map.entrySet()) {
    
    
//                    request.append("&").append(pair.getKey()).append("=")
//                            .append(pair.getValue() == null ? "" : URLEncoder.encode(pair.getValue(), SystemConst.DEFAULT_CHARSET));
//                }
//            }
//            return request.toString();
//        } catch (UnsupportedEncodingException e) {
    
    
//            return null;
//        }
//    }

    //这是改造过的prepare
    private static String prepare(String data, String signature, Map<String, String> map) throws Exception {
    
    
        StringBuilder request = new StringBuilder();
        request.append(Request.CHANNEL).append("=").append(URLEncoder.encode(channel, SystemConst.DEFAULT_CHARSET));
        if (CommonUtil.isNotEmpty(data)) {
    
    
            request.append("&").append(Request.DATA).append("=").append(URLEncoder.encode(data, SystemConst.DEFAULT_CHARSET));
        }
        if (CommonUtil.isNotEmpty(signature)) {
    
    
            request.append("&").append(Request.SIGNATURE).append("=").append(URLEncoder.encode(signature, SystemConst.DEFAULT_CHARSET));
        }
        if (CommonUtil.isNotEmpty(map)) {
    
    
            for (Map.Entry<String, String> pair : map.entrySet()) {
    
    
                request.append("&").append(pair.getKey()).append("=")
                        .append(pair.getValue() == null ? "" : URLEncoder.encode(pair.getValue(), SystemConst.DEFAULT_CHARSET));
            }
        }
        return request.toString();
    }

    //这是原来的deal方法
//    private String deal(String uri, String method, String request) {
    
    
//        HttpURLConnection connection = null;
//        try {
    
    
//            connection = httpClient.connect(url + uri, method);
//            System.out.println(url + uri);
//            System.out.println(method);
//            System.out.println(request);
//            int responseCode = httpClient.send(connection, request == null ? null : CommonUtil.getBytes(request));
//            System.out.println("responseCode:" + responseCode);
//            System.out.println(connection.getHeaderFields());
//            return CommonUtil.getString(httpClient.receive(connection));
//        } catch (Exception e) {
    
    
//            e.printStackTrace();
//            return e.getMessage();
//        } finally {
    
    
//            httpClient.disconnect(connection);
//        }
//    }

    /**
     * 处理http请求
     * @param uri
     * @param method
     * @param request
     * @return
     */
    private static JSONObject deal(String uri, String method, String request) throws Exception {
    
    
        HttpURLConnection connection = httpClient.connect(url + uri, method);

        log.info("请求地址:{}", url + uri);
        log.info("请求方法:{}", method);
        log.info("请求参数:{}", request);

        int responseCode = httpClient.send(connection, request == null ? null : CommonUtil.getBytes(request));

        log.info("响应码:{}", responseCode);
//        log.info("连接头部信息:{}", connection.getHeaderFields());

        JSONObject resultJson = JSONObject.parseObject(new String(httpClient.receive(connection), SystemConst.DEFAULT_CHARSET));
        log.info("返回结果:{}", resultJson);

        handleResult(resultJson);
        return resultJson;
    }

    //这是原来的deal方法
//    private String deal(String uri, String method, String request, File file, String signature) {
    
    
//        HttpURLConnection connection = null;
//        try {
    
    
//            connection = httpClient.connect(url + uri, method);
//            System.out.println(url + uri);
//            System.out.println(method);
//            System.out.println(request);
//            int responseCode = httpClient.send(connection, request == null ? null : request, file, signature);
//            System.out.println("responseCode:" + responseCode);
//            return CommonUtil.getString(httpClient.receive(connection));
//        } catch (Exception e) {
    
    
//            e.printStackTrace();
//            return e.getMessage();
//        } finally {
    
    
//            httpClient.disconnect(connection);
//        }
//    }

    //这是改造的deal方法
    private static String deal(String uri, String method, String request, File file, String signature) throws Exception {
    
    
        HttpURLConnection connection = httpClient.connect(url + uri, method);
        log.info("请求地址:{}", url + uri);
        log.info("请求方法:{}", method);
        log.info("请求参数:{}", request);

        int responseCode = httpClient.send(connection, request == null ? null : request, file, signature);
        log.info("响应码:{}", responseCode);

        return CommonUtil.getString(httpClient.receive(connection));
    }

    /**
     * 处理安心签返回结果(如果有错误就抛出)
     * @param resultJson
     * @return
     */
    private static void handleResult(JSONObject resultJson) {
    
    
        VerifyUtil.checkParam(resultJson, "安心签返回结果为空!");  //VerifyUtil是一个判空的类,之前的文章中有给出(https://blog.csdn.net/studio_1/article/details/123845497),也可以用自己的方式判空
        String errorCode = resultJson.getString("errorCode");
        if (VerifyUtil.isNotEmpty(errorCode)) {
    
    
            String errorMessage = resultJson.getString("errorMessage");
            if (RetCodeEnum.CODE_60030401.getCode().equals(errorCode)) {
    
    
                log.info("errorMessage:{}", errorMessage);

                return;  //报这个错可以结束方法,返回错误码给前端
            }

            throw new RuntimeException(errorMessage);
        }


        JSONObject head = resultJson.getJSONObject("head");
        if (!RetCodeEnum.CODE_60000000.getCode().equals(head.getString("retCode")))  //60000000表示成功
            throw new RuntimeException(head.getString("retMessage"));
    }
}

おすすめ

転載: blog.csdn.net/studio_1/article/details/130159193