Преглед изворни кода

Merge branch 'feature/sax-xml' into develop

Daniel Qian пре 10 година
родитељ
комит
d10fcfb880
78 измењених фајлова са 843 додато и 1430 уклоњено
  1. 0 10
      pom.xml
  2. 0 229
      pom.xml.versionsBackup
  3. 66 61
      weixin-java-common/pom.xml
  4. 0 68
      weixin-java-common/pom.xml.versionsBackup
  5. 0 24
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/AdapterCDATA.java
  6. 0 21
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/MediaIdMarshaller.java
  7. 15 0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamCDataConverter.java
  8. 53 0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java
  9. 11 0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamMediaIdConverter.java
  10. 0 73
      weixin-java-cp/pom.xml.versionsBackup
  11. 2 2
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java
  12. 2 2
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java
  13. 3 3
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
  14. 8 7
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
  15. 3 3
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
  16. 79 95
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
  17. 6 11
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java
  18. 14 24
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java
  19. 15 18
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java
  20. 6 11
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java
  21. 13 19
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java
  22. 6 11
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java
  23. 3 3
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
  24. 2 9
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java
  25. 4 3
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java
  26. 2 2
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java
  27. 106 0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
  28. 0 93
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XmlTransformer.java
  29. 11 22
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
  30. 2 4
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java
  31. 3 5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpDepartAPITest.java
  32. 6 8
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java
  33. 2 4
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java
  34. 2 2
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
  35. 1 1
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpUserAPITest.java
  36. 4 8
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java
  37. 1 2
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
  38. 8 14
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java
  39. 0 5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
  40. 3 5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
  41. 0 72
      weixin-java-mp/pom.xml.versionsBackup
  42. 1 1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
  43. 0 32
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMpXmlOutImageMessage.java
  44. 81 99
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlMessage.java
  45. 27 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessage.java
  46. 14 24
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMessage.java
  47. 17 23
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMusicMessage.java
  48. 15 18
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutNewsMessage.java
  49. 6 11
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutTextMessage.java
  50. 13 19
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutVideoMessage.java
  51. 9 14
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutVoiceMessage.java
  52. 4 4
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/outxmlbuilder/ImageBuilder.java
  53. 0 1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java
  54. 1 1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java
  55. 0 1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java
  56. 0 1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java
  57. 0 2
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java
  58. 4 3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java
  59. 117 0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java
  60. 0 91
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XmlTransformer.java
  61. 19 30
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java
  62. 3 5
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java
  63. 2 4
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpCustomMessageAPITest.java
  64. 3 5
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpGroupAPITest.java
  65. 4 6
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java
  66. 6 8
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMediaAPITest.java
  67. 5 9
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMenuAPITest.java
  68. 2 2
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java
  69. 3 5
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpQrCodeAPITest.java
  70. 2 4
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpShortUrlAPITest.java
  71. 3 5
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpUserAPITest.java
  72. 1 2
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpCustomMessageTest.java
  73. 2 2
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessageTest.java
  74. 8 14
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java
  75. 4 8
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
  76. 3 9
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlet.java
  77. 1 12
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java
  78. 1 1
      weixin-java-mp/src/test/resources/testng.xml

+ 0 - 10
pom.xml

@@ -56,16 +56,6 @@
             <version>${httpclient.version}</version>
         </dependency>
         <dependency>
-            <groupId>javax.xml.bind</groupId>
-            <artifactId>jaxb-api</artifactId>
-            <version>2.2.7</version>
-        </dependency>
-        <dependency>
-            <groupId>com.sun.xml.bind</groupId>
-            <artifactId>jaxb-impl</artifactId>
-            <version>2.2.7</version>
-        </dependency>
-        <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
             <version>2.2.2</version>

+ 0 - 229
pom.xml.versionsBackup

@@ -1,229 +0,0 @@
-<?xml version="1.0"?>
-<project
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <modelVersion>4.0.0</modelVersion>
-    <groupId>me.chanjar</groupId>
-    <artifactId>weixin-java-parent</artifactId>
-    <version>1.0.5-SNAPSHOT</version>
-    <packaging>pom</packaging>
-    <name>WeiXin Java Tools - Parent</name>
-    <description>微信公众号、企业号上级POM</description>
-    <url>https://github.com/chanjarster/weixin-java-tools</url>
-
-    <licenses>
-        <license>
-            <name>The Apache License, Version 2.0</name>
-            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-        </license>
-    </licenses>
-
-    <developers>
-        <developer>
-            <name>Daniel Qian</name>
-            <email>chanjarster@gmail.com</email>
-        </developer>
-    </developers>
-
-    <scm>
-        <connection>scm:git:https://github.com/chanjarster/weixin-java-tools.git</connection>
-        <developerConnection>scm:git:git@github.com:chanjarster/weixin-java-tools.git</developerConnection>
-        <url>https://github.com/chanjarster/weixin-java-tools</url>
-    </scm>
-
-    <modules>
-        <module>weixin-java-common</module>
-        <module>weixin-java-cp</module>
-        <module>weixin-java-mp</module>
-    </modules>
-
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <downloadJavadocs>true</downloadJavadocs>
-        <downloadSources>true</downloadSources>
-        <httpclient.version>4.3.5</httpclient.version>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>fluent-hc</artifactId>
-            <version>${httpclient.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpmime</artifactId>
-            <version>${httpclient.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>javax.xml.bind</groupId>
-            <artifactId>jaxb-api</artifactId>
-            <version>2.2.7</version>
-        </dependency>
-        <dependency>
-            <groupId>com.sun.xml.bind</groupId>
-            <artifactId>jaxb-impl</artifactId>
-            <version>2.2.7</version>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-            <version>2.2.2</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-codec</groupId>
-            <artifactId>commons-codec</artifactId>
-            <version>1.9</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <version>2.4</version>
-        </dependency>
-    </dependencies>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>junit</groupId>
-                <artifactId>junit</artifactId>
-                <version>4.11</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>com.google.inject</groupId>
-                <artifactId>guice</artifactId>
-                <version>3.0</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.testng</groupId>
-                <artifactId>testng</artifactId>
-                <version>6.8.7</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.mockito</groupId>
-                <artifactId>mockito-all</artifactId>
-                <version>1.9.5</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-server</artifactId>
-                <version>9.3.0.M0</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-servlet</artifactId>
-                <version>9.3.0.M0</version>
-                <scope>test</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <distributionManagement>
-        <snapshotRepository>
-            <id>ossrh</id>
-            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
-        </snapshotRepository>
-        <repository>
-            <id>ossrh</id>
-            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
-        </repository>
-    </distributionManagement>
-
-    <profiles>
-        <profile>
-            <id>release</id>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-source-plugin</artifactId>
-                        <version>2.2.1</version>
-                        <executions>
-                            <execution>
-                                <id>attach-sources</id>
-                                <goals>
-                                    <goal>jar-no-fork</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-javadoc-plugin</artifactId>
-                        <version>2.9.1</version>
-                        <executions>
-                            <execution>
-                                <id>attach-javadocs</id>
-                                <goals>
-                                    <goal>jar</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                        <configuration>
-                            <charset>UTF-8</charset>
-                            <locale>zh_CN</locale>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-gpg-plugin</artifactId>
-                        <version>1.5</version>
-                        <executions>
-                            <execution>
-                                <id>sign-artifacts</id>
-                                <phase>verify</phase>
-                                <goals>
-                                    <goal>sign</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
-    <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-surefire-plugin</artifactId>
-                    <version>2.17</version>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-
-        <plugins>
-            <plugin>
-                <groupId>org.sonatype.plugins</groupId>
-                <artifactId>nexus-staging-maven-plugin</artifactId>
-                <version>1.6.3</version>
-                <extensions>true</extensions>
-                <configuration>
-                    <serverId>ossrh</serverId>
-                    <nexusUrl>https://oss.sonatype.org/</nexusUrl>
-                    <autoReleaseAfterClose>false</autoReleaseAfterClose>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-release-plugin</artifactId>
-                <version>2.5</version>
-                <configuration>
-                    <autoVersionSubmodules>true</autoVersionSubmodules>
-                    <useReleaseProfile>false</useReleaseProfile>
-                    <releaseProfiles>release</releaseProfiles>
-                    <goals>deploy</goals>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-
-</project>

+ 66 - 61
weixin-java-common/pom.xml

@@ -1,68 +1,73 @@
 <?xml version="1.0"?>
 <project
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>me.chanjar</groupId>
-        <artifactId>weixin-java-parent</artifactId>
-        <version>1.0.7-SNAPSHOT</version>
-    </parent>
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>me.chanjar</groupId>
+    <artifactId>weixin-java-parent</artifactId>
+    <version>1.0.7-SNAPSHOT</version>
+  </parent>
 
-    <artifactId>weixin-java-common</artifactId>
-    <name>WeiXin Java Tools - Common</name>
-    <description>微信公众号、企业号Java SDK Common</description>
+  <artifactId>weixin-java-common</artifactId>
+  <name>WeiXin Java Tools - Common</name>
+  <description>微信公众号、企业号Java SDK Common</description>
 
-    <dependencies>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <version>6.8.7</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
-            <version>1.9.5</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.inject</groupId>
-            <artifactId>guice</artifactId>
-            <version>3.0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
+  <dependencies>
+    <dependency>
+      <groupId>com.thoughtworks.xstream</groupId>
+      <artifactId>xstream</artifactId>
+      <version>1.4.7</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.testng</groupId>
+      <artifactId>testng</artifactId>
+      <version>6.8.7</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.9.5</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.inject</groupId>
+      <artifactId>guice</artifactId>
+      <version>3.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
+      <version>9.3.0.M0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-servlet</artifactId>
+      <version>9.3.0.M0</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <suiteXmlFiles>
-                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
-                    </suiteXmlFiles>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <suiteXmlFiles>
+            <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
+          </suiteXmlFiles>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 
 </project>

+ 0 - 68
weixin-java-common/pom.xml.versionsBackup

@@ -1,68 +0,0 @@
-<?xml version="1.0"?>
-<project
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>me.chanjar</groupId>
-        <artifactId>weixin-java-parent</artifactId>
-        <version>1.0.5-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>weixin-java-common</artifactId>
-    <name>WeiXin Java Tools - Common</name>
-    <description>微信公众号、企业号Java SDK Common</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <version>6.8.7</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
-            <version>1.9.5</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.inject</groupId>
-            <artifactId>guice</artifactId>
-            <version>3.0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <suiteXmlFiles>
-                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
-                    </suiteXmlFiles>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>

+ 0 - 24
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/AdapterCDATA.java

@@ -1,24 +0,0 @@
-package me.chanjar.weixin.common.util.xml;
-
-import javax.xml.bind.annotation.adapters.XmlAdapter;
-
-/**
- * 
- * http://stackoverflow.com/questions/14193944/jaxb-marshalling-unmarshalling-with-cdata
- * 
- * @author Daniel Qian
- *
- */
-public class AdapterCDATA extends XmlAdapter<String, String> {
-
-    @Override
-    public String marshal(String arg0) throws Exception {
-        return "<![CDATA[" + arg0 + "]]>";
-    }
-    
-    @Override
-    public String unmarshal(String arg0) throws Exception {
-        return arg0;
-    }
-    
-}

+ 0 - 21
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/MediaIdMarshaller.java

@@ -1,21 +0,0 @@
-package me.chanjar.weixin.common.util.xml;
-
-import javax.xml.bind.annotation.adapters.XmlAdapter;
-
-/**
- * @author Daniel Qian
- */
-public class MediaIdMarshaller extends XmlAdapter<String, String> {
-
-  @Override
-  public String marshal(String arg0) throws Exception {
-    return "<MediaId><![CDATA[" + arg0 + "]]></MediaId>";
-  }
-
-  @Override
-  public String unmarshal(String arg0) throws Exception {
-    // do nothing
-    return arg0;
-  }
-
-}

+ 15 - 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamCDataConverter.java

@@ -0,0 +1,15 @@
+package me.chanjar.weixin.common.util.xml;
+
+import com.thoughtworks.xstream.converters.basic.StringConverter;
+
+/**
+ * Created by qianjia on 15/1/19.
+ */
+public class XStreamCDataConverter extends StringConverter {
+
+  @Override
+  public String toString(Object obj) {
+    return "<![CDATA[" + super.toString(obj) + "]]>";
+  }
+
+}

+ 53 - 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java

@@ -0,0 +1,53 @@
+package me.chanjar.weixin.common.util.xml;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.basic.DoubleConverter;
+import com.thoughtworks.xstream.converters.basic.FloatConverter;
+import com.thoughtworks.xstream.converters.basic.IntConverter;
+import com.thoughtworks.xstream.core.util.QuickWriter;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
+import com.thoughtworks.xstream.io.xml.XppDriver;
+import com.thoughtworks.xstream.security.NoTypePermission;
+import com.thoughtworks.xstream.security.NullPermission;
+import com.thoughtworks.xstream.security.PrimitiveTypePermission;
+
+import java.io.Writer;
+
+/**
+ * Created by qianjia on 15/1/19.
+ */
+public class XStreamInitializer {
+
+  public static XStream getInstance() {
+    XStream xstream = new XStream(new XppDriver() {
+
+      @Override
+      public HierarchicalStreamWriter createWriter(Writer out) {
+        return new PrettyPrintWriter(out, getNameCoder()) {
+          protected String PREFIX_CDATA = "<![CDATA[";
+          protected String SUFFIX_CDATA = "]]>";
+          protected String PREFIX_MEDIA_ID = "<MediaId>";
+          protected String SUFFIX_MEDIA_ID = "</MediaId>";
+          @Override
+          protected void writeText(QuickWriter writer, String text) {
+            if (text.startsWith(PREFIX_CDATA) && text.endsWith(SUFFIX_CDATA)) {
+              writer.write(text);
+            } else if (text.startsWith(PREFIX_MEDIA_ID) && text.endsWith(SUFFIX_MEDIA_ID)) {
+              writer.write(text);
+            } else {
+              super.writeText(writer, text);
+            }
+
+          }
+        };
+      }
+    });
+    xstream.ignoreUnknownElements();
+    xstream.setMode(XStream.NO_REFERENCES);
+    xstream.addPermission(NullPermission.NULL);
+    xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
+    return xstream;
+  }
+
+}

+ 11 - 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamMediaIdConverter.java

@@ -0,0 +1,11 @@
+package me.chanjar.weixin.common.util.xml;
+
+/**
+ * Created by qianjia on 15/1/19.
+ */
+public class XStreamMediaIdConverter extends XStreamCDataConverter {
+  @Override
+  public String toString(Object obj) {
+    return "<MediaId>" + super.toString(obj) + "</MediaId>";
+  }
+}

+ 0 - 73
weixin-java-cp/pom.xml.versionsBackup

@@ -1,73 +0,0 @@
-<?xml version="1.0"?>
-<project
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>me.chanjar</groupId>
-        <artifactId>weixin-java-parent</artifactId>
-        <version>1.0.5-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>weixin-java-cp</artifactId>
-    <name>WeiXin Java Tools - CP</name>
-    <description>微信企业号Java SDK</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>me.chanjar</groupId>
-            <artifactId>weixin-java-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <version>6.8.7</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
-            <version>1.9.5</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.inject</groupId>
-            <artifactId>guice</artifactId>
-            <version>3.0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <suiteXmlFiles>
-                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
-                    </suiteXmlFiles>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>

+ 2 - 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageHandler.java

@@ -1,10 +1,10 @@
 package me.chanjar.weixin.cp.api;
 
-import java.util.Map;
-
 import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
 import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
 
+import java.util.Map;
+
 /**
  * 处理微信推送消息的处理器接口
  * @author Daniel Qian

+ 2 - 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageInterceptor.java

@@ -1,9 +1,9 @@
 package me.chanjar.weixin.cp.api;
 
-import java.util.Map;
-
 import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
 
+import java.util.Map;
+
 /**
  * 微信消息拦截器,可以用来做验证
  * @author Daniel Qian

+ 3 - 3
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java

@@ -1,5 +1,8 @@
 package me.chanjar.weixin.cp.api;
 
+import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -8,9 +11,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.regex.Pattern;
 
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
-
 /**
  * <pre>
  * 微信消息路由器,通过代码化的配置,把来自微信的消息交给handler处理

+ 8 - 7
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java

@@ -1,17 +1,18 @@
 package me.chanjar.weixin.cp.api;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
 import me.chanjar.weixin.common.bean.WxMenu;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.util.http.RequestExecutor;
-import me.chanjar.weixin.cp.bean.*;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
+import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.WxCpTag;
 import me.chanjar.weixin.cp.bean.WxCpUser;
-import me.chanjar.weixin.common.exception.WxErrorException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
 
 /**
  * 微信API的Service

+ 3 - 3
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java

@@ -1,11 +1,11 @@
 package me.chanjar.weixin.cp.bean;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import me.chanjar.weixin.cp.bean.messagebuilder.*;
 import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * 消息
  * @author Daniel Qian

+ 79 - 95
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java

@@ -1,14 +1,13 @@
 package me.chanjar.weixin.cp.bean;
 
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 import me.chanjar.weixin.cp.api.WxCpConfigStorage;
 import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
-import me.chanjar.weixin.cp.util.xml.XmlTransformer;
+import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
 import org.apache.commons.io.IOUtils;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.annotation.*;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -25,103 +24,102 @@ import java.util.List;
  *
  * @author Daniel Qian
  */
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxCpXmlMessage {
 
   ///////////////////////
   // 以下都是微信推送过来的消息的xml的element所对应的属性
   ///////////////////////
 
-  @XmlElement(name="AgentID")
+  @XStreamAlias("AgentID")
   private Integer agentId;
 
-  @XmlElement(name = "ToUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("ToUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String toUserName;
 
-  @XmlElement(name = "FromUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("FromUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String fromUserName;
 
-  @XmlElement(name = "CreateTime")
+  @XStreamAlias("CreateTime")
   private Long createTime;
 
-  @XmlElement(name = "MsgType")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("MsgType")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String msgType;
 
-  @XmlElement(name = "Content")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Content")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String content;
 
-  @XmlElement(name = "MsgId")
+  @XStreamAlias("MsgId")
   private Long msgId;
 
-  @XmlElement(name = "PicUrl")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("PicUrl")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String picUrl;
 
-  @XmlElement(name = "MediaId")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("MediaId")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String mediaId;
 
-  @XmlElement(name = "Format")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Format")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String format;
 
-  @XmlElement(name = "ThumbMediaId")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("ThumbMediaId")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String thumbMediaId;
 
-  @XmlElement(name = "Location_X")
+  @XStreamAlias("Location_X")
   private Double locationX;
 
-  @XmlElement(name = "Location_Y")
+  @XStreamAlias("Location_Y")
   private Double locationY;
 
-  @XmlElement(name = "Scale")
+  @XStreamAlias("Scale")
   private Double scale;
 
-  @XmlElement(name = "Label")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Label")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String label;
 
-  @XmlElement(name = "Title")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Title")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String title;
 
-  @XmlElement(name = "Description")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Description")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String description;
 
-  @XmlElement(name = "Url")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Url")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String url;
 
-  @XmlElement(name = "Event")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Event")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String event;
 
-  @XmlElement(name = "EventKey")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("EventKey")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String eventKey;
 
-  @XmlElement(name = "Ticket")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Ticket")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String ticket;
 
-  @XmlElement(name = "Latitude")
+  @XStreamAlias("Latitude")
   private Double latitude;
 
-  @XmlElement(name = "Longitude")
+  @XStreamAlias("Longitude")
   private Double longitude;
 
-  @XmlElement(name = "Precision")
+  @XStreamAlias("Precision")
   private Double precision;
 
-  @XmlElement(name = "Recognition")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Recognition")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String recognition;
 
   ///////////////////////////////////////
@@ -130,37 +128,37 @@ public class WxCpXmlMessage {
   /**
    * 群发的结果
    */
-  @XmlElement(name = "Status")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Status")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String status;
   /**
    * group_id下粉丝数;或者openid_list中的粉丝数
    */
-  @XmlElement(name = "TotalCount")
+  @XStreamAlias("TotalCount")
   private Integer totalCount;
   /**
    * 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount
    */
-  @XmlElement(name = "FilterCount")
+  @XStreamAlias("FilterCount")
   private Integer filterCount;
   /**
    * 发送成功的粉丝数
    */
-  @XmlElement(name = "SentCount")
+  @XStreamAlias("SentCount")
   private Integer sentCount;
   /**
    * 发送失败的粉丝数
    */
-  @XmlElement(name = "ErrorCount")
+  @XStreamAlias("ErrorCount")
   private Integer errorCount;
 
-  @XmlElement(name = "ScanCodeInfo")
+  @XStreamAlias("ScanCodeInfo")
   private ScanCodeInfo scanCodeInfo = new ScanCodeInfo();
 
-  @XmlElement(name = "SendPicsInfo")
+  @XStreamAlias("SendPicsInfo")
   private SendPicsInfo sendPicsInfo = new SendPicsInfo();
 
-  @XmlElement(name = "SendLocationInfo")
+  @XStreamAlias("SendLocationInfo")
   private SendLocationInfo sendLocationInfo = new SendLocationInfo();
 
   public Integer getAgentId() {
@@ -390,19 +388,11 @@ public class WxCpXmlMessage {
   }
 
   protected static WxCpXmlMessage fromXml(String xml) {
-    try {
-      return XmlTransformer.fromXml(WxCpXmlMessage.class, xml);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
+    return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml);
   }
 
   protected static WxCpXmlMessage fromXml(InputStream is) {
-    try {
-      return XmlTransformer.fromXml(WxCpXmlMessage.class, is);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
+    return XStreamTransformer.fromXml(WxCpXmlMessage.class, is);
   }
 
   /**
@@ -499,16 +489,15 @@ public class WxCpXmlMessage {
     this.sendLocationInfo = sendLocationInfo;
   }
 
-  @XmlRootElement(name = "ScanCodeInfo")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("ScanCodeInfo")
   public static class ScanCodeInfo {
 
-    @XmlElement(name = "ScanType")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("ScanType")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String scanType;
 
-    @XmlElement(name = "ScanResult")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("ScanResult")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String scanResult;
 
     /**
@@ -538,15 +527,13 @@ public class WxCpXmlMessage {
 
   }
 
-  @XmlRootElement(name = "SendPicsInfo")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("SendPicsInfo")
   public static class SendPicsInfo {
 
-    @XmlElement(name = "Count")
+    @XStreamAlias("Count")
     private Long count;
 
-    @XmlElementWrapper(name="PicList")
-    @XmlElement(name = "item")
+    @XStreamAlias("PicList")
     protected final List<Item> picList = new ArrayList<Item>();
 
     public Long getCount() {
@@ -561,13 +548,11 @@ public class WxCpXmlMessage {
       return picList;
     }
 
-    @XmlRootElement(name = "item")
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "WxXmlMessage.SendPicsInfo.Item")
+    @XStreamAlias("item")
     public static class Item {
 
-      @XmlElement(name = "PicMd5Sum")
-      @XmlJavaTypeAdapter(AdapterCDATA.class)
+      @XStreamAlias("PicMd5Sum")
+      @XStreamConverter(value=XStreamCDataConverter.class)
       private String PicMd5Sum;
 
       public String getPicMd5Sum() {
@@ -580,28 +565,27 @@ public class WxCpXmlMessage {
     }
   }
 
-  @XmlRootElement(name = "SendLocationInfo")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("SendLocationInfo")
   public static class SendLocationInfo {
 
-    @XmlElement(name = "Location_X")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Location_X")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String locationX;
 
-    @XmlElement(name = "Location_Y")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Location_Y")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String locationY;
 
-    @XmlElement(name = "Scale")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Scale")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String scale;
 
-    @XmlElement(name = "Label")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Label")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String label;
 
-    @XmlElement(name = "Poiname")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Poiname")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String poiname;
 
     public String getLocationX() {

+ 6 - 11
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java

@@ -1,20 +1,15 @@
 package me.chanjar.weixin.cp.bean;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.MediaIdMarshaller;
+import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage {
   
-  @XmlElement(name="Image")
-  @XmlJavaTypeAdapter(MediaIdMarshaller.class)
+  @XStreamAlias("Image")
+  @XStreamConverter(value=XStreamMediaIdConverter.class)
   private String mediaId;
 
   public WxCpXmlOutImageMessage() {

+ 14 - 24
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java

@@ -1,35 +1,29 @@
 package me.chanjar.weixin.cp.bean;
 
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 import me.chanjar.weixin.cp.api.WxCpConfigStorage;
 import me.chanjar.weixin.cp.bean.outxmlbuilder.*;
 import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
-import me.chanjar.weixin.cp.util.xml.XmlTransformer;
+import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+@XStreamAlias("xml")
+public abstract class WxCpXmlOutMessage {
 
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class WxCpXmlOutMessage {
-
-  @XmlElement(name="ToUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("ToUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   protected String toUserName;
   
-  @XmlElement(name="FromUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("FromUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   protected String fromUserName;
   
-  @XmlElement(name="CreateTime")
+  @XStreamAlias("CreateTime")
   protected Long createTime;
   
-  @XmlElement(name="MsgType")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("MsgType")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   protected String msgType;
 
   public String getToUserName() {
@@ -65,11 +59,7 @@ public class WxCpXmlOutMessage {
   }
   
   protected String toXml() {
-    try {
-      return XmlTransformer.toXml((Class)this.getClass(), this);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
+    return XStreamTransformer.toXml((Class)this.getClass(), this);
   }
 
   /**

+ 15 - 18
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java

@@ -1,22 +1,20 @@
 package me.chanjar.weixin.cp.bean;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import javax.xml.bind.annotation.*;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.util.ArrayList;
 import java.util.List;
 
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {
 
-  @XmlElement(name = "ArticleCount")
+  @XStreamAlias("ArticleCount")
   protected int articleCount;
   
-  @XmlElementWrapper(name="Articles")
-  @XmlElement(name = "item")
+  @XStreamAlias("Articles")
   protected final List<Item> articles = new ArrayList<Item>();
   
   public WxCpXmlOutNewsMessage() {
@@ -37,24 +35,23 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {
   }
   
   
-  @XmlRootElement(name = "Item")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("item")
   public static class Item {
     
-    @XmlElement(name = "Title")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Title")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String Title;
 
-    @XmlElement(name = "Description")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Description")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String Description;
 
-    @XmlElement(name="PicUrl")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("PicUrl")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String PicUrl;
     
-    @XmlElement(name="Url")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Url")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String Url;
     
     public String getTitle() {

+ 6 - 11
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java

@@ -1,20 +1,15 @@
 package me.chanjar.weixin.cp.bean;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage {
   
-  @XmlElement(name="Content")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Content")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String content;
 
   public WxCpXmlOutTextMessage() {

+ 13 - 19
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java

@@ -1,19 +1,14 @@
 package me.chanjar.weixin.cp.bean;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
 
-  @XmlElement(name = "Video")
+  @XStreamAlias("Video")
   protected final Video video = new Video();
 
   public WxCpXmlOutVideoMessage() {
@@ -45,20 +40,19 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
   }
   
 
-  @XmlRootElement(name = "Video")
-  @XmlAccessorType(XmlAccessType.FIELD)
-  private static class Video {
+  @XStreamAlias("Video")
+  public static class Video {
     
-    @XmlElement(name = "MediaId")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("MediaId")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String mediaId;
 
-    @XmlElement(name = "Title")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Title")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String title;
 
-    @XmlElement(name = "Description")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Description")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String description;
 
     public String getMediaId() {

+ 6 - 11
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java

@@ -1,20 +1,15 @@
 package me.chanjar.weixin.cp.bean;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.MediaIdMarshaller;
+import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter;
 
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage {
   
-  @XmlElement(name="Voice")
-  @XmlJavaTypeAdapter(MediaIdMarshaller.class)
+  @XStreamAlias("Voice")
+  @XStreamConverter(value=XStreamMediaIdConverter.class)
   private String mediaId;
 
   public WxCpXmlOutVoiceMessage() {

+ 3 - 3
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java

@@ -1,11 +1,11 @@
 package me.chanjar.weixin.cp.bean.outxmlbuilder;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
 import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage.Item;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * 图文消息builder
  * @author Daniel Qian

+ 2 - 9
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java

@@ -8,18 +8,11 @@
  */
 package me.chanjar.weixin.cp.util.json;
 
-import java.lang.reflect.Type;
-
+import com.google.gson.*;
 import me.chanjar.weixin.common.util.json.GsonHelper;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
 
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
 
 /**
  * @author Daniel Qian

+ 4 - 3
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java

@@ -2,11 +2,12 @@ package me.chanjar.weixin.cp.util.json;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
-import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
 import me.chanjar.weixin.common.bean.result.WxError;
-import me.chanjar.weixin.common.util.json.WxMediaUploadResultAdapter;
 import me.chanjar.weixin.common.util.json.WxErrorAdapter;
-import me.chanjar.weixin.cp.bean.*;
+import me.chanjar.weixin.cp.bean.WxCpDepart;
+import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.WxCpTag;
+import me.chanjar.weixin.cp.bean.WxCpUser;
 
 public class WxCpGsonBuilder {
 

+ 2 - 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java

@@ -8,12 +8,12 @@
  */
 package me.chanjar.weixin.cp.util.json;
 
-import java.lang.reflect.Type;
-
 import com.google.gson.*;
 import me.chanjar.weixin.common.util.json.GsonHelper;
 import me.chanjar.weixin.cp.bean.WxCpUser;
 
+import java.lang.reflect.Type;
+
 /**
  * @author Daniel Qian
  */

+ 106 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java

@@ -0,0 +1,106 @@
+package me.chanjar.weixin.cp.util.xml;
+
+import com.thoughtworks.xstream.XStream;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import me.chanjar.weixin.cp.bean.*;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by qianjia on 15/1/19.
+ */
+public class XStreamTransformer {
+
+  protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
+
+  /**
+   * xml -> pojo
+   *
+   * @param clazz
+   * @param xml
+   * @return
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> T fromXml(Class<T> clazz, String xml) {
+    T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
+    return object;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> T fromXml(Class<T> clazz, InputStream is) {
+    T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
+    return object;
+  }
+
+  /**
+   * pojo -> xml
+   *
+   * @param clazz
+   * @param object
+   * @return
+   */
+  public static <T> String toXml(Class<T> clazz, T object) {
+    return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
+  }
+
+  private static Map<Class, XStream> configXStreamInstance() {
+    Map<Class, XStream> map = new HashMap<Class, XStream>();
+    map.put(WxCpXmlMessage.class, config_WxCpXmlMessage());
+    map.put(WxCpXmlOutNewsMessage.class, config_WxCpXmlOutNewsMessage());
+    map.put(WxCpXmlOutTextMessage.class, config_WxCpXmlOutTextMessage());
+    map.put(WxCpXmlOutImageMessage.class, config_WxCpXmlOutImageMessage());
+    map.put(WxCpXmlOutVideoMessage.class, config_WxCpXmlOutVideoMessage());
+    map.put(WxCpXmlOutVoiceMessage.class, config_WxCpXmlOutVoiceMessage());
+    return map;
+  }
+
+  private static XStream config_WxCpXmlMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpXmlMessage.class);
+    xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
+    xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
+    xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
+    xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
+    return xstream;
+  }
+
+  private static XStream config_WxCpXmlOutImageMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutImageMessage.class);
+    return xstream;
+  }
+
+  private static XStream config_WxCpXmlOutNewsMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
+    xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
+    return xstream;
+  }
+
+  private static XStream config_WxCpXmlOutTextMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutTextMessage.class);
+    return xstream;
+  }
+
+  private static XStream config_WxCpXmlOutVideoMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
+    xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
+    return xstream;
+  }
+
+  private static XStream config_WxCpXmlOutVoiceMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpXmlOutMessage.class);
+    xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
+    return xstream;
+  }
+
+}

+ 0 - 93
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XmlTransformer.java

@@ -1,93 +0,0 @@
-package me.chanjar.weixin.cp.util.xml;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-
-import javax.xml.bind.*;
-
-import me.chanjar.weixin.cp.bean.*;
-import org.xml.sax.InputSource;
-
-import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
-
-public class XmlTransformer {
-
-  protected static final JAXBContext JAXB_CONTEXT = initJAXBContext();
-
-  /**
-   * xml -> pojo
-   *
-   * @param clazz
-   * @param xml
-   * @return
-   * @throws JAXBException
-   */
-  @SuppressWarnings("unchecked")
-  public static <T> T fromXml(Class<T> clazz, String xml) throws JAXBException {
-    Unmarshaller um = JAXB_CONTEXT.createUnmarshaller();
-    T object = (T) um.unmarshal(new StringReader(xml));
-    return object;
-  }
-
-  @SuppressWarnings("unchecked")
-  public static <T> T fromXml(Class<T> clazz, InputStream is) throws JAXBException {
-    Unmarshaller um = JAXB_CONTEXT.createUnmarshaller();
-    InputSource inputSource = new InputSource(is);
-    inputSource.setEncoding("utf-8");
-    T object = (T) um.unmarshal(inputSource);
-    return object;
-  }
-
-  /**
-   * pojo -> xml
-   *
-   * @param clazz
-   * @param object
-   * @return
-   * @throws JAXBException
-   */
-  public static <T> String toXml(Class<T> clazz, T object) throws JAXBException {
-    StringWriter stringWriter = new StringWriter();
-    toXml(clazz, object, stringWriter);
-    return stringWriter.getBuffer().toString();
-  }
-
-  public static <T> void toXml(Class<T> clazz, T object, Writer writer) throws JAXBException {
-    Marshaller m = JAXB_CONTEXT.createMarshaller();
-    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-    m.setProperty(CharacterEscapeHandler.class.getName(), CHAR_ESCAPE_HANDLER);
-    m.setProperty(Marshaller.JAXB_FRAGMENT, true);
-    m.marshal(object, writer);
-  }
-
-  protected static final CharacterEscapeHandler CHAR_ESCAPE_HANDLER = new CharacterUnescapeHandler();
-
-  protected static class CharacterUnescapeHandler implements CharacterEscapeHandler {
-    public void escape(char[] ac, int i, int j, boolean flag, Writer writer) throws IOException {
-      writer.write(ac, i, j);
-    }
-  }
-
-  private static JAXBContext initJAXBContext() {
-    /*
-     * JAXBContext对象是线程安全的,根据官方文档的建议将对象作为全局实例
-     * https://jaxb.java.net/guide/Performance_and_thread_safety.html
-     */
-    try {
-      return JAXBContext.newInstance(
-          WxCpXmlOutMessage.class,
-          WxCpXmlOutImageMessage.class,
-          WxCpXmlOutNewsMessage.class,
-          WxCpXmlOutTextMessage.class,
-          WxCpXmlOutVideoMessage.class,
-          WxCpXmlOutVoiceMessage.class,
-          WxCpXmlMessage.class);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-}

+ 11 - 22
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java

@@ -1,23 +1,17 @@
 package me.chanjar.weixin.cp.api;
 
-import java.io.InputStream;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-
 import com.google.inject.Binder;
 import com.google.inject.Module;
-import org.xml.sax.InputSource;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+
+import java.io.InputStream;
 
 public class ApiTestModule implements Module {
 
   @Override
   public void configure(Binder binder) {
-    try {
       InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
       WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, is1);
       WxCpServiceImpl wxService = new WxCpServiceImpl();
@@ -25,21 +19,16 @@ public class ApiTestModule implements Module {
 
       binder.bind(WxCpServiceImpl.class).toInstance(wxService);
       binder.bind(WxCpConfigStorage.class).toInstance(config);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
   }
 
-  public static <T> T fromXml(Class<T> clazz, InputStream is) throws JAXBException {
-    Unmarshaller um = JAXBContext.newInstance(clazz).createUnmarshaller();
-    InputSource inputSource = new InputSource(is);
-    inputSource.setEncoding("utf-8");
-    T object = (T) um.unmarshal(inputSource);
-    return object;
+  public static <T> T fromXml(Class<T> clazz, InputStream is) {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.alias("xml", clazz);
+    xstream.processAnnotations(clazz);
+    return (T) xstream.fromXML(is);
   }
 
-  @XmlRootElement(name = "xml")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("xml")
   public static class WxXmlCpInMemoryConfigStorage extends WxCpInMemoryConfigStorage {
     
     protected String userId;

+ 2 - 4
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java

@@ -1,14 +1,12 @@
 package me.chanjar.weixin.cp.api;
 
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.util.StringUtils;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
-
 /**
  * 基础API测试
  * @author Daniel Qian

+ 3 - 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpDepartAPITest.java

@@ -1,15 +1,13 @@
 package me.chanjar.weixin.cp.api;
 
-import java.util.List;
-
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
+import java.util.List;
 
 /**
  * 测试部门接口

+ 6 - 8
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java

@@ -1,20 +1,18 @@
 package me.chanjar.weixin.cp.api;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
+import com.google.inject.Inject;
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 测试多媒体文件上传下载

+ 2 - 4
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java

@@ -1,14 +1,12 @@
 package me.chanjar.weixin.cp.api;
 
+import com.google.inject.Inject;
 import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.cp.bean.WxCpMessage;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
-
 /***
  * 测试发送消息
  * @author Daniel Qian

+ 2 - 2
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java

@@ -1,7 +1,5 @@
 package me.chanjar.weixin.cp.api;
 
-import java.util.Map;
-
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
 import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
@@ -9,6 +7,8 @@ import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import java.util.Map;
+
 /**
  * 测试消息路由器
  * @author Daniel Qian

+ 1 - 1
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpUserAPITest.java

@@ -1,9 +1,9 @@
 package me.chanjar.weixin.cp.api;
 
 import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
 import me.chanjar.weixin.cp.bean.WxCpUser;
-import me.chanjar.weixin.common.exception.WxErrorException;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;

+ 4 - 8
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java

@@ -1,19 +1,15 @@
 package me.chanjar.weixin.cp.api;
 
-import javax.xml.bind.JAXBException;
-
+import com.google.inject.Inject;
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.bean.WxMenu;
+import me.chanjar.weixin.common.bean.WxMenu.WxMenuButton;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
-
-import me.chanjar.weixin.common.bean.WxMenu.WxMenuButton;
-import me.chanjar.weixin.common.exception.WxErrorException;
-
 /**
  * 测试菜单
  * @author Daniel Qian
@@ -42,7 +38,7 @@ public class WxMenuAPITest {
   }
   
   @DataProvider(name="menu")
-  public Object[][] getMenu() throws JAXBException {
+  public Object[][] getMenu() {
     WxMenu menu = new WxMenu();
     WxMenuButton button1 = new WxMenuButton();
     button1.setType(WxConsts.BUTTON_CLICK);

+ 1 - 2
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java

@@ -1,11 +1,10 @@
 package me.chanjar.weixin.cp.bean;
 
 import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.cp.bean.WxCpMessage.WxArticle;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.cp.bean.WxCpMessage.WxArticle;
-
 @Test
 public class WxCpMessageTest {
 

+ 8 - 14
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java

@@ -1,21 +1,16 @@
 package me.chanjar.weixin.cp.demo;
 
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
 import me.chanjar.weixin.cp.api.WxCpInMemoryConfigStorage;
-import org.xml.sax.InputSource;
 
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
 import java.io.InputStream;
 
 /**
  * @author Daniel Qian
  */
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage {
 
   @Override
@@ -25,11 +20,10 @@ class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage {
   }
 
 
-  public static WxCpDemoInMemoryConfigStorage fromXml(InputStream is) throws JAXBException {
-    Unmarshaller um = JAXBContext.newInstance(WxCpDemoInMemoryConfigStorage.class).createUnmarshaller();
-    InputSource inputSource = new InputSource(is);
-    inputSource.setEncoding("utf-8");
-    return (WxCpDemoInMemoryConfigStorage) um.unmarshal(inputSource);
+  public static WxCpDemoInMemoryConfigStorage fromXml(InputStream is) {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxCpDemoInMemoryConfigStorage.class);
+    return (WxCpDemoInMemoryConfigStorage) xstream.fromXML(is);
   }
 
 }

+ 0 - 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java

@@ -8,7 +8,6 @@ import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.servlet.ServletHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
 
-import javax.xml.bind.JAXBException;
 import java.io.InputStream;
 import java.util.Map;
 
@@ -37,7 +36,6 @@ public class WxCpDemoServer {
   }
 
   private static void initWeixin() {
-    try {
       InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
       WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1);
 
@@ -87,8 +85,5 @@ public class WxCpDemoServer {
           .end()
       ;
 
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
   }
 }

+ 3 - 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java

@@ -1,20 +1,18 @@
 package me.chanjar.weixin.cp.demo;
 
 import me.chanjar.weixin.common.util.StringUtils;
-import me.chanjar.weixin.cp.api.*;
+import me.chanjar.weixin.cp.api.WxCpConfigStorage;
+import me.chanjar.weixin.cp.api.WxCpMessageRouter;
+import me.chanjar.weixin.cp.api.WxCpService;
 import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
 import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
 import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.xml.bind.JAXBException;
 import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
 
 /**
  * @author Daniel Qian

+ 0 - 72
weixin-java-mp/pom.xml.versionsBackup

@@ -1,72 +0,0 @@
-<?xml version="1.0"?>
-<project
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
-        xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>me.chanjar</groupId>
-        <artifactId>weixin-java-parent</artifactId>
-        <version>1.0.5-SNAPSHOT</version>
-    </parent>
-    <artifactId>weixin-java-mp</artifactId>
-    <name>WeiXin Java Tools - MP</name>
-    <description>微信公众号Java SDK</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>me.chanjar</groupId>
-            <artifactId>weixin-java-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <version>6.8.7</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-all</artifactId>
-            <version>1.9.5</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.inject</groupId>
-            <artifactId>guice</artifactId>
-            <version>3.0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
-            <version>9.3.0.M0</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <suiteXmlFiles>
-                        <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
-                    </suiteXmlFiles>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>

+ 1 - 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java

@@ -2,10 +2,10 @@ package me.chanjar.weixin.mp.api;
 
 import me.chanjar.weixin.common.bean.WxMenu;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.util.http.RequestExecutor;
 import me.chanjar.weixin.mp.bean.*;
 import me.chanjar.weixin.mp.bean.result.*;
-import me.chanjar.weixin.common.exception.WxErrorException;
 
 import java.io.File;
 import java.io.IOException;

+ 0 - 32
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMpXmlOutImageMessage.java

@@ -1,32 +0,0 @@
-package me.chanjar.weixin.mp.bean;
-
-import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.MediaIdMarshaller;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class WxMpMpXmlOutImageMessage extends WxMpXmlOutMessage {
-  
-  @XmlElement(name="Image")
-  @XmlJavaTypeAdapter(MediaIdMarshaller.class)
-  private String mediaId;
-
-  public WxMpMpXmlOutImageMessage() {
-    this.msgType = WxConsts.XML_MSG_IMAGE;
-  }
-  
-  public String getMediaId() {
-    return mediaId;
-  }
-
-  public void setMediaId(String mediaId) {
-    this.mediaId = mediaId;
-  }
-  
-}

+ 81 - 99
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlMessage.java

@@ -1,14 +1,13 @@
 package me.chanjar.weixin.mp.bean;
 
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 import me.chanjar.weixin.mp.api.WxMpConfigStorage;
 import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil;
-import me.chanjar.weixin.mp.util.xml.XmlTransformer;
+import me.chanjar.weixin.mp.util.xml.XStreamTransformer;
 import org.apache.commons.io.IOUtils;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.annotation.*;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -25,100 +24,99 @@ import java.util.List;
  *
  * @author chanjarster
  */
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxMpXmlMessage {
 
   ///////////////////////
   // 以下都是微信推送过来的消息的xml的element所对应的属性
   ///////////////////////
 
-  @XmlElement(name = "ToUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("ToUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String toUserName;
 
-  @XmlElement(name = "FromUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("FromUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String fromUserName;
 
-  @XmlElement(name = "CreateTime")
+  @XStreamAlias("CreateTime")
   private Long createTime;
 
-  @XmlElement(name = "MsgType")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("MsgType")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String msgType;
 
-  @XmlElement(name = "Content")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Content")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String content;
 
-  @XmlElement(name = "MsgId")
+  @XStreamAlias("MsgId")
   private Long msgId;
 
-  @XmlElement(name = "PicUrl")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("PicUrl")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String picUrl;
 
-  @XmlElement(name = "MediaId")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("MediaId")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String mediaId;
 
-  @XmlElement(name = "Format")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Format")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String format;
 
-  @XmlElement(name = "ThumbMediaId")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("ThumbMediaId")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String thumbMediaId;
 
-  @XmlElement(name = "Location_X")
+  @XStreamAlias("Location_X")
   private Double locationX;
 
-  @XmlElement(name = "Location_Y")
+  @XStreamAlias("Location_Y")
   private Double locationY;
 
-  @XmlElement(name = "Scale")
+  @XStreamAlias("Scale")
   private Double scale;
 
-  @XmlElement(name = "Label")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Label")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String label;
 
-  @XmlElement(name = "Title")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Title")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String title;
 
-  @XmlElement(name = "Description")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Description")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String description;
 
-  @XmlElement(name = "Url")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Url")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String url;
 
-  @XmlElement(name = "Event")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Event")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String event;
 
-  @XmlElement(name = "EventKey")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("EventKey")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String eventKey;
 
-  @XmlElement(name = "Ticket")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Ticket")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String ticket;
 
-  @XmlElement(name = "Latitude")
+  @XStreamAlias("Latitude")
   private Double latitude;
 
-  @XmlElement(name = "Longitude")
+  @XStreamAlias("Longitude")
   private Double longitude;
 
-  @XmlElement(name = "Precision")
+  @XStreamAlias("Precision")
   private Double precision;
 
-  @XmlElement(name = "Recognition")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Recognition")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String recognition;
 
   ///////////////////////////////////////
@@ -127,37 +125,37 @@ public class WxMpXmlMessage {
   /**
    * 群发的结果
    */
-  @XmlElement(name = "Status")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Status")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String status;
   /**
    * group_id下粉丝数;或者openid_list中的粉丝数
    */
-  @XmlElement(name = "TotalCount")
+  @XStreamAlias("TotalCount")
   private Integer totalCount;
   /**
    * 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount
    */
-  @XmlElement(name = "FilterCount")
+  @XStreamAlias("FilterCount")
   private Integer filterCount;
   /**
    * 发送成功的粉丝数
    */
-  @XmlElement(name = "SentCount")
+  @XStreamAlias("SentCount")
   private Integer sentCount;
   /**
    * 发送失败的粉丝数
    */
-  @XmlElement(name = "ErrorCount")
+  @XStreamAlias("ErrorCount")
   private Integer errorCount;
 
-  @XmlElement(name = "ScanCodeInfo")
+  @XStreamAlias("ScanCodeInfo")
   private ScanCodeInfo scanCodeInfo = new ScanCodeInfo();
 
-  @XmlElement(name = "SendPicsInfo")
+  @XStreamAlias("SendPicsInfo")
   private SendPicsInfo sendPicsInfo = new SendPicsInfo();
 
-  @XmlElement(name = "SendLocationInfo")
+  @XStreamAlias("SendLocationInfo")
   private SendLocationInfo sendLocationInfo = new SendLocationInfo();
 
   public String getToUserName() {
@@ -380,21 +378,11 @@ public class WxMpXmlMessage {
   }
 
   public static WxMpXmlMessage fromXml(String xml) {
-    try {
-      // 操蛋的微信,模板消息推送成功的消息是MsgID,其他消息推送过来是MsgId
-      xml = xml.replaceAll("<MsgID>", "<MsgId>").replaceAll("</MsgID>", "</MsgId>");
-      return XmlTransformer.fromXml(WxMpXmlMessage.class, xml);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
+    return XStreamTransformer.fromXml(WxMpXmlMessage.class, xml);
   }
 
   public static WxMpXmlMessage fromXml(InputStream is) {
-    try {
-      return fromXml(IOUtils.toString(is, "UTF-8"));
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
+    return XStreamTransformer.fromXml(WxMpXmlMessage.class, is);
   }
 
   /**
@@ -491,16 +479,15 @@ public class WxMpXmlMessage {
     this.sendLocationInfo = sendLocationInfo;
   }
 
-  @XmlRootElement(name = "ScanCodeInfo")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("ScanCodeInfo")
   public static class ScanCodeInfo {
 
-    @XmlElement(name = "ScanType")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("ScanType")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String scanType;
 
-    @XmlElement(name = "ScanResult")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("ScanResult")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String scanResult;
 
     /**
@@ -530,15 +517,13 @@ public class WxMpXmlMessage {
 
   }
 
-  @XmlRootElement(name = "SendPicsInfo")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("SendPicsInfo")
   public static class SendPicsInfo {
 
-    @XmlElement(name = "Count")
+    @XStreamAlias("Count")
     private Long count;
 
-    @XmlElementWrapper(name="PicList")
-    @XmlElement(name = "item")
+    @XStreamAlias("PicList")
     protected final List<Item> picList = new ArrayList<Item>();
 
     public Long getCount() {
@@ -553,47 +538,44 @@ public class WxMpXmlMessage {
       return picList;
     }
 
-    @XmlRootElement(name = "item")
-    @XmlAccessorType(XmlAccessType.FIELD)
-    @XmlType(name = "WxXmlMessage.SendPicsInfo.Item")
+    @XStreamAlias("item")
     public static class Item {
 
-      @XmlElement(name = "PicMd5Sum")
-      @XmlJavaTypeAdapter(AdapterCDATA.class)
-      private String PicMd5Sum;
+      @XStreamAlias("PicMd5Sum")
+      @XStreamConverter(value=XStreamCDataConverter.class)
+      private String picMd5Sum;
 
       public String getPicMd5Sum() {
-        return PicMd5Sum;
+        return picMd5Sum;
       }
 
       public void setPicMd5Sum(String picMd5Sum) {
-        PicMd5Sum = picMd5Sum;
+        this.picMd5Sum = picMd5Sum;
       }
     }
   }
 
-  @XmlRootElement(name = "SendLocationInfo")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("SendLocationInfo")
   public static class SendLocationInfo {
 
-    @XmlElement(name = "Location_X")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Location_X")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String locationX;
 
-    @XmlElement(name = "Location_Y")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Location_Y")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String locationY;
 
-    @XmlElement(name = "Scale")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Scale")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String scale;
 
-    @XmlElement(name = "Label")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Label")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String label;
 
-    @XmlElement(name = "Poiname")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Poiname")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String poiname;
 
     public String getLocationX() {

+ 27 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessage.java

@@ -0,0 +1,27 @@
+package me.chanjar.weixin.mp.bean;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter;
+
+@XStreamAlias("xml")
+public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage {
+
+  @XStreamAlias("Image")
+  @XStreamConverter(value = XStreamMediaIdConverter.class)
+  private String mediaId;
+
+  public String getMediaId() {
+    return mediaId;
+  }
+
+  public void setMediaId(String mediaId) {
+    this.mediaId = mediaId;
+  }
+
+  public WxMpXmlOutImageMessage() {
+    this.msgType = WxConsts.XML_MSG_IMAGE;
+  }
+
+}

+ 14 - 24
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMessage.java

@@ -1,35 +1,29 @@
 package me.chanjar.weixin.mp.bean;
 
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 import me.chanjar.weixin.mp.api.WxMpConfigStorage;
 import me.chanjar.weixin.mp.bean.outxmlbuilder.*;
 import me.chanjar.weixin.mp.util.crypto.WxMpCryptUtil;
-import me.chanjar.weixin.mp.util.xml.XmlTransformer;
+import me.chanjar.weixin.mp.util.xml.XStreamTransformer;
 
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+@XStreamAlias("xml")
+public abstract class WxMpXmlOutMessage {
 
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class WxMpXmlOutMessage {
-
-  @XmlElement(name="ToUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("ToUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   protected String toUserName;
   
-  @XmlElement(name="FromUserName")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("FromUserName")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   protected String fromUserName;
   
-  @XmlElement(name="CreateTime")
+  @XStreamAlias("CreateTime")
   protected Long createTime;
   
-  @XmlElement(name="MsgType")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("MsgType")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   protected String msgType;
 
   public String getToUserName() {
@@ -65,11 +59,7 @@ public class WxMpXmlOutMessage {
   }
   
   public String toXml() {
-    try {
-      return XmlTransformer.toXml((Class)this.getClass(), this);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
+    return XStreamTransformer.toXml((Class) this.getClass(), this);
   }
 
   /**

+ 17 - 23
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutMusicMessage.java

@@ -1,19 +1,14 @@
 package me.chanjar.weixin.mp.bean;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxMpXmlOutMusicMessage extends WxMpXmlOutMessage {
 
-  @XmlElement(name = "Music")
+  @XStreamAlias("Music")
   protected final Music music = new Music();
 
   public WxMpXmlOutMusicMessage() {
@@ -60,28 +55,27 @@ public class WxMpXmlOutMusicMessage extends WxMpXmlOutMessage {
     music.setHqMusicUrl(hqMusicUrl);
   }
   
-  @XmlRootElement(name = "Music")
-  @XmlAccessorType(XmlAccessType.FIELD)
-  private static class Music {
+  @XStreamAlias("Music")
+  public static class Music {
     
-    @XmlElement(name = "Title")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Title")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String title;
 
-    @XmlElement(name = "Description")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Description")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String description;
 
-    @XmlElement(name="ThumbMediaId")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("ThumbMediaId")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String thumbMediaId;
     
-    @XmlElement(name="MusicUrl")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("MusicUrl")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String musicUrl;
     
-    @XmlElement(name="HQMusicUrl")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("HQMusicUrl")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String hqMusicUrl;
     
     public String getTitle() {

+ 15 - 18
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutNewsMessage.java

@@ -1,22 +1,20 @@
 package me.chanjar.weixin.mp.bean;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import javax.xml.bind.annotation.*;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import java.util.ArrayList;
 import java.util.List;
 
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage {
 
-  @XmlElement(name = "ArticleCount")
+  @XStreamAlias("ArticleCount")
   protected int articleCount;
   
-  @XmlElementWrapper(name="Articles")
-  @XmlElement(name = "item")
+  @XStreamAlias("Articles")
   protected final List<Item> articles = new ArrayList<Item>();
   
   public WxMpXmlOutNewsMessage() {
@@ -37,24 +35,23 @@ public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage {
   }
   
   
-  @XmlRootElement(name = "Item")
-  @XmlAccessorType(XmlAccessType.FIELD)
+  @XStreamAlias("item")
   public static class Item {
     
-    @XmlElement(name = "Title")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Title")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String Title;
 
-    @XmlElement(name = "Description")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Description")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String Description;
 
-    @XmlElement(name="PicUrl")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("PicUrl")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String PicUrl;
     
-    @XmlElement(name="Url")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Url")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String Url;
     
     public String getTitle() {

+ 6 - 11
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutTextMessage.java

@@ -1,20 +1,15 @@
 package me.chanjar.weixin.mp.bean;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxMpXmlOutTextMessage extends WxMpXmlOutMessage {
   
-  @XmlElement(name="Content")
-  @XmlJavaTypeAdapter(AdapterCDATA.class)
+  @XStreamAlias("Content")
+  @XStreamConverter(value=XStreamCDataConverter.class)
   private String content;
 
   public WxMpXmlOutTextMessage() {

+ 13 - 19
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutVideoMessage.java

@@ -1,19 +1,14 @@
 package me.chanjar.weixin.mp.bean;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.AdapterCDATA;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxMpXmlOutVideoMessage extends WxMpXmlOutMessage {
 
-  @XmlElement(name = "Video")
+  @XStreamAlias("Video")
   protected final Video video = new Video();
 
   public WxMpXmlOutVideoMessage() {
@@ -45,20 +40,19 @@ public class WxMpXmlOutVideoMessage extends WxMpXmlOutMessage {
   }
   
 
-  @XmlRootElement(name = "Video")
-  @XmlAccessorType(XmlAccessType.FIELD)
-  private static class Video {
+  @XStreamAlias("Video")
+    public static class Video {
     
-    @XmlElement(name = "MediaId")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("MediaId")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String mediaId;
 
-    @XmlElement(name = "Title")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Title")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String title;
 
-    @XmlElement(name = "Description")
-    @XmlJavaTypeAdapter(AdapterCDATA.class)
+    @XStreamAlias("Description")
+    @XStreamConverter(value=XStreamCDataConverter.class)
     private String description;
 
     public String getMediaId() {

+ 9 - 14
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlOutVoiceMessage.java

@@ -1,26 +1,21 @@
 package me.chanjar.weixin.mp.bean;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
 import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.util.xml.MediaIdMarshaller;
+import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage {
-  
-  @XmlElement(name="Voice")
-  @XmlJavaTypeAdapter(MediaIdMarshaller.class)
+
+  @XStreamAlias("Voice")
+  @XStreamConverter(value = XStreamMediaIdConverter.class)
   private String mediaId;
 
   public WxMpXmlOutVoiceMessage() {
     this.msgType = WxConsts.XML_MSG_VOICE;
   }
-  
+
   public String getMediaId() {
     return mediaId;
   }
@@ -28,5 +23,5 @@ public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage {
   public void setMediaId(String mediaId) {
     this.mediaId = mediaId;
   }
-  
+
 }

+ 4 - 4
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/outxmlbuilder/ImageBuilder.java

@@ -1,12 +1,12 @@
 package me.chanjar.weixin.mp.bean.outxmlbuilder;
 
-import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlOutImageMessage;
 
 /**
  * 图片消息builder
  * @author chanjarster
  */
-public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxMpMpXmlOutImageMessage> {
+public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxMpXmlOutImageMessage> {
 
   private String mediaId;
 
@@ -15,8 +15,8 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxMpMpXmlOutIm
     return this;
   }
 
-  public WxMpMpXmlOutImageMessage build() {
-    WxMpMpXmlOutImageMessage m = new WxMpMpXmlOutImageMessage();
+  public WxMpXmlOutImageMessage build() {
+    WxMpXmlOutImageMessage m = new WxMpXmlOutImageMessage();
     setCommon(m);
     m.setMediaId(this.mediaId);
     return m;

+ 0 - 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java

@@ -1,6 +1,5 @@
 package me.chanjar.weixin.mp.bean.result;
 
-import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 
 /**

+ 1 - 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java

@@ -1,12 +1,12 @@
 package me.chanjar.weixin.mp.util.http;
 
 import me.chanjar.weixin.common.bean.result.WxError;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.util.fs.FileUtils;
 import me.chanjar.weixin.common.util.http.InputStreamResponseHandler;
 import me.chanjar.weixin.common.util.http.RequestExecutor;
 import me.chanjar.weixin.common.util.http.Utf8ResponseHandler;
 import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
-import me.chanjar.weixin.common.exception.WxErrorException;
 import org.apache.http.Header;
 import org.apache.http.HttpHost;
 import org.apache.http.client.ClientProtocolException;

+ 0 - 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java

@@ -4,7 +4,6 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import me.chanjar.weixin.mp.bean.*;
 import me.chanjar.weixin.mp.bean.result.*;
-import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
 
 public class WxMpGsonBuilder {
 

+ 0 - 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java

@@ -1,7 +1,6 @@
 package me.chanjar.weixin.mp.util.json;
 
 import com.google.gson.*;
-import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.util.json.GsonHelper;
 import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
 

+ 0 - 2
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java

@@ -10,8 +10,6 @@ package me.chanjar.weixin.mp.util.json;
 
 import com.google.gson.*;
 import me.chanjar.weixin.common.util.json.GsonHelper;
-import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
-import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
 import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
 
 import java.lang.reflect.Type;

+ 4 - 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java

@@ -8,9 +8,10 @@
  */
 package me.chanjar.weixin.mp.util.json;
 
-import com.google.gson.*;
-import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
 import me.chanjar.weixin.mp.bean.WxMpTemplateData;
 import me.chanjar.weixin.mp.bean.WxMpTemplateMessage;
 

+ 117 - 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java

@@ -0,0 +1,117 @@
+package me.chanjar.weixin.mp.util.xml;
+
+import com.thoughtworks.xstream.XStream;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import me.chanjar.weixin.mp.bean.*;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by qianjia on 15/1/19.
+ */
+public class XStreamTransformer {
+
+  protected static final Map<Class, XStream> CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
+
+  /**
+   * xml -> pojo
+   *
+   * @param clazz
+   * @param xml
+   * @return
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> T fromXml(Class<T> clazz, String xml) {
+    T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
+    return object;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> T fromXml(Class<T> clazz, InputStream is) {
+    T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
+    return object;
+  }
+
+  /**
+   * pojo -> xml
+   *
+   * @param clazz
+   * @param object
+   * @return
+   */
+  public static <T> String toXml(Class<T> clazz, T object) {
+    return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
+  }
+
+  private static Map<Class, XStream> configXStreamInstance() {
+    Map<Class, XStream> map = new HashMap<Class, XStream>();
+    map.put(WxMpXmlMessage.class, config_WxMpXmlMessage());
+    map.put(WxMpXmlOutMusicMessage.class, config_WxMpXmlOutMusicMessage());
+    map.put(WxMpXmlOutNewsMessage.class, config_WxMpXmlOutNewsMessage());
+    map.put(WxMpXmlOutTextMessage.class, config_WxMpXmlOutTextMessage());
+    map.put(WxMpXmlOutImageMessage.class, config_WxMpXmlOutImageMessage());
+    map.put(WxMpXmlOutVideoMessage.class, config_WxMpXmlOutVideoMessage());
+    map.put(WxMpXmlOutVoiceMessage.class, config_WxMpXmlOutVoiceMessage());
+    return map;
+  }
+
+  private static XStream config_WxMpXmlMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpXmlMessage.class);
+    xstream.processAnnotations(WxMpXmlMessage.ScanCodeInfo.class);
+    xstream.processAnnotations(WxMpXmlMessage.SendPicsInfo.class);
+    xstream.processAnnotations(WxMpXmlMessage.SendPicsInfo.Item.class);
+    xstream.processAnnotations(WxMpXmlMessage.SendLocationInfo.class);
+
+    xstream.aliasField("MsgID", WxMpXmlMessage.class, "msgId");
+    return xstream;
+  }
+
+  private static XStream config_WxMpXmlOutImageMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpXmlOutMessage.class);
+    xstream.processAnnotations(WxMpXmlOutImageMessage.class);
+    return xstream;
+  }
+
+  private static XStream config_WxMpXmlOutNewsMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpXmlOutMessage.class);
+    xstream.processAnnotations(WxMpXmlOutNewsMessage.class);
+    xstream.processAnnotations(WxMpXmlOutNewsMessage.Item.class);
+    return xstream;
+  }
+
+  private static XStream config_WxMpXmlOutMusicMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpXmlOutMessage.class);
+    xstream.processAnnotations(WxMpXmlOutMusicMessage.class);
+    xstream.processAnnotations(WxMpXmlOutMusicMessage.Music.class);
+    return xstream;
+  }
+
+  private static XStream config_WxMpXmlOutTextMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpXmlOutMessage.class);
+    xstream.processAnnotations(WxMpXmlOutTextMessage.class);
+    return xstream;
+  }
+
+  private static XStream config_WxMpXmlOutVideoMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpXmlOutMessage.class);
+    xstream.processAnnotations(WxMpXmlOutVideoMessage.class);
+    xstream.processAnnotations(WxMpXmlOutVideoMessage.Video.class);
+    return xstream;
+  }
+
+  private static XStream config_WxMpXmlOutVoiceMessage() {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpXmlOutMessage.class);
+    xstream.processAnnotations(WxMpXmlOutVoiceMessage.class);
+    return xstream;
+  }
+
+}

+ 0 - 91
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XmlTransformer.java

@@ -1,91 +0,0 @@
-package me.chanjar.weixin.mp.util.xml;
-
-import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
-import me.chanjar.weixin.mp.bean.*;
-import org.xml.sax.InputSource;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import java.io.*;
-
-public class XmlTransformer {
-
-  protected static final JAXBContext JAXB_CONTEXT = initJAXBContext();
-
-  /**
-   * xml -> pojo
-   *
-   * @param clazz
-   * @param xml
-   * @return
-   * @throws JAXBException
-   */
-  @SuppressWarnings("unchecked")
-  public static <T> T fromXml(Class<T> clazz, String xml) throws JAXBException {
-    Unmarshaller um = JAXB_CONTEXT.createUnmarshaller();
-    T object = (T) um.unmarshal(new StringReader(xml));
-    return object;
-  }
-
-  @SuppressWarnings("unchecked")
-  public static <T> T fromXml(Class<T> clazz, InputStream is) throws JAXBException {
-    Unmarshaller um = JAXB_CONTEXT.createUnmarshaller();
-    InputSource inputSource = new InputSource(is);
-    inputSource.setEncoding("utf-8");
-    T object = (T) um.unmarshal(inputSource);
-    return object;
-  }
-
-  /**
-   * pojo -> xml
-   *
-   * @param clazz
-   * @param object
-   * @return
-   * @throws JAXBException
-   */
-  public static <T> String toXml(Class<T> clazz, T object) throws JAXBException {
-    StringWriter stringWriter = new StringWriter();
-    toXml(clazz, object, stringWriter);
-    return stringWriter.getBuffer().toString();
-  }
-
-  public static <T> void toXml(Class<T> clazz, T object, Writer writer) throws JAXBException {
-    Marshaller m = JAXB_CONTEXT.createMarshaller();
-    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-    m.setProperty(CharacterEscapeHandler.class.getName(), CHAR_ESCAPE_HANDLER);
-    m.setProperty(Marshaller.JAXB_FRAGMENT, true);
-    m.marshal(object, writer);
-  }
-
-  protected static final CharacterEscapeHandler CHAR_ESCAPE_HANDLER = new CharacterUnescapeHandler();
-
-  protected static class CharacterUnescapeHandler implements CharacterEscapeHandler {
-    public void escape(char[] ac, int i, int j, boolean flag, Writer writer) throws IOException {
-      writer.write(ac, i, j);
-    }
-  }
-
-  private static JAXBContext initJAXBContext() {
-    /*
-     * JAXBContext对象是线程安全的,根据官方文档的建议将对象作为全局实例
-     * https://jaxb.java.net/guide/Performance_and_thread_safety.html
-     */
-    try {
-      return JAXBContext.newInstance(
-          WxMpXmlOutMessage.class,
-          WxMpMpXmlOutImageMessage.class,
-          WxMpXmlOutNewsMessage.class,
-          WxMpXmlOutMusicMessage.class,
-          WxMpXmlOutTextMessage.class,
-          WxMpXmlOutVideoMessage.class,
-          WxMpXmlOutVoiceMessage.class,
-          WxMpXmlMessage.class);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-}

+ 19 - 30
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/ApiTestModule.java

@@ -1,46 +1,35 @@
 package me.chanjar.weixin.mp.api;
 
-import java.io.InputStream;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-
 import com.google.inject.Binder;
 import com.google.inject.Module;
-import org.xml.sax.InputSource;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+
+import java.io.InputStream;
 
 public class ApiTestModule implements Module {
 
   @Override
   public void configure(Binder binder) {
-    try {
-      InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
-      WxXmlMpInMemoryConfigStorage config = fromXml(WxXmlMpInMemoryConfigStorage.class, is1);
-      WxMpServiceImpl wxService = new WxMpServiceImpl();
-      wxService.setWxMpConfigStorage(config);
-
-      binder.bind(WxMpServiceImpl.class).toInstance(wxService);
-      binder.bind(WxMpConfigStorage.class).toInstance(config);
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
+    InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
+    WxXmlMpInMemoryConfigStorage config = fromXml(WxXmlMpInMemoryConfigStorage.class, is1);
+    WxMpServiceImpl wxService = new WxMpServiceImpl();
+    wxService.setWxMpConfigStorage(config);
+
+    binder.bind(WxMpServiceImpl.class).toInstance(wxService);
+    binder.bind(WxMpConfigStorage.class).toInstance(config);
   }
 
-  public static <T> T fromXml(Class<T> clazz, InputStream is) throws JAXBException {
-    Unmarshaller um = JAXBContext.newInstance(clazz).createUnmarshaller();
-    InputSource inputSource = new InputSource(is);
-    inputSource.setEncoding("utf-8");
-    T object = (T) um.unmarshal(inputSource);
-    return object;
+  public static <T> T fromXml(Class<T> clazz, InputStream is) {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.alias("xml", clazz);
+    xstream.processAnnotations(clazz);
+    return (T) xstream.fromXML(is);
   }
 
-  @XmlRootElement(name = "xml")
-  @XmlAccessorType(XmlAccessType.FIELD)
-  public static class WxXmlMpInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
+  @XStreamAlias("xml")
+    public static class WxXmlMpInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
     
     protected String openId;
 

+ 3 - 5
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxBaseAPITest.java

@@ -1,14 +1,12 @@
 package me.chanjar.weixin.mp.api;
 
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.util.StringUtils;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
-
 /**
  * 基础API测试
  * @author chanjarster
@@ -16,7 +14,7 @@ import com.google.inject.Inject;
  */
 @Test(groups = "baseAPI")
 @Guice(modules = ApiTestModule.class)
-public class WxBaseAPITest {
+public class WxMpBaseAPITest {
 
   @Inject
   protected WxMpServiceImpl wxService;

+ 2 - 4
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpCustomMessageAPITest.java

@@ -1,14 +1,12 @@
 package me.chanjar.weixin.mp.api;
 
+import com.google.inject.Inject;
 import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
-
 /***
  * 测试发送客服消息
  * @author chanjarster

+ 3 - 5
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpGroupAPITest.java

@@ -1,15 +1,13 @@
 package me.chanjar.weixin.mp.api;
 
-import java.util.List;
-
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.mp.bean.WxMpGroup;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
+import java.util.List;
 
 /**
  * 测试分组接口

+ 4 - 6
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMassMessageAPITest.java

@@ -1,10 +1,9 @@
 package me.chanjar.weixin.mp.api;
 
-import java.io.IOException;
-import java.io.InputStream;
-
+import com.google.inject.Inject;
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage;
 import me.chanjar.weixin.mp.bean.WxMpMassNews;
 import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage;
@@ -16,9 +15,8 @@ import org.testng.annotations.DataProvider;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
+import java.io.IOException;
+import java.io.InputStream;
 
 /**
  * 测试群发消息

+ 6 - 8
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMediaAPITest.java

@@ -1,20 +1,18 @@
 package me.chanjar.weixin.mp.api;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
+import com.google.inject.Inject;
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 测试多媒体文件上传下载

+ 5 - 9
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMenuAPITest.java

@@ -1,19 +1,15 @@
 package me.chanjar.weixin.mp.api;
 
-import javax.xml.bind.JAXBException;
-
+import com.google.inject.Inject;
 import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.bean.WxMenu;
+import me.chanjar.weixin.common.bean.WxMenu.WxMenuButton;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import com.google.inject.Inject;
-
-import me.chanjar.weixin.common.bean.WxMenu;
-import me.chanjar.weixin.common.bean.WxMenu.WxMenuButton;
-import me.chanjar.weixin.common.exception.WxErrorException;
-
 /**
  * 测试菜单
  * @author chanjarster
@@ -42,7 +38,7 @@ public class WxMpMenuAPITest {
   }
   
   @DataProvider(name="menu")
-  public Object[][] getMenu() throws JAXBException {
+  public Object[][] getMenu() {
     WxMenu menu = new WxMenu();
     WxMenuButton button1 = new WxMenuButton();
     button1.setType(WxConsts.BUTTON_CLICK);

+ 2 - 2
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java

@@ -1,7 +1,5 @@
 package me.chanjar.weixin.mp.api;
 
-import java.util.Map;
-
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
 import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
@@ -9,6 +7,8 @@ import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import java.util.Map;
+
 /**
  * 测试消息路由器
  * @author chanjarster

+ 3 - 5
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpQrCodeAPITest.java

@@ -1,15 +1,13 @@
 package me.chanjar.weixin.mp.api;
 
-import java.io.File;
-
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
+import java.io.File;
 
 /**
  * 测试用户相关的接口

+ 2 - 4
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpShortUrlAPITest.java

@@ -1,13 +1,11 @@
 package me.chanjar.weixin.mp.api;
 
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
-
 /**
  * 测试短连接
  * 

+ 3 - 5
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpUserAPITest.java

@@ -1,15 +1,13 @@
 package me.chanjar.weixin.mp.api;
 
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.exception.WxErrorException;
+import me.chanjar.weixin.mp.bean.result.WxMpUser;
 import me.chanjar.weixin.mp.bean.result.WxMpUserList;
 import org.testng.Assert;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.mp.bean.result.WxMpUser;
-import me.chanjar.weixin.common.exception.WxErrorException;
-
-import com.google.inject.Inject;
-
 /**
  * 测试用户相关的接口
  * @author chanjarster

+ 1 - 2
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpCustomMessageTest.java

@@ -1,11 +1,10 @@
 package me.chanjar.weixin.mp.bean;
 
 import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.mp.bean.WxMpCustomMessage.WxArticle;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import me.chanjar.weixin.mp.bean.WxMpCustomMessage.WxArticle;
-
 @Test
 public class WxMpCustomMessageTest {
 

+ 2 - 2
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/WxMpXmlOutImageMessageTest.java

@@ -7,7 +7,7 @@ import org.testng.annotations.Test;
 public class WxMpXmlOutImageMessageTest {
 
   public void test() {
-    WxMpMpXmlOutImageMessage m = new WxMpMpXmlOutImageMessage();
+    WxMpXmlOutImageMessage m = new WxMpXmlOutImageMessage();
     m.setMediaId("ddfefesfsdfef");
     m.setCreateTime(1122l);
     m.setFromUserName("from");
@@ -25,7 +25,7 @@ public class WxMpXmlOutImageMessageTest {
   }
   
   public void testBuild() {
-    WxMpMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build();
+    WxMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId("ddfefesfsdfef").fromUser("from").toUser("to").build();
     String expected = "<xml>"
         + "<ToUserName><![CDATA[to]]></ToUserName>"
         + "<FromUserName><![CDATA[from]]></FromUserName>"

+ 8 - 14
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java

@@ -1,21 +1,16 @@
 package me.chanjar.weixin.mp.demo;
 
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
 import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
-import org.xml.sax.InputSource;
 
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
 import java.io.InputStream;
 
 /**
  * @author Daniel Qian
  */
-@XmlRootElement(name = "xml")
-@XmlAccessorType(XmlAccessType.FIELD)
+@XStreamAlias("xml")
 class WxMpDemoInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
 
   @Override
@@ -25,11 +20,10 @@ class WxMpDemoInMemoryConfigStorage extends WxMpInMemoryConfigStorage {
   }
 
 
-  public static WxMpDemoInMemoryConfigStorage fromXml(InputStream is) throws JAXBException {
-    Unmarshaller um = JAXBContext.newInstance(WxMpDemoInMemoryConfigStorage.class).createUnmarshaller();
-    InputSource inputSource = new InputSource(is);
-    inputSource.setEncoding("utf-8");
-    return (WxMpDemoInMemoryConfigStorage) um.unmarshal(inputSource);
+  public static WxMpDemoInMemoryConfigStorage fromXml(InputStream is) {
+    XStream xstream = XStreamInitializer.getInstance();
+    xstream.processAnnotations(WxMpDemoInMemoryConfigStorage.class);
+    return (WxMpDemoInMemoryConfigStorage) xstream.fromXML(is);
   }
 
 }

+ 4 - 8
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java

@@ -4,14 +4,14 @@ import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
 import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.mp.api.*;
-import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage;
 import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.WxMpXmlOutImageMessage;
 import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
 import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.*;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
 
-import javax.xml.bind.JAXBException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map;
@@ -41,7 +41,6 @@ public class WxMpDemoServer {
   }
 
   private static void initWeixin() {
-    try {
       InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
       WxMpDemoInMemoryConfigStorage config = WxMpDemoInMemoryConfigStorage.fromXml(is1);
 
@@ -67,7 +66,7 @@ public class WxMpDemoServer {
           try {
             WxMediaUploadResult wxMediaUploadResult = wxMpService
                 .mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg"));
-            WxMpMpXmlOutImageMessage m
+            WxMpXmlOutImageMessage m
                 = WxMpXmlOutMessage
                 .IMAGE()
                 .mediaId(wxMediaUploadResult.getMediaId())
@@ -117,8 +116,5 @@ public class WxMpDemoServer {
           .end()
       ;
 
-    } catch (JAXBException e) {
-      throw new RuntimeException(e);
-    }
   }
 }

+ 3 - 9
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlet.java

@@ -1,23 +1,17 @@
 package me.chanjar.weixin.mp.demo;
 
-import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
-import me.chanjar.weixin.common.exception.WxErrorException;
 import me.chanjar.weixin.common.util.StringUtils;
-import me.chanjar.weixin.mp.api.*;
-import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage;
+import me.chanjar.weixin.mp.api.WxMpConfigStorage;
+import me.chanjar.weixin.mp.api.WxMpMessageRouter;
+import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
 import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
-import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.xml.bind.JAXBException;
 import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
 
 /**
  * @author Daniel Qian

+ 1 - 12
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java

@@ -1,26 +1,15 @@
 package me.chanjar.weixin.mp.demo;
 
-import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
 import me.chanjar.weixin.common.exception.WxErrorException;
-import me.chanjar.weixin.common.util.StringUtils;
-import me.chanjar.weixin.mp.api.*;
-import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage;
-import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
-import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
-import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
+import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
 import me.chanjar.weixin.mp.bean.result.WxMpUser;
 
-import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.xml.bind.JAXBException;
 import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
 
 public class WxMpOAuth2Servlet extends HttpServlet {
 

+ 1 - 1
weixin-java-mp/src/test/resources/testng.xml

@@ -3,7 +3,7 @@
 <suite name="Weixin-java-tool-suite" verbose="1">
 	<test name="API_Test">
 		<classes>
-			<class name="me.chanjar.weixin.mp.api.WxBaseAPITest" />
+			<class name="me.chanjar.weixin.mp.api.WxMpBaseAPITest" />
 			<class name="me.chanjar.weixin.mp.api.WxMpCustomMessageAPITest" />
 			<class name="me.chanjar.weixin.mp.api.WxMpMenuAPITest" />
 			<class name="me.chanjar.weixin.mp.api.WxMpGroupAPITest" />