import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.ConcurrentModificationException;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.NoSuchPaddingException;
 import javax.crypto.spec.GCMParameterSpec;
 import javax.crypto.spec.SecretKeySpec;import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.type.TypeFactory;/**
  * l 网络游戏防沉迷实名认证系统一键完成测试样例<br>
  * 1、首先登录【网络游戏防沉迷实名认证系统】后台:https://wlc.nppa.gov.cn/fcm_company/index.html#/interface/test<br>
  * 2、【数据共享】-》【接口测试】-》【预置参数】【修改】IP白名单为你的网络出口ip,(这块我找it要的)<br>
  * 3、【数据共享】-》【接口测试】-》【预置参数】获得 应用标识(APPID)、游戏备案识别码(bizId)、用户密钥(Secret Key)<br>
  * 4、【数据共享】-》【接口测试】-》【测试用例】操作各个测试用例【开始测试】,分别获取对应的【测试码】填写到代码测试码集中去
  * 5、直接本地跑main方法
  * @author Omanhom
  *
  */
 public class TestCase4Nppa {
     // 应用标识(APPID)
     static String appId = "";
     // 游戏备案识别码(bizId)
     static String bizId = "";
     // 用户密钥(Secret Key)
     static String secretKey = "";
     static Map<String, String> testCodeMap = new HashMap<String, String>();// 测试码集
     static {
         testCodeMap.put("testcase01", "");
         testCodeMap.put("testcase02", "");
         testCodeMap.put("testcase03", "");
         testCodeMap.put("testcase04", "");
         testCodeMap.put("testcase05", "");
         testCodeMap.put("testcase06", "");
         testCodeMap.put("testcase07", "");
         testCodeMap.put("testcase08", "");
     }    static ObjectMapper mapper = new ObjectMapper();
    public static void main(String args[]) {
         testcase01();
         testcase02();
         testcase03();
         testcase04();
         testcase05();
         testcase06();
         testcase07();
         testcase08();
     }    /**
      * testcase01-实名认证接口-认证成功
      */
     protected static void testcase01() {
         String testCase01Code = testCodeMap.get("testcase01");
         String result = null;
         String testcase01 = "{\"ai\":\"100000000000000001\",\"name\":\"某一一\",\"idNum\":\"110000190101010001\"}";
         result = TestCase4Nppa.doPostCheck(testCase01Code, TestCase4Nppa.toMap(testcase01));
         System.out.println("==================testcase01-实名认证接口:" + result);
     }    /**
      * testcase02-实名认证接口-认证中
      */
     protected static void testcase02() {
         String testCase02Code = testCodeMap.get("testcase02");
         String result = null;
         String testcase02 = "{\"ai\":\"200000000000000001\",\"name\":\"某二一\",\"idNum\":\"110000190201010009\"}";
         result = TestCase4Nppa.doPostCheck(testCase02Code, TestCase4Nppa.toMap(testcase02));
         System.out.println("==================testcase02-实名认证接口:" + result);
     }    /**
      * testcase03-实名认证接口-认证失败
      */
     protected static void testcase03() {
         String testCase03Code = testCodeMap.get("testcase03");
         String result = null;
         while (true) {
             String testcase03 = "{\"ai\":\"200000000000000008\",\"name\":\"岑程文\",\"idNum\":\"421023199012080656\"}";
             result = TestCase4Nppa.doPostCheck(testCase03Code, TestCase4Nppa.toMap(testcase03));
             System.out.println("==================testcase03-实名认证接口:" + result);
             JsonNode jn = toJsonNode(result);
             if (jn != null && jn.get("errcode").asInt() == 0)
                 break;
         }
     }    /**
      * testcase04-实名认证结果查询接口-认证成功
      */
     protected static void testcase04() {
         String testCase04Code = testCodeMap.get("testcase04");
         String result = null;
         result = TestCase4Nppa.doGetQuery(testCase04Code, "100000000000000001");
         System.out.println("==================testcase04-实名认证结果查询接口:" + result);
     }    /**
      * testcase05-实名认证结果查询接口-认证失败
      */
     protected static void testcase05() {
         String testCase05Code = testCodeMap.get("testcase05");
         String result = null;
         result = TestCase4Nppa.doGetQuery(testCase05Code, "200000000000000001");
         System.out.println("==================testcase05-实名认证结果查询接口:" + result);
     }    /**
      * testcase06-实名认证结果查询接口-认证中
      */
     protected static void testcase06() {
         String testCase06Code = testCodeMap.get("testcase06");
         String result = null;
         while (true) {
             result = TestCase4Nppa.doGetQuery(testCase06Code, "300000000000000001");
             System.out.println("==================testcase06-实名认证结果查询接口:" + result);
             JsonNode jn = toJsonNode(result);
             if (jn != null && jn.get("errcode").asInt() == 0)
                 break;
         }
     }    /**
      * testcase07-游戏用户行为数据上报接口-模拟“游客模式”下游戏用户行为数据上报场景,调用测试系统中的游戏用户行为数据上报接口;如果测试系统返回“上报成功”则通过测试
      */
     protected static void testcase07() {
         String testCase07Code = testCodeMap.get("testcase07");
         String result = null;
         Map<String, Object> userData = new HashMap<String, Object>();
         userData.put("no", 1);// [条目编码]在批量模式中标识一条行为数据,取值范围 1-128
         userData.put("si", "95edkzei5exh47pk0z2twm6zpielesrd");// [游戏内部会话标识]一个会话标识只能对应唯一的实名用户,一个实名用户可以拥有多个会话标识;同一用户单次游戏会话中,上下线动作必须使用同一会话标识上报备注:会话标识仅标识一次用户会话,生命周期仅为一次上线和与之匹配的一次下线,不会对生命周期之外的任何业务有任何影响
         userData.put("bt", 0);// [用户行为类型]游戏用户行为类型0:下线,1:上线
         userData.put("ot", System.currentTimeMillis() / 1000);// [行为发生时间]行为发生时间戳,单位秒,
         userData.put("ct", 2);// [上报类型]用户行为数据上报类型,0:已认证通过用户,2:游客用户
         userData.put("di", "ecvndx6r6xfwofmufs3lbimcr639r33t");// [设备标识]游客模式设备标识,由游戏运营单位生成,游客用户下必填
         List<Map<String, Object>> coreLists = new ArrayList<Map<String, Object>>();
         coreLists.add(userData);
         Map<String, Object> testData = new HashMap<String, Object>();
         testData.put("collections", coreLists);
         result = doPostLoginout(testCase07Code, testData);
         System.out.println("==================testcase07-游戏用户行为数据上报接口:" + result);
     }    /**
      * testcase08-游戏用户行为数据上报接口-模拟“已认证”游戏用户的行为数据上报场景,调用测试系统中的游戏用户行为数据上报接口;如果测试系统返回“上报成功”则通过测试
      */
     protected static void testcase08() {
         String testCase08Code = testCodeMap.get("testcase08");
         String result = null;
         Map<String, Object> userData = new HashMap<String, Object>();
         userData.put("no", 1);// [条目编码]在批量模式中标识一条行为数据,取值范围 1-128
         userData.put("si", "95edkzei5exh47pk0z2twm6zpielesrd");// [游戏内部会话标识]一个会话标识只能对应唯一的实名用户,一个实名用户可以拥有多个会话标识;同一用户单次游戏会话中,上下线动作必须使用同一会话标识上报备注:会话标识仅标识一次用户会话,生命周期仅为一次上线和与之匹配的一次下线,不会对生命周期之外的任何业务有任何影响
         userData.put("bt", 0);// [用户行为类型]游戏用户行为类型0:下线,1:上线
         userData.put("ot", System.currentTimeMillis() / 1000);// [行为发生时间]行为发生时间戳,单位秒,
         userData.put("ct", 0);// [上报类型]用户行为数据上报类型,0:已认证通过用户,2:游客用户
         userData.put("di", "ecvndx6r6xfwofmufs3lbimcr639r33t");// [设备标识]游客模式设备标识,由游戏运营单位生成,游客用户下必填
         userData.put("pi", "1fffbjzos82bs9cnyj1dna7d6d29zg4esnh99u");// [用户唯一标识]已通过实名认证用户的唯一标识,已认证通过用户必填
         List<Map<String, Object>> coreLists = new ArrayList<Map<String, Object>>();
         coreLists.add(userData);
         Map<String, Object> testData = new HashMap<String, Object>();
         testData.put("collections", coreLists);
         result = doPostLoginout(testCase08Code, testData);
         System.out.println("==================testcase08-游戏用户行为数据上报接口:" + result);
     }    public static String doPostCheck(String testCode, Map<String, Object> paramMap) {
         String url = "https://wlc.nppa.gov.cn/test/authentication/check/" + testCode;
         long nowTime = System.currentTimeMillis();
         String content = toString(paramMap);
         System.out.println(content);        // 1.3 处理密钥(将16进制字符串密钥转换为byte数组)
         byte[] keyBytes = hexStringToByte(secretKey);
         // 2 业务参数加密(AES-128/GCM + BASE64算法加密)计算
         String encryptStr = aesGcmEncrypt(content, keyBytes);
         // System.out.println("业务参数解密结果:" + aesGcmDecrypt(encryptStr, keyBytes));        String str = "";
         Map<String, String> signMap = new TreeMap<String, String>();
         signMap.put("appId", appId);
         signMap.put("bizId", bizId);
         signMap.put("timestamps", "" + nowTime);
         for (Map.Entry<String, String> entry : signMap.entrySet()) {
             str += entry.getKey() + entry.getValue();
         }
         // 3 签名
         /*
          * 签名规则:1 将除去sign的系统参数和除去请求体外的业务参数,根据参数的key进行字典排序,并按照Key-Value的格式拼接成一个字符串。将请求体中的参数拼接在字符串最后。 2 将secretKey拼接在步骤1获得字符串最前面,得到待加密字符串。 3 使用SHA256算法对待加密字符串进行计算,得到数据签名。 4 将得到的数据签名赋值给系统参数sign。
          */
         // 3.1 拼接待签名字符串(下方示例代码中相应字符串均为写死,仅用于参考拼接流程,具体请参照实际接口参数)
         StringBuilder sb = new StringBuilder();
         // 3.1.1 拼接密钥
         sb.append(secretKey);
         // 3.1.2 拼接除去sign的系统参数和除去请求体外的业务参数(含请求URL中的参数,例如get请求。注意需要字典排序)
         sb.append(str);
         // 3.1.3 拼接请求体(保持json字符串格式,data对应的值应为上方加密算法计算出的encryptStr加密字符串)
         sb.append("{\"data\":\"" + encryptStr + "\"}");
         String toBeSignStr = sb.toString();
         System.out.println("待签名字符串:" + toBeSignStr);        // 3.1 签名计算(SHA256)
         String sign;
         try {
             sign = sign(toBeSignStr);
             System.out.println("签名结果:" + sign);
         } catch (NoSuchAlgorithmException e) {
             System.out.println("签名失败");
             e.printStackTrace();
             return "";
         }        CloseableHttpClient httpClient = null;
         CloseableHttpResponse httpResponse = null;
         String result = "";
         // 创建httpClient实例
         httpClient = HttpClients.createDefault();
         // 创建httpPost远程连接实例
         HttpPost httpPost = new HttpPost(url);
         // 配置请求参数实例
         RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)// 设置连接主机服务超时时间
                 .setConnectionRequestTimeout(5000)// 设置连接请求超时时间
                 .setSocketTimeout(5000)// 设置读取数据连接超时时间
                 .build();
         // 为httpPost实例设置配置
         httpPost.setConfig(requestConfig);
         // 设置请求头
         httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
         httpPost.addHeader("appId", signMap.get("appId"));
         httpPost.addHeader("bizId", signMap.get("bizId"));
         httpPost.addHeader("timestamps", signMap.get("timestamps"));
         httpPost.addHeader("sign", sign);        // 封装post请求参数
         if (null != paramMap && paramMap.size() > 0) {
             // 为httpPost设置封装好的请求参数
             try {
                 // httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
                 // httpPost.setEntity(new StringEntity("你的json串"));
                 httpPost.setEntity(new StringEntity("{\"data\":\"" + encryptStr + "\"}"));
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
         }
         try {
             System.out.println(httpPost.toString());
             // httpClient对象执行post请求,并返回响应参数对象
             httpResponse = httpClient.execute(httpPost);
             // 从响应对象中获取响应内容
             HttpEntity entity = httpResponse.getEntity();
             result = EntityUtils.toString(entity);
         } catch (ClientProtocolException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             // 关闭资源
             if (null != httpResponse) {
                 try {
                     httpResponse.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
             if (null != httpClient) {
                 try {
                     httpClient.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
         }
         return result;
     }    public static String doGetQuery(String testCode, String ai) {
         String params = "ai=" + ai;
         System.out.println(params);
         String url = "https://wlc.nppa.gov.cn/test/authentication/query/" + testCode;        long nowTime = System.currentTimeMillis();
         String str = "";
         Map<String, String> signMap = new TreeMap<String, String>();
         signMap.put("appId", appId);
         signMap.put("bizId", bizId);
         signMap.put("timestamps", "" + nowTime);
         for (Map.Entry<String, String> entry : signMap.entrySet()) {
             str += entry.getKey() + entry.getValue();
         }
         // 3 签名
         /*
          * 签名规则:1 将除去sign的系统参数和除去请求体外的业务参数,根据参数的key进行字典排序,并按照Key-Value的格式拼接成一个字符串。将请求体中的参数拼接在字符串最后。 2 将secretKey拼接在步骤1获得字符串最前面,得到待加密字符串。 3 使用SHA256算法对待加密字符串进行计算,得到数据签名。 4 将得到的数据签名赋值给系统参数sign。
          */
         // 3.1 拼接待签名字符串(下方示例代码中相应字符串均为写死,仅用于参考拼接流程,具体请参照实际接口参数)
         StringBuilder sb = new StringBuilder();
         // 3.1.1 拼接密钥
         sb.append(secretKey);
         sb.append("ai" + ai);
         sb.append(str);
         String toBeSignStr = sb.toString();
         System.out.println("待签名字符串:" + toBeSignStr);        // 3.1 签名计算(SHA256)
         String sign;
         try {
             sign = sign(toBeSignStr);
             System.out.println("签名结果:" + sign);
         } catch (NoSuchAlgorithmException e) {
             System.out.println("签名失败");
             e.printStackTrace();
             return "";
         }        CloseableHttpClient httpClient = null;
         CloseableHttpResponse httpResponse = null;
         String result = "";
         // 创建httpClient实例
         httpClient = HttpClients.createDefault();        HttpGet httpGet = new HttpGet(url + "?" + params);
         // 配置请求参数实例
         RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)// 设置连接主机服务超时时间
                 .setConnectionRequestTimeout(5000)// 设置连接请求超时时间
                 .setSocketTimeout(5000)// 设置读取数据连接超时时间
                 .build();
         // 为httpGet实例设置配置
         httpGet.setConfig(requestConfig);
         // 设置请求头
         httpGet.addHeader("appId", signMap.get("appId"));
         httpGet.addHeader("bizId", signMap.get("bizId"));
         httpGet.addHeader("timestamps", signMap.get("timestamps"));
         httpGet.addHeader("sign", sign);        try {
             System.out.println(httpGet.toString());
             // httpClient对象执行post请求,并返回响应参数对象
             httpResponse = httpClient.execute(httpGet);
             // 从响应对象中获取响应内容
             HttpEntity entity = httpResponse.getEntity();
             result = EntityUtils.toString(entity);
         } catch (ClientProtocolException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             // 关闭资源
             if (null != httpResponse) {
                 try {
                     httpResponse.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
             if (null != httpClient) {
                 try {
                     httpClient.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
         }
         return result;
     }    public static String doPostLoginout(String testCode, Map<String, Object> paramMap) {
         String url = "https://wlc.nppa.gov.cn/test/collection/loginout/" + testCode;
         long nowTime = new Date().getTime();
         String content = toString(paramMap);
         System.out.println(content);        // 1.3 处理密钥(将16进制字符串密钥转换为byte数组)
         byte[] keyBytes = hexStringToByte(secretKey);
         // 2 业务参数加密(AES-128/GCM + BASE64算法加密)计算
         String encryptStr = aesGcmEncrypt(content, keyBytes);
         // System.out.println("业务参数解密结果:" + aesGcmDecrypt(encryptStr, keyBytes));        String str = "";
         Map<String, String> signMap = new TreeMap<String, String>();
         signMap.put("appId", appId);
         signMap.put("bizId", bizId);
         signMap.put("timestamps", "" + nowTime);
         for (Map.Entry<String, String> entry : signMap.entrySet()) {
             str += entry.getKey() + entry.getValue();
         }
         // 3 签名
         /*
          * 签名规则:1 将除去sign的系统参数和除去请求体外的业务参数,根据参数的key进行字典排序,并按照Key-Value的格式拼接成一个字符串。将请求体中的参数拼接在字符串最后。 2 将secretKey拼接在步骤1获得字符串最前面,得到待加密字符串。 3 使用SHA256算法对待加密字符串进行计算,得到数据签名。 4 将得到的数据签名赋值给系统参数sign。
          */
         // 3.1 拼接待签名字符串(下方示例代码中相应字符串均为写死,仅用于参考拼接流程,具体请参照实际接口参数)
         StringBuilder sb = new StringBuilder();
         // 3.1.1 拼接密钥
         sb.append(secretKey);
         // 3.1.2 拼接除去sign的系统参数和除去请求体外的业务参数(含请求URL中的参数,例如get请求。注意需要字典排序)
         sb.append(str);
         // 3.1.3 拼接请求体(保持json字符串格式,data对应的值应为上方加密算法计算出的encryptStr加密字符串)
         sb.append("{\"data\":\"" + encryptStr + "\"}");
         String toBeSignStr = sb.toString();
         System.out.println("待签名字符串:" + toBeSignStr);        // 3.1 签名计算(SHA256)
         String sign;
         try {
             sign = sign(toBeSignStr);
             System.out.println("签名结果:" + sign);
         } catch (NoSuchAlgorithmException e) {
             System.out.println("签名失败");
             e.printStackTrace();
             return "";
         }        CloseableHttpClient httpClient = null;
         CloseableHttpResponse httpResponse = null;
         String result = "";
         // 创建httpClient实例
         httpClient = HttpClients.createDefault();
         // 创建httpPost远程连接实例
         HttpPost httpPost = new HttpPost(url);
         // 配置请求参数实例
         RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)// 设置连接主机服务超时时间
                 .setConnectionRequestTimeout(5000)// 设置连接请求超时时间
                 .setSocketTimeout(5000)// 设置读取数据连接超时时间
                 .build();
         // 为httpPost实例设置配置
         httpPost.setConfig(requestConfig);
         // 设置请求头
         httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
         httpPost.addHeader("appId", signMap.get("appId"));
         httpPost.addHeader("bizId", signMap.get("bizId"));
         httpPost.addHeader("timestamps", signMap.get("timestamps"));
         httpPost.addHeader("sign", sign);        // 封装post请求参数
         if (null != paramMap && paramMap.size() > 0) {
             // 为httpPost设置封装好的请求参数
             try {
                 httpPost.setEntity(new StringEntity("{\"data\":\"" + encryptStr + "\"}"));
             } catch (UnsupportedEncodingException e) {
                 e.printStackTrace();
             }
         }
         try {
             System.out.println(httpPost.toString());
             // httpClient对象执行post请求,并返回响应参数对象
             httpResponse = httpClient.execute(httpPost);
             // 从响应对象中获取响应内容
             HttpEntity entity = httpResponse.getEntity();
             result = EntityUtils.toString(entity);
         } catch (ClientProtocolException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             // 关闭资源
             if (null != httpResponse) {
                 try {
                     httpResponse.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
             if (null != httpClient) {
                 try {
                     httpClient.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
         }
         return result;
     }    /**
      * <p>
      * 
      * @title sign
      *        </p>
      *        <p>
      * @description 签名
      *              </p>
      *
      * @param toBeSignStr
      *            待签名字符串
      * @return java.lang.String
      */
     private static String sign(String toBeSignStr) throws NoSuchAlgorithmException {
         MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
         messageDigest.update(toBeSignStr.getBytes(UTF_8));
         return byteToHexString(messageDigest.digest());
     }    /**
      * <p>
      * 
      * @title aesGcmEncrypt
      *        </p>
      *        <p>
      * @description Aes-Gcm加密
      *              </p>
      *
      * @param content
      *            待加密文本
      * @param key
      *            密钥
      * @return java.lang.String
      */
     private static String aesGcmEncrypt(String content, byte[] key) {
         try {
             // 根据指定算法ALGORITHM自成密码器
             Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
             SecretKeySpec skey = new SecretKeySpec(key, "AES");
             cipher.init(Cipher.ENCRYPT_MODE, skey);
             // 获取向量
             byte[] ivb = cipher.getIV();
             byte[] encodedByteArray = cipher.doFinal(content.getBytes(UTF_8));
             byte[] message = new byte[ivb.length + encodedByteArray.length];
             System.arraycopy(ivb, 0, message, 0, ivb.length);
             System.arraycopy(encodedByteArray, 0, message, ivb.length, encodedByteArray.length);
             return Base64.getEncoder().encodeToString(message);
         } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
             // 建议自行调整为日志输出或抛出异常
             return null;
         }
     }    /**
      * <p>
      * 
      * @title aesGcmDecrypt
      *        </p>
      *        <p>
      * @description Aes-Gcm解密
      *              </p>
      *
      * @param content
      *            带解密文本
      * @param key
      *            密钥
      * @return java.lang.String
      */
     private static String aesGcmDecrypt(String content, byte[] key) {
         try {
             // 根据指定算法ALGORITHM自成密码器
             Cipher decryptCipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
             SecretKeySpec skey = new SecretKeySpec(key, "AES");
             byte[] encodedArrayWithIv = Base64.getDecoder().decode(content);
             GCMParameterSpec decryptSpec = new GCMParameterSpec(128, encodedArrayWithIv, 0, 12);
             decryptCipher.init(Cipher.DECRYPT_MODE, skey, decryptSpec);
             byte[] b = decryptCipher.doFinal(encodedArrayWithIv, 12, encodedArrayWithIv.length - 12);
             return new String(b, UTF_8);
         } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
             // 建议自行调整为日志输出或抛出异常
             return null;
         }
     }    /**
      * <p>
      * 
      * @title byteToHexString
      *        </p>
      *        <p>
      * @description byte数组转化为16进制字符串
      *              </p>
      *
      * @param bytes
      *            byte数组
      * @return java.lang.String
      */
     private static String byteToHexString(byte[] bytes) {
         StringBuilder sb = new StringBuilder();
         for (byte aByte : bytes) {
             String strHex = Integer.toHexString(aByte);
             if (strHex.length() > 3) {
                 sb.append(strHex.substring(6));
             } else {
                 if (strHex.length() < 2) {
                     sb.append("0").append(strHex);
                 } else {
                     sb.append(strHex);
                 }
             }
         }
         return sb.toString();
     }    /**
      * <p>
      * 
      * @title hexStringToByte
      *        </p>
      *        <p>
      * @description 十六进制string转二进制byte[]
      *              </p>
      *
      * @param str
      *            十六进制字符串
      * @return byte[]
      */
     private static byte[] hexStringToByte(String str) {
         byte[] baKeyword = new byte[str.length() / 2];
         for (int i = 0; i < baKeyword.length; i++) {
             try {
                 baKeyword[i] = (byte) (0xff & Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16));
             } catch (Exception e) {
                 // 建议自行调整为日志输出或抛出异常
                 e.printStackTrace();
             }
         }
         return baKeyword;
     }    private static String toString(Object object) {
         if (object == null) {
             return null;
         } else {
             try {
                 return mapper.writeValueAsString(object);
             } catch (ConcurrentModificationException arg2) {
                 arg2.printStackTrace();
                 return null;
             } catch (Exception arg3) {
                 arg3.printStackTrace();
                 return null;
             }
         }
     }    @SuppressWarnings("unchecked")
     private static Map<String, Object> toMap(String content) {
         if (StringUtils.isBlank(content)) {
             return null;
         } else {
             try {
                 return (Map<String, Object>) mapper.readValue(content, TypeFactory.defaultInstance().constructMapType(Map.class, String.class, Object.class));
             } catch (Exception arg2) {
                 arg2.printStackTrace();
                 return null;
             }
         }
     }    private static JsonNode toJsonNode(String content) {
         if (StringUtils.isBlank(content))
             return null;
         JsonFactory factory = mapper.getFactory();
         JsonNode actualObj = null;
         try {
             JsonParser e = factory.createParser(content);
             actualObj = (JsonNode) mapper.readTree(e);
         } catch (Exception arg3) {
             arg3.printStackTrace();
         }
         return actualObj;
     }
 }