فهرست منبع

fix 修改 wx-java-cp

Young 2 سال پیش
والد
کامیت
b17a4946a9
47فایلهای تغییر یافته به همراه432 افزوده شده و 462 حذف شده
  1. 1 1
      wx-java-tools/wx-java-common/src/main/java/cn/nosum/wx/common/utils/crypto/SHA1.java
  2. 231 231
      wx-java-tools/wx-java-common/src/main/java/cn/nosum/wx/common/utils/crypto/WxCryptUtil.java
  3. 4 4
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/WxCpChatService.java
  4. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/WxCpOaService.java
  5. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/WxCpDepart.java
  6. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/WxCpTag.java
  7. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/WxCpUser.java
  8. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/external/WxCpContactWayInfo.java
  9. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/message/WxCpMessage.java
  10. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/message/WxCpXmlMessage.java
  11. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/message/WxCpXmlOutMessage.java
  12. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/FileBuilder.java
  13. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/ImageBuilder.java
  14. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/NewsBuilder.java
  15. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/TextBuilder.java
  16. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/VideoBuilder.java
  17. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/VoiceBuilder.java
  18. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalApplier.java
  19. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalApplyData.java
  20. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalComment.java
  21. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalDetail.java
  22. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalDetailResult.java
  23. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalInfo.java
  24. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalInfoQueryFilter.java
  25. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalRecord.java
  26. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalRecordDetail.java
  27. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApproverAttr.java
  28. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpCheckinData.java
  29. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpOperator.java
  30. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpRecordSpStatus.java
  31. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpSpStatus.java
  32. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/applydata/ApplyDataContent.java
  33. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/applydata/ContentTitle.java
  34. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/applydata/ContentValue.java
  35. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/ImageBuilder.java
  36. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/NewsBuilder.java
  37. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/TextBuilder.java
  38. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/VideoBuilder.java
  39. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/VoiceBuilder.java
  40. 1 0
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/crypto/WxCpCryptUtil.java
  41. 40 48
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpChatGsonAdapter.java
  42. 106 106
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpConclusionAdapter.java
  43. 2 9
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpDepartGsonAdapter.java
  44. 1 1
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpGsonBuilder.java
  45. 6 8
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpMenuGsonAdapter.java
  46. 2 9
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpTagGsonAdapter.java
  47. 2 9
      wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpUserGsonAdapter.java

+ 1 - 1
wx-java-tools/wx-java-common/src/main/java/cn/nosum/wx/common/utils/crypto/SHA1.java

@@ -7,7 +7,7 @@ import java.util.Arrays;
 
 /**
  *
- * @author Daniel Qian
+ * @author Young
  */
 public class SHA1 {
 

+ 231 - 231
wx-java-tools/wx-java-common/src/main/java/cn/nosum/wx/common/utils/crypto/WxCryptUtil.java

@@ -32,250 +32,250 @@ import java.util.Random;
  */
 public class WxCryptUtil {
 
-  private static final Base64 BASE64 = new Base64();
-  private static final Charset CHARSET = StandardCharsets.UTF_8;
-
-  private static final ThreadLocal<DocumentBuilder> BUILDER_LOCAL = ThreadLocal.withInitial(() -> {
-    try {
-      final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-      factory.setExpandEntityReferences(false);
-      factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
-      return factory.newDocumentBuilder();
-    } catch (ParserConfigurationException exc) {
-      throw new IllegalArgumentException(exc);
+    private static final Base64 BASE64 = new Base64();
+    private static final Charset CHARSET = StandardCharsets.UTF_8;
+
+    private static final ThreadLocal<DocumentBuilder> BUILDER_LOCAL = ThreadLocal.withInitial(() -> {
+        try {
+            final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setExpandEntityReferences(false);
+            factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+            return factory.newDocumentBuilder();
+        } catch (ParserConfigurationException exc) {
+            throw new IllegalArgumentException(exc);
+        }
+    });
+
+    protected byte[] aesKey;
+    protected String token;
+    protected String appidOrCorpid;
+
+    public WxCryptUtil() {
     }
-  });
-
-  protected byte[] aesKey;
-  protected String token;
-  protected String appidOrCorpid;
-
-  public WxCryptUtil() {
-  }
-
-  /**
-   * 构造函数.
-   *
-   * @param token          公众平台上,开发者设置的token
-   * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
-   * @param appidOrCorpid  公众平台appid/corpid
-   */
-  public WxCryptUtil(String token, String encodingAesKey, String appidOrCorpid) {
-    this.token = token;
-    this.appidOrCorpid = appidOrCorpid;
-    this.aesKey = Base64.decodeBase64(CharMatcher.whitespace().removeFrom(encodingAesKey));
-  }
-
-  private static String extractEncryptPart(String xml) {
-    try {
-      DocumentBuilder db = BUILDER_LOCAL.get();
-      Document document = db.parse(new InputSource(new StringReader(xml)));
-
-      Element root = document.getDocumentElement();
-      return root.getElementsByTagName("Encrypt").item(0).getTextContent();
-    } catch (Exception e) {
-      throw new WxRuntimeException(e);
-    }
-  }
-
-  /**
-   * 将一个数字转换成生成4个字节的网络字节序bytes数组.
-   */
-  private static byte[] number2BytesInNetworkOrder(int number) {
-    byte[] orderBytes = new byte[4];
-    orderBytes[3] = (byte) (number & 0xFF);
-    orderBytes[2] = (byte) (number >> 8 & 0xFF);
-    orderBytes[1] = (byte) (number >> 16 & 0xFF);
-    orderBytes[0] = (byte) (number >> 24 & 0xFF);
-    return orderBytes;
-  }
-
-  /**
-   * 4个字节的网络字节序bytes数组还原成一个数字.
-   */
-  private static int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) {
-    int sourceNumber = 0;
-    for (int i = 0; i < 4; i++) {
-      sourceNumber <<= 8;
-      sourceNumber |= bytesInNetworkOrder[i] & 0xff;
-    }
-    return sourceNumber;
-  }
-
-  /**
-   * 随机生成16位字符串.
-   */
-  private static String genRandomStr() {
-    String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-    Random random = new Random();
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < 16; i++) {
-      int number = random.nextInt(base.length());
-      sb.append(base.charAt(number));
+
+    /**
+     * 构造函数.
+     *
+     * @param token          公众平台上,开发者设置的token
+     * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
+     * @param appidOrCorpid  公众平台appid/corpid
+     */
+    public WxCryptUtil(String token, String encodingAesKey, String appidOrCorpid) {
+        this.token = token;
+        this.appidOrCorpid = appidOrCorpid;
+        this.aesKey = Base64.decodeBase64(CharMatcher.whitespace().removeFrom(encodingAesKey));
     }
-    return sb.toString();
-  }
-
-  /**
-   * 生成xml消息.
-   *
-   * @param encrypt   加密后的消息密文
-   * @param signature 安全签名
-   * @param timestamp 时间戳
-   * @param nonce     随机字符串
-   * @return 生成的xml字符串
-   */
-  private static String generateXml(String encrypt, String signature, String timestamp, String nonce) {
-    String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
-      + "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
-      + "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n"
-      + "</xml>";
-    return String.format(format, encrypt, signature, timestamp, nonce);
-  }
-
-  /**
-   * 将公众平台回复用户的消息加密打包.
-   * <ol>
-   * <li>对要发送的消息进行AES-CBC加密</li>
-   * <li>生成安全签名</li>
-   * <li>将消息密文和安全签名打包成xml格式</li>
-   * </ol>
-   *
-   * @param plainText 公众平台待回复用户的消息,xml格式的字符串
-   * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
-   */
-  public String encrypt(String plainText) {
-    // 加密
-    String encryptedXml = encrypt(genRandomStr(), plainText);
-
-    // 生成安全签名
-    String timeStamp = Long.toString(System.currentTimeMillis() / 1000L);
-    String nonce = genRandomStr();
-
-    String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml);
-    return generateXml(encryptedXml, signature, timeStamp, nonce);
-  }
-
-  /**
-   * 对明文进行加密.
-   *
-   * @param plainText 需要加密的明文
-   * @return 加密后base64编码的字符串
-   */
-  public String encrypt(String randomStr, String plainText) {
-    ByteGroup byteCollector = new ByteGroup();
-    byte[] randomStringBytes = randomStr.getBytes(CHARSET);
-    byte[] plainTextBytes = plainText.getBytes(CHARSET);
-    byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(plainTextBytes.length);
-    byte[] appIdBytes = this.appidOrCorpid.getBytes(CHARSET);
-
-    // randomStr + networkBytesOrder + text + appid
-    byteCollector.addBytes(randomStringBytes);
-    byteCollector.addBytes(bytesOfSizeInNetworkOrder);
-    byteCollector.addBytes(plainTextBytes);
-    byteCollector.addBytes(appIdBytes);
-
-    // ... + pad: 使用自定义的填充方式对明文进行补位填充
-    byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
-    byteCollector.addBytes(padBytes);
-
-    // 获得最终的字节流, 未加密
-    byte[] unencrypted = byteCollector.toBytes();
-
-    try {
-      // 设置加密模式为AES的CBC模式
-      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
-      SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
-      IvParameterSpec iv = new IvParameterSpec(this.aesKey, 0, 16);
-      cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
-
-      // 加密
-      byte[] encrypted = cipher.doFinal(unencrypted);
-
-      // 使用BASE64对加密后的字符串进行编码
-      return BASE64.encodeToString(encrypted);
-    } catch (Exception e) {
-      throw new WxRuntimeException(e);
+
+    private static String extractEncryptPart(String xml) {
+        try {
+            DocumentBuilder db = BUILDER_LOCAL.get();
+            Document document = db.parse(new InputSource(new StringReader(xml)));
+
+            Element root = document.getDocumentElement();
+            return root.getElementsByTagName("Encrypt").item(0).getTextContent();
+        } catch (Exception e) {
+            throw new WxRuntimeException(e);
+        }
     }
-  }
-
-  /**
-   * 检验消息的真实性,并且获取解密后的明文.
-   * <ol>
-   * <li>利用收到的密文生成安全签名,进行签名验证</li>
-   * <li>若验证通过,则提取xml中的加密消息</li>
-   * <li>对消息进行解密</li>
-   * </ol>
-   *
-   * @param msgSignature 签名串,对应URL参数的msg_signature
-   * @param timeStamp    时间戳,对应URL参数的timestamp
-   * @param nonce        随机串,对应URL参数的nonce
-   * @param encryptedXml 密文,对应POST请求的数据
-   * @return 解密后的原文
-   */
-  public String decrypt(String msgSignature, String timeStamp, String nonce, String encryptedXml) {
-    // 密钥,公众账号的app corpSecret
-    // 提取密文
-    String cipherText = extractEncryptPart(encryptedXml);
-
-    // 验证安全签名
-    String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText);
-    if (!signature.equals(msgSignature)) {
-      throw new WxRuntimeException("加密消息签名校验失败");
+
+    /**
+     * 将一个数字转换成生成4个字节的网络字节序bytes数组.
+     */
+    private static byte[] number2BytesInNetworkOrder(int number) {
+        byte[] orderBytes = new byte[4];
+        orderBytes[3] = (byte) (number & 0xFF);
+        orderBytes[2] = (byte) (number >> 8 & 0xFF);
+        orderBytes[1] = (byte) (number >> 16 & 0xFF);
+        orderBytes[0] = (byte) (number >> 24 & 0xFF);
+        return orderBytes;
     }
 
-    // 解密
-    return decrypt(cipherText);
-  }
-
-  /**
-   * 对密文进行解密.
-   *
-   * @param cipherText 需要解密的密文
-   * @return 解密得到的明文
-   */
-  public String decrypt(String cipherText) {
-    byte[] original;
-    try {
-      // 设置解密模式为AES的CBC模式
-      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
-      SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
-      IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(this.aesKey, 0, 16));
-      cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
-
-      // 使用BASE64对密文进行解码
-      byte[] encrypted = Base64.decodeBase64(cipherText);
-
-      // 解密
-      original = cipher.doFinal(encrypted);
-    } catch (Exception e) {
-      throw new WxRuntimeException(e);
+    /**
+     * 4个字节的网络字节序bytes数组还原成一个数字.
+     */
+    private static int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) {
+        int sourceNumber = 0;
+        for (int i = 0; i < 4; i++) {
+            sourceNumber <<= 8;
+            sourceNumber |= bytesInNetworkOrder[i] & 0xff;
+        }
+        return sourceNumber;
     }
 
-    String xmlContent;
-    String fromAppid;
-    try {
-      // 去除补位字符
-      byte[] bytes = PKCS7Encoder.decode(original);
+    /**
+     * 随机生成16位字符串.
+     */
+    private static String genRandomStr() {
+        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+        Random random = new Random();
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 16; i++) {
+            int number = random.nextInt(base.length());
+            sb.append(base.charAt(number));
+        }
+        return sb.toString();
+    }
 
-      // 分离16位随机字符串,网络字节序和AppId
-      byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
+    /**
+     * 生成xml消息.
+     *
+     * @param encrypt   加密后的消息密文
+     * @param signature 安全签名
+     * @param timestamp 时间戳
+     * @param nonce     随机字符串
+     * @return 生成的xml字符串
+     */
+    private static String generateXml(String encrypt, String signature, String timestamp, String nonce) {
+        String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
+                + "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
+                + "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n"
+                + "</xml>";
+        return String.format(format, encrypt, signature, timestamp, nonce);
+    }
 
-      int xmlLength = bytesNetworkOrder2Number(networkOrder);
+    /**
+     * 将公众平台回复用户的消息加密打包.
+     * <ol>
+     * <li>对要发送的消息进行AES-CBC加密</li>
+     * <li>生成安全签名</li>
+     * <li>将消息密文和安全签名打包成xml格式</li>
+     * </ol>
+     *
+     * @param plainText 公众平台待回复用户的消息,xml格式的字符串
+     * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
+     */
+    public String encrypt(String plainText) {
+        // 加密
+        String encryptedXml = encrypt(genRandomStr(), plainText);
+
+        // 生成安全签名
+        String timeStamp = Long.toString(System.currentTimeMillis() / 1000L);
+        String nonce = genRandomStr();
+
+        String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml);
+        return generateXml(encryptedXml, signature, timeStamp, nonce);
+    }
 
-      xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
-      fromAppid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
-    } catch (Exception e) {
-      throw new WxRuntimeException(e);
+    /**
+     * 对明文进行加密.
+     *
+     * @param plainText 需要加密的明文
+     * @return 加密后base64编码的字符串
+     */
+    public String encrypt(String randomStr, String plainText) {
+        ByteGroup byteCollector = new ByteGroup();
+        byte[] randomStringBytes = randomStr.getBytes(CHARSET);
+        byte[] plainTextBytes = plainText.getBytes(CHARSET);
+        byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(plainTextBytes.length);
+        byte[] appIdBytes = this.appidOrCorpid.getBytes(CHARSET);
+
+        // randomStr + networkBytesOrder + text + appid
+        byteCollector.addBytes(randomStringBytes);
+        byteCollector.addBytes(bytesOfSizeInNetworkOrder);
+        byteCollector.addBytes(plainTextBytes);
+        byteCollector.addBytes(appIdBytes);
+
+        // ... + pad: 使用自定义的填充方式对明文进行补位填充
+        byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
+        byteCollector.addBytes(padBytes);
+
+        // 获得最终的字节流, 未加密
+        byte[] unencrypted = byteCollector.toBytes();
+
+        try {
+            // 设置加密模式为AES的CBC模式
+            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+            SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
+            IvParameterSpec iv = new IvParameterSpec(this.aesKey, 0, 16);
+            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
+
+            // 加密
+            byte[] encrypted = cipher.doFinal(unencrypted);
+
+            // 使用BASE64对加密后的字符串进行编码
+            return BASE64.encodeToString(encrypted);
+        } catch (Exception e) {
+            throw new WxRuntimeException(e);
+        }
     }
 
-    // appid不相同的情况 暂时忽略这段判断
-//    if (!fromAppid.equals(this.appidOrCorpid)) {
-//      throw new WxRuntimeException("AppID不正确,请核实!");
-//    }
+    /**
+     * 检验消息的真实性,并且获取解密后的明文.
+     * <ol>
+     * <li>利用收到的密文生成安全签名,进行签名验证</li>
+     * <li>若验证通过,则提取xml中的加密消息</li>
+     * <li>对消息进行解密</li>
+     * </ol>
+     *
+     * @param msgSignature 签名串,对应URL参数的msg_signature
+     * @param timeStamp    时间戳,对应URL参数的timestamp
+     * @param nonce        随机串,对应URL参数的nonce
+     * @param encryptedXml 密文,对应POST请求的数据
+     * @return 解密后的原文
+     */
+    public String decrypt(String msgSignature, String timeStamp, String nonce, String encryptedXml) {
+        // 密钥,公众账号的app corpSecret
+        // 提取密文
+        String cipherText = extractEncryptPart(encryptedXml);
+
+        // 验证安全签名
+        String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText);
+        if (!signature.equals(msgSignature)) {
+            throw new WxRuntimeException("加密消息签名校验失败");
+        }
+
+        // 解密
+        return decrypt(cipherText);
+    }
 
-    return xmlContent;
+    /**
+     * 对密文进行解密.
+     *
+     * @param cipherText 需要解密的密文
+     * @return 解密得到的明文
+     */
+    public String decrypt(String cipherText) {
+        byte[] original;
+        try {
+            // 设置解密模式为AES的CBC模式
+            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+            SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
+            IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(this.aesKey, 0, 16));
+            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
+
+            // 使用BASE64对密文进行解码
+            byte[] encrypted = Base64.decodeBase64(cipherText);
+
+            // 解密
+            original = cipher.doFinal(encrypted);
+        } catch (Exception e) {
+            throw new WxRuntimeException(e);
+        }
+
+        String xmlContent;
+        /// String fromAppid;
+        try {
+            // 去除补位字符
+            byte[] bytes = PKCS7Encoder.decode(original);
+
+            // 分离16位随机字符串,网络字节序和AppId
+            byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
+
+            int xmlLength = bytesNetworkOrder2Number(networkOrder);
+
+            xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
+            /// fromAppid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
+        } catch (Exception e) {
+            throw new WxRuntimeException(e);
+        }
+
+        // appid不相同的情况 暂时忽略这段判断
+        /// if (!fromAppid.equals(this.appidOrCorpid)) {
+        ///    throw new WxRuntimeException("AppID不正确,请核实!");
+        /// }
+
+        return xmlContent;
 
-  }
+    }
 
 }

+ 4 - 4
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/WxCpChatService.java

@@ -22,7 +22,7 @@ public interface WxCpChatService {
      * @param chatId 群聊的唯一标志,不能与已有的群重复;字符串类型,最长32个字符。只允许字符0-9及字母a-zA-Z。如果不填,系统会随机生成群id
      * @return 创建的群聊会话chatId
      */
-    String create(String name, String owner, List<String> users, String chatId) ;
+    String create(String name, String owner, List<String> users, String chatId);
 
     /**
      * 修改群聊会话.
@@ -33,7 +33,7 @@ public interface WxCpChatService {
      * @param usersToAdd    添加成员的id列表,若不需要更新,则传递空对象或者空集合
      * @param usersToDelete 踢出成员的id列表,若不需要更新,则传递空对象或者空集合
      */
-    void update(String chatId, String name, String owner, List<String> usersToAdd, List<String> usersToDelete) ;
+    void update(String chatId, String name, String owner, List<String> usersToAdd, List<String> usersToDelete);
 
     /**
      * 获取群聊会话.
@@ -41,7 +41,7 @@ public interface WxCpChatService {
      * @param chatId 群聊编号
      * @return 群聊会话
      */
-    WxCpChat get(String chatId) ;
+    WxCpChat get(String chatId);
 
     /**
      * 应用支持推送文本、图片、视频、文件、图文等类型.
@@ -51,6 +51,6 @@ public interface WxCpChatService {
      *
      * @param message 要发送的消息内容对象
      */
-    void sendMsg(WxCpAppChatMessage message) ;
+    void sendMsg(WxCpAppChatMessage message);
 
 }

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/WxCpOaService.java

@@ -9,7 +9,7 @@ import java.util.List;
 /**
  * 企业微信OA相关接口.
  *
- * @author Element
+ * @author Young
  */
 public interface WxCpOaService {
 

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/WxCpDepart.java

@@ -8,7 +8,7 @@ import java.io.Serializable;
 /**
  * 企业微信的部门.
  *
- * @author Daniel Qian
+ * @author Young
  */
 @Data
 public class WxCpDepart implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/WxCpTag.java

@@ -9,7 +9,7 @@ import java.io.Serializable;
 
 /**
  * Created by Daniel Qian.
- * @author Daniel Qian
+ * @author Young
  */
 @Data
 @AllArgsConstructor

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/WxCpUser.java

@@ -14,7 +14,7 @@ import java.util.List;
 /**
  * 微信用户信息.
  *
- * @author Daniel Qian
+ * @author Young
  */
 @Data
 @Accessors(chain = true)

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/external/WxCpContactWayInfo.java

@@ -15,7 +15,7 @@ import java.util.List;
 /**
  * 「联系我」方式 对象
  *
- * @author element
+ * @author Young
  */
 @Data
 @NoArgsConstructor

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/message/WxCpMessage.java

@@ -20,7 +20,7 @@ import static cn.nosum.wx.common.api.WxConsts.MessageType.*;
 /**
  * 消息.
  *
- * @author Daniel Qian
+ * @author Young
  */
 @Data
 public class WxCpMessage implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/message/WxCpXmlMessage.java

@@ -35,7 +35,7 @@ import java.util.Map;
  * https://work.weixin.qq.com/api/doc#12974
  * </pre>
  *
- * @author Daniel Qian
+ * @author Young
  */
 @Data
 @Slf4j

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/message/WxCpXmlOutMessage.java

@@ -15,7 +15,7 @@ import java.io.Serializable;
  * 被动回复消息.
  * https://work.weixin.qq.com/api/doc#12975
  *
- * @author Daniel Qian
+ * @author Young
  */
 @XStreamAlias("xml")
 @Data

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/FileBuilder.java

@@ -9,7 +9,7 @@ import cn.nosum.wx.cp.entity.message.WxCpMessage;
  * 用法: WxCustomMessage m = WxCustomMessage.FILE().mediaId(...).toUser(...).build();
  * </pre>
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class FileBuilder extends BaseBuilder<FileBuilder> {
   private String mediaId;

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/ImageBuilder.java

@@ -9,7 +9,7 @@ import cn.nosum.wx.cp.entity.message.WxCpMessage;
  * 用法: WxCustomMessage m = WxCustomMessage.IMAGE().mediaId(...).toUser(...).build();
  * </pre>
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class ImageBuilder extends BaseBuilder<ImageBuilder> {
   private String mediaId;

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/NewsBuilder.java

@@ -15,7 +15,7 @@ import java.util.List;
  * WxCustomMessage m = WxCustomMessage.NEWS().addArticle(article).toUser(...).build();
  * </pre>
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class NewsBuilder extends BaseBuilder<NewsBuilder> {
 

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/TextBuilder.java

@@ -9,7 +9,7 @@ import cn.nosum.wx.cp.entity.message.WxCpMessage;
  * 用法: WxCustomMessage m = WxCustomMessage.TEXT().content(...).toUser(...).build();
  * </pre>
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class TextBuilder extends BaseBuilder<TextBuilder> {
   private String content;

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/VideoBuilder.java

@@ -15,7 +15,7 @@ import cn.nosum.wx.cp.entity.message.WxCpMessage;
  *                              .build();
  * </pre>
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class VideoBuilder extends BaseBuilder<VideoBuilder> {
   private String mediaId;

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/messagebuilder/VoiceBuilder.java

@@ -9,7 +9,7 @@ import cn.nosum.wx.cp.entity.message.WxCpMessage;
  * 用法: WxCustomMessage m = WxCustomMessage.VOICE().mediaId(...).toUser(...).build();
  * </pre>
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class VoiceBuilder extends BaseBuilder<VoiceBuilder> {
   private String mediaId;

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalApplier.java

@@ -7,7 +7,7 @@ import java.io.Serializable;
 
 /**
  * 申请人信息
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalApplier extends WxCpOperator implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalApplyData.java

@@ -9,7 +9,7 @@ import java.util.List;
 /**
  * 审批申请数据
  *
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalApplyData implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalComment.java

@@ -9,7 +9,7 @@ import java.util.List;
 /**
  * 审批申请备注信息
  *
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalComment implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalDetail.java

@@ -9,7 +9,7 @@ import java.util.List;
 /**
  * 审批申请详情
  *
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalDetail implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalDetailResult.java

@@ -8,7 +8,7 @@ import java.io.Serializable;
 /**
  * 审批申请详情响应结果
  *
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalDetailResult implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalInfo.java

@@ -7,7 +7,7 @@ import java.io.Serializable;
 import java.util.List;
 
 /**
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalInfo implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalInfoQueryFilter.java

@@ -14,7 +14,7 @@ import java.io.Serializable;
  *  不同类型的筛选条件之间为“与”的关系,同类型筛选条件之间为“或”的关系
  * </pre>
  *
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalInfoQueryFilter implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalRecord.java

@@ -8,7 +8,7 @@ import java.util.List;
 
 /**
  * 审批流程信息
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalRecord implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApprovalRecordDetail.java

@@ -8,7 +8,7 @@ import java.util.List;
 
 /**
  * 审批节点详情
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpApprovalRecordDetail implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpApproverAttr.java

@@ -5,7 +5,7 @@ import com.google.gson.annotations.SerializedName;
 /**
  * 审批方式
  *
- * @author element
+ * @author Young
  */
 public enum WxCpApproverAttr {
   /**

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpCheckinData.java

@@ -9,7 +9,7 @@ import java.util.List;
 /**
  * 企业微信打卡数据.
  *
- * @author Element
+ * @author Young
  */
 @Data
 public class WxCpCheckinData implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpOperator.java

@@ -9,7 +9,7 @@ import java.io.Serializable;
 /**
  * 企业微信操作人
  *
- * @author element
+ * @author Young
  */
 @Data
 public class WxCpOperator implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpRecordSpStatus.java

@@ -7,7 +7,7 @@ import com.google.gson.annotations.SerializedName;
  *
  * 1-审批中;2-已同意;3-已驳回;4-已转审
  *
- * @author element
+ * @author Young
  */
 public enum WxCpRecordSpStatus {
 

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/WxCpSpStatus.java

@@ -6,7 +6,7 @@ import com.google.gson.annotations.SerializedName;
  * 审批单状态
  * (1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付)
  *
- * @author element
+ * @author Young
  */
 public enum WxCpSpStatus {
 

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/applydata/ApplyDataContent.java

@@ -8,7 +8,7 @@ import java.io.Serializable;
 import java.util.List;
 
 /**
- * @author element
+ * @author Young
  */
 @Data
 @Accessors(chain = true)

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/applydata/ContentTitle.java

@@ -5,7 +5,7 @@ import lombok.Data;
 import java.io.Serializable;
 
 /**
- * @author element
+ * @author Young
  */
 @Data
 public class ContentTitle implements Serializable {

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/oa/applydata/ContentValue.java

@@ -8,7 +8,7 @@ import java.io.Serializable;
 import java.util.List;
 
 /**
- * @author element
+ * @author Young
  */
 @Data
 @Accessors(chain = true)

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/ImageBuilder.java

@@ -6,7 +6,7 @@ import cn.nosum.wx.cp.entity.message.WxCpXmlOutImageMessage;
 /**
  * 图片消息builder
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxCpXmlOutImageMessage> {
 

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/NewsBuilder.java

@@ -10,7 +10,7 @@ import java.util.List;
 /**
  * 图文消息builder
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class NewsBuilder extends BaseBuilder<NewsBuilder, WxCpXmlOutNewsMessage> {
   private List<Item> articles = new ArrayList<>();

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/TextBuilder.java

@@ -6,7 +6,7 @@ import cn.nosum.wx.cp.entity.message.WxCpXmlOutTextMessage;
 /**
  * 文本消息builder
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class TextBuilder extends BaseBuilder<TextBuilder, WxCpXmlOutTextMessage> {
   private String content;

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/VideoBuilder.java

@@ -6,7 +6,7 @@ import cn.nosum.wx.cp.entity.message.WxCpXmlOutVideoMessage;
 /**
  * 视频消息builder
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class VideoBuilder extends BaseBuilder<VideoBuilder, WxCpXmlOutVideoMessage> {
 

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/entity/outxmlbuilder/VoiceBuilder.java

@@ -6,7 +6,7 @@ import cn.nosum.wx.cp.entity.message.WxCpXmlOutVoiceMessage;
 /**
  * 语音消息builder
  *
- * @author Daniel Qian
+ * @author Young
  */
 public final class VoiceBuilder extends BaseBuilder<VoiceBuilder, WxCpXmlOutVoiceMessage> {
 

+ 1 - 0
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/crypto/WxCpCryptUtil.java

@@ -6,6 +6,7 @@ import com.google.common.base.CharMatcher;
 import com.google.common.io.BaseEncoding;
 
 public class WxCpCryptUtil extends WxCryptUtil {
+
   public WxCpCryptUtil(WxCpConfigStorage wxCpConfigStorage) {
     /*
      * @param token          公众平台上,开发者设置的token

+ 40 - 48
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpChatGsonAdapter.java

@@ -1,11 +1,3 @@
-/*
- * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
- *
- * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
- * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
- * arose from modification of the original source, or other redistribution of this source
- * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
- */
 package cn.nosum.wx.cp.utils.json;
 
 import cn.nosum.wx.common.utils.json.GsonHelper;
@@ -17,53 +9,53 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
- * 群聊适配器
+ * 群聊适配器.
  *
- * @author gaigeshen
+ * @author Young
  */
 public class WxCpChatGsonAdapter implements JsonSerializer<WxCpChat>, JsonDeserializer<WxCpChat> {
 
-  @Override
-  public JsonElement serialize(WxCpChat chat, Type typeOfSrc, JsonSerializationContext context) {
-    JsonObject json = new JsonObject();
-    if (chat.getId() != null) { 
-      json.addProperty("chatid", chat.getId());
-    }
-    if (chat.getName() != null) {
-      json.addProperty("name", chat.getName());
-    } 
-    if (chat.getOwner() != null) {
-      json.addProperty("owner", chat.getOwner());
+    @Override
+    public JsonElement serialize(WxCpChat chat, Type typeOfSrc, JsonSerializationContext context) {
+        JsonObject json = new JsonObject();
+        if (chat.getId() != null) {
+            json.addProperty("chatid", chat.getId());
+        }
+        if (chat.getName() != null) {
+            json.addProperty("name", chat.getName());
+        }
+        if (chat.getOwner() != null) {
+            json.addProperty("owner", chat.getOwner());
+        }
+        if (chat.getUsers() != null) {
+            JsonArray users = new JsonArray();
+            for (String user : chat.getUsers()) {
+                users.add(user);
+            }
+            json.add("userlist", users);
+        }
+        return json;
     }
-    if (chat.getUsers() != null) {
-      JsonArray users = new JsonArray();
-      for (String user : chat.getUsers()) {
-        users.add(user);
-      }
-      json.add("userlist", users);
-    }
-    return json;
-  }
 
-  @Override
-  public WxCpChat deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
-    JsonObject chatJson = json.getAsJsonObject();
+    @Override
+    public WxCpChat deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+        JsonObject chatJson = json.getAsJsonObject();
+
+        WxCpChat chat = new WxCpChat();
+        chat.setId(GsonHelper.getAsString(chatJson.get("chatid")));
+        chat.setName(GsonHelper.getAsString(chatJson.get("name")));
+        chat.setOwner(GsonHelper.getAsString(chatJson.get("owner")));
+
+        JsonArray usersJson = chatJson.getAsJsonArray("userlist");
+        if (usersJson != null) {
+            List<String> users = new ArrayList<>(usersJson.size());
+            chat.setUsers(users);
+            for (JsonElement userJson : usersJson) {
+                users.add(userJson.getAsString());
+            }
+        }
 
-    WxCpChat chat = new WxCpChat();
-    chat.setId(GsonHelper.getAsString(chatJson.get("chatid")));
-    chat.setName(GsonHelper.getAsString(chatJson.get("name")));
-    chat.setOwner(GsonHelper.getAsString(chatJson.get("owner")));
-    
-    JsonArray usersJson = chatJson.getAsJsonArray("userlist");
-    if (usersJson != null) {
-      List<String> users = new ArrayList<>(usersJson.size());
-      chat.setUsers(users);
-      for (JsonElement userJson : usersJson) {
-        users.add(userJson.getAsString());
-      }
+        return chat;
     }
-    
-    return chat;
-  }
 
 }

+ 106 - 106
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpConclusionAdapter.java

@@ -9,115 +9,115 @@ import java.lang.reflect.Type;
 /**
  * 结束语序列化转换器
  *
- * @author element
+ * @author Young
  */
 public class WxCpConclusionAdapter implements JsonSerializer<WxCpContactWayInfo.ContactWay.Conclusion>, JsonDeserializer<WxCpContactWayInfo.ContactWay.Conclusion> {
-  @Override
-  public WxCpContactWayInfo.ContactWay.Conclusion deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
-    JsonObject jsonObject = json.getAsJsonObject();
-
-    WxCpContactWayInfo.ContactWay.Conclusion conclusion = new WxCpContactWayInfo.ContactWay.Conclusion();
-
-    if (jsonObject.get("text") != null) {
-      JsonObject jsonText = jsonObject.get("text").getAsJsonObject();
-
-      if (jsonText.get("content") != null) {
-        conclusion.setTextContent(jsonText.get("content").getAsString());
-      }
-    }
-
-    if (jsonObject.get("image") != null) {
-      JsonObject jsonImage = jsonObject.get("image").getAsJsonObject();
-
-      if (jsonImage.get("media_id") != null) {
-        conclusion.setImgMediaId(jsonImage.get("media_id").getAsString());
-      }
-
-      if (jsonImage.get("pic_url") != null) {
-        conclusion.setImgPicUrl(jsonImage.get("pic_url").getAsString());
-      }
-    }
-
-    if (jsonObject.get("link") != null) {
-      JsonObject jsonLink = jsonObject.get("link").getAsJsonObject();
-
-      if (jsonLink.get("title") != null) {
-        conclusion.setLinkTitle(jsonLink.get("title").getAsString());
-      }
-      if (jsonLink.get("picurl") != null) {
-        conclusion.setLinkPicUrl(jsonLink.get("picurl").getAsString());
-      }
-      if (jsonLink.get("desc") != null) {
-        conclusion.setLinkDesc(jsonLink.get("desc").getAsString());
-      }
-      if (jsonLink.get("url") != null) {
-        conclusion.setLinkUrl(jsonLink.get("url").getAsString());
-      }
-    }
-
-    if (jsonObject.get("miniprogram") != null) {
-
-      JsonObject jsonMiniProgram = jsonObject.get("miniprogram").getAsJsonObject();
-      if (jsonMiniProgram.get("title") != null) {
-        conclusion.setMiniProgramTitle(jsonMiniProgram.get("title").getAsString());
-      }
-      if (jsonMiniProgram.get("pic_media_id") != null) {
-        conclusion.setMiniProgramPicMediaId(jsonMiniProgram.get("pic_media_id").getAsString());
-      }
-      if (jsonMiniProgram.get("appid") != null) {
-        conclusion.setMiniProgramAppId(jsonMiniProgram.get("appid").getAsString());
-      }
-      if (jsonMiniProgram.get("page") != null) {
-        conclusion.setMiniProgramPage(jsonMiniProgram.get("page").getAsString());
-      }
-
-    }
-
-    return conclusion;
-  }
-
-  @Override
-  public JsonElement serialize(WxCpContactWayInfo.ContactWay.Conclusion src, Type typeOfSrc, JsonSerializationContext context) {
-    JsonObject json = new JsonObject();
-    if (StringUtils.isNotBlank(src.getTextContent())) {
-      JsonObject jsonText = new JsonObject();
-      jsonText.addProperty("content", src.getTextContent());
-      json.add("text", jsonText);
+    @Override
+    public WxCpContactWayInfo.ContactWay.Conclusion deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+        JsonObject jsonObject = json.getAsJsonObject();
+
+        WxCpContactWayInfo.ContactWay.Conclusion conclusion = new WxCpContactWayInfo.ContactWay.Conclusion();
+
+        if (jsonObject.get("text") != null) {
+            JsonObject jsonText = jsonObject.get("text").getAsJsonObject();
+
+            if (jsonText.get("content") != null) {
+                conclusion.setTextContent(jsonText.get("content").getAsString());
+            }
+        }
+
+        if (jsonObject.get("image") != null) {
+            JsonObject jsonImage = jsonObject.get("image").getAsJsonObject();
+
+            if (jsonImage.get("media_id") != null) {
+                conclusion.setImgMediaId(jsonImage.get("media_id").getAsString());
+            }
+
+            if (jsonImage.get("pic_url") != null) {
+                conclusion.setImgPicUrl(jsonImage.get("pic_url").getAsString());
+            }
+        }
+
+        if (jsonObject.get("link") != null) {
+            JsonObject jsonLink = jsonObject.get("link").getAsJsonObject();
+
+            if (jsonLink.get("title") != null) {
+                conclusion.setLinkTitle(jsonLink.get("title").getAsString());
+            }
+            if (jsonLink.get("picurl") != null) {
+                conclusion.setLinkPicUrl(jsonLink.get("picurl").getAsString());
+            }
+            if (jsonLink.get("desc") != null) {
+                conclusion.setLinkDesc(jsonLink.get("desc").getAsString());
+            }
+            if (jsonLink.get("url") != null) {
+                conclusion.setLinkUrl(jsonLink.get("url").getAsString());
+            }
+        }
+
+        if (jsonObject.get("miniprogram") != null) {
+
+            JsonObject jsonMiniProgram = jsonObject.get("miniprogram").getAsJsonObject();
+            if (jsonMiniProgram.get("title") != null) {
+                conclusion.setMiniProgramTitle(jsonMiniProgram.get("title").getAsString());
+            }
+            if (jsonMiniProgram.get("pic_media_id") != null) {
+                conclusion.setMiniProgramPicMediaId(jsonMiniProgram.get("pic_media_id").getAsString());
+            }
+            if (jsonMiniProgram.get("appid") != null) {
+                conclusion.setMiniProgramAppId(jsonMiniProgram.get("appid").getAsString());
+            }
+            if (jsonMiniProgram.get("page") != null) {
+                conclusion.setMiniProgramPage(jsonMiniProgram.get("page").getAsString());
+            }
+
+        }
+
+        return conclusion;
     }
 
-    if (StringUtils.isNotBlank(src.getImgMediaId()) || StringUtils.isNotBlank(src.getImgPicUrl())) {
-      JsonObject jsonImg = new JsonObject();
-      jsonImg.addProperty("media_id", src.getImgMediaId());
-      jsonImg.addProperty("pic_url", src.getImgPicUrl());
-      json.add("image", jsonImg);
+    @Override
+    public JsonElement serialize(WxCpContactWayInfo.ContactWay.Conclusion src, Type typeOfSrc, JsonSerializationContext context) {
+        JsonObject json = new JsonObject();
+        if (StringUtils.isNotBlank(src.getTextContent())) {
+            JsonObject jsonText = new JsonObject();
+            jsonText.addProperty("content", src.getTextContent());
+            json.add("text", jsonText);
+        }
+
+        if (StringUtils.isNotBlank(src.getImgMediaId()) || StringUtils.isNotBlank(src.getImgPicUrl())) {
+            JsonObject jsonImg = new JsonObject();
+            jsonImg.addProperty("media_id", src.getImgMediaId());
+            jsonImg.addProperty("pic_url", src.getImgPicUrl());
+            json.add("image", jsonImg);
+        }
+
+        if (StringUtils.isNotBlank(src.getLinkTitle())
+                || StringUtils.isNotBlank(src.getLinkPicUrl())
+                || StringUtils.isNotBlank(src.getLinkDesc())
+                || StringUtils.isNotBlank(src.getLinkUrl())
+        ) {
+            JsonObject jsonLink = new JsonObject();
+            jsonLink.addProperty("title", src.getLinkTitle());
+            jsonLink.addProperty("picurl", src.getLinkPicUrl());
+            jsonLink.addProperty("desc", src.getLinkDesc());
+            jsonLink.addProperty("url", src.getLinkUrl());
+            json.add("link", jsonLink);
+        }
+
+        if (StringUtils.isNotBlank(src.getMiniProgramTitle())
+                || StringUtils.isNotBlank(src.getMiniProgramPicMediaId())
+                || StringUtils.isNotBlank(src.getMiniProgramAppId())
+                || StringUtils.isNotBlank(src.getMiniProgramPage())
+        ) {
+            JsonObject jsonMiniProgram = new JsonObject();
+            jsonMiniProgram.addProperty("title", src.getMiniProgramTitle());
+            jsonMiniProgram.addProperty("pic_media_id", src.getMiniProgramPicMediaId());
+            jsonMiniProgram.addProperty("appid", src.getMiniProgramAppId());
+            jsonMiniProgram.addProperty("page", src.getMiniProgramPage());
+            json.add("miniprogram", jsonMiniProgram);
+        }
+
+        return json;
     }
-
-    if (StringUtils.isNotBlank(src.getLinkTitle())
-      || StringUtils.isNotBlank(src.getLinkPicUrl())
-      || StringUtils.isNotBlank(src.getLinkDesc())
-      || StringUtils.isNotBlank(src.getLinkUrl())
-    ) {
-      JsonObject jsonLink = new JsonObject();
-      jsonLink.addProperty("title", src.getLinkTitle());
-      jsonLink.addProperty("picurl", src.getLinkPicUrl());
-      jsonLink.addProperty("desc", src.getLinkDesc());
-      jsonLink.addProperty("url", src.getLinkUrl());
-      json.add("link", jsonLink);
-    }
-
-    if (StringUtils.isNotBlank(src.getMiniProgramTitle())
-      || StringUtils.isNotBlank(src.getMiniProgramPicMediaId())
-      || StringUtils.isNotBlank(src.getMiniProgramAppId())
-      || StringUtils.isNotBlank(src.getMiniProgramPage())
-    ) {
-      JsonObject jsonMiniProgram = new JsonObject();
-      jsonMiniProgram.addProperty("title", src.getMiniProgramTitle());
-      jsonMiniProgram.addProperty("pic_media_id", src.getMiniProgramPicMediaId());
-      jsonMiniProgram.addProperty("appid", src.getMiniProgramAppId());
-      jsonMiniProgram.addProperty("page", src.getMiniProgramPage());
-      json.add("miniprogram", jsonMiniProgram);
-    }
-
-    return json;
-  }
 }

+ 2 - 9
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpDepartGsonAdapter.java

@@ -1,11 +1,4 @@
-/*
- * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
- *
- * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
- * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
- * arose from modification of the original source, or other redistribution of this source
- * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
- */
+
 package cn.nosum.wx.cp.utils.json;
 
 import cn.nosum.wx.common.utils.json.GsonHelper;
@@ -17,7 +10,7 @@ import java.lang.reflect.Type;
 /**
  * WxCpDepart的gson适配器.
  *
- * @author Daniel Qian
+ * @author Young
  */
 public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDeserializer<WxCpDepart> {
   private static final String ID = "id";

+ 1 - 1
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpGsonBuilder.java

@@ -12,7 +12,7 @@ import com.google.gson.GsonBuilder;
 
 
 /**
- * @author Daniel Qian
+ * @author Young
  */
 public class WxCpGsonBuilder {
 

+ 6 - 8
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpMenuGsonAdapter.java

@@ -9,16 +9,14 @@ import com.google.gson.JsonParseException;
 import java.lang.reflect.Type;
 
 /**
- * <pre>
- * 企业号菜单json转换适配器
- * Created by Binary Wang on 2017-6-25.
+ * 企业号菜单json转换适配器.
+ *
  * @author Young
- * </pre>
  */
 public class WxCpMenuGsonAdapter extends WxMenuGsonAdapter {
 
-  @Override
-  public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
-    return this.buildMenuFromJson(json.getAsJsonObject().get("button").getAsJsonArray());
-  }
+    @Override
+    public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+        return this.buildMenuFromJson(json.getAsJsonObject().get("button").getAsJsonArray());
+    }
 }

+ 2 - 9
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpTagGsonAdapter.java

@@ -1,11 +1,4 @@
-/*
- * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
- *
- * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
- * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
- * arose from modification of the original source, or other redistribution of this source
- * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
- */
+
 package cn.nosum.wx.cp.utils.json;
 
 import cn.nosum.wx.common.utils.json.GsonHelper;
@@ -15,7 +8,7 @@ import com.google.gson.*;
 import java.lang.reflect.Type;
 
 /**
- * @author Daniel Qian
+ * @author Young
  */
 public class WxCpTagGsonAdapter implements JsonSerializer<WxCpTag>, JsonDeserializer<WxCpTag> {
 

+ 2 - 9
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/utils/json/WxCpUserGsonAdapter.java

@@ -1,11 +1,4 @@
-/*
- * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
- *
- * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
- * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
- * arose from modification of the original source, or other redistribution of this source
- * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
- */
+
 
 package cn.nosum.wx.cp.utils.json;
 
@@ -21,7 +14,7 @@ import static cn.nosum.wx.cp.entity.WxCpUser.*;
 /**
  * cp user gson adapter.
  *
- * @author Daniel Qian
+ * @author Young
  */
 public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSerializer<WxCpUser> {
   private static final String EXTERNAL_PROFILE = "external_profile";