diff --git a/.gitignore b/.gitignore index 4ee3979b32..f50d5eb350 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ Temporary Items .apdisk /.sonar/ sonar-project.properties + +!/.mvn/wrapper/maven-wrapper.jar +*.versionsBackup diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000..c6feb8bb6f Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..a447c9fa81 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index b0ff29de1b..2f01901cf5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,15 +8,15 @@ language: java jdk: - oraclejdk8 -script: "mvn clean package -Dmaven.test.skip=true" - +script: "./mvnw clean package -DskipTests=true" + #script: # - mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar - + branches: only: - develop - + cache: directories: - '$HOME/.m2/repository' diff --git a/alipay_qrcode.jpg b/alipay_qrcode.jpg deleted file mode 100644 index 105f1d8753..0000000000 Binary files a/alipay_qrcode.jpg and /dev/null differ diff --git a/check-dependency-updates.sh b/check-dependency-updates.sh new file mode 100755 index 0000000000..13e8f0ef30 --- /dev/null +++ b/check-dependency-updates.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +./mvnw org.codehaus.mojo:versions-maven-plugin:display-dependency-updates diff --git a/check-plugin-updates.sh b/check-plugin-updates.sh new file mode 100755 index 0000000000..0ce88b4df6 --- /dev/null +++ b/check-plugin-updates.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +./mvnw org.codehaus.mojo:versions-maven-plugin:display-plugin-updates diff --git a/check-property-updates.sh b/check-property-updates.sh new file mode 100755 index 0000000000..4dd46a17d1 --- /dev/null +++ b/check-property-updates.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +./mvnw org.codehaus.mojo:versions-maven-plugin:display-property-updates diff --git a/demo.md b/demo.md new file mode 100644 index 0000000000..dd10a36bb2 --- /dev/null +++ b/demo.md @@ -0,0 +1,16 @@ + +## Demo项目 +### 说明 +1. 在码云和GitHub上均可访问,会尽量保持同步,请根据自己情况选用。 +1. 一般来说,Github上的版本应该是最新的,但也有可能没及时同步,此种情况下请以github上的版本为准,有问题也请在github对应项目issues页面提问)。 +1. 欢迎提供更多的demo实现。 + +### Demo列表 +1. 微信支付Demo:[GitHub](http://github.com/binarywang/weixin-java-pay-demo)、[码云](http://gitee.com/binary/weixin-java-pay-demo) +1. 企业号/企业微信Demo:[GitHub](http://github.com/binarywang/weixin-java-cp-demo)、[码云](http://gitee.com/binary/weixin-java-cp-demo) +1. 微信小程序Demo:[GitHub](http://github.com/binarywang/weixin-java-miniapp-demo)、[码云](http://gitee.com/binary/weixin-java-miniapp-demo) +1. 开放平台Demo:[GitHub](http://github.com/Wechat-Group/weixin-java-open-demo)、[码云](http://gitee.com/binary/weixin-java-open-demo) +1. 公众号Demo: + - 使用Spring MVC实现的公众号Demo:[GitHub](http://github.com/binarywang/weixin-java-mp-demo-springmvc)、[码云](https://gitee.com/binary/weixin-java-mp-demo) + - 使用Spring Boot实现的公众号Demo(支持多公众号):[GitHub](http://github.com/binarywang/weixin-java-mp-demo-springboot)、[码云](http://gitee.com/binary/weixin-java-mp-demo-springboot) + - 含公众号和部分微信支付代码的Demo:[GitHub](http://github.com/Wechat-Group/weixin-java-tools-springmvc)、[码云](http://gitee.com/binary/weixin-java-tools-springmvc) diff --git a/mvnw b/mvnw new file mode 100755 index 0000000000..6ecc150ae0 --- /dev/null +++ b/mvnw @@ -0,0 +1,236 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + wdir=$(cd "$wdir/.."; pwd) + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in $@ +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000000..8bb8275416 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,146 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in %* +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index f93c5dd5c6..7cbd71163d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,10 +6,10 @@ 4.0.0 com.github.binarywang weixin-java-parent - 2.8.0 + 3.2.0 pom - WeiXin Java Tools - Parent - 微信公众号、企业号上级POM + Weixin Java Tools - Parent + 微信开发Java SDK https://github.com/wechat-group/weixin-java-tools @@ -80,6 +80,11 @@ crskyp@gmail.com https://github.com/crskyp + + 007 + 007gzs@gmail.com + https://github.com/007gzs + @@ -94,6 +99,7 @@ weixin-java-mp weixin-java-pay weixin-java-miniapp + weixin-java-open @@ -102,8 +108,6 @@ 1.7 UTF-8 - true - true 4.5 9.3.0.RC0 @@ -219,12 +223,25 @@ ${jetty.version} test + + org.assertj + assertj-guava + 3.0.0 + test + + redis.clients jedis 2.9.0 provided + + org.projectlombok + lombok + 1.16.18 + provided + @@ -341,15 +358,6 @@ deploy - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.0 - - UTF-8 - - - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/qrcodes/alipay_qrcode.jpg b/qrcodes/alipay_qrcode.jpg new file mode 100644 index 0000000000..d71e76797f Binary files /dev/null and b/qrcodes/alipay_qrcode.jpg differ diff --git a/qrcodes/cp_mp_qrcodes.png b/qrcodes/cp_mp_qrcodes.png new file mode 100644 index 0000000000..4e0a1283ba Binary files /dev/null and b/qrcodes/cp_mp_qrcodes.png differ diff --git a/qrcodes/cp_qrcode.png b/qrcodes/cp_qrcode.png new file mode 100644 index 0000000000..468369a8ed Binary files /dev/null and b/qrcodes/cp_qrcode.png differ diff --git a/qrcodes/cp_qrcode_l.png b/qrcodes/cp_qrcode_l.png new file mode 100644 index 0000000000..90c0537846 Binary files /dev/null and b/qrcodes/cp_qrcode_l.png differ diff --git a/qrcodes/ding_qrcode.jpg b/qrcodes/ding_qrcode.jpg new file mode 100644 index 0000000000..3d77f6f5c0 Binary files /dev/null and b/qrcodes/ding_qrcode.jpg differ diff --git a/qrcodes/mp_qrcode.jpg b/qrcodes/mp_qrcode.jpg new file mode 100644 index 0000000000..b5b0dc6f47 Binary files /dev/null and b/qrcodes/mp_qrcode.jpg differ diff --git a/qrcodes/wechat_qrcode.jpg b/qrcodes/wechat_qrcode.jpg new file mode 100644 index 0000000000..7edb351058 Binary files /dev/null and b/qrcodes/wechat_qrcode.jpg differ diff --git a/qrcodes/wepay_qrcode.jpg b/qrcodes/wepay_qrcode.jpg new file mode 100644 index 0000000000..85a7cd8e56 Binary files /dev/null and b/qrcodes/wepay_qrcode.jpg differ diff --git a/qrcodes/wepay_qrcode_s.jpg b/qrcodes/wepay_qrcode_s.jpg new file mode 100644 index 0000000000..da8d1e03a5 Binary files /dev/null and b/qrcodes/wepay_qrcode_s.jpg differ diff --git a/quality-checks/google_checks.xml b/quality-checks/google_checks.xml index 925172dab6..b1b2a46f20 100644 --- a/quality-checks/google_checks.xml +++ b/quality-checks/google_checks.xml @@ -32,7 +32,7 @@ - + @@ -40,7 +40,7 @@ - + @@ -52,7 +52,7 @@ - + @@ -69,9 +69,9 @@ + value="WhitespaceAround: ''{0}''后面没有空格。Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/> + value="WhitespaceAround: ''{0}''前面没有加空格。"/> @@ -83,28 +83,14 @@ - - - - - - - - - - - - - - + value="包名 ''{0}'' 必须匹配模式:''{1}''。"/> + value="类型名 ''{0}'' 必须匹配模式:''{1}''。"/> @@ -114,28 +100,28 @@ + value="参数名''{0}'' 必须匹配模式:''{1}''。"/> + value="本地变量名 ''{0}'' 必须匹配模式:''{1}''。"/> + value="类的类型名 ''{0}'' 必须匹配模式:''{1}''。"/> + value="方法类型名 ''{0}'' 必须匹配模式:''{1}''。"/> + value="Interface type name ''{0}'' 必须匹配模式:''{1}''。"/> @@ -148,14 +134,6 @@ - - - - - - - - @@ -163,9 +141,12 @@ + + + - - + @@ -183,7 +164,6 @@ - @@ -204,7 +184,7 @@ + value="方法名 ''{0}'' 必须匹配模式:''{1}''."/> @@ -212,6 +192,5 @@ - diff --git a/readme.md b/readme.md index 48f0aac8c7..fb3b8c3867 100644 --- a/readme.md +++ b/readme.md @@ -1,95 +1,148 @@ -微信支付/公众号/企业号/小程序的Java开发工具包(SDK) +## 全能微信Java开发工具包(SDK) +#### 支持包括微信支付、开放平台、公众号、企业微信/企业号、小程序等微信功能的后端开发。 --------------------------------- -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent) +[![码云Gitee](https://gitee.com/binary/weixin-java-tools/badge/star.svg?theme=blue)](https://gitee.com/binary/weixin-java-tools) +[![Github](http://github-svg-buttons.herokuapp.com/star.svg?user=Wechat-Group&repo=weixin-java-tools&style=flat&background=1081C1)](https://github.com/Wechat-Group/weixin-java-tools) +[![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/weixin-java-parent.svg)](http://mvnrepository.com/artifact/com.github.binarywang/weixin-java-parent) [![Build Status](https://travis-ci.org/Wechat-Group/weixin-java-tools.svg?branch=develop)](https://travis-ci.org/Wechat-Group/weixin-java-tools) +[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/idea/) -#### 声明: ***本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。*** - -### [出现`java.security.InvalidKeyException: Illegal key size`问题的解决办法](https://github.com/Wechat-Group/weixin-java-tools/wiki/%E5%8A%A0%E8%A7%A3%E5%AF%86%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E5%8A%9E%E6%B3%95) (太多人遇到此问题而不知所措,因此特意置顶,希望能引起新手的注意) +--------------------------------- +### 重要信息 -***新人提示:本项目仅是一个开发工具包(即SDK),未提供Web实现,建议使用maven或gradle引用本项目即可使用本SDK提供的各种功能,详情可参考下文中提到的Demo项目或本项目中的部分单元测试代码;另外微信开发新手请务必阅读[Wiki首页](https://github.com/Wechat-Group/weixin-java-tools/wiki)的常见问题部分,可以少走很多弯路,节省不少时间。*** +1. **2018-09-24 发布 [【3.2.0正式版】](https://github.com/Wechat-Group/weixin-java-tools/releases)**! +1. 新手重要提示:本项目仅是一个SDK开发工具包,未提供Web实现,建议使用maven或gradle引用本项目即可使用本SDK提供的各种功能,详情可参考 **[【Demo项目】](demo.md)** 或本项目中的部分单元测试代码;另外微信开发新手请务必阅读[【开发文档 Wiki 首页】](https://github.com/Wechat-Group/weixin-java-tools/wiki)的常见问题部分,可以少走很多弯路,节省不少时间。 +1. [出现`Illegal key size`问题的解决办法](https://github.com/Wechat-Group/weixin-java-tools/wiki/%E5%8A%A0%E8%A7%A3%E5%AF%86%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E5%8A%9E%E6%B3%95) (太多人遇到此问题而不知所措,因此特意置顶,希望能引起新手的注意,其他常见问题请查阅 [【开发文档Wiki】](https://github.com/wechat-group/weixin-java-tools/wiki)首页) +1. **更多精彩内容,请扫描以下二维码关注新开通的微信公众号【WX开发助手】,或者加入企业微信,或者[访问此页面扫码](http://www.binarywang.com/article/cp_and_mp) ,也可以在微信中搜索 `weixin-java-tools`或 `WX开发助手` 关注公众号,公众号会及时通知SDK相关更新信息,并不定期分享微信开发相关技术知识。** -## Demo项目列表 -* https://github.com/binarywang/weixin-java-pay-demo (微信支付Demo) -* https://github.com/binarywang/weixin-java-cp-demo (企业号/企业微信Demo) -* https://github.com/binarywang/weixin-java-miniapp-demo (微信小程序Demo) -* https://github.com/binarywang/weixin-java-mp-demo (公众号Demo,使用Spring MVC实现) -* https://github.com/binarywang/weixin-java-mp-demo-springboot (公众号Demo,使用Spring Boot实现) -* https://github.com/binarywang/weixin-java-mp-multi-demo (支持多公众号) -* https://github.com/wechat-group/weixin-java-tools-springmvc (公众号Demo,内含部分微信支付代码) +![微信公众号及企业微信](qrcodes/cp_mp_qrcodes.png) ---------------------------------- -### 重要提示信息(部分为新手必读): -1. 最新更新:**2017-9-3 发布[【2.8.0正式版】](https://github.com/Wechat-Group/weixin-java-tools/releases)**! -1. 开源中国本项目的首页地址:https://www.oschina.net/p/weixin-java-tools-new (欢迎大家积极留言评分 🙂) -1. SDK详细开发文档请查阅 [【Wiki】](https://github.com/wechat-group/weixin-java-tools/wiki),部分文档可能未能及时更新,如有发现,可以及时上报或者自行修改。 -1. 各个模块的Javadoc可以在线查看(有可能是最新的测试版本的,请注意观察版本号):[weixin-java-miniapp](https://binarywang.github.io/weixin-java-miniapp-javadoc/)、[weixin-java-pay](https://binarywang.github.io/weixin-java-pay-javadoc/)、[weixin-java-mp](https://binarywang.github.io/weixin-java-mp-javadoc/)、[weixin-java-common](https://binarywang.github.io/weixin-java-common-javadoc/)、[weixin-java-cp](https://binarywang.github.io/weixin-java-cp-javadoc/) -1. 本SDK要求的最低JDK版本是7,还在使用JDK6的用户请参考[【此项目】]( https://github.com/binarywang/weixin-java-tools-for-jdk6) ,而其他更早的JDK版本则需要自己改造实现。 +-------------------------------- +### 其他说明 +1. 本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。 +1. [开源中国本项目的首页](https://www.oschina.net/p/weixin-java-tools-new),欢迎大家积极留言评分 🙂 +1. SDK详细开发文档请查阅 [【开发文档Wiki】](https://github.com/wechat-group/weixin-java-tools/wiki),部分文档可能未能及时更新,如有发现,可以及时上报或者自行修改。 +1. **阅读源码的同学请注意,本SDK为简化代码编译时加入了lombok支持,如果不了解lombok的话,请先学习下相关知识,比如可以阅读[此文章](https://mp.weixin.qq.com/s/cUc-bUcprycADfNepnSwZQ);** 1. 如有新功能需求,发现BUG,或者由于微信官方接口调整导致的代码问题,可以直接在[【Issues】](https://github.com/Wechat-Group/weixin-java-tools/issues)页提出issue,便于讨论追踪问题; 1. 如果想贡献代码,请阅读[【代码贡献指南】](contribution.md); -1. **捐助渠道已开通,如有意向请点击[【支付宝二维码】](alipay_qrcode.jpg)捐赠,或者直接前往[【托管于码云的项目首页】](http://gitee.com/binary/weixin-java-tools),在评论区上方可以找到“捐助”按钮。非常感谢各位捐助的同学!** +1. **如果本SDK对您有所帮助,欢迎对我们的努力进行肯定,可以扫描[【支付宝付款码】](qrcodes/alipay_qrcode.jpg)或者[【微信支付二维码】](qrcodes/wepay_qrcode.jpg)进行打赏,或者直接前往[【托管于码云的项目首页】](http://gitee.com/binary/weixin-java-tools),在评论区上方可以找到“捐助”按钮。非常感谢各位打赏和捐助的同学!** +1. 各个模块的Javadoc可以在线查看:[weixin-java-miniapp](http://binary.ac.cn/weixin-java-miniapp-javadoc/)、[weixin-java-pay](http://binary.ac.cn/weixin-java-pay-javadoc/)、[weixin-java-mp](http://binary.ac.cn/weixin-java-mp-javadoc/)、[weixin-java-common](http://binary.ac.cn/weixin-java-common-javadoc/)、[weixin-java-cp](http://binary.ac.cn/weixin-java-cp-javadoc/)、[weixin-java-open](http://binary.ac.cn/weixin-java-open-javadoc/) +1. 本SDK要求的最低JDK版本是1.7,还在使用JDK6的用户请参考[【此项目】]( https://github.com/binarywang/weixin-java-tools-for-jdk6) ,而其他更早的JDK版本则需要自己改造实现。 +1. 本SDK项目在以下代码托管网站同步更新: +* 码云:https://gitee.com/binary/weixin-java-tools +* GitHub:https://github.com/wechat-group/weixin-java-tools + +---------------------------------- +### 使用案例 +1. 开源项目:https://github.com/workcheng/weiya +1. 开源项目:https://github.com/jmdhappy/xxpay-master +1. 微信点餐系统开源项目:http://www.sqmax.top/springboot-project/ +1. 小程序:[喵星人贴吧助手(扫码关注)](http://p98ahz3tg.bkt.clouddn.com/miniappqrcode.jpg) +1. 平台:[小猪餐餐](http://www.xzcancan.com/) +1. 平台:[餐饮系统](http://canyin.daydao.com) +1. 公众号:中国电信上海网厅(sh_189) +1. 公众号:E答平台 +1. 公众号:[全民约跑健身便利店](http://www.oneminsport.com/) +1. 公众号:[洽洽食品](https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQFM8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycDRPOXBZbVZib2UxMDAwME0wN2gAAgRIu4RbAwQAAAAA)、[洽洽合伙人](https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQFP8jwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyOUpJaU5VcXBlWTAxMDAwME0wN1oAAgSau4RbAwQAAAAA) +1. 公众号和小程序:民医台(可自行搜索) +1. 洽洽企业号 +1. 高善人力资源 +1. 其他更多案例请[【访问这里】](https://github.com/Wechat-Group/weixin-java-tools/issues/729),持续更新中。 --------------------------------- -## 使用交流方式说明: -1. QQ群: [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=731dc3e7ea31ebe25376cc1a791445468612c63fd0e9e05399b088ec81fd9e15) 或 [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://jq.qq.com/?_wv=1027&k=40lRskK),推荐点击按钮入群,当然如果无法成功操作,请自行搜索群号343954419进行添加 ) -1. 由于群容量有限,即将爆满,故开启付费入群模式以保证只有真实交流需求的人进入,如果确实因为各种原因无法付费入群的,请联系群主说明原因即可入群;并为保证群的活跃度,本群将不定期清理长时间不活跃的同学; -1. 微信群: 因微信群已达到100人限制,故如有想加入微信群的,请入QQ群后联系管理员,提供微信号以便邀请加入; -1. 新手提问前,请先阅读此文章:http://t.cn/RV93MRB +### 技术交流方式 +1. QQ群:(**注意:目前为付费群,刚入群会有5分钟禁言,稍等片刻即可正常发言**) [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=731dc3e7ea31ebe25376cc1a791445468612c63fd0e9e05399b088ec81fd9e15) 或 [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://jq.qq.com/?_wv=1027&k=40lRskK),推荐点击按钮入群,当然如果无法成功操作,请自行搜索群号`343954419`进行添加;由于群容量有限,为了维持运营千人QQ群的所需支付的QQ年费会员费用,故开启付费入群模式,申请者只需支付少量金额即可加入,这样也可以保证只有真实交流需求的人进入,避免闲杂做广告人员的乱入;当然如果确实因为各种原因无法付费入群的,请联系群主说明原因即可入群; +1. 钉钉企业群:[请点击链接申请加入](https://h5.dingtalk.com/inviteColleague/index.html#/invite/9ed100cc4a/E1DF918E32E398D191E7FE61FE0552A6) 或者 [用手机钉钉APP扫码](qrcodes/ding_qrcode.jpg) 申请加入。 +1. 微信群: 因微信群已达到100人限制,故如有想加入微信群的,可以 [扫码加此微信](qrcodes/wechat_qrcode.jpg) 以便邀请加入(请务必注明“申请加入微信开发群”,否则不予理睬,谢谢配合~); +1. 新手提问前,请先阅读[【提问的智慧】](http://www.binarywang.com/article/smart-questions),并确保已查阅过 [【开发文档Wiki】](https://github.com/wechat-group/weixin-java-tools/wiki); 1. 寻求帮助时需贴代码或大长串异常信息的,请利用http://paste.ubuntu.com --------------------------------- -## 版本说明 -1. 本项目定为大约每两个月发布一次正式版,版本号格式为X.X.0(如2.1.0,2.2.0等),遇到重大问题需修复会及时提交新版本,欢迎大家随时提交Pull Request; -1. BUG修复和新特性一般会先发布成小版本作为临时测试版本(如2.4.5.BETA,2.4.6.BETA等,即尾号不为0,并添加BETA字样,以区别于正式版); -1. 目前最新版本号为 [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.binarywang/weixin-java-parent) ,也可以通过访问链接 [【微信支付】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-pay%22) 、[【微信小程序】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-miniapp%22) 、[【公众号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-mp%22) 、[【企业号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-cp%22) -分别查看所有最新的版本。 - ---------------------------------- -#### 本项目在几个著名的代码托管网站同步更新,地址分别是: -* 码云:http://git.oschina.net/binary/weixin-java-tools -* GitHub: https://github.com/wechat-group/weixin-java-tools -* Bitbucket:https://bitbucket.org/binarywang/weixin-java-tools -* Coding: https://git.coding.net/binarywang/weixin-java-tools.git - ---------------------------------- -## Maven 最新正式版本 - -* 微信小程序: - -```xml - - com.github.binarywang -  weixin-java-miniapp -  2.8.0 - -``` - -* 微信支付: - -```xml - - com.github.binarywang - weixin-java-pay - 2.8.0 - -``` - -* 公众号(订阅号及服务号): +### Maven引用 +注意:最新版本(包括测试版)为 [![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/weixin-java-parent.svg)](http://mvnrepository.com/artifact/com.github.binarywang/weixin-java-parent),以下为最新正式版。 ```xml com.github.binarywang - weixin-java-mp - 2.8.0 +  (不同模块参考下文) +  3.2.0 ``` +* 各模块的`artifactId`: + - 微信小程序:`weixin-java-miniapp` + - 微信支付:`weixin-java-pay` + - 微信开放平台:`weixin-java-open` + - 公众号:`weixin-java-mp` + - 企业号/企业微信:`weixin-java-cp` -* 企业号: +--------------------------------- +### 版本说明 +1. 本项目定为大约每两个月发布一次正式版,版本号格式为X.X.0(如2.1.0,2.2.0等),遇到重大问题需修复会及时提交新版本,欢迎大家随时提交Pull Request; +1. BUG修复和新特性一般会先发布成小版本作为临时测试版本(如3.1.8.B,即尾号不为0,并添加B,以区别于正式版); +1. 目前最新版本号为 [![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/weixin-java-parent.svg)](http://mvnrepository.com/artifact/com.github.binarywang/weixin-java-parent) ,也可以通过访问链接 [【微信支付】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-pay%22) 、[【微信小程序】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-miniapp%22) 、[【公众号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-mp%22) 、[【企业微信】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-cp%22)、[【开放平台】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-open%22) +分别查看所有最新的版本。 -```xml - - com.github.binarywang - weixin-java-cp - 2.8.0 - -``` +---------------------------------- +### 贡献者列表 +特别感谢以下参与贡献的所有同学! +1. [chanjarster (Daniel Qian)](http://github.com/chanjarster) +1. [binarywang (Binary Wang)](http://github.com/binarywang) +1. [mgcnrx11](http://github.com/mgcnrx11) +1. [007gzs](http://github.com/007gzs) +1. [aimilin6688 (Jonk)](http://github.com/aimilin6688) +1. [kakotor](http://github.com/kakotor) +1. [kareanyi (MillerLin)](http://github.com/kareanyi) +1. [rememberber (周波)](http://github.com/rememberber) +1. [tianmu](http://github.com/tianmu) +1. [charmingoh (Charming)](http://github.com/charmingoh) +1. [ukid](http://github.com/ukid) +1. [forfuns (爱因斯唐)](http://github.com/forfuns) +1. [zxkane (Meng Xin Zhu)](http://github.com/zxkane) +1. [crskyp (我是木予)](http://github.com/crskyp) +1. [yuanqixun (yuanqixun)](http://github.com/yuanqixun) +1. [gaigeshen (gaigeshen)](http://github.com/gaigeshen) +1. [dylanleung (dylanleung)](http://github.com/dylanleung) +1. [huansinho](http://github.com/huansinho) +1. [codepiano (codepiano)](http://github.com/codepiano) +1. [stvliu (Steven Liu)](http://github.com/stvliu) +1. [ajffdnt](http://github.com/ajffdnt) +1. [fxdfxq (fxdfxq)](http://github.com/fxdfxq) +1. [unlimitedsola (Sola)](http://github.com/unlimitedsola) +1. [DDLeEHi](http://github.com/DDLeEHi) +1. [Hyseen](http://github.com/Hyseen) +1. [nickwongwong (Nick Wong)](http://github.com/nickwongwong) +1. [jink2005 (Jink2005)](http://github.com/jink2005) +1. [withinthefog (withinthefog)](http://github.com/withinthefog) +1. [iwareserictsai (Eric.Tsai)](http://github.com/iwareserictsai) +1. [lwxian](http://github.com/lwxian) +1. [xusheng1987 (flying)](http://github.com/xusheng1987) +1. [ZhaoxiongTan (xiong)](http://github.com/ZhaoxiongTan) +1. [SimonDolph (Simon Dolph)](http://github.com/SimonDolph) +1. [axeon](http://github.com/axeon) +1. [TonyLuo (Tony)](http://github.com/TonyLuo) +1. [dwandw (dwandw)](http://github.com/dwandw) +1. [alanchenup (alanchen)](http://github.com/alanchenup) +1. [zexpp5 (Lance7in)](http://github.com/zexpp5) +1. [xiaohulu (huluwa)](http://github.com/xiaohulu) +1. [aalx (devina)](http://github.com/aalx) +1. [rtsbtx (强哥)](http://github.com/rtsbtx) +1. [dracupid (Jingchen Zhao)](http://github.com/dracupid) +1. [lijunkun1988](http://github.com/lijunkun1988) +1. [lly835](http://github.com/lly835) +1. [mog0202 (蘑菇0202)](http://github.com/mog0202) +1. [bobbyguo (bobby_guo)](http://github.com/bobbyguo) +1. [huotaihe (白马度和)](http://github.com/huotaihe) +1. [dxwts (xuewu)](http://github.com/dxwts) +1. [aliangsoft (阿亮软件)](http://github.com/aliangsoft) +1. [Mkluas (Mklaus)](http://github.com/Mkluas) +1. [CodeIdeal (康阳)](http://github.com/CodeIdeal) +1. [leeis (IOMan)](http://github.com/leeis) +1. [lichenliang666 (李晨亮)](http://github.com/lichenliang666) +1. [627535195](http://github.com/627535195) +1. [ztmark (Mark)](http://github.com/ztmark) +1. [gtyang](http://github.com/gtyang) +1. [scott-z (scott)](http://github.com/scott-z) +1. [borisbao (Boris)](http://github.com/borisbao) +1. [qsjia (QSJia)](http://github.com/qsjia) +1. [webcreazy (webcreazy)](http://github.com/webcreazy) +1. [cwivan (鱼丸Cwivan)](http://github.com/cwivan) diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 68c6130612..c1bfa3bc8b 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,12 +7,12 @@ com.github.binarywang weixin-java-parent - 2.8.0 + 3.2.0 weixin-java-common - WeiXin Java Tools - Common - 微信公众号、企业号Java SDK Common + Weixin Java Tools - Common + 微信开发Java SDK公共模块 @@ -74,6 +74,10 @@ com.google.guava guava + + org.projectlombok + lombok + ch.qos.logback @@ -105,6 +109,11 @@ jetty-servlet test + + org.assertj + assertj-guava + test + diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/WxType.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/WxType.java new file mode 100644 index 0000000000..3dd75addcb --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/WxType.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.common; + +/** + *
+ *  微信类型枚举.
+ *  Created by BinaryWang on 2018/5/14.
+ * 
+ * + * @author Binary Wang + */ +public enum WxType { + /** + * 企业微信 + */ + CP, + /** + * 微信公众号 + */ + MP, + /** + * 微信小程序 + */ + MiniApp, + /** + * 微信开放平台 + */ + Open, + /** + * 微信支付 + */ + Pay; +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index e416323e02..a1e3c073c8 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -3,187 +3,352 @@ import java.util.HashMap; import java.util.Map; +/** + * 微信开发所使用到的常量类. + * + * @author Daniel Qian & binarywang + */ public class WxConsts { - - /////////////////////// - // 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型 - /////////////////////// - public static final String XML_MSG_TEXT = "text"; - public static final String XML_MSG_IMAGE = "image"; - public static final String XML_MSG_VOICE = "voice"; - public static final String XML_MSG_SHORTVIDEO = "shortvideo"; - public static final String XML_MSG_VIDEO = "video"; - public static final String XML_MSG_NEWS = "news"; - public static final String XML_MSG_MUSIC = "music"; - public static final String XML_MSG_LOCATION = "location"; - public static final String XML_MSG_LINK = "link"; - public static final String XML_MSG_EVENT = "event"; - public static final String XML_MSG_DEVICE_TEXT = "device_text"; - public static final String XML_MSG_DEVICE_EVENT = "device_event"; - public static final String XML_MSG_DEVICE_STATUS = "device_status"; - public static final String XML_MSG_HARDWARE = "hardware"; - public static final String XML_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; - - /////////////////////// - // 主动发送消息(即客服消息)的消息类型 - /////////////////////// - public static final String CUSTOM_MSG_TEXT = "text";//文本消息 - public static final String CUSTOM_MSG_IMAGE = "image";//图片消息 - public static final String CUSTOM_MSG_VOICE = "voice";//语音消息 - public static final String CUSTOM_MSG_VIDEO = "video";//视频消息 - public static final String CUSTOM_MSG_MUSIC = "music";//音乐消息 - public static final String CUSTOM_MSG_NEWS = "news";//图文消息(点击跳转到外链) - public static final String CUSTOM_MSG_MPNEWS = "mpnews";//图文消息(点击跳转到图文消息页面) - public static final String CUSTOM_MSG_FILE = "file";//发送文件(CP专用) - public static final String CUSTOM_MSG_TEXTCARD = "textcard";//文本卡片消息(CP专用) - public static final String CUSTOM_MSG_WXCARD = "wxcard";//卡券消息 - public static final String CUSTOM_MSG_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; - public static final String CUSTOM_MSG_SAFE_NO = "0"; - public static final String CUSTOM_MSG_SAFE_YES = "1"; - - /////////////////////// - // 群发消息的消息类型 - /////////////////////// - public static final String MASS_MSG_NEWS = "mpnews"; - public static final String MASS_MSG_TEXT = "text"; - public static final String MASS_MSG_VOICE = "voice"; - public static final String MASS_MSG_IMAGE = "image"; - public static final String MASS_MSG_VIDEO = "mpvideo"; - - /////////////////////// - // 群发消息后微信端推送给服务器的反馈消息 - /////////////////////// - public static final String MASS_ST_SUCCESS = "send success"; - public static final String MASS_ST_FAIL = "send fail"; - public static final String MASS_ST_10001 = "err(10001)"; - public static final String MASS_ST_20001 = "err(20001)"; - public static final String MASS_ST_20004 = "err(20004)"; - public static final String MASS_ST_20002 = "err(20002)"; - public static final String MASS_ST_20006 = "err(20006)"; - public static final String MASS_ST_20008 = "err(20008)"; - public static final String MASS_ST_20013 = "err(20013)"; - public static final String MASS_ST_22000 = "err(22000)"; - public static final String MASS_ST_21000 = "err(21000)"; - - /** - * 群发反馈消息代码所对应的文字描述 - */ - public static final Map MASS_ST_2_DESC = new HashMap<>(); - - /////////////////////// - // 微信端推送过来的事件类型 - /////////////////////// - public static final String EVT_SUBSCRIBE = "subscribe"; - public static final String EVT_UNSUBSCRIBE = "unsubscribe"; - public static final String EVT_SCAN = "SCAN"; - public static final String EVT_LOCATION = "LOCATION"; - public static final String EVT_CLICK = "CLICK"; - public static final String EVT_VIEW = "VIEW"; - public static final String EVT_MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH"; - public static final String EVT_SCANCODE_PUSH = "scancode_push"; - public static final String EVT_SCANCODE_WAITMSG = "scancode_waitmsg"; - public static final String EVT_PIC_SYSPHOTO = "pic_sysphoto"; - public static final String EVT_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; - public static final String EVT_PIC_WEIXIN = "pic_weixin"; - public static final String EVT_LOCATION_SELECT = "location_select"; - public static final String EVT_TEMPLATESENDJOBFINISH = "TEMPLATESENDJOBFINISH"; - public static final String EVT_ENTER_AGENT = "enter_agent"; - - /////////////////////// - // 上传多媒体文件的类型 - /////////////////////// - public static final String MEDIA_IMAGE = "image"; - public static final String MEDIA_VOICE = "voice"; - public static final String MEDIA_VIDEO = "video"; - public static final String MEDIA_THUMB = "thumb"; - public static final String MEDIA_FILE = "file"; - - - /////////////////////// - // 自定义菜单的按钮类型 - /////////////////////// /** - * 点击推事件 + * 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型. */ - public static final String BUTTON_CLICK = "click"; - /** - * 跳转URL - */ - public static final String BUTTON_VIEW = "view"; - /** - * 跳转到小程序 - */ - public static final String BUTTON_MINIPROGRAM = "miniprogram"; - /** - * 扫码推事件 - */ - public static final String BUTTON_SCANCODE_PUSH = "scancode_push"; + public static class XmlMsgType { + public static final String TEXT = "text"; + public static final String IMAGE = "image"; + public static final String VOICE = "voice"; + public static final String SHORTVIDEO = "shortvideo"; + public static final String VIDEO = "video"; + public static final String NEWS = "news"; + public static final String MUSIC = "music"; + public static final String LOCATION = "location"; + public static final String LINK = "link"; + public static final String EVENT = "event"; + public static final String DEVICE_TEXT = "device_text"; + public static final String DEVICE_EVENT = "device_event"; + public static final String DEVICE_STATUS = "device_status"; + public static final String HARDWARE = "hardware"; + public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; + } + /** - * 扫码推事件且弹出“消息接收中”提示框 + * 主动发送消息(即客服消息)的消息类型. */ - public static final String BUTTON_SCANCODE_WAITMSG = "scancode_waitmsg"; + public static class KefuMsgType { + /** + * 文本消息. + */ + public static final String TEXT = "text"; + /** + * 图片消息. + */ + public static final String IMAGE = "image"; + /** + * 语音消息. + */ + public static final String VOICE = "voice"; + /** + * 视频消息. + */ + public static final String VIDEO = "video"; + /** + * 音乐消息. + */ + public static final String MUSIC = "music"; + /** + * 图文消息(点击跳转到外链). + */ + public static final String NEWS = "news"; + /** + * 图文消息(点击跳转到图文消息页面). + */ + public static final String MPNEWS = "mpnews"; + /** + * 发送文件(CP专用). + */ + public static final String FILE = "file"; + /** + * 文本卡片消息(CP专用). + */ + public static final String TEXTCARD = "textcard"; + /** + * 卡券消息. + */ + public static final String WXCARD = "wxcard"; + /** + * 转发到客服的消息. + */ + public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service"; + + /** + * 小程序卡片(要求小程序与公众号已关联) + */ + public static final String MINIPROGRAMPAGE = "miniprogrampage"; + } + /** - * 弹出系统拍照发图 + * 表示是否是保密消息,0表示否,1表示是,默认0. */ - public static final String BUTTON_PIC_SYSPHOTO = "pic_sysphoto"; + public static class KefuMsgSafe { + public static final String NO = "0"; + public static final String YES = "1"; + } + /** - * 弹出拍照或者相册发图 + * 群发消息的消息类型. */ - public static final String BUTTON_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; + public static class MassMsgType { + public static final String MPNEWS = "mpnews"; + public static final String TEXT = "text"; + public static final String VOICE = "voice"; + public static final String IMAGE = "image"; + public static final String MPVIDEO = "mpvideo"; + } + /** - * 弹出微信相册发图器 + * 群发消息后微信端推送给服务器的反馈消息. */ - public static final String BUTTON_PIC_WEIXIN = "pic_weixin"; + public static class MassMsgStatus { + public static final String SEND_SUCCESS = "send success"; + public static final String SEND_FAIL = "send fail"; + public static final String ERR_10001 = "err(10001)"; + public static final String ERR_20001 = "err(20001)"; + public static final String ERR_20004 = "err(20004)"; + public static final String ERR_20002 = "err(20002)"; + public static final String ERR_20006 = "err(20006)"; + public static final String ERR_20008 = "err(20008)"; + public static final String ERR_20013 = "err(20013)"; + public static final String ERR_22000 = "err(22000)"; + public static final String ERR_21000 = "err(21000)"; + + /** + * 群发反馈消息代码所对应的文字描述. + */ + public static final Map STATUS_DESC = new HashMap<>(); + + static { + STATUS_DESC.put(SEND_SUCCESS, "发送成功"); + STATUS_DESC.put(SEND_FAIL, "发送失败"); + STATUS_DESC.put(ERR_10001, "涉嫌广告"); + STATUS_DESC.put(ERR_20001, "涉嫌政治"); + STATUS_DESC.put(ERR_20004, "涉嫌社会"); + STATUS_DESC.put(ERR_20002, "涉嫌色情"); + STATUS_DESC.put(ERR_20006, "涉嫌违法犯罪"); + STATUS_DESC.put(ERR_20008, "涉嫌欺诈"); + STATUS_DESC.put(ERR_20013, "涉嫌版权"); + STATUS_DESC.put(ERR_22000, "涉嫌互推_互相宣传"); + STATUS_DESC.put(ERR_21000, "涉嫌其他"); + } + } + /** - * 弹出地理位置选择器 + * 微信端推送过来的事件类型. */ - public static final String BUTTON_LOCATION_SELECT = "location_select"; + public static class EventType { + public static final String SUBSCRIBE = "subscribe"; + public static final String UNSUBSCRIBE = "unsubscribe"; + public static final String SCAN = "SCAN"; + public static final String LOCATION = "LOCATION"; + public static final String CLICK = "CLICK"; + public static final String VIEW = "VIEW"; + public static final String MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH"; + /** + * 扫码推事件的事件推送 + */ + public static final String SCANCODE_PUSH = "scancode_push"; + /** + * 扫码推事件且弹出“消息接收中”提示框的事件推送. + */ + public static final String SCANCODE_WAITMSG = "scancode_waitmsg"; + /** + * 弹出系统拍照发图的事件推送. + */ + public static final String PIC_SYSPHOTO = "pic_sysphoto"; + /** + * 弹出拍照或者相册发图的事件推送. + */ + public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; + /** + * 弹出微信相册发图器的事件推送. + */ + public static final String PIC_WEIXIN = "pic_weixin"; + /** + * 弹出地理位置选择器的事件推送. + */ + public static final String LOCATION_SELECT = "location_select"; + + public static final String TEMPLATE_SEND_JOB_FINISH = "TEMPLATESENDJOBFINISH"; + /** + * 微信小店 订单付款通知. + */ + public static final String MERCHANT_ORDER = "merchant_order"; + + /** + * 卡券事件:卡券通过审核 + */ + public static final String CARD_PASS_CHECK = "card_pass_check"; + + /** + * 卡券事件:卡券未通过审核 + */ + public static final String CARD_NOT_PASS_CHECK = "card_not_pass_check"; + + /** + * 卡券事件:用户领取卡券 + */ + public static final String CARD_USER_GET_CARD = "user_get_card"; + + /** + * 卡券事件:用户转赠卡券 + */ + public static final String CARD_USER_GIFTING_CARD = "user_gifting_card"; + + + /** + * 卡券事件:用户核销卡券 + */ + public static final String CARD_USER_CONSUME_CARD = "user_consume_card"; + + + /** + * 卡券事件:用户通过卡券的微信买单完成时推送 + */ + public static final String CARD_USER_PAY_FROM_PAY_CELL = "user_pay_from_pay_cell"; + + + /** + * 卡券事件:用户提交会员卡开卡信息 + */ + public static final String CARD_SUBMIT_MEMBERCARD_USER_INFO = "submit_membercard_user_info"; + + /** + * 卡券事件:用户打开查看卡券 + */ + public static final String CARD_USER_VIEW_CARD = "user_view_card"; + + /** + * 卡券事件:用户删除卡券 + */ + public static final String CARD_USER_DEL_CARD = "user_del_card"; + + /** + * 卡券事件:用户在卡券里点击查看公众号进入会话时(需要用户已经关注公众号) + */ + public static final String CARD_USER_ENTER_SESSION_FROM_CARD = "user_enter_session_from_card"; + + /** + * 卡券事件:当用户的会员卡积分余额发生变动时 + */ + public static final String CARD_UPDATE_MEMBER_CARD = "update_member_card"; + + /** + * 卡券事件:当某个card_id的初始库存数大于200且当前库存小于等于100时,用户尝试领券会触发发送事件给商户,事件每隔12h发送一次 + */ + public static final String CARD_SKU_REMIND = "card_sku_remind"; + + /** + * 卡券事件:当商户朋友的券券点发生变动时 + */ + public static final String CARD_PAY_ORDER = "card_pay_order"; + + + } + /** - * 下发消息(除文本消息) + * 上传多媒体(临时素材)文件的类型. */ - public static final String BUTTON_MEDIA_ID = "media_id"; + public static class MediaFileType { + public static final String IMAGE = "image"; + public static final String VOICE = "voice"; + public static final String VIDEO = "video"; + public static final String THUMB = "thumb"; + public static final String FILE = "file"; + } + /** - * 跳转图文消息URL + * 自定义菜单的按钮类型. */ - public static final String BUTTON_VIEW_LIMITED = "view_limited"; + public static class MenuButtonType { + /** + * 点击推事件. + */ + public static final String CLICK = "click"; + /** + * 跳转URL. + */ + public static final String VIEW = "view"; + /** + * 跳转到小程序. + */ + public static final String MINIPROGRAM = "miniprogram"; + /** + * 扫码推事件. + */ + public static final String SCANCODE_PUSH = "scancode_push"; + /** + * 扫码推事件且弹出“消息接收中”提示框. + */ + public static final String SCANCODE_WAITMSG = "scancode_waitmsg"; + /** + * 弹出系统拍照发图. + */ + public static final String PIC_SYSPHOTO = "pic_sysphoto"; + /** + * 弹出拍照或者相册发图. + */ + public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; + /** + * 弹出微信相册发图器. + */ + public static final String PIC_WEIXIN = "pic_weixin"; + /** + * 弹出地理位置选择器. + */ + public static final String LOCATION_SELECT = "location_select"; + /** + * 下发消息(除文本消息). + */ + public static final String MEDIA_ID = "media_id"; + /** + * 跳转图文消息URL. + */ + public static final String VIEW_LIMITED = "view_limited"; + } /** - * 不弹出授权页面,直接跳转,只能获取用户openid + * oauth2网页授权的scope. */ - public static final String OAUTH2_SCOPE_BASE = "snsapi_base"; + public static class OAuth2Scope { + /** + * 不弹出授权页面,直接跳转,只能获取用户openid. + */ + public static final String SNSAPI_BASE = "snsapi_base"; + + /** + * 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息. + */ + public static final String SNSAPI_USERINFO = "snsapi_userinfo"; + + /** + * 手动授权,可获取成员的详细信息,包含手机、邮箱。只适用于企业微信或企业号. + */ + public static final String SNSAPI_PRIVATEINFO = "snsapi_privateinfo"; + } - /////////////////////// - // oauth2网页授权的scope - /////////////////////// /** - * 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 + * 网页应用登录授权作用域. */ - public static final String OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo"; + public static class QrConnectScope { + public static final String SNSAPI_LOGIN = "snsapi_login"; + } /** - * 网页应用登录授权作用域 snsapi_login + * 永久素材类型. */ - public static final String QRCONNECT_SCOPE_SNSAPI_LOGIN = "snsapi_login"; - - /////////////////////// - // 永久素材类型 - /////////////////////// - public static final String MATERIAL_NEWS = "news"; - public static final String MATERIAL_VOICE = "voice"; - public static final String MATERIAL_IMAGE = "image"; - public static final String MATERIAL_VIDEO = "video"; - - static { - MASS_ST_2_DESC.put(MASS_ST_SUCCESS, "发送成功"); - MASS_ST_2_DESC.put(MASS_ST_FAIL, "发送失败"); - MASS_ST_2_DESC.put(MASS_ST_10001, "涉嫌广告"); - MASS_ST_2_DESC.put(MASS_ST_20001, "涉嫌政治"); - MASS_ST_2_DESC.put(MASS_ST_20004, "涉嫌社会"); - MASS_ST_2_DESC.put(MASS_ST_20002, "涉嫌色情"); - MASS_ST_2_DESC.put(MASS_ST_20006, "涉嫌违法犯罪"); - MASS_ST_2_DESC.put(MASS_ST_20008, "涉嫌欺诈"); - MASS_ST_2_DESC.put(MASS_ST_20013, "涉嫌版权"); - MASS_ST_2_DESC.put(MASS_ST_22000, "涉嫌互推_互相宣传"); - MASS_ST_2_DESC.put(MASS_ST_21000, "涉嫌其他"); + public static class MaterialType { + public static final String NEWS = "news"; + public static final String VOICE = "voice"; + public static final String IMAGE = "image"; + public static final String VIDEO = "video"; } + } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java index d6acf55b52..83242e2f7a 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java @@ -1,9 +1,11 @@ package me.chanjar.weixin.common.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; /** - * WxErrorException处理器 + * WxErrorException处理器. + * + * @author Daniel Qian */ public interface WxErrorExceptionHandler { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java index 831458a443..3993dab548 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java @@ -2,22 +2,23 @@ /** *
- * 消息重复检查器
+ * 消息重复检查器.
  * 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
  * 
+ * + * @author Daniel Qian */ public interface WxMessageDuplicateChecker { /** + * 判断消息是否重复. *

公众号的排重方式

- *

+ * *

普通消息:关于重试的消息排重,推荐使用msgid排重。文档参考

*

事件消息:关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。文档参考

- *

+ * *

企业号的排重方式

- *

- * 官方文档完全没有写,参照公众号的方式排重。 - *

+ *

官方文档完全没有写,参照公众号的方式排重。

*

或者可以采取更简单的方式,如果有MsgId就用MsgId排重,如果没有就用FromUserName+CreateTime排重

* * @param messageId messageId需要根据上面讲的方式构造 diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java index 1281e26012..c0f57c83c4 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java @@ -6,46 +6,48 @@ /** *
- * 默认消息重复检查器
+ * 默认消息重复检查器.
  * 将每个消息id保存在内存里,每隔5秒清理已经过期的消息id,每个消息id的过期时间是15秒
  * 
+ * + * @author Daniel Qian */ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChecker { /** - * 一个消息ID在内存的过期时间:15秒 + * 一个消息ID在内存的过期时间:15秒. */ private final Long timeToLive; /** - * 每隔多少周期检查消息ID是否过期:5秒 + * 每隔多少周期检查消息ID是否过期:5秒. */ private final Long clearPeriod; /** - * 消息id->消息时间戳的map + * 消息id->消息时间戳的map. */ private final ConcurrentHashMap msgId2Timestamp = new ConcurrentHashMap<>(); /** - * 后台清理线程是否已经开启 + * 后台清理线程是否已经开启. */ private final AtomicBoolean backgroundProcessStarted = new AtomicBoolean(false); /** - * WxMsgIdInMemoryDuplicateChecker构造函数 + * 无参构造方法. *
    * 一个消息ID在内存的过期时间:15秒
    * 每隔多少周期检查消息ID是否过期:5秒
    * 
*/ public WxMessageInMemoryDuplicateChecker() { - this.timeToLive = 15 * 1000l; - this.clearPeriod = 5 * 1000l; + this.timeToLive = 15 * 1000L; + this.clearPeriod = 5 * 1000L; } /** - * WxMsgIdInMemoryDuplicateChecker构造函数 + * 构造方法. * * @param timeToLive 一个消息ID在内存的过期时间:毫秒 * @param clearPeriod 每隔多少周期检查消息ID是否过期:毫秒 @@ -66,7 +68,8 @@ public void run() { while (true) { Thread.sleep(WxMessageInMemoryDuplicateChecker.this.clearPeriod); Long now = System.currentTimeMillis(); - for (Map.Entry entry : WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet()) { + for (Map.Entry entry : + WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet()) { if (now - entry.getValue() > WxMessageInMemoryDuplicateChecker.this.timeToLive) { WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet().remove(entry); } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java index 6476205a54..3935e5f55d 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java @@ -1,9 +1,16 @@ package me.chanjar.weixin.common.bean; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - import java.io.Serializable; +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * access token. + * + * @author Daniel Qian + */ +@Data public class WxAccessToken implements Serializable { private static final long serialVersionUID = 8709719312922168909L; @@ -15,20 +22,4 @@ public static WxAccessToken fromJson(String json) { return WxGsonBuilder.create().fromJson(json, WxAccessToken.class); } - public String getAccessToken() { - return this.accessToken; - } - - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - public int getExpiresIn() { - return this.expiresIn; - } - - public void setExpiresIn(int expiresIn) { - this.expiresIn = expiresIn; - } - } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java index df272318e7..17d8ab9f00 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java @@ -1,17 +1,20 @@ package me.chanjar.weixin.common.bean; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; + /** - * 卡券Api签名 + * 卡券Api签名. * * @author YuJian * @version 15/11/8 */ +@Data public class WxCardApiSignature implements Serializable { - private static final long serialVersionUID = 158176707226975979L; private String appId; @@ -34,78 +37,6 @@ public class WxCardApiSignature implements Serializable { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getAppId() { - return this.appId; - } - - public void setAppId(String appId) { - this.appId = appId; - } - - public String getCardId() { - return this.cardId; - } - - public void setCardId(String cardId) { - this.cardId = cardId; - } - - public String getCardType() { - return this.cardType; - } - - public void setCardType(String cardType) { - this.cardType = cardType; - } - - public String getLocationId() { - return this.locationId; - } - - public void setLocationId(String locationId) { - this.locationId = locationId; - } - - public String getCode() { - return this.code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getOpenId() { - return this.openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public Long getTimestamp() { - return this.timestamp; - } - - public void setTimestamp(Long timestamp) { - this.timestamp = timestamp; - } - - public String getNonceStr() { - return this.nonceStr; - } - - public void setNonceStr(String nonceStr) { - this.nonceStr = nonceStr; - } - - public String getSignature() { - return this.signature; - } - - public void setSignature(String signature) { - this.signature = signature; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java index 7837158361..759f5e12fe 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java @@ -2,9 +2,20 @@ import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** - * jspai signature + * jspai signature. + * + * @author Daniel Qian */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor public class WxJsapiSignature implements Serializable { private static final long serialVersionUID = -1116808193154384804L; @@ -18,43 +29,4 @@ public class WxJsapiSignature implements Serializable { private String signature; - public String getSignature() { - return this.signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - - public String getNonceStr() { - return nonceStr; - } - - public void setNonceStr(String nonceStr) { - this.nonceStr = nonceStr; - } - - public long getTimestamp() { - return this.timestamp; - } - - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getAppId() { - return appId; - } - - public void setAppId(String appId) { - this.appId = appId; - } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java index 4e61a46591..8b43646a55 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java @@ -1,8 +1,5 @@ package me.chanjar.weixin.common.bean.menu; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - import java.io.InputStream; import java.io.InputStreamReader; import java.io.Serializable; @@ -10,13 +7,19 @@ import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + /** - * 菜单(公众号和企业号共用的) + * 菜单(公众号和企业号共用的). * * @author Daniel Qian */ +@Data public class WxMenu implements Serializable { - private static final long serialVersionUID = -7083914585539687746L; private List buttons = new ArrayList<>(); @@ -36,23 +39,8 @@ public static WxMenu fromJson(String json) { * 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu */ public static WxMenu fromJson(InputStream is) { - return WxGsonBuilder.create().fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); - } - - public List getButtons() { - return this.buttons; - } - - public void setButtons(List buttons) { - this.buttons = buttons; - } - - public WxMenuRule getMatchRule() { - return this.matchRule; - } - - public void setMatchRule(WxMenuRule matchRule) { - this.matchRule = matchRule; + return WxGsonBuilder.create() + .fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class); } public String toJson() { @@ -61,7 +49,7 @@ public String toJson() { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java index aa6ea4cfb2..5e0b9db961 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java @@ -1,18 +1,27 @@ package me.chanjar.weixin.common.bean.menu; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +/** + * menu button. + * + * @author Daniel Qian + */ +@Data public class WxMenuButton implements Serializable { private static final long serialVersionUID = -1070939403109776555L; /** *
-   * 菜单的响应动作类型:
+   * 菜单的响应动作类型.
    * view表示网页类型,
    * click表示点击类型,
    * miniprogram表示小程序类型
@@ -21,13 +30,13 @@ public class WxMenuButton implements Serializable {
   private String type;
 
   /**
-   * 菜单标题,不超过16个字节,子菜单不超过60个字节
+   * 菜单标题,不超过16个字节,子菜单不超过60个字节.
    */
   private String name;
 
   /**
    * 
-   * 菜单KEY值,用于消息接口推送,不超过128字节
+   * 菜单KEY值,用于消息接口推送,不超过128字节.
    * click等点击类型必须
    * 
*/ @@ -35,7 +44,8 @@ public class WxMenuButton implements Serializable { /** *
-   * 网页链接,用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
+   * 网页链接.
+   * 用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
    * view、miniprogram类型必须
    * 
*/ @@ -43,7 +53,7 @@ public class WxMenuButton implements Serializable { /** *
-   * 调用新增永久素材接口返回的合法media_id
+   * 调用新增永久素材接口返回的合法media_id.
    * media_id类型和view_limited类型必须
    * 
*/ @@ -52,7 +62,7 @@ public class WxMenuButton implements Serializable { /** *
-   * 小程序的appid
+   * 小程序的appid.
    * miniprogram类型必须
    * 
*/ @@ -61,7 +71,7 @@ public class WxMenuButton implements Serializable { /** *
-   * 小程序的页面路径
+   * 小程序的页面路径.
    * miniprogram类型必须
    * 
*/ @@ -73,70 +83,7 @@ public class WxMenuButton implements Serializable { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getKey() { - return this.key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getUrl() { - return this.url; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public void setUrl(String url) { - this.url = url; - } - - public List getSubButtons() { - return this.subButtons; - } - - public void setSubButtons(List subButtons) { - this.subButtons = subButtons; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getAppId() { - return appId; - } - - public void setAppId(String appId) { - this.appId = appId; - } - - public String getPagePath() { - return pagePath; - } - - public void setPagePath(String pagePath) { - this.pagePath = pagePath; - } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java index e0182c9678..632279b92a 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java @@ -1,12 +1,26 @@ package me.chanjar.weixin.common.bean.menu; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +/** + * menu rule. + * + * @author Daniel Qian + */ +@Data public class WxMenuRule implements Serializable { private static final long serialVersionUID = -4587181819499286670L; + /** + * 变态的微信接口,反序列化时这里反人类的使用和序列化时不一样的名字. + */ + @SerializedName(value = "tag_id", alternate = "group_id") private String tagId; private String sex; private String country; @@ -15,64 +29,8 @@ public class WxMenuRule implements Serializable { private String clientPlatformType; private String language; - public String getTagId() { - return this.tagId; - } - - public void setTagId(String tagId) { - this.tagId = tagId; - } - - public String getSex() { - return this.sex; - } - - public void setSex(String sex) { - this.sex = sex; - } - - public String getCountry() { - return this.country; - } - - public void setCountry(String country) { - this.country = country; - } - - public String getProvince() { - return this.province; - } - - public void setProvince(String province) { - this.province = province; - } - - public String getCity() { - return this.city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getClientPlatformType() { - return this.clientPlatformType; - } - - public void setClientPlatformType(String clientPlatformType) { - this.clientPlatformType = clientPlatformType; - } - - public String getLanguage() { - return this.language; - } - - public void setLanguage(String language) { - this.language = language; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java deleted file mode 100644 index 46c0ae89be..0000000000 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java +++ /dev/null @@ -1,84 +0,0 @@ -package me.chanjar.weixin.common.bean.result; - -import me.chanjar.weixin.common.util.json.WxGsonBuilder; - -import java.io.Serializable; - -/** - * 微信错误码说明,请阅读: 全局返回码说明 - * - * @author Daniel Qian - */ -public class WxError implements Serializable { - - private static final long serialVersionUID = 7869786563361406291L; - - private int errorCode; - - private String errorMsg; - - private String json; - - public static WxError fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxError.class); - } - - public static Builder newBuilder() { - return new Builder(); - } - - public int getErrorCode() { - return this.errorCode; - } - - public void setErrorCode(int errorCode) { - this.errorCode = errorCode; - } - - public String getErrorMsg() { - return this.errorMsg; - } - - public void setErrorMsg(String errorMsg) { - this.errorMsg = errorMsg; - } - - public String getJson() { - return this.json; - } - - public void setJson(String json) { - this.json = json; - } - - @Override - public String toString() { - if (this.json != null) { - return this.json; - } - return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; - } - - public static class Builder { - private int errorCode; - private String errorMsg; - - public Builder setErrorCode(int errorCode) { - this.errorCode = errorCode; - return this; - } - - public Builder setErrorMsg(String errorMsg) { - this.errorMsg = errorMsg; - return this; - } - - public WxError build() { - WxError wxError = new WxError(); - wxError.setErrorCode(this.errorCode); - wxError.setErrorMsg(this.errorMsg); - return wxError; - } - - } -} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java index 706de712c7..d6ffd50c51 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java @@ -1,14 +1,22 @@ package me.chanjar.weixin.common.bean.result; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import java.io.Serializable; + import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; -import java.io.Serializable; +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +/** + * + * @author Daniel Qian + */ +@Data public class WxMediaUploadResult implements Serializable { private static final long serialVersionUID = 330834334738622341L; + private String url; private String type; private String mediaId; private String thumbMediaId; @@ -18,38 +26,6 @@ public static WxMediaUploadResult fromJson(String json) { return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class); } - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public long getCreatedAt() { - return this.createdAt; - } - - public void setCreatedAt(long createdAt) { - this.createdAt = createdAt; - } - - public String getThumbMediaId() { - return this.thumbMediaId; - } - - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } - @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java new file mode 100644 index 0000000000..0ae580620a --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java @@ -0,0 +1,806 @@ +package me.chanjar.weixin.common.error; + +import lombok.Getter; + +/** + *
+ * 企业微信全局错误码.
+ * 参考文档:企业微信全局错误码
+ * Created by Binary Wang on 2018/5/13.
+ * 
+ * + * @author Binary Wang + */ +@Getter +public enum WxCpErrorMsgEnum { + /** + * 系统繁忙;服务器暂不可用,建议稍候重试。建议重试次数不超过3次。 + */ + CODE_1(-1, "系统繁忙;服务器暂不可用,建议稍候重试。建议重试次数不超过3次。"), + /** + * 请求成功;接口调用成功 + */ + CODE_0(0, "请求成功;接口调用成功"), + /** + * 不合法的secret参数;secret在应用详情/通讯录管理助手可查看 + */ + CODE_40001(40001, "不合法的secret参数;secret在应用详情/通讯录管理助手可查看"), + /** + * 无效的UserID + */ + CODE_40003(40003, "无效的UserID"), + /** + * 不合法的媒体文件类型;不满足系统文件要求。参考:上传的媒体文件限制 + */ + CODE_40004(40004, "不合法的媒体文件类型;不满足系统文件要求。参考:上传的媒体文件限制"), + /** + * 不合法的type参数;合法的type取值,参考:上传临时素材 + */ + CODE_40005(40005, "不合法的type参数;合法的type取值,参考:上传临时素材"), + /** + * 不合法的文件大小;系统文件要求,参考:上传的媒体文件限制 + */ + CODE_40006(40006, "不合法的文件大小;系统文件要求,参考:上传的媒体文件限制"), + /** + * 不合法的media_id参数 + */ + CODE_40007(40007, "不合法的media_id参数"), + /** + * 不合法的msgtype参数;合法的msgtype取值,参考:消息类型 + */ + CODE_40008(40008, "不合法的msgtype参数;合法的msgtype取值,参考:消息类型"), + /** + * 上传图片大小不是有效值;图片大小的系统限制,参考上传的媒体文件限制 + */ + CODE_40009(40009, "上传图片大小不是有效值;图片大小的系统限制,参考上传的媒体文件限制"), + /** + * 上传视频大小不是有效值;视频大小的系统限制,参考上传的媒体文件限制 + */ + CODE_40011(40011, "上传视频大小不是有效值;视频大小的系统限制,参考上传的媒体文件限制"), + /** + * 不合法的CorpID;需确认CorpID是否填写正确,在 web管理端-设置 可查看 + */ + CODE_40013(40013, "不合法的CorpID;需确认CorpID是否填写正确,在 web管理端-设置 可查看"), + /** + * 不合法的access_token + */ + CODE_40014(40014, "不合法的access_token"), + /** + * 不合法的按钮个数;菜单按钮1-3个 + */ + CODE_40016(40016, "不合法的按钮个数;菜单按钮1-3个"), + /** + * 不合法的按钮类型;支持的类型,参考:按钮类型 + */ + CODE_40017(40017, "不合法的按钮类型;支持的类型,参考:按钮类型"), + /** + * 不合法的按钮名字长度;长度应不超过16个字节 + */ + CODE_40018(40018, "不合法的按钮名字长度;长度应不超过16个字节"), + /** + * 不合法的按钮KEY长度;长度应不超过128字节 + */ + CODE_40019(40019, "不合法的按钮KEY长度;长度应不超过128字节"), + /** + * 不合法的按钮URL长度;长度应不超过1024字节 + */ + CODE_40020(40020, "不合法的按钮URL长度;长度应不超过1024字节"), + /** + * 不合法的子菜单级数;只能包含一级菜单和二级菜单 + */ + CODE_40022(40022, "不合法的子菜单级数;只能包含一级菜单和二级菜单"), + /** + * 不合法的子菜单按钮个数;子菜单按钮1-5个 + */ + CODE_40023(40023, "不合法的子菜单按钮个数;子菜单按钮1-5个"), + /** + * 不合法的子菜单按钮类型;支持的类型,参考:按钮类型 + */ + CODE_40024(40024, "不合法的子菜单按钮类型;支持的类型,参考:按钮类型"), + /** + * 不合法的子菜单按钮名字长度;支持的类型,参考:按钮类型 + */ + CODE_40025(40025, "不合法的子菜单按钮名字长度;支持的类型,参考:按钮类型"), + /** + * 不合法的子菜单按钮KEY长度;长度应不超过60个字节 + */ + CODE_40026(40026, "不合法的子菜单按钮KEY长度;长度应不超过60个字节"), + /** + * 不合法的子菜单按钮URL长度;长度应不超过1024字节 + */ + CODE_40027(40027, "不合法的子菜单按钮URL长度;长度应不超过1024字节"), + /** + * 不合法的oauth_code + */ + CODE_40029(40029, "不合法的oauth_code"), + /** + * 不合法的UserID列表;指定的UserID列表,至少存在一个UserID不在通讯录中 + */ + CODE_40031(40031, "不合法的UserID列表;指定的UserID列表,至少存在一个UserID不在通讯录中"), + /** + * 不合法的UserID列表长度 + */ + CODE_40032(40032, "不合法的UserID列表长度"), + /** + * 不合法的请求字符;不能包含\\uxxxx格式的字符 + */ + CODE_40033(40033, "不合法的请求字符;不能包含\\uxxxx格式的字符"), + /** + * 不合法的参数 + */ + CODE_40035(40035, "不合法的参数"), + /** + * chatid不存在;会话需要先创建后,才可修改会话详情或者发起聊天 + */ + CODE_40050(40050, "chatid不存在;会话需要先创建后,才可修改会话详情或者发起聊天"), + /** + * 不合法的子菜单url域名 + */ + CODE_40054(40054, "不合法的子菜单url域名"), + /** + * 不合法的菜单url域名 + */ + CODE_40055(40055, "不合法的菜单url域名"), + /** + * 不合法的agentid + */ + CODE_40056(40056, "不合法的agentid"), + /** + * 不合法的callbackurl或者callbackurl验证失败;可自助到开发调试工具重现 + */ + CODE_40057(40057, "不合法的callbackurl或者callbackurl验证失败;可自助到开发调试工具重现"), + /** + * 不合法的参数;传递参数不符合系统要求,需要参照具体API接口说明 + */ + CODE_40058(40058, "不合法的参数;传递参数不符合系统要求,需要参照具体API接口说明"), + /** + * 不合法的上报地理位置标志位;开关标志位只能填 0 或者 1 + */ + CODE_40059(40059, "不合法的上报地理位置标志位;开关标志位只能填 0 或者 1"), + /** + * 参数为空 + */ + CODE_40063(40063, "参数为空"), + /** + * 不合法的部门列表;部门列表为空,或者至少存在一个部门ID不存在于通讯录中 + */ + CODE_40066(40066, "不合法的部门列表;部门列表为空,或者至少存在一个部门ID不存在于通讯录中"), + /** + * 不合法的标签ID;标签ID未指定,或者指定的标签ID不存在 + */ + CODE_40068(40068, "不合法的标签ID;标签ID未指定,或者指定的标签ID不存在"), + /** + * 指定的标签范围结点全部无效 + */ + CODE_40070(40070, "指定的标签范围结点全部无效"), + /** + * 不合法的标签名字;标签名字已经存在 + */ + CODE_40071(40071, "不合法的标签名字;标签名字已经存在"), + /** + * 不合法的标签名字长度;不允许为空,最大长度限制为32个字(汉字或英文字母) + */ + CODE_40072(40072, "不合法的标签名字长度;不允许为空,最大长度限制为32个字(汉字或英文字母)"), + /** + * 不合法的openid;openid不存在,需确认获取来源 + */ + CODE_40073(40073, "不合法的openid;openid不存在,需确认获取来源"), + /** + * news消息不支持保密消息类型;图文消息支持保密类型需改用mpnews + */ + CODE_40074(40074, "news消息不支持保密消息类型;图文消息支持保密类型需改用mpnews"), + /** + * 不合法的pre_auth_code参数;预授权码不存在,参考:获取预授权码 + */ + CODE_40077(40077, "不合法的pre_auth_code参数;预授权码不存在,参考:获取预授权码"), + /** + * 不合法的auth_code参数;需确认获取来源,并且只能消费一次 + */ + CODE_40078(40078, "不合法的auth_code参数;需确认获取来源,并且只能消费一次"), + /** + * 不合法的suite_secret;套件secret可在第三方管理端套件详情查看 + */ + CODE_40080(40080, "不合法的suite_secret;套件secret可在第三方管理端套件详情查看"), + /** + * 不合法的suite_token + */ + CODE_40082(40082, "不合法的suite_token"), + /** + * 不合法的suite_id;suite_id不存在 + */ + CODE_40083(40083, "不合法的suite_id;suite_id不存在"), + /** + * 不合法的permanent_code参数 + */ + CODE_40084(40084, "不合法的permanent_code参数"), + /** + * 不合法的的suite_ticket参数;suite_ticket不存在或者已失效 + */ + CODE_40085(40085, "不合法的的suite_ticket参数;suite_ticket不存在或者已失效"), + /** + * 不合法的第三方应用appid;至少有一个不存在应用id + */ + CODE_40086(40086, "不合法的第三方应用appid;至少有一个不存在应用id"), + /** + * jobid不存在;请检查 jobid 来源 + */ + CODE_40088(40088, "jobid不存在;请检查 jobid 来源"), + /** + * 批量任务的结果已清理;系统仅保存最近5次批量任务的结果。可在通讯录查看实际导入情况 + */ + CODE_40089(40089, "批量任务的结果已清理;系统仅保存最近5次批量任务的结果。可在通讯录查看实际导入情况"), + /** + * secret不合法;可能用了别的企业的secret + */ + CODE_40091(40091, "secret不合法;可能用了别的企业的secret"), + /** + * 导入文件存在不合法的内容 + */ + CODE_40092(40092, "导入文件存在不合法的内容"), + /** + * 不合法的jsapi_ticket参数;ticket已失效,或者拼写错误 + */ + CODE_40093(40093, "不合法的jsapi_ticket参数;ticket已失效,或者拼写错误"), + /** + * 不合法的URL;缺少主页URL参数,或者URL不合法(链接需要带上协议头,以 http:// 或者 https:// 开头) + */ + CODE_40094(40094, "不合法的URL;缺少主页URL参数,或者URL不合法(链接需要带上协议头,以 http:// 或者 https:// 开头)"), + /** + * 缺少access_token参数 + */ + CODE_41001(41001, "缺少access_token参数"), + /** + * 缺少corpid参数 + */ + CODE_41002(41002, "缺少corpid参数"), + /** + * 缺少secret参数 + */ + CODE_41004(41004, "缺少secret参数"), + /** + * 缺少media_id参数;media_id为调用接口必填参数,请确认是否有传递 + */ + CODE_41006(41006, "缺少media_id参数;media_id为调用接口必填参数,请确认是否有传递"), + /** + * 缺少auth code参数 + */ + CODE_41008(41008, "缺少auth code参数"), + /** + * 缺少userid参数 + */ + CODE_41009(41009, "缺少userid参数"), + /** + * 缺少url参数 + */ + CODE_41010(41010, "缺少url参数"), + /** + * 缺少agentid参数 + */ + CODE_41011(41011, "缺少agentid参数"), + /** + * 缺少 description 参数;发送文本卡片消息接口,description 是必填字段 + */ + CODE_41033(41033, "缺少 description 参数;发送文本卡片消息接口,description 是必填字段"), + /** + * 缺少title参数;发送图文消息,标题是必填参数。请确认参数是否有传递。 + */ + CODE_41016(41016, "缺少title参数;发送图文消息,标题是必填参数。请确认参数是否有传递。"), + /** + * 缺少 department 参数 + */ + CODE_41019(41019, "缺少 department 参数"), + /** + * 缺少tagid参数 + */ + CODE_41017(41017, "缺少tagid参数"), + /** + * 缺少suite_id参数 + */ + CODE_41021(41021, "缺少suite_id参数"), + /** + * 缺少suite_access_token参数 + */ + CODE_41022(41022, "缺少suite_access_token参数"), + /** + * 缺少suite_ticket参数 + */ + CODE_41023(41023, "缺少suite_ticket参数"), + /** + * 缺少secret参数 + */ + CODE_41024(41024, "缺少secret参数"), + /** + * 缺少permanent_code参数 + */ + CODE_41025(41025, "缺少permanent_code参数"), + /** + * access_token已过期;access_token有时效性,需要重新获取一次 + */ + CODE_42001(42001, "access_token已过期;access_token有时效性,需要重新获取一次"), + /** + * pre_auth_code已过期;pre_auth_code有时效性,需要重新获取一次 + */ + CODE_42007(42007, "pre_auth_code已过期;pre_auth_code有时效性,需要重新获取一次"), + /** + * suite_access_token已过期;suite_access_token有时效性,需要重新获取一次 + */ + CODE_42009(42009, "suite_access_token已过期;suite_access_token有时效性,需要重新获取一次"), + /** + * 指定的userid未绑定微信或未关注微信插件;需要成员使用微信登录企业微信或者关注微信插件才能获取openid + */ + CODE_43004(43004, "指定的userid未绑定微信或未关注微信插件;需要成员使用微信登录企业微信或者关注微信插件才能获取openid"), + /** + * 多媒体文件为空;上传格式参考:上传临时素材,确认header和body的内容正确。 + */ + CODE_44001(44001, "多媒体文件为空;上传格式参考:上传临时素材,确认header和body的内容正确。"), + /** + * 文本消息content参数为空;发文本消息content为必填参数,且不能为空 + */ + CODE_44004(44004, "文本消息content参数为空;发文本消息content为必填参数,且不能为空"), + /** + * 多媒体文件大小超过限制;图片不可超过5M;音频不可超过5M;文件不可超过20M + */ + CODE_45001(45001, "多媒体文件大小超过限制;图片不可超过5M;音频不可超过5M;文件不可超过20M"), + /** + * 消息内容大小超过限制 + */ + CODE_45002(45002, "消息内容大小超过限制"), + /** + * 应用description参数长度不符合系统限制;设置应用若带有description参数,则长度必须为4至120个字符 + */ + CODE_45004(45004, "应用description参数长度不符合系统限制;设置应用若带有description参数,则长度必须为4至120个字符"), + /** + * 语音播放时间超过限制;语音播放时长不能超过60秒 + */ + CODE_45007(45007, "语音播放时间超过限制;语音播放时长不能超过60秒"), + /** + * 图文消息的文章数量不符合系统限制;图文消息的文章数量不能超过8条 + */ + CODE_45008(45008, "图文消息的文章数量不符合系统限制;图文消息的文章数量不能超过8条"), + /** + * 接口调用超过限制 + */ + CODE_45009(45009, "接口调用超过限制"), + /** + * 应用name参数长度不符合系统限制;设置应用若带有name参数,则不允许为空,且不超过32个字符 + */ + CODE_45022(45022, "应用name参数长度不符合系统限制;设置应用若带有name参数,则不允许为空,且不超过32个字符"), + /** + * 帐号数量超过上限 + */ + CODE_45024(45024, "帐号数量超过上限"), + /** + * 触发删除用户数的保护;限制参考:全量覆盖成员 + */ + CODE_45026(45026, "触发删除用户数的保护;限制参考:全量覆盖成员"), + /** + * 图文消息author参数长度超过限制;最长64个字节 + */ + CODE_45032(45032, "图文消息author参数长度超过限制;最长64个字节"), + /** + * 接口并发调用超过限制 + */ + CODE_45033(45033, "接口并发调用超过限制"), + /** + * 菜单未设置;菜单需发布后才能获取到数据 + */ + CODE_46003(46003, "菜单未设置;菜单需发布后才能获取到数据"), + /** + * 指定的用户不存在;需要确认指定的用户存在于通讯录中 + */ + CODE_46004(46004, "指定的用户不存在;需要确认指定的用户存在于通讯录中"), + /** + * API接口无权限调用 + */ + CODE_48002(48002, "API接口无权限调用"), + /** + * 不合法的suite_id;确认suite_access_token由指定的suite_id生成 + */ + CODE_48003(48003, "不合法的suite_id;确认suite_access_token由指定的suite_id生成"), + /** + * 授权关系无效;可能是无授权或授权已被取消 + */ + CODE_48004(48004, "授权关系无效;可能是无授权或授权已被取消"), + /** + * API接口已废弃;接口已不再支持,建议改用新接口或者新方案 + */ + CODE_48005(48005, "API接口已废弃;接口已不再支持,建议改用新接口或者新方案"), + /** + * redirect_url未登记可信域名 + */ + CODE_50001(50001, "redirect_url未登记可信域名"), + /** + * 成员不在权限范围;请检查应用或管理组的权限范围 + */ + CODE_50002(50002, "成员不在权限范围;请检查应用或管理组的权限范围"), + /** + * 应用已禁用;禁用的应用无法使用API接口。可在”管理端-企业应用”启用应用 + */ + CODE_50003(50003, "应用已禁用;禁用的应用无法使用API接口。可在”管理端-企业应用”启用应用"), + /** + * 部门长度不符合限制;部门名称不能为空且长度不能超过32个字 + */ + CODE_60001(60001, "部门长度不符合限制;部门名称不能为空且长度不能超过32个字"), + /** + * 部门ID不存在;需要确认部门ID是否有带,并且存在通讯录中 + */ + CODE_60003(60003, "部门ID不存在;需要确认部门ID是否有带,并且存在通讯录中"), + /** + * 父部门不存在;需要确认父亲部门ID是否有带,并且存在通讯录中 + */ + CODE_60004(60004, "父部门不存在;需要确认父亲部门ID是否有带,并且存在通讯录中"), + /** + * 部门下存在成员;不允许删除有成员的部门 + */ + CODE_60005(60005, "部门下存在成员;不允许删除有成员的部门"), + /** + * 部门下存在子部门;不允许删除有子部门的部门 + */ + CODE_60006(60006, "部门下存在子部门;不允许删除有子部门的部门"), + /** + * 不允许删除根部门 + */ + CODE_60007(60007, "不允许删除根部门"), + /** + * 部门已存在;部门ID或者部门名称已存在 + */ + CODE_60008(60008, "部门已存在;部门ID或者部门名称已存在"), + /** + * 部门名称含有非法字符;不能含有 \\:?*“< >| 等字符 + */ + CODE_60009(60009, "部门名称含有非法字符;不能含有 \\ :?*“< >| 等字符"), + /** + * 部门存在循环关系 + */ + CODE_60010(60010, "部门存在循环关系"), + /** + * 指定的成员/部门/标签参数无权限 + */ + CODE_60011(60011, "指定的成员/部门/标签参数无权限"), + /** + * 不允许删除默认应用;默认应用的id为0 + */ + CODE_60012(60012, "不允许删除默认应用;默认应用的id为0"), + /** + * 访问ip不在白名单之中;请确认访问ip是否在服务商白名单IP列表 + */ + CODE_60020(60020, "访问ip不在白名单之中;请确认访问ip是否在服务商白名单IP列表"), + /** + * 不允许修改第三方应用的主页 URL;第三方应用类型,不允许通过接口修改该应用的主页 URL + */ + CODE_60028(60028, "不允许修改第三方应用的主页 URL;第三方应用类型,不允许通过接口修改该应用的主页 URL"), + /** + * UserID已存在 + */ + CODE_60102(60102, "UserID已存在"), + /** + * 手机号码不合法;长度不超过32位,字符仅支持数字,加号和减号 + */ + CODE_60103(60103, "手机号码不合法;长度不超过32位,字符仅支持数字,加号和减号"), + /** + * 手机号码已存在;同一个企业内,成员的手机号不能重复。建议更换手机号,或者更新已有的手机记录。 + */ + CODE_60104(60104, "手机号码已存在;同一个企业内,成员的手机号不能重复。建议更换手机号,或者更新已有的手机记录。"), + /** + * 邮箱不合法;长度不超过64位,且为有效的email格式 + */ + CODE_60105(60105, "邮箱不合法;长度不超过64位,且为有效的email格式"), + /** + * 邮箱已存在;同一个企业内,成员的邮箱不能重复。建议更换邮箱,或者更新已有的邮箱记录。 + */ + CODE_60106(60106, "邮箱已存在;同一个企业内,成员的邮箱不能重复。建议更换邮箱,或者更新已有的邮箱记录。"), + /** + * 微信号不合法;微信号格式由字母、数字、”-“、”_“组成,长度为 3-20 字节,首字符必须是字母或”-“或”_“ + */ + CODE_60107(60107, "微信号不合法;微信号格式由字母、数字、”-“、”_“组成,长度为 3-20 字节,首字符必须是字母或”-“或”_“"), + /** + * 用户所属部门数量超过限制;用户同时归属部门不超过20个 + */ + CODE_60110(60110, "用户所属部门数量超过限制;用户同时归属部门不超过20个"), + /** + * UserID不存在;UserID参数为空,或者不存在通讯录中 + */ + CODE_60111(60111, "UserID不存在;UserID参数为空,或者不存在通讯录中"), + /** + * 成员name参数不合法;不能为空,且不能超过64字符 + */ + CODE_60112(60112, "成员name参数不合法;不能为空,且不能超过64字符"), + /** + * 无效的部门id;部门不存在通讯录中 + */ + CODE_60123(60123, "无效的部门id;部门不存在通讯录中"), + /** + * 无效的父部门id;父部门不存在通讯录中 + */ + CODE_60124(60124, "无效的父部门id;父部门不存在通讯录中"), + /** + * 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符 + */ + CODE_60125(60125, "非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符"), + /** + * 缺少department参数 + */ + CODE_60127(60127, "缺少department参数"), + /** + * 成员手机和邮箱都为空;成员手机和邮箱至少有个非空 + */ + CODE_60129(60129, "成员手机和邮箱都为空;成员手机和邮箱至少有个非空"), + /** + * 发票已被其他公众号锁定 + */ + CODE_72023(72023, "发票已被其他公众号锁定"), + /** + * 发票状态错误;reimburse_status状态错误,参考:更新发票状态 + */ + CODE_72024(72024, "发票状态错误;reimburse_status状态错误,参考:更新发票状态"), + /** + * 存在发票不属于该用户;只能批量更新该openid的发票,参考:批量更新发票状态 + */ + CODE_72037(72037, "存在发票不属于该用户;只能批量更新该openid的发票,参考:批量更新发票状态"), + /** + * 可信域名不正确,或者无ICP备案 + */ + CODE_80001(80001, "可信域名不正确,或者无ICP备案"), + /** + * 部门下的结点数超过限制(3W) + */ + CODE_81001(81001, "部门下的结点数超过限制(3W)"), + /** + * 部门最多15层 + */ + CODE_81002(81002, "部门最多15层"), + /** + * 无权限操作标签 + */ + CODE_81011(81011, "无权限操作标签"), + /** + * UserID、部门ID、标签ID全部非法或无权限 + */ + CODE_81013(81013, "UserID、部门ID、标签ID全部非法或无权限"), + /** + * 标签添加成员,单次添加user或party过多 + */ + CODE_81014(81014, "标签添加成员,单次添加user或party过多"), + /** + * 指定的成员/部门/标签全部无效 + */ + CODE_82001(82001, "指定的成员/部门/标签全部无效"), + /** + * 不合法的PartyID列表长度;发消息,单次不能超过100个部门 + */ + CODE_82002(82002, "不合法的PartyID列表长度;发消息,单次不能超过100个部门"), + /** + * 不合法的TagID列表长度;发消息,单次不能超过100个标签 + */ + CODE_82003(82003, "不合法的TagID列表长度;发消息,单次不能超过100个标签"), + /** + * 成员票据过期 + */ + CODE_84014(84014, "成员票据过期"), + /** + * 成员票据无效;确认user_ticket参数来源是否正确。参考接口:根据code获取成员信息 + */ + CODE_84015(84015, "成员票据无效;确认user_ticket参数来源是否正确。参考接口:根据code获取成员信息"), + /** + * 缺少templateid参数 + */ + CODE_84019(84019, "缺少templateid参数"), + /** + * templateid不存在;确认参数是否有带,并且已创建 + */ + CODE_84020(84020, "templateid不存在;确认参数是否有带,并且已创建"), + /** + * 缺少register_code参数 + */ + CODE_84021(84021, "缺少register_code参数"), + /** + * 无效的register_code参数 + */ + CODE_84022(84022, "无效的register_code参数"), + /** + * 不允许调用设置通讯录同步完成接口 + */ + CODE_84023(84023, "不允许调用设置通讯录同步完成接口"), + /** + * 无注册信息 + */ + CODE_84024(84024, "无注册信息"), + /** + * 不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节 + */ + CODE_84025(84025, "不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节"), + /** + * 包含不合法的词语 + */ + CODE_85002(85002, "包含不合法的词语"), + /** + * 每企业每个月设置的可信域名不可超过20个 + */ + CODE_85004(85004, "每企业每个月设置的可信域名不可超过20个"), + /** + * 可信域名未通过所有权校验 + */ + CODE_85005(85005, "可信域名未通过所有权校验"), + /** + * 参数 chatid 不合法 + */ + CODE_86001(86001, "参数 chatid 不合法"), + /** + * 参数 chatid 不存在 + */ + CODE_86003(86003, "参数 chatid 不存在"), + /** + * 参数 群名不合法 + */ + CODE_86004(86004, "参数 群名不合法"), + /** + * 参数 群主不合法 + */ + CODE_86005(86005, "参数 群主不合法"), + /** + * 群成员数过多或过少 + */ + CODE_86006(86006, "群成员数过多或过少"), + /** + * 不合法的群成员 + */ + CODE_86007(86007, "不合法的群成员"), + /** + * 非法操作非自己创建的群 + */ + CODE_86008(86008, "非法操作非自己创建的群"), + /** + * 存在非法会话成员ID + */ + CODE_86216(86216, "存在非法会话成员ID"), + /** + * 会话发送者不在会话成员列表中;会话的发送者,必须是会话的成员列表之一 + */ + CODE_86217(86217, "会话发送者不在会话成员列表中;会话的发送者,必须是会话的成员列表之一"), + /** + * 指定的会话参数不合法 + */ + CODE_86220(86220, "指定的会话参数不合法"), + /** + * 未认证摇一摇周边 + */ + CODE_90001(90001, "未认证摇一摇周边"), + /** + * 缺少摇一摇周边ticket参数 + */ + CODE_90002(90002, "缺少摇一摇周边ticket参数"), + /** + * 摇一摇周边ticket参数不合法 + */ + CODE_90003(90003, "摇一摇周边ticket参数不合法"), + /** + * 非法的对外属性类型 + */ + CODE_90100(90100, "非法的对外属性类型"), + /** + * 对外属性:文本类型长度不合法;文本长度不可超过12个UTF8字符 + */ + CODE_90101(90101, "对外属性:文本类型长度不合法;文本长度不可超过12个UTF8字符"), + /** + * 对外属性:网页类型标题长度不合法;标题长度不可超过12个UTF8字符 + */ + CODE_90102(90102, "对外属性:网页类型标题长度不合法;标题长度不可超过12个UTF8字符"), + /** + * 对外属性:网页url不合法 + */ + CODE_90103(90103, "对外属性:网页url不合法"), + /** + * 对外属性:小程序类型标题长度不合法;标题长度不可超过12个UTF8字符 + */ + CODE_90104(90104, "对外属性:小程序类型标题长度不合法;标题长度不可超过12个UTF8字符"), + /** + * 对外属性:小程序类型pagepath不合法 + */ + CODE_90105(90105, "对外属性:小程序类型pagepath不合法"), + /** + * 对外属性:请求参数不合法 + */ + CODE_90106(90106, "对外属性:请求参数不合法"), + /** + * 获取ticket的类型无效 + */ + CODE_91040(91040, "获取ticket的类型无效"), + /** + * 无权限操作指定的应用 + */ + CODE_301002(301002, "无权限操作指定的应用"), + /** + * 不允许删除创建者;创建者不允许从通讯录中删除。如果需要删除该成员,需要先在WEB管理端转移创建者身份。 + */ + CODE_301005(301005, "不允许删除创建者;创建者不允许从通讯录中删除。如果需要删除该成员,需要先在WEB管理端转移创建者身份。"), + /** + * 参数 position 不合法;长度不允许超过128个字符 + */ + CODE_301012(301012, "参数 position 不合法;长度不允许超过128个字符"), + /** + * 参数 telephone 不合法;telephone必须由1-32位的纯数字或’-‘号组成。 + */ + CODE_301013(301013, "参数 telephone 不合法;telephone必须由1-32位的纯数字或’-‘号组成。"), + /** + * 参数 english_name 不合法;参数如果有传递,不允许为空字符串,同时不能超过64字节,只能是由字母、数字、点(.)、减号(-)、空格或下划线(_)组成 + */ + CODE_301014(301014, "参数 english_name 不合法;参数如果有传递,不允许为空字符串,同时不能超过64字节,只能是由字母、数字、点(.)、减号(-)、空格或下划线(_)组成"), + /** + * 参数 mediaid 不合法;请检查 mediaid 来源,应该通过上传临时素材的图片类型获得mediaid + */ + CODE_301015(301015, "参数 mediaid 不合法;请检查 mediaid 来源,应该通过上传临时素材的图片类型获得mediaid"), + /** + * 上传语音文件不符合系统要求;语音文件的系统限制,参考上传的媒体文件限制 + */ + CODE_301016(301016, "上传语音文件不符合系统要求;语音文件的系统限制,参考上传的媒体文件限制"), + /** + * 上传语音文件仅支持AMR格式;语音文件的系统限制,参考上传的媒体文件限制 + */ + CODE_301017(301017, "上传语音文件仅支持AMR格式;语音文件的系统限制,参考上传的媒体文件限制"), + /** + * 参数 userid 无效;至少有一个userid不存在于通讯录中 + */ + CODE_301021(301021, "参数 userid 无效;至少有一个userid不存在于通讯录中"), + /** + * 获取打卡数据失败;系统失败,可重试处理 + */ + CODE_301022(301022, "获取打卡数据失败;系统失败,可重试处理"), + /** + * useridlist非法或超过限额;列表数量不能为0且不超过100 + */ + CODE_301023(301023, "useridlist非法或超过限额;列表数量不能为0且不超过100"), + /** + * 获取打卡记录时间间隔超限;保证开始时间大于0 且结束时间大于 0 且结束时间大于开始时间,且间隔少于93天 + */ + CODE_301024(301024, "获取打卡记录时间间隔超限;保证开始时间大于0 且结束时间大于 0 且结束时间大于开始时间,且间隔少于93天"), + /** + * 不允许更新该用户的userid + */ + CODE_301036(301036, "不允许更新该用户的userid"), + /** + * 批量导入任务的文件中userid有重复 + */ + CODE_302003(302003, "批量导入任务的文件中userid有重复"), + /** + * 组织架构不合法(1不是一棵树,2 多个一样的partyid,3 partyid空,4 partyid name 空,5 同一个父节点下有两个子节点 部门名字一样 可能是以上情况,请一一排查) + */ + CODE_302004(302004, "组织架构不合法(1不是一棵树,2 多个一样的partyid,3 partyid空,4 partyid name 空,5 同一个父节点下有两个子节点 部门名字一样 可能是以上情况,请一一排查)"), + /** + * 批量导入系统失败,请重新尝试导入 + */ + CODE_302005(302005, "批量导入系统失败,请重新尝试导入"), + /** + * 批量导入任务的文件中partyid有重复 + */ + CODE_302006(302006, "批量导入任务的文件中partyid有重复"), + /** + * 批量导入任务的文件中,同一个部门下有两个子部门名字一样 + */ + CODE_302007(302007, "批量导入任务的文件中,同一个部门下有两个子部门名字一样"), + /** + * CorpId参数无效;指定的CorpId不存在 + */ + CODE_2000002(2000002, "CorpId参数无效;指定的CorpId不存在"); + + private int code; + private String msg; + + WxCpErrorMsgEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + /** + * 通过错误代码查找其中文含义. + */ + public static String findMsgByCode(int code) { + WxCpErrorMsgEnum[] values = WxCpErrorMsgEnum.values(); + for (WxCpErrorMsgEnum value : values) { + if (value.code == code) { + return value.msg; + } + } + + return null; + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java new file mode 100644 index 0000000000..fc9b624fa3 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java @@ -0,0 +1,80 @@ +package me.chanjar.weixin.common.error; + +import java.io.Serializable; + +import org.apache.commons.lang3.StringUtils; + +import lombok.Builder; +import lombok.Data; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +/** + * 微信错误码. + * 请阅读: + * 公众平台:全局返回码说明 + * 企业微信:全局错误码 + * + * @author Daniel Qian & Binary Wang + */ +@Data +@Builder +public class WxError implements Serializable { + private static final long serialVersionUID = 7869786563361406291L; + + /** + * 微信错误代码. + */ + private int errorCode; + + /** + * 微信错误信息. + * (如果可以翻译为中文,就为中文) + */ + private String errorMsg; + + /** + * 微信接口返回的错误原始信息(英文). + */ + private String errorMsgEn; + + private String json; + + public static WxError fromJson(String json) { + return fromJson(json, null); + } + + public static WxError fromJson(String json, WxType type) { + final WxError wxError = WxGsonBuilder.create().fromJson(json, WxError.class); + if (StringUtils.isNotEmpty(wxError.getErrorMsg())) { + wxError.setErrorMsgEn(wxError.getErrorMsg()); + } + + if (type == null) { + return wxError; + } + + if (type == WxType.MP) { + final String msg = WxMpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); + if (msg != null) { + wxError.setErrorMsg(msg); + } + } else if (type == WxType.CP) { + final String msg = WxCpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); + if (msg != null) { + wxError.setErrorMsg(msg); + } + } + + return wxError; + } + + @Override + public String toString() { + if (this.json != null) { + return this.json; + } + return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/exception/WxErrorException.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxErrorException.java similarity index 81% rename from weixin-java-common/src/main/java/me/chanjar/weixin/common/exception/WxErrorException.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxErrorException.java index 4038e60185..6e9a2c538d 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/exception/WxErrorException.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxErrorException.java @@ -1,9 +1,9 @@ -package me.chanjar.weixin.common.exception; - -import me.chanjar.weixin.common.bean.result.WxError; +package me.chanjar.weixin.common.error; +/** + * @author Daniel Qian + */ public class WxErrorException extends Exception { - private static final long serialVersionUID = -6357149550353160810L; private WxError error; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMpErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMpErrorMsgEnum.java new file mode 100644 index 0000000000..3882252b72 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMpErrorMsgEnum.java @@ -0,0 +1,654 @@ +package me.chanjar.weixin.common.error; + +import lombok.Getter; + +/** + *
+ * 微信公众平台全局返回码.
+ * 参考文档:公众平台全局返回码
+ * Created by Binary Wang on 2018/5/13.
+ * 
+ * + * @author Binary Wang + */ +@Getter +public enum WxMpErrorMsgEnum { + /** + * 系统繁忙,此时请开发者稍候再试 + */ + CODE_1(-1, "系统繁忙,此时请开发者稍候再试"), + /** + * 请求成功 + */ + CODE_0(0, "请求成功"), + /** + * 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口 + */ + CODE_40001(40001, "获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口"), + /** + * 不合法的凭证类型 + */ + CODE_40002(40002, "不合法的凭证类型"), + /** + * 不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID + */ + CODE_40003(40003, "不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID"), + /** + * 不合法的媒体文件类型 + */ + CODE_40004(40004, "不合法的媒体文件类型"), + /** + * 不合法的文件类型 + */ + CODE_40005(40005, "不合法的文件类型"), + /** + * 不合法的文件大小 + */ + CODE_40006(40006, "不合法的文件大小"), + /** + * 不合法的媒体文件 id + */ + CODE_40007(40007, "不合法的媒体文件 id"), + /** + * 不合法的消息类型 + */ + CODE_40008(40008, "不合法的消息类型"), + /** + * 不合法的图片文件大小 + */ + CODE_40009(40009, "不合法的图片文件大小"), + /** + * 不合法的语音文件大小 + */ + CODE_40010(40010, "不合法的语音文件大小"), + /** + * 不合法的视频文件大小 + */ + CODE_40011(40011, "不合法的视频文件大小"), + /** + * 不合法的缩略图文件大小 + */ + CODE_40012(40012, "不合法的缩略图文件大小"), + /** + * 不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写 + */ + CODE_40013(40013, "不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写"), + /** + * 不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 + */ + CODE_40014(40014, "不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口"), + /** + * 不合法的菜单类型 + */ + CODE_40015(40015, "不合法的菜单类型"), + /** + * 不合法的按钮个数 + */ + CODE_40016(40016, "不合法的按钮个数"), + /** + * 不合法的按钮个数 + */ + CODE_40017(40017, "不合法的按钮个数"), + /** + * 不合法的按钮名字长度 + */ + CODE_40018(40018, "不合法的按钮名字长度"), + /** + * 不合法的按钮 KEY 长度 + */ + CODE_40019(40019, "不合法的按钮 KEY 长度"), + /** + * 不合法的按钮 URL 长度 + */ + CODE_40020(40020, "不合法的按钮 URL 长度"), + /** + * 不合法的菜单版本号 + */ + CODE_40021(40021, "不合法的菜单版本号"), + /** + * 不合法的子菜单级数 + */ + CODE_40022(40022, "不合法的子菜单级数"), + /** + * 不合法的子菜单按钮个数 + */ + CODE_40023(40023, "不合法的子菜单按钮个数"), + /** + * 不合法的子菜单按钮类型 + */ + CODE_40024(40024, "不合法的子菜单按钮类型"), + /** + * 不合法的子菜单按钮名字长度 + */ + CODE_40025(40025, "不合法的子菜单按钮名字长度"), + /** + * 不合法的子菜单按钮 KEY 长度 + */ + CODE_40026(40026, "不合法的子菜单按钮 KEY 长度"), + /** + * 不合法的子菜单按钮 URL 长度 + */ + CODE_40027(40027, "不合法的子菜单按钮 URL 长度"), + /** + * 不合法的自定义菜单使用用户 + */ + CODE_40028(40028, "不合法的自定义菜单使用用户"), + /** + * 不合法的 oauth_code + */ + CODE_40029(40029, "不合法的 oauth_code"), + /** + * 不合法的 refresh_token + */ + CODE_40030(40030, "不合法的 refresh_token"), + /** + * 不合法的 openid 列表 + */ + CODE_40031(40031, "不合法的 openid 列表"), + /** + * 不合法的 openid 列表长度 + */ + CODE_40032(40032, "不合法的 openid 列表长度"), + /** + * 不合法的请求字符,不能包含\\uxxxx 格式的字符 + */ + CODE_40033(40033, "不合法的请求字符,不能包含\\uxxxx 格式的字符"), + /** + * 不合法的参数 + */ + CODE_40035(40035, "不合法的参数"), + /** + * 不合法的请求格式 + */ + CODE_40038(40038, "不合法的请求格式"), + /** + * 不合法的 URL 长度 + */ + CODE_40039(40039, "不合法的 URL 长度"), + /** + * 不合法的分组 id + */ + CODE_40050(40050, "不合法的分组 id"), + /** + * 分组名字不合法 + */ + CODE_40051(40051, "分组名字不合法"), + /** + * 删除单篇图文时,指定的 article_idx 不合法 + */ + CODE_40060(40060, "删除单篇图文时,指定的 article_idx 不合法"), + /** + * 分组名字不合法 + */ + CODE_40117(40117, "分组名字不合法"), + /** + * media_id 大小不合法 + */ + CODE_40118(40118, "media_id 大小不合法"), + /** + * button 类型错误 + */ + CODE_40119(40119, "button 类型错误"), + /** + * button 类型错误 + */ + CODE_40120(40120, "button 类型错误"), + /** + * 不合法的 media_id 类型 + */ + CODE_40121(40121, "不合法的 media_id 类型"), + /** + * 微信号不合法 + */ + CODE_40132(40132, "微信号不合法"), + /** + * 不支持的图片格式 + */ + CODE_40137(40137, "不支持的图片格式"), + /** + * 请勿添加其他公众号的主页链接 + */ + CODE_40155(40155, "请勿添加其他公众号的主页链接"), + /** + * 缺少 access_token 参数 + */ + CODE_41001(41001, "缺少 access_token 参数"), + /** + * 缺少 appid 参数 + */ + CODE_41002(41002, "缺少 appid 参数"), + /** + * 缺少 refresh_token 参数 + */ + CODE_41003(41003, "缺少 refresh_token 参数"), + /** + * 缺少 secret 参数 + */ + CODE_41004(41004, "缺少 secret 参数"), + /** + * 缺少多媒体文件数据 + */ + CODE_41005(41005, "缺少多媒体文件数据"), + /** + * 缺少 media_id 参数 + */ + CODE_41006(41006, "缺少 media_id 参数"), + /** + * 缺少子菜单数据 + */ + CODE_41007(41007, "缺少子菜单数据"), + /** + * 缺少 oauth code + */ + CODE_41008(41008, "缺少 oauth code"), + /** + * 缺少 openid + */ + CODE_41009(41009, "缺少 openid"), + /** + * access_token 超时,请检查 access_token 的有效期,请参考基础支持 - 获取 access_token 中,对 access_token 的详细机制说明 + */ + CODE_42001(42001, "access_token 超时,请检查 access_token 的有效期,请参考基础支持 - 获取 access_token 中,对 access_token 的详细机制说明"), + /** + * refresh_token 超时 + */ + CODE_42002(42002, "refresh_token 超时"), + /** + * oauth_code 超时 + */ + CODE_42003(42003, "oauth_code 超时"), + /** + * 用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权 + */ + CODE_42007(42007, "用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权"), + /** + * 需要 GET 请求 + */ + CODE_43001(43001, "需要 GET 请求"), + /** + * 需要 POST 请求 + */ + CODE_43002(43002, "需要 POST 请求"), + /** + * 需要 HTTPS 请求 + */ + CODE_43003(43003, "需要 HTTPS 请求"), + /** + * 需要接收者关注 + */ + CODE_43004(43004, "需要接收者关注"), + /** + * 需要好友关系 + */ + CODE_43005(43005, "需要好友关系"), + /** + * 需要将接收者从黑名单中移除 + */ + CODE_43019(43019, "需要将接收者从黑名单中移除"), + /** + * 多媒体文件为空 + */ + CODE_44001(44001, "多媒体文件为空"), + /** + * POST 的数据包为空 + */ + CODE_44002(44002, "POST 的数据包为空"), + /** + * 图文消息内容为空 + */ + CODE_44003(44003, "图文消息内容为空"), + /** + * 文本消息内容为空 + */ + CODE_44004(44004, "文本消息内容为空"), + /** + * 多媒体文件大小超过限制 + */ + CODE_45001(45001, "多媒体文件大小超过限制"), + /** + * 消息内容超过限制 + */ + CODE_45002(45002, "消息内容超过限制"), + /** + * 标题字段超过限制 + */ + CODE_45003(45003, "标题字段超过限制"), + /** + * 描述字段超过限制 + */ + CODE_45004(45004, "描述字段超过限制"), + /** + * 链接字段超过限制 + */ + CODE_45005(45005, "链接字段超过限制"), + /** + * 图片链接字段超过限制 + */ + CODE_45006(45006, "图片链接字段超过限制"), + /** + * 语音播放时间超过限制 + */ + CODE_45007(45007, "语音播放时间超过限制"), + /** + * 图文消息超过限制 + */ + CODE_45008(45008, "图文消息超过限制"), + /** + * 接口调用超过限制 + */ + CODE_45009(45009, "接口调用超过限制"), + /** + * 创建菜单个数超过限制 + */ + CODE_45010(45010, "创建菜单个数超过限制"), + /** + * API 调用太频繁,请稍候再试 + */ + CODE_45011(45011, "API 调用太频繁,请稍候再试"), + /** + * 回复时间超过限制 + */ + CODE_45015(45015, "回复时间超过限制"), + /** + * 系统分组,不允许修改 + */ + CODE_45016(45016, "系统分组,不允许修改"), + /** + * 分组名字过长 + */ + CODE_45017(45017, "分组名字过长"), + /** + * 分组数量超过上限 + */ + CODE_45018(45018, "分组数量超过上限"), + /** + * 客服接口下行条数超过上限 + */ + CODE_45047(45047, "客服接口下行条数超过上限"), + /** + * 不存在媒体数据 + */ + CODE_46001(46001, "不存在媒体数据"), + /** + * 不存在的菜单版本 + */ + CODE_46002(46002, "不存在的菜单版本"), + /** + * 不存在的菜单数据 + */ + CODE_46003(46003, "不存在的菜单数据"), + /** + * 不存在的用户 + */ + CODE_46004(46004, "不存在的用户"), + /** + * 解析 JSON/XML 内容错误 + */ + CODE_47001(47001, "解析 JSON/XML 内容错误"), + /** + * api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限 + */ + CODE_48001(48001, "api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限"), + /** + * 粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” ) + */ + CODE_48002(48002, "粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” )"), + /** + * api 接口被封禁,请登录 mp.weixin.qq.com 查看详情 + */ + CODE_48004(48004, "api 接口被封禁,请登录 mp.weixin.qq.com 查看详情"), + /** + * api 禁止删除被自动回复和自定义菜单引用的素材 + */ + CODE_48005(48005, "api 禁止删除被自动回复和自定义菜单引用的素材"), + /** + * api 禁止清零调用次数,因为清零次数达到上限 + */ + CODE_48006(48006, "api 禁止清零调用次数,因为清零次数达到上限"), + /** + * 没有该类型消息的发送权限 + */ + CODE_48008(48008, "没有该类型消息的发送权限"), + /** + * 用户未授权该 api + */ + CODE_50001(50001, "用户未授权该 api"), + /** + * 用户受限,可能是违规后接口被封禁 + */ + CODE_50002(50002, "用户受限,可能是违规后接口被封禁"), + /** + * 用户未关注公众号 + */ + CODE_50005(50005, "用户未关注公众号"), + /** + * 参数错误 (invalid parameter) + */ + CODE_61451(61451, "参数错误 (invalid parameter)"), + /** + * 无效客服账号 (invalid kf_account) + */ + CODE_61452(61452, "无效客服账号 (invalid kf_account)"), + /** + * 客服帐号已存在 (kf_account exsited) + */ + CODE_61453(61453, "客服帐号已存在 (kf_account exsited)"), + /** + * 客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length) + */ + CODE_61454(61454, "客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length)"), + /** + * 客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account) + */ + CODE_61455(61455, "客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account)"), + /** + * 客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded) + */ + CODE_61456(61456, "客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded)"), + /** + * 无效头像文件类型 (invalid file type) + */ + CODE_61457(61457, "无效头像文件类型 (invalid file type)"), + /** + * 系统错误 (system error) + */ + CODE_61450(61450, "系统错误 (system error)"), + /** + * 日期格式错误 + */ + CODE_61500(61500, "日期格式错误"), + /** + * 不存在此 menuid 对应的个性化菜单 + */ + CODE_65301(65301, "不存在此 menuid 对应的个性化菜单"), + /** + * 没有相应的用户 + */ + CODE_65302(65302, "没有相应的用户"), + /** + * 没有默认菜单,不能创建个性化菜单 + */ + CODE_65303(65303, "没有默认菜单,不能创建个性化菜单"), + /** + * MatchRule 信息为空 + */ + CODE_65304(65304, "MatchRule 信息为空"), + /** + * 个性化菜单数量受限 + */ + CODE_65305(65305, "个性化菜单数量受限"), + /** + * 不支持个性化菜单的帐号 + */ + CODE_65306(65306, "不支持个性化菜单的帐号"), + /** + * 个性化菜单信息为空 + */ + CODE_65307(65307, "个性化菜单信息为空"), + /** + * 包含没有响应类型的 button + */ + CODE_65308(65308, "包含没有响应类型的 button"), + /** + * 个性化菜单开关处于关闭状态 + */ + CODE_65309(65309, "个性化菜单开关处于关闭状态"), + /** + * 填写了省份或城市信息,国家信息不能为空 + */ + CODE_65310(65310, "填写了省份或城市信息,国家信息不能为空"), + /** + * 填写了城市信息,省份信息不能为空 + */ + CODE_65311(65311, "填写了城市信息,省份信息不能为空"), + /** + * 不合法的国家信息 + */ + CODE_65312(65312, "不合法的国家信息"), + /** + * 不合法的省份信息 + */ + CODE_65313(65313, "不合法的省份信息"), + /** + * 不合法的城市信息 + */ + CODE_65314(65314, "不合法的城市信息"), + /** + * 该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接) + */ + CODE_65316(65316, "该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接)"), + /** + * 不合法的 URL + */ + CODE_65317(65317, "不合法的 URL"), + /** + * POST 数据参数不合法 + */ + CODE_9001001(9001001, "POST 数据参数不合法"), + /** + * 远端服务不可用 + */ + CODE_9001002(9001002, "远端服务不可用"), + /** + * Ticket 不合法 + */ + CODE_9001003(9001003, "Ticket 不合法"), + /** + * 获取摇周边用户信息失败 + */ + CODE_9001004(9001004, "获取摇周边用户信息失败"), + /** + * 获取商户信息失败 + */ + CODE_9001005(9001005, "获取商户信息失败"), + /** + * 获取 OpenID 失败 + */ + CODE_9001006(9001006, "获取 OpenID 失败"), + /** + * 上传文件缺失 + */ + CODE_9001007(9001007, "上传文件缺失"), + /** + * 上传素材的文件类型不合法 + */ + CODE_9001008(9001008, "上传素材的文件类型不合法"), + /** + * 上传素材的文件尺寸不合法 + */ + CODE_9001009(9001009, "上传素材的文件尺寸不合法"), + /** + * 上传失败 + */ + CODE_9001010(9001010, "上传失败"), + /** + * 帐号不合法 + */ + CODE_9001020(9001020, "帐号不合法"), + /** + * 已有设备激活率低于 50% ,不能新增设备 + */ + CODE_9001021(9001021, "已有设备激活率低于 50% ,不能新增设备"), + /** + * 设备申请数不合法,必须为大于 0 的数字 + */ + CODE_9001022(9001022, "设备申请数不合法,必须为大于 0 的数字"), + /** + * 已存在审核中的设备 ID 申请 + */ + CODE_9001023(9001023, "已存在审核中的设备 ID 申请"), + /** + * 一次查询设备 ID 数量不能超过 50 + */ + CODE_9001024(9001024, "一次查询设备 ID 数量不能超过 50"), + /** + * 设备 ID 不合法 + */ + CODE_9001025(9001025, "设备 ID 不合法"), + /** + * 页面 ID 不合法 + */ + CODE_9001026(9001026, "页面 ID 不合法"), + /** + * 页面参数不合法 + */ + CODE_9001027(9001027, "页面参数不合法"), + /** + * 一次删除页面 ID 数量不能超过 10 + */ + CODE_9001028(9001028, "一次删除页面 ID 数量不能超过 10"), + /** + * 页面已应用在设备中,请先解除应用关系再删除 + */ + CODE_9001029(9001029, "页面已应用在设备中,请先解除应用关系再删除"), + /** + * 一次查询页面 ID 数量不能超过 50 + */ + CODE_9001030(9001030, "一次查询页面 ID 数量不能超过 50"), + /** + * 时间区间不合法 + */ + CODE_9001031(9001031, "时间区间不合法"), + /** + * 保存设备与页面的绑定关系参数错误 + */ + CODE_9001032(9001032, "保存设备与页面的绑定关系参数错误"), + /** + * 门店 ID 不合法 + */ + CODE_9001033(9001033, "门店 ID 不合法"), + /** + * 设备备注信息过长 + */ + CODE_9001034(9001034, "设备备注信息过长"), + /** + * 设备申请参数不合法 + */ + CODE_9001035(9001035, "设备申请参数不合法"), + /** + * 查询起始值 begin 不合法 + */ + CODE_9001036(9001036, "查询起始值 begin 不合法"); + + private int code; + private String msg; + + WxMpErrorMsgEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } + + /** + * 通过错误代码查找其中文含义. + */ + public static String findMsgByCode(int code) { + WxMpErrorMsgEnum[] values = WxMpErrorMsgEnum.values(); + for (WxMpErrorMsgEnum value : values) { + if (value.code == code) { + return value.msg; + } + } + + return null; + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/Constants.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/Constants.java index f30a0ae0d0..98d45e31d4 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/Constants.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/Constants.java @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -23,9 +23,6 @@ * * @author Craig R. McClanahan */ - public class Constants { - - public static final String Package = "me.chanjar.weixin.common.session"; - + public static final String PACKAGE = "me.chanjar.weixin.common.session"; } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSession.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSession.java index 77d4d28291..05cb41363f 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSession.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSession.java @@ -1,5 +1,9 @@ package me.chanjar.weixin.common.session; +/** + * + * @author Daniel Qian + */ public interface InternalSession { /** diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java index a92e107154..e3d9ab8351 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java @@ -1,5 +1,8 @@ package me.chanjar.weixin.common.session; +/** + * @author Daniel Qian + */ public interface InternalSessionManager { /** diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java index f9d61707e3..3c4ec20c8d 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java @@ -1,23 +1,29 @@ package me.chanjar.weixin.common.session; -import me.chanjar.weixin.common.util.res.StringManager; - -import java.util.*; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import me.chanjar.weixin.common.util.res.StringManager; + +/** + * @author Daniel Qian + */ public class StandardSession implements WxSession, InternalSession { /** * The string manager for this package. */ - protected static final StringManager sm = StringManager.getManager(Constants.Package); + protected static final StringManager SM = StringManager.getManager(Constants.PACKAGE); /** * Type array. */ private static final String[] EMPTY_ARRAY = new String[0]; - // ------------------------------ WxSession protected Map attributes = new ConcurrentHashMap<>(); /** * The session identifier of this Session. @@ -73,7 +79,7 @@ public Object getAttribute(String name) { if (!isValidInternal()) { throw new IllegalStateException - (sm.getString("sessionImpl.getAttribute.ise")); + (SM.getString("sessionImpl.getAttribute.ise")); } if (name == null) { @@ -86,7 +92,7 @@ public Object getAttribute(String name) { @Override public Enumeration getAttributeNames() { if (!isValidInternal()) { - throw new IllegalStateException(sm.getString("sessionImpl.getAttributeNames.ise")); + throw new IllegalStateException(SM.getString("sessionImpl.getAttributeNames.ise")); } Set names = new HashSet<>(); @@ -98,7 +104,7 @@ public Enumeration getAttributeNames() { public void setAttribute(String name, Object value) { // Name cannot be null if (name == null) { - throw new IllegalArgumentException(sm.getString("sessionImpl.setAttribute.namenull")); + throw new IllegalArgumentException(SM.getString("sessionImpl.setAttribute.namenull")); } // Null value is the same as removeAttribute() @@ -109,7 +115,7 @@ public void setAttribute(String name, Object value) { // Validate our current state if (!isValidInternal()) { - throw new IllegalStateException(sm.getString("sessionImpl.setAttribute.ise", getIdInternal())); + throw new IllegalStateException(SM.getString("sessionImpl.setAttribute.ise", getIdInternal())); } this.attributes.put(name, value); @@ -123,8 +129,9 @@ public void removeAttribute(String name) { @Override public void invalidate() { - if (!isValidInternal()) - throw new IllegalStateException(sm.getString("sessionImpl.invalidate.ise")); + if (!isValidInternal()) { + throw new IllegalStateException(SM.getString("sessionImpl.invalidate.ise")); + } // Cause this session to expire expire(); diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionFacade.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionFacade.java index e449308961..aa9f877136 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionFacade.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionFacade.java @@ -2,6 +2,9 @@ import java.util.Enumeration; +/** + * @author Daniel Qian + */ public class StandardSessionFacade implements WxSession { /** diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionManager.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionManager.java index f20fd5c2a3..bf2e735872 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionManager.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionManager.java @@ -1,20 +1,22 @@ package me.chanjar.weixin.common.session; -import me.chanjar.weixin.common.util.res.StringManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import me.chanjar.weixin.common.util.res.StringManager; + /** - * 基于内存的session manager + * 基于内存的session manager. + * + * @author Daniel Qian */ public class StandardSessionManager implements WxSessionManager, InternalSessionManager { - protected static final StringManager sm = - StringManager.getManager(Constants.Package); + protected static final StringManager SM = StringManager.getManager(Constants.PACKAGE); /** * The descriptive name of this Manager implementation (for logging). */ @@ -82,7 +84,7 @@ public WxSession getSession(String sessionId) { public WxSession getSession(String sessionId, boolean create) { if (sessionId == null) { throw new IllegalStateException - (sm.getString("sessionManagerImpl.getSession.ise")); + (SM.getString("sessionManagerImpl.getSession.ise")); } InternalSession session = findSession(sessionId); @@ -124,25 +126,24 @@ public void remove(InternalSession session, boolean update) { @Override public InternalSession findSession(String id) { - - if (id == null) + if (id == null) { return (null); + } return this.sessions.get(id); - } @Override public InternalSession createSession(String sessionId) { if (sessionId == null) { throw new IllegalStateException - (sm.getString("sessionManagerImpl.createSession.ise")); + (SM.getString("sessionManagerImpl.createSession.ise")); } if ((this.maxActiveSessions >= 0) && (getActiveSessions() >= this.maxActiveSessions)) { this.rejectedSessions++; throw new TooManyActiveSessionsException( - sm.getString("sessionManagerImpl.createSession.tmase"), + SM.getString("sessionManagerImpl.createSession.tmase"), this.maxActiveSessions); } @@ -192,7 +193,7 @@ public void run() { while (true) { try { // 每秒清理一次 - Thread.sleep(StandardSessionManager.this.backgroundProcessorDelay * 1000l); + Thread.sleep(StandardSessionManager.this.backgroundProcessorDelay * 1000L); backgroundProcess(); } catch (InterruptedException e) { StandardSessionManager.this.log.error("SessionManagerImpl.backgroundProcess error", e); @@ -230,8 +231,9 @@ public InternalSession[] findSessions() { @Override public void backgroundProcess() { this.count = (this.count + 1) % this.processExpiresFrequency; - if (this.count == 0) + if (this.count == 0) { processExpires(); + } } /** @@ -243,16 +245,18 @@ public void processExpires() { InternalSession sessions[] = findSessions(); int expireHere = 0; - if (this.log.isDebugEnabled()) + if (this.log.isDebugEnabled()) { this.log.debug("Start expire sessions {} at {} sessioncount {}", getName(), timeNow, sessions.length); - for (int i = 0; i < sessions.length; i++) { - if (sessions[i] != null && !sessions[i].isValid()) { + } + for (InternalSession session : sessions) { + if (session != null && !session.isValid()) { expireHere++; } } long timeEnd = System.currentTimeMillis(); - if (this.log.isDebugEnabled()) + if (this.log.isDebugEnabled()) { this.log.debug("End expire sessions {} processingTime {} expired sessions: {}", getName(), timeEnd - timeNow, expireHere); + } this.processingTime += (timeEnd - timeNow); } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/TooManyActiveSessionsException.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/TooManyActiveSessionsException.java index fa1b45fafe..114dd1c4ed 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/TooManyActiveSessionsException.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/TooManyActiveSessionsException.java @@ -19,6 +19,8 @@ /** * An exception that indicates the maximum number of active sessions has been * reached and the server is refusing to create any new sessions. + * + * @author Daniel Qian */ public class TooManyActiveSessionsException extends IllegalStateException { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSession.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSession.java index 25bed2d274..3aa79f9ad2 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSession.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSession.java @@ -2,6 +2,9 @@ import java.util.Enumeration; +/** + * @author Daniel Qian + */ public interface WxSession { Object getAttribute(String name); diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSessionManager.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSessionManager.java index c966ddab28..789e272875 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSessionManager.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/WxSessionManager.java @@ -1,5 +1,8 @@ package me.chanjar.weixin.common.session; +/** + * @author Daniel Qian + */ public interface WxSessionManager { /** diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java index 630821e954..4b7f9be6a7 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java @@ -1,11 +1,9 @@ package me.chanjar.weixin.common.util; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.thoughtworks.xstream.annotations.XStreamAlias; import me.chanjar.weixin.common.annotation.Required; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,14 +12,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; /** *
  * bean操作的一些工具类
  * Created by Binary Wang on 2016-10-21.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author binarywang(Binary Wang) */ public class BeanUtils { private static Logger log = LoggerFactory.getLogger(BeanUtils.class); @@ -30,7 +28,6 @@ public class BeanUtils { * 检查bean里标记为@Required的field是否为空,为空则抛异常 * * @param bean 要检查的bean对象 - * @throws WxErrorException */ public static void checkRequiredFields(Object bean) throws WxErrorException { List requiredFields = Lists.newArrayList(); @@ -42,55 +39,28 @@ public static void checkRequiredFields(Object bean) throws WxErrorException { boolean isAccessible = field.isAccessible(); field.setAccessible(true); if (field.isAnnotationPresent(Required.class)) { - if (field.get(bean) == null || (field.get(bean) instanceof String && StringUtils.isBlank(field.get(bean).toString()))) { - //两种情况,一种是值为null,另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 + // 两种情况,一种是值为null, + // 另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值 + boolean isRequiredMissing = field.get(bean) == null + || (field.get(bean) instanceof String + && StringUtils.isBlank(field.get(bean).toString()) + ); + if (isRequiredMissing) { requiredFields.add(field.getName()); } } field.setAccessible(isAccessible); } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); + log.error(e.getMessage(), e); } } if (!requiredFields.isEmpty()) { String msg = "必填字段 " + requiredFields + " 必须提供值"; log.debug(msg); - throw new WxErrorException(WxError.newBuilder().setErrorMsg(msg).build()); + throw new WxErrorException(WxError.builder().errorMsg(msg).build()); } } - /** - * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象 - * - * @param bean 包含@XStreamAlias的xml bean对象 - * @return map对象 - */ - public static Map xmlBean2Map(Object bean) { - Map result = Maps.newHashMap(); - List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); - fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); - for (Field field : fields) { - try { - boolean isAccessible = field.isAccessible(); - field.setAccessible(true); - if (field.get(bean) == null) { - field.setAccessible(isAccessible); - continue; - } - - if (field.isAnnotationPresent(XStreamAlias.class)) { - result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); - } - - field.setAccessible(isAccessible); - } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - - } - - return result; - } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java new file mode 100644 index 0000000000..983d9a668f --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java @@ -0,0 +1,24 @@ +package me.chanjar.weixin.common.util; + +import org.apache.commons.lang3.StringUtils; + +/** + *
+ *  数据处理工具类
+ *  Created by BinaryWang on 2018/5/8.
+ * 
+ * + * @author Binary Wang + */ +public class DataUtils { + /** + * 将数据中包含的secret字符使用星号替换,防止日志打印时被输出 + */ + public static E handleDataWithSecret(E data) { + E dataForLog = data; + if(data instanceof String && StringUtils.contains((String)data, "&secret=")){ + dataForLog = (E) StringUtils.replaceAll((String)data,"&secret=\\w+&","&secret=******&"); + } + return dataForLog; + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java index 7ad976abd8..7487a0fe29 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.common.util; import me.chanjar.weixin.common.api.WxErrorExceptionHandler; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java new file mode 100644 index 0000000000..9ea33b123e --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.common.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Hex; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +/** + *
+ *  签名工具类
+ *  Created by BinaryWang on 2018/7/11.
+ * 
+ * + * @author Binary Wang + */ +@Slf4j +public class SignUtils { + /** + * HmacSHA256 签名算法 + * + * @param message 签名数据 + * @param key 签名密钥 + */ + public static String createHmacSha256Sign(String message, String key) { + try { + Mac sha256 = Mac.getInstance("HmacSHA256"); + SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256"); + sha256.init(secretKeySpec); + byte[] bytes = sha256.doFinal(message.getBytes()); + return Hex.encodeHexString(bytes).toUpperCase(); + } catch (NoSuchAlgorithmException | InvalidKeyException e) { + SignUtils.log.error(e.getMessage(), e); + } + + return null; + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java deleted file mode 100644 index 333e484a8f..0000000000 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java +++ /dev/null @@ -1,63 +0,0 @@ -package me.chanjar.weixin.common.util; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; - -/** - *
- * 自定义的ToString方法,用于产生去掉空值属性的字符串
- * Created by Binary Wang on 2016-10-27.
- * @author binarywang(Binary Wang)
- * 
- */ -public class ToStringUtils { - public static final ToStringStyle THE_STYLE = new SimpleMultiLineToStringStyle(); - - /** - * 用于产生去掉空值属性并以换行符分割各属性键值的toString字符串 - * - * @param obj - */ - public static String toSimpleString(Object obj) { - String toStringResult = ToStringBuilder.reflectionToString(obj, THE_STYLE); - String[] split = toStringResult.split(SimpleMultiLineToStringStyle.LINE_SEPARATOR); - StringBuilder result = new StringBuilder(); - for (String string : split) { - if (string.endsWith(SimpleMultiLineToStringStyle.NULL_TEXT)) { - continue; - } - - result.append(string + SimpleMultiLineToStringStyle.LINE_SEPARATOR); - } - - if (result.length() == 0) { - return ""; - } - - //如果没有非空的属性,就输出 - if (StringUtils.countMatches(result, SimpleMultiLineToStringStyle.LINE_SEPARATOR) == 2) { - return result.toString().split(SimpleMultiLineToStringStyle.LINE_SEPARATOR)[0] - + "]"; - } - - return result.deleteCharAt(result.length() - 1).toString(); - } - - private static class SimpleMultiLineToStringStyle extends ToStringStyle { - private static final long serialVersionUID = 4645306494220335355L; - private static final String LINE_SEPARATOR = "\n"; - private static final String NULL_TEXT = ""; - - public SimpleMultiLineToStringStyle() { - super(); - this.setContentStart("["); - this.setFieldSeparator(LINE_SEPARATOR + " "); - this.setFieldSeparatorAtStart(true); - this.setContentEnd(LINE_SEPARATOR + "]"); - this.setNullText(NULL_TEXT); - this.setUseShortClassName(true); - this.setUseIdentityHashCode(false); - } - } -} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java index b12ec65555..bff08d680d 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java @@ -1,26 +1,26 @@ -package me.chanjar.weixin.common.util.crypto; - -import java.util.ArrayList; - -public class ByteGroup { - ArrayList byteContainer = new ArrayList<>(); - - public byte[] toBytes() { - byte[] bytes = new byte[this.byteContainer.size()]; - for (int i = 0; i < this.byteContainer.size(); i++) { - bytes[i] = this.byteContainer.get(i); - } - return bytes; - } - - public ByteGroup addBytes(byte[] bytes) { - for (byte b : bytes) { - this.byteContainer.add(b); - } - return this; - } - - public int size() { - return this.byteContainer.size(); - } -} +package me.chanjar.weixin.common.util.crypto; + +import java.util.ArrayList; + +public class ByteGroup { + ArrayList byteContainer = new ArrayList<>(); + + public byte[] toBytes() { + byte[] bytes = new byte[this.byteContainer.size()]; + for (int i = 0; i < this.byteContainer.size(); i++) { + bytes[i] = this.byteContainer.get(i); + } + return bytes; + } + + public ByteGroup addBytes(byte[] bytes) { + for (byte b : bytes) { + this.byteContainer.add(b); + } + return this; + } + + public int size() { + return this.byteContainer.size(); + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java index 145896a577..8ce94cbac0 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java @@ -1,68 +1,68 @@ -/** - * 对公众平台发送给公众账号的消息加解密示例代码. - * - * @copyright Copyright (c) 1998-2014 Tencent Inc. - */ - -// ------------------------------------------------------------------------ - -package me.chanjar.weixin.common.util.crypto; - -import java.nio.charset.Charset; -import java.util.Arrays; - -/** - * 提供基于PKCS7算法的加解 - */ -public class PKCS7Encoder { - - private static final Charset CHARSET = Charset.forName("utf-8"); - private static final int BLOCK_SIZE = 32; - - /** - * 获得对明文进行补位填充的字节. - * - * @param count 需要进行填充补位操作的明文字节个数 - * @return 补齐用的字节数组 - */ - public static byte[] encode(int count) { - // 计算需要填充的位数 - int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); - if (amountToPad == 0) { - amountToPad = BLOCK_SIZE; - } - // 获得补位所用的字符 - char padChr = chr(amountToPad); - String tmp = new String(); - for (int index = 0; index < amountToPad; index++) { - tmp += padChr; - } - return tmp.getBytes(CHARSET); - } - - /** - * 删除解密后明文的补位字符 - * - * @param decrypted 解密后的明文 - * @return 删除补位字符后的明文 - */ - public static byte[] decode(byte[] decrypted) { - int pad = decrypted[decrypted.length - 1]; - if (pad < 1 || pad > 32) { - pad = 0; - } - return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); - } - - /** - * 将数字转化成ASCII码对应的字符,用于对明文进行补码 - * - * @param a 需要转化的数字 - * @return 转化得到的字符 - */ - public static char chr(int a) { - byte target = (byte) (a & 0xFF); - return (char) target; - } - -} +/** + * 对公众平台发送给公众账号的消息加解密示例代码. + * + * @copyright Copyright (c) 1998-2014 Tencent Inc. + */ + +// ------------------------------------------------------------------------ + +package me.chanjar.weixin.common.util.crypto; + +import java.nio.charset.Charset; +import java.util.Arrays; + +/** + * 提供基于PKCS7算法的加解 + */ +public class PKCS7Encoder { + + private static final Charset CHARSET = Charset.forName("utf-8"); + private static final int BLOCK_SIZE = 32; + + /** + * 获得对明文进行补位填充的字节. + * + * @param count 需要进行填充补位操作的明文字节个数 + * @return 补齐用的字节数组 + */ + public static byte[] encode(int count) { + // 计算需要填充的位数 + int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); + if (amountToPad == 0) { + amountToPad = BLOCK_SIZE; + } + // 获得补位所用的字符 + char padChr = chr(amountToPad); + String tmp = new String(); + for (int index = 0; index < amountToPad; index++) { + tmp += padChr; + } + return tmp.getBytes(CHARSET); + } + + /** + * 删除解密后明文的补位字符 + * + * @param decrypted 解密后的明文 + * @return 删除补位字符后的明文 + */ + public static byte[] decode(byte[] decrypted) { + int pad = decrypted[decrypted.length - 1]; + if (pad < 1 || pad > 32) { + pad = 0; + } + return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); + } + + /** + * 将数字转化成ASCII码对应的字符,用于对明文进行补码 + * + * @param a 需要转化的数字 + * @return 转化得到的字符 + */ + public static char chr(int a) { + byte target = (byte) (a & 0xFF); + return (char) target; + } + +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java index c91e8ac089..f16d3bd3ea 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java @@ -28,10 +28,10 @@ */ public class WxCryptUtil { - private static final Base64 base64 = new Base64(); + private static final Base64 BASE64 = new Base64(); private static final Charset CHARSET = StandardCharsets.UTF_8; - private static final ThreadLocal builderLocal = new ThreadLocal() { + private static final ThreadLocal BUILDER_LOCAL = new ThreadLocal() { @Override protected DocumentBuilder initialValue() { try { @@ -65,7 +65,7 @@ public WxCryptUtil(String token, String encodingAesKey, static String extractEncryptPart(String xml) { try { - DocumentBuilder db = builderLocal.get(); + DocumentBuilder db = BUILDER_LOCAL.get(); Document document = db.parse(new InputSource(new StringReader(xml))); Element root = document.getDocumentElement(); @@ -192,7 +192,7 @@ protected String encrypt(String randomStr, String plainText) { byte[] encrypted = cipher.doFinal(unencrypted); // 使用BASE64对加密后的字符串进行编码 - return base64.encodeToString(encrypted); + return BASE64.encodeToString(encrypted); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java index df031b3371..1b051a4718 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java @@ -1,52 +1,37 @@ package me.chanjar.weixin.common.util.fs; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; public class FileUtils { - /** - * 创建临时文件 + * 创建临时文件. * - * @param inputStream + * @param inputStream 输入文件流 * @param name 文件名 * @param ext 扩展名 * @param tmpDirFile 临时文件夹目录 */ public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException { - File tmpFile; - if (tmpDirFile == null) { - tmpFile = File.createTempFile(name, '.' + ext); - } else { - tmpFile = File.createTempFile(name, '.' + ext, tmpDirFile); - } - - tmpFile.deleteOnExit(); - - try (FileOutputStream fos = new FileOutputStream(tmpFile)) { - int read = 0; - byte[] bytes = new byte[1024 * 100]; - while ((read = inputStream.read(bytes)) != -1) { - fos.write(bytes, 0, read); - } + File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile); - fos.flush(); - return tmpFile; - } + resultFile.deleteOnExit(); + org.apache.commons.io.FileUtils.copyToFile(inputStream, resultFile); + return resultFile; } /** - * 创建临时文件 + * 创建临时文件. * - * @param inputStream + * @param inputStream 输入文件流 * @param name 文件名 * @param ext 扩展名 */ public static File createTmpFile(InputStream inputStream, String name, String ext) throws IOException { - return createTmpFile(inputStream, name, ext, null); + return createTmpFile(inputStream, name, ext, Files.createTempDirectory("weixin-java-tools-temp").toFile()); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/BaseMediaDownloadRequestExecutor.java similarity index 85% rename from weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/BaseMediaDownloadRequestExecutor.java index d948859748..990e162008 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/BaseMediaDownloadRequestExecutor.java @@ -12,11 +12,11 @@ * * @author Daniel Qian */ -public abstract class MediaDownloadRequestExecutor implements RequestExecutor { - +public abstract class BaseMediaDownloadRequestExecutor implements RequestExecutor { protected RequestHttp requestHttp; protected File tmpDirFile; - public MediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { + + public BaseMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { this.requestHttp = requestHttp; this.tmpDirFile = tmpDirFile; } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java index a75aa963e0..ceaeffbd1e 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java @@ -1,8 +1,8 @@ package me.chanjar.weixin.common.util.http; import jodd.http.HttpResponse; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import okhttp3.Response; import org.apache.http.Header; import org.apache.http.client.methods.CloseableHttpResponse; @@ -19,6 +19,8 @@ * @author Binary Wang */ public class HttpResponseProxy { + private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\""); + private CloseableHttpResponse apacheHttpResponse; private HttpResponse joddHttpResponse; private Response okHttpResponse; @@ -56,7 +58,7 @@ public String getFileName() throws WxErrorException { private String getFileName(CloseableHttpResponse response) throws WxErrorException { Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); } return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue()); @@ -74,15 +76,15 @@ private String getFileName(Response response) throws WxErrorException { private String extractFileNameFromContentString(String content) throws WxErrorException { if (content == null || content.length() == 0) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); } - Pattern p = Pattern.compile(".*filename=\"(.*)\""); - Matcher m = p.matcher(content); + Matcher m = PATTERN.matcher(content); if (m.matches()) { return m.group(1); } - throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); + + throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build()); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpType.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpType.java index c692eb9100..eff5907f7a 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpType.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpType.java @@ -4,5 +4,16 @@ * Created by ecoolper on 2017/4/28. */ public enum HttpType { - JODD_HTTP, APACHE_HTTP, OK_HTTP; + /** + * jodd-http. + */ + JODD_HTTP, + /** + * apache httpclient. + */ + APACHE_HTTP, + /** + * okhttp. + */ + OK_HTTP } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java index 583db4f5ae..a5a9423fd0 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.common.util.http; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import java.io.IOException; @@ -9,51 +9,13 @@ * * @param 返回值类型 * @param 请求参数类型 + * @author Daniel Qian */ public interface RequestExecutor { /** * @param uri uri * @param data 数据 - * @throws WxErrorException - * @throws IOException */ T execute(String uri, E data) throws WxErrorException, IOException; - - /** - * apache-http实现方式 - * @param httpclient - * @param httpProxy - * @param uri - * @param data - * @return - * @throws WxErrorException - * @throws IOException - *//* - T executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, IOException; - - *//** - * jodd-http实现方式 - * @param provider - * @param proxyInfo - * @param uri - * @param data - * @return - * @throws WxErrorException - * @throws IOException - *//* - T executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, E data) throws WxErrorException, IOException; - - - *//** okhttp实现方式 - * @param pool - * @param proxyInfo - * @param uri - * @param data - * @return - * @throws WxErrorException - * @throws IOException - *//* - T executeOkhttp(ConnectionPool pool, final OkHttpProxyInfo proxyInfo, String uri, E data) throws WxErrorException, IOException; -*/ } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java index 939b624785..fcd56c48a7 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java @@ -4,51 +4,41 @@ import org.apache.http.impl.client.CloseableHttpClient; /** - * httpclient build interface + * httpclient build interface. * * @author kakotor */ public interface ApacheHttpClientBuilder { /** - * 构建httpclient实例 + * 构建httpclient实例. * * @return new instance of CloseableHttpClient */ CloseableHttpClient build(); /** - * 代理服务器地址 - * - * @param httpProxyHost + * 代理服务器地址. */ ApacheHttpClientBuilder httpProxyHost(String httpProxyHost); /** - * 代理服务器端口 - * - * @param httpProxyPort + * 代理服务器端口. */ ApacheHttpClientBuilder httpProxyPort(int httpProxyPort); /** - * 代理服务器用户名 - * - * @param httpProxyUsername + * 代理服务器用户名. */ ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername); /** - * 代理服务器密码 - * - * @param httpProxyPassword + * 代理服务器密码. */ ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword); /** - * ssl连接socket工厂 - * - * @param sslConnectionSocketFactory + * ssl连接socket工厂. */ ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory); } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientSimpleGetRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientSimpleGetRequestExecutor.java index e47216e6cd..658ea4afd0 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientSimpleGetRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientSimpleGetRequestExecutor.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.common.util.http.apache; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import org.apache.http.HttpHost; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpDnsClientBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpDnsClientBuilder.java index d3e5a1c167..033add1aa0 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpDnsClientBuilder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpDnsClientBuilder.java @@ -1,6 +1,7 @@ package me.chanjar.weixin.common.util.http.apache; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; @@ -29,9 +30,8 @@ import java.util.concurrent.atomic.AtomicBoolean; /** - * httpclient 连接管理器 自带DNS解析 - *

- * 大部分代码拷贝自:DefaultApacheHttpClientBuilder + * httpclient 连接管理器 自带DNS解析. + *

大部分代码拷贝自:DefaultApacheHttpClientBuilder

* * @author Andy.Huo */ @@ -64,7 +64,7 @@ public boolean retryRequest(IOException exception, int executionCount, HttpConte private String httpProxyPassword; /** - * 闲置连接监控线程 + * 闲置连接监控线程. */ private IdleConnectionMonitorThread idleConnectionMonitorThread; private HttpClientBuilder httpClientBuilder; @@ -162,7 +162,7 @@ public void setCheckWaitTime(int checkWaitTime) { } /** - * 每路的最大链接数,默认10 + * 每路的最大链接数,默认10. * * @param maxConnPerHost 每路的最大链接数,默认10 */ @@ -171,7 +171,7 @@ public void setMaxConnPerHost(int maxConnPerHost) { } /** - * 最大总连接数,默认50 + * 最大总连接数,默认50. * * @param maxTotalConn 最大总连接数,默认50 */ @@ -180,7 +180,7 @@ public void setMaxTotalConn(int maxTotalConn) { } /** - * 自定义httpclient的User Agent + * 自定义httpclient的User Agent. * * @param userAgent User Agent */ @@ -196,9 +196,12 @@ private synchronized void prepare() { if (prepared.get()) { return; } - Registry registry = RegistryBuilder.create() - .register("http", this.plainConnectionSocketFactory).register("https", this.sslConnectionSocketFactory) - .build(); + + Registry registry = + RegistryBuilder.create() + .register("http", this.plainConnectionSocketFactory) + .register("https", this.sslConnectionSocketFactory) + .build(); @SuppressWarnings("resource") PoolingHttpClientConnectionManager connectionManager; @@ -219,8 +222,8 @@ private synchronized void prepare() { connectionManager .setDefaultSocketConfig(SocketConfig.copy(SocketConfig.DEFAULT).setSoTimeout(this.soTimeout).build()); - this.idleConnectionMonitorThread = new IdleConnectionMonitorThread(connectionManager, this.idleConnTimeout, - this.checkWaitTime); + this.idleConnectionMonitorThread = new IdleConnectionMonitorThread( + connectionManager, this.idleConnTimeout, this.checkWaitTime); this.idleConnectionMonitorThread.setDaemon(true); this.idleConnectionMonitorThread.start(); @@ -237,6 +240,7 @@ private synchronized void prepare() { provider.setCredentials(new AuthScope(this.httpProxyHost, this.httpProxyPort), new UsernamePasswordCredentials(this.httpProxyUsername, this.httpProxyPassword)); this.httpClientBuilder.setDefaultCredentialsProvider(provider); + this.httpClientBuilder.setProxy(new HttpHost(this.httpProxyHost, this.httpProxyPort)); } if (StringUtils.isNotBlank(this.userAgent)) { @@ -267,8 +271,10 @@ public static class IdleConnectionMonitorThread extends Thread { private final int checkWaitTime; private volatile boolean shutdown; - public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout, - int checkWaitTime) { + /** + * 构造方法. + */ + public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout, int checkWaitTime) { super("IdleConnectionMonitorThread"); this.connMgr = connMgr; this.idleConnTimeout = idleConnTimeout; @@ -289,12 +295,18 @@ public void run() { } } + /** + * 触发. + */ public void trigger() { synchronized (this) { notifyAll(); } } + /** + * 关闭. + */ public void shutdown() { this.shutdown = true; synchronized (this) { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java index 0a5a504873..2ce8750822 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java @@ -1,11 +1,9 @@ package me.chanjar.weixin.common.util.http.apache; -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.HttpResponseProxy; -import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; -import me.chanjar.weixin.common.util.http.RequestHttp; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; @@ -16,14 +14,17 @@ import org.apache.http.entity.ContentType; import org.apache.http.impl.client.CloseableHttpClient; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.HttpResponseProxy; +import me.chanjar.weixin.common.util.http.RequestHttp; /** * Created by ecoolper on 2017/5/5. */ -public class ApacheMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor { +public class ApacheMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor { public ApacheMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { super(requestHttp, tmpDirFile); @@ -45,8 +46,7 @@ public File execute(String uri, String queryParam) throws WxErrorException, IOEx } try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet); - InputStream inputStream = InputStreamResponseHandler.INSTANCE - .handleResponse(response)) { + InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response)) { Header[] contentTypeHeader = response.getHeaders("Content-Type"); if (contentTypeHeader != null && contentTypeHeader.length > 0) { if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaUploadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaUploadRequestExecutor.java index bdddf0dfb9..6684bb9362 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaUploadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaUploadRequestExecutor.java @@ -1,8 +1,8 @@ package me.chanjar.weixin.common.util.http.apache; -import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import org.apache.http.HttpEntity; @@ -10,7 +10,6 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java index cc85fa76d7..2517dbcd71 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.common.util.http.apache; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; import org.apache.http.Consts; @@ -39,9 +39,7 @@ public String execute(String uri, String postEntity) throws WxErrorException, IO try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); if (responseContent.isEmpty()) { - throw new WxErrorException( - WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") - .build()); + throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); } if (responseContent.startsWith("")) { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java index 19c79bdcf2..dfca21a7b2 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/DefaultApacheHttpClientBuilder.java @@ -1,6 +1,7 @@ package me.chanjar.weixin.common.util.http.apache; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; import org.apache.http.annotation.NotThreadSafe; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; @@ -226,29 +227,26 @@ private synchronized void prepare() { .setConnectionManager(connectionManager) .setConnectionManagerShared(true) .setSSLSocketFactory(this.buildSSLConnectionSocketFactory()) - .setDefaultRequestConfig( - RequestConfig.custom() - .setSocketTimeout(this.soTimeout) - .setConnectTimeout(this.connectionTimeout) - .setConnectionRequestTimeout(this.connectionRequestTimeout) - .build() - ) - .setRetryHandler(this.httpRequestRetryHandler); - - if (StringUtils.isNotBlank(this.httpProxyHost) - && StringUtils.isNotBlank(this.httpProxyUsername)) { + .setDefaultRequestConfig(RequestConfig.custom() + .setSocketTimeout(this.soTimeout) + .setConnectTimeout(this.connectionTimeout) + .setConnectionRequestTimeout(this.connectionRequestTimeout) + .build() + ).setRetryHandler(this.httpRequestRetryHandler); + + if (StringUtils.isNotBlank(this.httpProxyHost) && StringUtils.isNotBlank(this.httpProxyUsername)) { // 使用代理服务器 需要用户认证的代理服务器 CredentialsProvider provider = new BasicCredentialsProvider(); - provider.setCredentials( - new AuthScope(this.httpProxyHost, this.httpProxyPort), - new UsernamePasswordCredentials(this.httpProxyUsername, - this.httpProxyPassword)); + provider.setCredentials(new AuthScope(this.httpProxyHost, this.httpProxyPort), + new UsernamePasswordCredentials(this.httpProxyUsername, this.httpProxyPassword)); httpClientBuilder.setDefaultCredentialsProvider(provider); + httpClientBuilder.setProxy(new HttpHost(this.httpProxyHost, this.httpProxyPort)); } if (StringUtils.isNotBlank(this.userAgent)) { httpClientBuilder.setUserAgent(this.userAgent); } + this.closeableHttpClient = httpClientBuilder.build(); prepared.set(true); } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java index bbd8bec47c..a0918f5b35 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java @@ -1,28 +1,29 @@ package me.chanjar.weixin.common.util.http.jodd; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; + import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; import jodd.http.HttpResponse; import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.HttpResponseProxy; -import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.StringUtils; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; /** * Created by ecoolper on 2017/5/5. */ -public class JoddHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor { +public class JoddHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor { public JoddHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { super(requestHttp, tmpDirFile); @@ -57,9 +58,12 @@ public File execute(String uri, String queryParam) throws WxErrorException, IOEx return null; } - InputStream inputStream = new ByteArrayInputStream(response.bodyBytes()); - return FileUtils.createTmpFile(inputStream, FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName), - super.tmpDirFile); + try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) { + return FileUtils.createTmpFile(inputStream, + FilenameUtils.getBaseName(fileName), + FilenameUtils.getExtension(fileName), + super.tmpDirFile); + } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaUploadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaUploadRequestExecutor.java index b4eef26a79..8ef4ddec1e 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaUploadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaUploadRequestExecutor.java @@ -6,9 +6,9 @@ import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimpleGetRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimpleGetRequestExecutor.java index 63386e77a8..bee1d174f7 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimpleGetRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimpleGetRequestExecutor.java @@ -3,8 +3,8 @@ import jodd.http.*; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java index 8fa349c67a..b4ee996971 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java @@ -5,9 +5,8 @@ import jodd.http.HttpResponse; import jodd.http.ProxyInfo; import jodd.util.StringPool; - -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; @@ -40,9 +39,8 @@ public String execute(String uri, String postEntity) throws WxErrorException, IO String responseContent = response.bodyText(); if (responseContent.isEmpty()) { - throw new WxErrorException( - WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") - .build()); + throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容") + .build()); } if (responseContent.startsWith("")) { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaDownloadRequestExecutor.java index 0923527b71..6f0a535fdf 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaDownloadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaDownloadRequestExecutor.java @@ -1,9 +1,9 @@ package me.chanjar.weixin.common.util.http.okhttp; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.HttpResponseProxy; -import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -21,7 +21,7 @@ /** * Created by ecoolper on 2017/5/5. */ -public class OkHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor { +public class OkHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); public OkHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { @@ -56,11 +56,14 @@ public File execute(String uri, String queryParam) throws WxErrorException, IOEx return null; } - File file = File.createTempFile(FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName), - super.tmpDirFile); + File file = File.createTempFile( + FilenameUtils.getBaseName(fileName), "." + FilenameUtils.getExtension(fileName), super.tmpDirFile + ); + try (BufferedSink sink = Okio.buffer(Okio.sink(file))) { sink.writeAll(response.body().source()); } + file.deleteOnExit(); return file; } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaUploadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaUploadRequestExecutor.java index 9edeee89be..02fffb1b1b 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaUploadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaUploadRequestExecutor.java @@ -1,8 +1,8 @@ package me.chanjar.weixin.common.util.http.okhttp; -import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import okhttp3.*; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimpleGetRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimpleGetRequestExecutor.java index e468c609c8..380014d003 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimpleGetRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimpleGetRequestExecutor.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.common.util.http.okhttp; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import okhttp3.*; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimplePostRequestExecutor.java index bc54d7b4cd..8ba0906b38 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpSimplePostRequestExecutor.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.common.util.http.okhttp; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; import okhttp3.*; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java index 6166da9e04..882853945a 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java @@ -1,14 +1,5 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.common.util.json; - import com.google.common.collect.Lists; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -16,7 +7,6 @@ import java.util.List; - public class GsonHelper { public static boolean isNull(JsonElement element) { @@ -77,7 +67,7 @@ public static Long getAsLong(JsonElement element) { public static long getAsPrimitiveLong(JsonElement element) { Long r = getAsLong(element); - return r == null ? 0l : r; + return r == null ? 0L : r; } public static Integer getAsInteger(JsonElement element) { @@ -95,7 +85,7 @@ public static Boolean getAsBoolean(JsonElement element) { public static boolean getAsPrimitiveBool(JsonElement element) { Boolean r = getAsBoolean(element); - return r != null && r.booleanValue(); + return r != null && r; } public static Double getAsDouble(JsonElement element) { @@ -130,6 +120,20 @@ public static Integer[] getIntArray(JsonObject o, String string) { return result.toArray(new Integer[0]); } + public static String[] getStringArray(JsonObject o, String string) { + JsonArray jsonArray = getAsJsonArray(o.getAsJsonArray(string)); + if (jsonArray == null) { + return null; + } + + List result = Lists.newArrayList(); + for (int i = 0; i < jsonArray.size(); i++) { + result.add(jsonArray.get(i).getAsString()); + } + + return result.toArray(new String[0]); + } + public static Long[] getLongArray(JsonObject o, String string) { JsonArray jsonArray = getAsJsonArray(o.getAsJsonArray(string)); if (jsonArray == null) { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxAccessTokenAdapter.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxAccessTokenAdapter.java index e7d700e9d1..4d19ec3ad9 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxAccessTokenAdapter.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxAccessTokenAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.common.util.json; import com.google.gson.*; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java index cc426bc8ca..0ea52b9a86 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java @@ -1,36 +1,31 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.common.util.json; import com.google.gson.*; -import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.error.WxError; import java.lang.reflect.Type; /** - * @author Daniel Qian + * @author Daniel Qian. */ public class WxErrorAdapter implements JsonDeserializer { @Override - public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - WxError wxError = new WxError(); + public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + WxError.WxErrorBuilder errorBuilder = WxError.builder(); JsonObject wxErrorJsonObject = json.getAsJsonObject(); if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) { - wxError.setErrorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); + errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode"))); } if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) { - wxError.setErrorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); + errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg"))); } - wxError.setJson(json.toString()); - return wxError; + + errorBuilder.json(json.toString()); + + return errorBuilder.build(); } } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java index 9847d16211..7c7d92f03c 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxGsonBuilder.java @@ -4,7 +4,7 @@ import com.google.gson.GsonBuilder; import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; public class WxGsonBuilder { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMediaUploadResultAdapter.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMediaUploadResultAdapter.java index 662b744274..3cb32c5ede 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMediaUploadResultAdapter.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMediaUploadResultAdapter.java @@ -1,18 +1,14 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.common.util.json; -import com.google.gson.*; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; - import java.lang.reflect.Type; +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 me.chanjar.weixin.common.bean.result.WxMediaUploadResult; + /** * @author Daniel Qian */ @@ -20,22 +16,25 @@ public class WxMediaUploadResultAdapter implements JsonDeserializer> managers = - new Hashtable<>(); + private static final Map> MANAGERS = new Hashtable<>(); private static int LOCALE_CACHE_SIZE = 10; /** * The ResourceBundle for this StringManager. @@ -118,16 +117,16 @@ public static final synchronized StringManager getManager( public static final synchronized StringManager getManager( String packageName, Locale locale) { - Map map = managers.get(packageName); + Map map = MANAGERS.get(packageName); if (map == null) { - /* - * Don't want the HashMap to be expanded beyond LOCALE_CACHE_SIZE. - * Expansion occurs when size() exceeds capacity. Therefore keep - * size at or below capacity. - * removeEldestEntry() executes after insertion therefore the test - * for removal needs to use one less than the maximum desired size - * - */ + /* + * Don't want the HashMap to be expanded beyond LOCALE_CACHE_SIZE. + * Expansion occurs when size() exceeds capacity. Therefore keep + * size at or below capacity. + * removeEldestEntry() executes after insertion therefore the test + * for removal needs to use one less than the maximum desired size + * + */ map = new LinkedHashMap(LOCALE_CACHE_SIZE, 1, true) { private static final long serialVersionUID = 1L; @@ -137,7 +136,7 @@ protected boolean removeEldestEntry( return size() > (LOCALE_CACHE_SIZE - 1); } }; - managers.put(packageName, map); + MANAGERS.put(packageName, map); } StringManager mgr = map.get(locale); diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java index aa2ce1763d..d97062ee61 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java @@ -1,6 +1,9 @@ package me.chanjar.weixin.common.util.xml; +import java.io.Writer; + import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; @@ -8,12 +11,10 @@ import com.thoughtworks.xstream.security.NullPermission; import com.thoughtworks.xstream.security.PrimitiveTypePermission; -import java.io.Writer; - public class XStreamInitializer { public static XStream getInstance() { - XStream xstream = new XStream(new XppDriver() { + XStream xstream = new XStream(new PureJavaReflectionProvider(), new XppDriver() { @Override public HierarchicalStreamWriter createWriter(Writer out) { @@ -37,15 +38,18 @@ protected void writeText(QuickWriter writer, String text) { @Override public String encodeNode(String name) { - return name;//防止将_转换成__ + //防止将_转换成__ + return name; } }; } }); + xstream.ignoreUnknownElements(); xstream.setMode(XStream.NO_REFERENCES); xstream.addPermission(NullPermission.NULL); xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); + xstream.setClassLoader(Thread.currentThread().getContextClassLoader()); return xstream; } diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateCheckerTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateCheckerTest.java index 8599b29f89..6f98b3d986 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateCheckerTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateCheckerTest.java @@ -3,15 +3,17 @@ import org.testng.Assert; import org.testng.annotations.Test; +import java.util.concurrent.TimeUnit; + import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; @Test public class WxMessageInMemoryDuplicateCheckerTest { - private WxMessageInMemoryDuplicateChecker checker = new WxMessageInMemoryDuplicateChecker(2000l, 1000l); + private WxMessageInMemoryDuplicateChecker checker = new WxMessageInMemoryDuplicateChecker(2000L, 1000L); public void test() throws InterruptedException { - Long[] msgIds = new Long[]{1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l}; + Long[] msgIds = new Long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L}; // 第一次检查 for (Long msgId : msgIds) { @@ -20,14 +22,14 @@ public void test() throws InterruptedException { } // 过1秒再检查 - Thread.sleep(1000l); + TimeUnit.SECONDS.sleep(1); for (Long msgId : msgIds) { boolean result = checker.isDuplicate(String.valueOf(msgId)); assertTrue(result); } // 过1.5秒再检查 - Thread.sleep(1500l); + TimeUnit.MILLISECONDS.sleep(1500L); for (Long msgId : msgIds) { boolean result = checker.isDuplicate(String.valueOf(msgId)); assertFalse(result); diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/error/WxErrorTest.java similarity index 53% rename from weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java rename to weixin-java-common/src/test/java/me/chanjar/weixin/common/error/WxErrorTest.java index 477fcdabc0..bbefd4879b 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/error/WxErrorTest.java @@ -1,36 +1,34 @@ -package me.chanjar.weixin.common.bean; +package me.chanjar.weixin.common.error; -import me.chanjar.weixin.common.bean.result.WxError; -import org.testng.*; -import org.testng.annotations.*; +import org.testng.Assert; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; @Test public class WxErrorTest { public void testFromJson() { - String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 40003); - Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); + assertEquals(40003, wxError.getErrorCode()); + assertEquals(wxError.getErrorMsg(), "invalid openid"); } public void testFromBadJson1() { - String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 40003); - Assert.assertEquals(wxError.getErrorMsg(), "invalid openid"); + assertEquals(40003, wxError.getErrorCode()); + assertEquals(wxError.getErrorMsg(), "invalid openid"); } public void testFromBadJson2() { - String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; WxError wxError = WxError.fromJson(json); - Assert.assertTrue(wxError.getErrorCode() == 0); - Assert.assertEquals(wxError.getErrorMsg(), null); + assertEquals(0, wxError.getErrorCode()); + assertEquals(wxError.getErrorMsg(), null); } diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/session/SessionTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/session/SessionTest.java index 93ad2bfc0c..84d80eab0d 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/session/SessionTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/session/SessionTest.java @@ -80,7 +80,7 @@ public void testBackgroundProcess(WxSessionManager sessionManager) throws Interr InternalSession abc = ism.createSession("abc"); abc.endAccess(); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -99,7 +99,7 @@ public void testBackgroundProcess2(WxSessionManager sessionManager) throws Inter abc.setMaxInactiveInterval(1); abc.endAccess(); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/DataUtilsTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/DataUtilsTest.java new file mode 100644 index 0000000000..af34880901 --- /dev/null +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/DataUtilsTest.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.common.util; + +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.*; + +/** + *
+ *  Created by BinaryWang on 2018/5/8.
+ * 
+ * + * @author Binary Wang + */ +public class DataUtilsTest { + + @Test + public void testHandleDataWithSecret() { + String data = "js_code=001tZveq0SMoiq1AEXeq0ECJeq0tZveZ&secret=5681022fa1643845392367ea88888888&grant_type=authorization_code&appid=wxe156d4848d999999"; + final String s = DataUtils.handleDataWithSecret(data); + assertThat(s).contains("&secret=******&"); + } +} diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/SHA1Test.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/SHA1Test.java index 323fc7060e..ffdb613128 100644 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/SHA1Test.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/SHA1Test.java @@ -10,7 +10,7 @@ * Created by BinaryWang on 2017/6/10. *
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ public class SHA1Test { @Test diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 233a94ecc3..cba660670b 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,11 +7,11 @@ com.github.binarywang weixin-java-parent - 2.8.0 + 3.2.0 weixin-java-cp - WeiXin Java Tools - CP + Weixin Java Tools - CP 微信企业号Java SDK @@ -69,6 +69,16 @@ logback-classic test + + org.projectlombok + lombok + + + + org.assertj + assertj-guava + test + diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java new file mode 100644 index 0000000000..4eb52a903d --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java @@ -0,0 +1,129 @@ +package me.chanjar.weixin.cp; + +/** + *
+ * 企业微信常量
+ * Created by Binary Wang on 2018/8/25.
+ * 
+ * + * @author Binary Wang + */ +public class WxCpConsts { + /** + * 企业微信端推送过来的事件类型. + * 参考文档:https://work.weixin.qq.com/api/doc#12974 + */ + public static class EventType { + /** + * 成员关注事件. + */ + public static final String SUBSCRIBE = "subscribe"; + + /** + * 成员取消关注事件. + */ + public static final String UNSUBSCRIBE = "unsubscribe"; + + /** + * 进入应用事件. + */ + public static final String ENTER_AGENT = "enter_agent"; + + /** + * 上报地理位置. + */ + public static final String LOCATION = "LOCATION"; + + /** + * 异步任务完成事件推送. + */ + public static final String BATCH_JOB_RESULT = "batch_job_result"; + + /** + * 企业微信通讯录变更事件. + */ + public static final String CHANGE_CONTACT = "change_contact"; + + /** + * 点击菜单拉取消息的事件推送. + */ + public static final String CLICK = "click"; + + /** + * 点击菜单跳转链接的事件推送. + */ + public static final String VIEW = "view"; + + /** + * 扫码推事件的事件推送. + */ + public static final String SCANCODE_PUSH = "scancode_push"; + + /** + * 扫码推事件且弹出“消息接收中”提示框的事件推送. + */ + public static final String SCANCODE_WAITMSG = "scancode_waitmsg"; + + /** + * 弹出系统拍照发图的事件推送. + */ + public static final String PIC_SYSPHOTO = "pic_sysphoto"; + + /** + * 弹出拍照或者相册发图的事件推送. + */ + public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; + + /** + * 弹出微信相册发图器的事件推送. + */ + public static final String PIC_WEIXIN = "pic_weixin"; + + /** + * 弹出地理位置选择器的事件推送. + */ + public static final String LOCATION_SELECT = "location_select"; + + } + + /** + * 企业微信通讯录变更事件. + */ + public static class ContactChangeType { + /** + * 新增成员事件. + */ + public static final String CREATE_USER = "create_user"; + + /** + * 更新成员事件. + */ + public static final String UPDATE_USER = "update_user"; + + /** + * 删除成员事件. + */ + public static final String DELETE_USER = "delete_user"; + + /** + * 新增部门事件. + */ + public static final String CREATE_PARTY = "create_party"; + + /** + * 更新部门事件. + */ + public static final String UPDATE_PARTY = "update_party"; + + /** + * 删除部门事件. + */ + public static final String DELETE_PARTY = "delete_party"; + + /** + * 标签成员变更事件. + */ + public static final String UPDATE_TAG = "update_tag"; + + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpAgentService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpAgentService.java new file mode 100644 index 0000000000..feea8acbd1 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpAgentService.java @@ -0,0 +1,52 @@ +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpAgent; + +import java.util.List; + +/** + *
+ *  管理企业号应用
+ *  文档地址:https://work.weixin.qq.com/api/doc#10087
+ *  Created by huansinho on 2018/4/13.
+ * 
+ * + * @author huansinho + */ +public interface WxCpAgentService { + + /** + *
+   * 获取企业号应用信息
+   * 该API用于获取企业号某个应用的基本信息,包括头像、昵称、帐号类型、认证类型、可见范围等信息
+   * 详情请见: https://work.weixin.qq.com/api/doc#10087
+   * 
+ * + * @param agentId 企业应用的id + * @return 部门id + */ + WxCpAgent get(Integer agentId) throws WxErrorException; + + /** + *
+   * 设置应用.
+   * 仅企业可调用,可设置当前凭证对应的应用;第三方不可调用。
+   * 详情请见: https://work.weixin.qq.com/api/doc#10088
+   * 
+ * + * @param agentInfo 应用信息 + */ + void set(WxCpAgent agentInfo) throws WxErrorException; + + /** + *
+   * 获取应用列表.
+   * 企业仅可获取当前凭证对应的应用;第三方仅可获取被授权的应用。
+   * 详情请见: https://work.weixin.qq.com/api/doc#11214
+   * 
+ * + */ + List list() throws WxErrorException; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java index 7ca1ade3e5..45da3c0d83 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.cp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.bean.WxCpDepart; import java.util.List; @@ -29,11 +29,12 @@ public interface WxCpDepartmentService { /** *
-   * 部门管理接口 - 查询所有部门
-   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=部门管理接口
+   * 部门管理接口 - 查询部门
+   * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E5.88.97.E8.A1.A8
    * 
+ * @param id 部门id。获取指定部门及其下的子部门。非必需,可为null */ - List listAll() throws WxErrorException; + List list(Integer id) throws WxErrorException; /** *
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java
index f813f1bf3f..19e6de4492 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMediaService.java
@@ -1,25 +1,28 @@
 package me.chanjar.weixin.cp.api;
 
-import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
-import me.chanjar.weixin.common.exception.WxErrorException;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 
+import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.error.WxErrorException;
+
 /**
  * 
- *  媒体管理接口
+ *  媒体管理接口.
  *  Created by BinaryWang on 2017/6/24.
  * 
* * @author Binary Wang */ public interface WxCpMediaService { + String MEDIA_GET_URL = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; + String MEDIA_UPLOAD_URL = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type="; + String IMG_UPLOAD_URL = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg"; /** *
-   * 上传多媒体文件
+   * 上传多媒体文件.
    * 上传的多媒体文件有格式和大小限制,如下:
    *   图片(image): 1M,支持JPG格式
    *   语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式
@@ -30,12 +33,14 @@ public interface WxCpMediaService {
    *
    * @param mediaType   媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts}
    * @param fileType    文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts}
-   * @param inputStream 输入流
+   * @param inputStream 输入流,需要调用方控制关闭该输入流
    */
   WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputStream)
     throws WxErrorException, IOException;
 
   /**
+   * 上传多媒体文件.
+   *
    * @param mediaType 媒体类型
    * @param file      文件对象
    * @see #upload(String, String, InputStream)
@@ -44,7 +49,7 @@ WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputS
 
   /**
    * 
-   * 下载多媒体文件
+   * 下载多媒体文件.
    * 根据微信文档,视频文件下载不了,会返回null
    * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件
    * 
@@ -54,4 +59,17 @@ WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputS */ File download(String mediaId) throws WxErrorException; + /** + *
+   * 上传图片.
+   * 上传图片得到图片URL,该URL永久有效
+   * 返回的图片URL,仅能用于图文消息(mpnews)正文中的图片展示;若用于非企业微信域名下的页面,图片将被屏蔽。
+   * 每个企业每天最多可上传100张图片
+   * 接口url格式:https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
+   * 
+ * + * @param file 上传的文件对象 + * @return 返回图片url + */ + String uploadImg(File file) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java index 012efefb7f..068c037a48 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMenuService.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.api; import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; /** *
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
index 3312489538..5f3d6daa82 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAuth2Service.java
@@ -1,6 +1,7 @@
 package me.chanjar.weixin.cp.api;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.WxCpUserDetail;
 
 /**
  * 
@@ -33,6 +34,19 @@ public interface WxCpOAuth2Service {
    */
   String buildAuthorizationUrl(String redirectUri, String state);
 
+  /**
+   * 
+   * 构造oauth2授权的url连接
+   * 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=企业获取code
+   * 
+ * + * @param redirectUri 跳转链接地址 + * @param state 状态码 + * @param scope 取值参考me.chanjar.weixin.common.api.WxConsts.OAuth2Scope类 + * @return url + */ + String buildAuthorizationUrl(String redirectUri, String state, String scope); + /** *
    * 用oauth2获取用户信息
@@ -50,18 +64,34 @@ public interface WxCpOAuth2Service {
 
   /**
    * 
-   * 用oauth2获取用户信息
+   * 根据code获取成员信息
    * http://qydev.weixin.qq.com/wiki/index.php?title=根据code获取成员信息
+   * https://work.weixin.qq.com/api/doc#10028/根据code获取成员信息
    * 因为企业号oauth2.0必须在应用设置里设置通过ICP备案的可信域名,所以无法测试,因此这个方法很可能是坏的。
    *
    * 注意: 这个方法不使用WxCpConfigStorage里的agentId,需要开发人员自己给出
    * 
* * @param agentId 企业号应用的id - * @param code 微信oauth授权返回的代码 - * @return [userid, deviceid] + * @param code 通过成员授权获取到的code,最大为512字节。每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。 + * @return [UserId, DeviceId, OpenId, user_ticket, expires_in] * @see #getUserInfo(String) */ String[] getUserInfo(Integer agentId, String code) throws WxErrorException; + /** + *
+   * 使用user_ticket获取成员详情.
+   *
+   * 文档地址:https://work.weixin.qq.com/api/doc#10028/%E4%BD%BF%E7%94%A8user_ticket%E8%8E%B7%E5%8F%96%E6%88%90%E5%91%98%E8%AF%A6%E6%83%85
+   * 请求方式:POST(HTTPS)
+   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=ACCESS_TOKEN
+   *
+   * 权限说明:
+   * 需要有对应应用的使用权限,且成员必须在授权应用的可见范围内。
+   * 
+ * + * @param userTicket 成员票据 + */ + WxCpUserDetail getUserDetail(String userTicket) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 03df947dc2..3e33c4eb55 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -1,9 +1,7 @@ package me.chanjar.weixin.cp.api; import me.chanjar.weixin.common.bean.WxJsapiSignature; -import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSession; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; @@ -12,16 +10,11 @@ import me.chanjar.weixin.cp.bean.*; import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - /** * 微信API的Service + * @author chanjaster */ public interface WxCpService { - /** *
    * 验证推送过来的消息的正确性
@@ -85,42 +78,6 @@ public interface WxCpService {
    */
   WxJsapiSignature createJsapiSignature(String url) throws WxErrorException;
 
-  /**
-   * @deprecated  请使用 {@link WxCpMenuService#create(WxMenu)}
-   */
-  @Deprecated
-  void menuCreate(WxMenu menu) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMenuService#create(Integer, WxMenu)}
-   */
-  @Deprecated
-  void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMenuService#delete()}  }
-   */
-  @Deprecated
-  void menuDelete() throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMenuService#delete(Integer)}
-   */
-  @Deprecated
-  void menuDelete(Integer agentId) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMenuService#get() }
-   */
-  @Deprecated
-  WxMenu menuGet() throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMenuService#get(Integer)}
-   */
-  @Deprecated
-  WxMenu menuGet(Integer agentId) throws WxErrorException;
-
   /**
    * 
    * 发送消息
@@ -131,175 +88,6 @@ public interface WxCpService {
    */
   WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException;
 
-  /**
-   * @deprecated  请使用 {@link WxCpDepartmentService#create(WxCpDepart)}
-   */
-  @Deprecated
-  Integer departCreate(WxCpDepart depart) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpDepartmentService#update(WxCpDepart)}
-   */
-  @Deprecated
-  void departUpdate(WxCpDepart group) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpDepartmentService#delete(Integer)}
-   */
-  @Deprecated
-  void departDelete(Integer departId) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpDepartmentService#listAll() }
-   */
-  @Deprecated
-  List departGet() throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMediaService#upload(String, String, InputStream)}
-   */
-  @Deprecated
-  WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream)
-    throws WxErrorException, IOException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMediaService#upload(String, File)}
-   */
-  @Deprecated
-  WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpMediaService#download(String)}
-   */
-  @Deprecated
-  File mediaDownload(String mediaId) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#authenticate(String)}
-   */
-  @Deprecated
-  void userAuthenticated(String userId) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#create(WxCpUser)}
-   */
-  @Deprecated
-  void userCreate(WxCpUser user) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#update(WxCpUser)}
-   */
-  @Deprecated
-  void userUpdate(WxCpUser user) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#delete(String...)}
-   */
-  @Deprecated
-  void userDelete(String userid) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#delete(String...)}
-   */
-  @Deprecated
-  void userDelete(String[] userids) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#getById(String)}
-   */
-  @Deprecated
-  WxCpUser userGet(String userid) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#listByDepartment(Integer, Boolean, Integer)}
-   */
-  @Deprecated
-  List userList(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpUserService#listSimpleByDepartment(Integer, Boolean, Integer)}
-   */
-  @Deprecated
-  List departGetUsers(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpTagService#create(String)}
-   */
-  @Deprecated
-  String tagCreate(String tagName) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpTagService#update(String, String)}
-   */
-  @Deprecated
-  void tagUpdate(String tagId, String tagName) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpTagService#delete(String)}
-   */
-  @Deprecated
-  void tagDelete(String tagId) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpTagService#listAll()}
-   */
-  @Deprecated
-  List tagGet() throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpTagService#listUsersByTagId(String)}
-   */
-  @Deprecated
-  List tagGetUsers(String tagId) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpTagService#addUsers2Tag(String, List, List)}
-   */
-  @Deprecated
-  void tagAddUsers(String tagId, List userIds, List partyIds) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpTagService#removeUsersFromTag(String, List)}
-   */
-  @Deprecated
-  void tagRemoveUsers(String tagId, List userIds) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpOAuth2Service#buildAuthorizationUrl(String)}
-   */
-  @Deprecated
-  String oauth2buildAuthorizationUrl(String state);
-
-  /**
-   * @deprecated  请使用 {@link WxCpOAuth2Service#buildAuthorizationUrl(String, String)}
-   */
-  @Deprecated
-  String oauth2buildAuthorizationUrl(String redirectUri, String state);
-
-  /**
-   * @deprecated  请使用 {@link WxCpOAuth2Service#getUserInfo(String)}
-   */
-  @Deprecated
-  String[] oauth2getUserInfo(String code) throws WxErrorException;
-
-  /**
-   * @deprecated  请使用 {@link WxCpOAuth2Service#getUserInfo(Integer, String)}
-   */
-  @Deprecated
-  String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException;
-
-  /**
-   * 
-   * 邀请成员关注
-   * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E9.82.80.E8.AF.B7.E6.88.90.E5.91.98.E5.85.B3.E6.B3.A8
-   * 
- * - * @param userId 用户的userid - * @param inviteTips 推送到微信上的提示语(只有认证号可以使用)。当使用微信推送时,该字段默认为“请关注XXX企业号”,邮件邀请时,该字段无效。 - * @return 1:微信邀请 2.邮件邀请 - */ - int invite(String userId, String inviteTips) throws WxErrorException; - /** *
    * 获取微信服务器的ip段
@@ -454,6 +242,8 @@ WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream i
    */
   WxCpUserService getUserService();
 
+  WxCpAgentService getAgentService();
+
   /**
    * http请求对象
    */
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java
index c96318b80b..9624f9e409 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTagService.java
@@ -1,15 +1,16 @@
 package me.chanjar.weixin.cp.api;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
+import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.bean.WxCpTag;
 import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult;
+import me.chanjar.weixin.cp.bean.WxCpTagGetResult;
 import me.chanjar.weixin.cp.bean.WxCpUser;
 
 import java.util.List;
 
 /**
  * 
- *  标签管理接口
+ *  标签管理接口.
  *  Created by BinaryWang on 2017/6/24.
  * 
* @@ -17,14 +18,14 @@ */ public interface WxCpTagService { /** - * 创建标签 + * 创建标签. * * @param tagName 标签名 */ String create(String tagName) throws WxErrorException; /** - * 更新标签 + * 更新标签. * * @param tagId 标签id * @param tagName 标签名 @@ -32,35 +33,49 @@ public interface WxCpTagService { void update(String tagId, String tagName) throws WxErrorException; /** - * 删除标签 + * 删除标签. * * @param tagId 标签id */ void delete(String tagId) throws WxErrorException; /** - * 获得标签列表 + * 获得标签列表. */ List listAll() throws WxErrorException; /** - * 获取标签成员 + * 获取标签成员. * * @param tagId 标签ID */ List listUsersByTagId(String tagId) throws WxErrorException; /** - * 增加标签成员 - * @param tagId 标签id - * @param userIds 用户ID 列表 + * 增加标签成员. + * + * @param tagId 标签id + * @param userIds 用户ID 列表 + * @param partyIds 企业部门ID列表 */ WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List userIds, List partyIds) throws WxErrorException; /** - * 移除标签成员 - * @param tagId 标签id - * @param userIds 用户id列表 + * 移除标签成员. + * + * @param tagId 标签id + * @param userIds 用户id列表 + * @param partyIds 企业部门ID列表 */ - WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List userIds) throws WxErrorException; + WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List userIds, List partyIds) throws WxErrorException; + + + /** + * 获取标签成员. + * 对应: http://qydev.weixin.qq.com/wiki/index.php?title=管理标签 中的get接口 + * + * @param tagId 标签id + */ + WxCpTagGetResult get(String tagId) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java index 49ef9134f5..9f9317256e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpUserService.java @@ -1,9 +1,12 @@ package me.chanjar.weixin.cp.api; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.cp.bean.WxCpUser; - import java.util.List; +import java.util.Map; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpInviteResult; +import me.chanjar.weixin.cp.bean.WxCpUser; +import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo; /** *
@@ -16,7 +19,7 @@
 public interface WxCpUserService {
   /**
    * 
-   *   用在二次验证的时候
+   *   用在二次验证的时候.
    *   企业在员工验证成功后,调用本方法告诉企业号平台该员工关注成功。
    * 
* @@ -26,7 +29,7 @@ public interface WxCpUserService { /** *
-   * 获取部门成员(详情)
+   * 获取部门成员(详情).
    *
    * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E6.88.90.E5.91.98.28.E8.AF.A6.E6.83.85.29
    * 
@@ -39,7 +42,7 @@ public interface WxCpUserService { /** *
-   * 获取部门成员
+   * 获取部门成员.
    *
    * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E6.88.90.E5.91.98
    * 
@@ -51,14 +54,14 @@ public interface WxCpUserService { List listSimpleByDepartment(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException; /** - * 新建用户 + * 新建用户. * * @param user 用户对象 */ void create(WxCpUser user) throws WxErrorException; /** - * 更新用户 + * 更新用户. * * @param user 用户对象 */ @@ -66,7 +69,7 @@ public interface WxCpUserService { /** *
-   * 删除用户/批量删除成员
+   * 删除用户/批量删除成员.
    * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E6.89.B9.E9.87.8F.E5.88.A0.E9.99.A4.E6.88.90.E5.91.98
    * 
* @@ -75,9 +78,74 @@ public interface WxCpUserService { void delete(String... userIds) throws WxErrorException; /** - * 获取用户 + * 获取用户. * * @param userid 用户id */ WxCpUser getById(String userid) throws WxErrorException; + + /** + *
+   * 邀请成员.
+   * 企业可通过接口批量邀请成员使用企业微信,邀请后将通过短信或邮件下发通知。
+   * 请求方式:POST(HTTPS)
+   * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/batch/invite?access_token=ACCESS_TOKEN
+   * 文档地址:https://work.weixin.qq.com/api/doc#12543
+   * 
+ * + * @param userIds 成员ID列表, 最多支持1000个。 + * @param partyIds 部门ID列表,最多支持100个。 + * @param tagIds 标签ID列表,最多支持100个。 + */ + WxCpInviteResult invite(List userIds, List partyIds, List tagIds) throws WxErrorException; + + /** + *
+   *  userid转openid.
+   *  该接口使用场景为微信支付、微信红包和企业转账。
+   *
+   * 在使用微信支付的功能时,需要自行将企业微信的userid转成openid。
+   * 在使用微信红包功能时,需要将应用id和userid转成appid和openid才能使用。
+   * 注:需要成员使用微信登录企业微信或者关注微信插件才能转成openid
+   *
+   * 文档地址:https://work.weixin.qq.com/api/doc#11279
+   * 
+ * + * @param userId 企业内的成员id + * @param agentId 非必填,整型,仅用于发红包。其它场景该参数不要填,如微信支付、企业转账、电子发票 + * @return map对象,可能包含以下值: + * - openid 企业微信成员userid对应的openid,若有传参agentid,则是针对该agentid的openid。否则是针对企业微信corpid的openid + * - appid 应用的appid,若请求包中不包含agentid则不返回appid。该appid在使用微信红包时会用到 + */ + Map userId2Openid(String userId, Integer agentId) throws WxErrorException; + + /** + *
+   * openid转userid.
+   *
+   * 该接口主要应用于使用微信支付、微信红包和企业转账之后的结果查询。
+   * 开发者需要知道某个结果事件的openid对应企业微信内成员的信息时,可以通过调用该接口进行转换查询。
+   * 权限说明:
+   * 管理组需对openid对应的企业微信成员有查看权限。
+   *
+   * 文档地址:https://work.weixin.qq.com/api/doc#11279
+   * 
+ * + * @param openid 在使用微信支付、微信红包和企业转账之后,返回结果的openid + * @return userid 该openid在企业微信对应的成员userid + */ + String openid2UserId(String openid) throws WxErrorException; + + /** + * 获取外部联系人详情. + *
+   *   企业可通过此接口,根据外部联系人的userid,拉取外部联系人详情。权限说明:
+   * 企业需要使用外部联系人管理secret所获取的accesstoken来调用
+   * 第三方应用需拥有“企业客户”权限。
+   * 第三方应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。
+   * 
+ * + * @param userId 外部联系人的userid + */ + WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java new file mode 100644 index 0000000000..e4914134c1 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java @@ -0,0 +1,68 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.WxCpAgentService; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpAgent; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.util.List; + + +/** + *
+ *  管理企业号应用
+ *  Created by huansinho on 2018/4/13.
+ * 
+ * + * @author huansinho + */ +public class WxCpAgentServiceImpl implements WxCpAgentService { + private static final JsonParser JSON_PARSER = new JsonParser(); + + private WxCpService mainService; + + public WxCpAgentServiceImpl(WxCpService mainService) { + this.mainService = mainService; + } + + @Override + public WxCpAgent get(Integer agentId) throws WxErrorException { + if (agentId == null) { + throw new IllegalArgumentException("缺少agentid参数"); + } + + String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/get?agentid=" + agentId; + String responseContent = this.mainService.get(url, null); + return WxCpAgent.fromJson(responseContent); + } + + @Override + public void set(WxCpAgent agentInfo) throws WxErrorException { + String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/set"; + String responseContent = this.mainService.post(url, agentInfo.toJson()); + JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + if (jsonObject.get("errcode").getAsInt() != 0) { + throw new WxErrorException(WxError.fromJson(responseContent)); + } + } + + @Override + public List list() throws WxErrorException { + String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/list"; + String responseContent = this.mainService.get(url, null); + JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + if (jsonObject.get("errcode").getAsInt() != 0) { + throw new WxErrorException(WxError.fromJson(responseContent)); + } + + return WxCpGsonBuilder.create().fromJson(jsonObject.get("agentlist").toString(), new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java index 82cd8c345c..6645219902 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java @@ -3,7 +3,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.json.GsonHelper; import me.chanjar.weixin.cp.api.WxCpDepartmentService; import me.chanjar.weixin.cp.api.WxCpService; @@ -48,13 +48,13 @@ public void delete(Integer departId) throws WxErrorException { } @Override - public List listAll() throws WxErrorException { + public List list(Integer id) throws WxErrorException { String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list"; + if (id != null) { + url += "?id=" + id; + } + String responseContent = this.mainService.get(url, null); - /* - * 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } - * 查询时返回的是 { groups : [ { id : ..., name : ..., count : ... }, ... ] } - */ JsonElement tmpJsonElement = new JsonParser().parse(responseContent); return WxCpGsonBuilder.INSTANCE.create() .fromJson(tmpJsonElement.getAsJsonObject().get("department"), diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java index 1364550aac..c3dc477495 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java @@ -1,24 +1,25 @@ package me.chanjar.weixin.cp.api.impl; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.UUID; + import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; -import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.cp.api.WxCpMediaService; import me.chanjar.weixin.cp.api.WxCpService; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.UUID; - /** *
- * 媒体管理接口
+ * 媒体管理接口.
  * Created by Binary Wang on 2017-6-25.
- * @author Binary Wang
  * 
+ * + * @author Binary Wang */ public class WxCpMediaServiceImpl implements WxCpMediaService { private WxCpService mainService; @@ -35,16 +36,22 @@ public WxMediaUploadResult upload(String mediaType, String fileType, InputStream @Override public WxMediaUploadResult upload(String mediaType, File file) throws WxErrorException { - String url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType; - return this.mainService.execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), url, file); + return this.mainService.execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), + MEDIA_UPLOAD_URL + mediaType, file); } @Override public File download(String mediaId) throws WxErrorException { - String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; return this.mainService.execute( - MediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(), + BaseMediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(), this.mainService.getWxCpConfigStorage().getTmpDirFile()), - url, "media_id=" + mediaId); + MEDIA_GET_URL, "media_id=" + mediaId); + } + + @Override + public String uploadImg(File file) throws WxErrorException { + final WxMediaUploadResult result = this.mainService + .execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), IMG_UPLOAD_URL, file); + return result.getUrl(); } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java index 7c3937d83e..f58eff4763 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImpl.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.api.impl; import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpMenuService; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java index a317bfb4e6..8f0375f340 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImpl.java @@ -1,19 +1,24 @@ package me.chanjar.weixin.cp.api.impl; +import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.URIUtil; import me.chanjar.weixin.common.util.json.GsonHelper; import me.chanjar.weixin.cp.api.WxCpOAuth2Service; import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpUserDetail; /** *
  *
  * Created by Binary Wang on 2017-6-25.
  * @author Binary Wang
+ *
+ * @author Binary Wang
  * 
*/ public class WxCpOAuth2ServiceImpl implements WxCpOAuth2Service { @@ -33,34 +38,55 @@ public String buildAuthorizationUrl(String state) { @Override public String buildAuthorizationUrl(String redirectUri, String state) { - String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"; - url += "appid=" + this.mainService.getWxCpConfigStorage().getCorpId(); - url += "&redirect_uri=" + URIUtil.encodeURIComponent(redirectUri); - url += "&response_type=code"; - url += "&scope=snsapi_base"; + return this.buildAuthorizationUrl(redirectUri, state, WxConsts.OAuth2Scope.SNSAPI_BASE); + } + + @Override + public String buildAuthorizationUrl(String redirectUri, String state, String scope) { + StringBuilder url = new StringBuilder("https://open.weixin.qq.com/connect/oauth2/authorize?"); + url.append("appid=").append(this.mainService.getWxCpConfigStorage().getCorpId()); + url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectUri)); + url.append("&response_type=code"); + url.append("&scope=").append(scope); + + if (WxConsts.OAuth2Scope.SNSAPI_PRIVATEINFO.equals(scope) + || WxConsts.OAuth2Scope.SNSAPI_USERINFO.equals(scope)) { + url.append("&agentid=").append(this.mainService.getWxCpConfigStorage().getAgentId()); + } + if (state != null) { - url += "&state=" + state; + url.append("&state=").append(state); } - url += "#wechat_redirect"; - return url; + url.append("#wechat_redirect"); + return url.toString(); } @Override public String[] getUserInfo(String code) throws WxErrorException { - return getUserInfo(this.mainService.getWxCpConfigStorage().getAgentId(), code); + return this.getUserInfo(this.mainService.getWxCpConfigStorage().getAgentId(), code); } @Override public String[] getUserInfo(Integer agentId, String code) throws WxErrorException { - String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?" - + "code=" + code - + "&agentid=" + agentId; + String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?code=%s&agentid=%d", + code, agentId); String responseText = this.mainService.get(url, null); JsonElement je = new JsonParser().parse(responseText); JsonObject jo = je.getAsJsonObject(); return new String[]{GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId"), - GsonHelper.getString(jo, "OpenId")}; + GsonHelper.getString(jo, "OpenId"), + GsonHelper.getString(jo, "user_ticket"), + GsonHelper.getString(jo, "expires_in") + }; } + @Override + public WxCpUserDetail getUserDetail(String userTicket) throws WxErrorException { + String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail"; + JsonObject param = new JsonObject(); + param.addProperty("user_ticket", userTicket); + String responseText = this.mainService.post(url, param.toString()); + return new GsonBuilder().create().fromJson(responseText, WxCpUserDetail.class); + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java index 83bc5e13c6..0c66e0ef77 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java @@ -5,13 +5,12 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import me.chanjar.weixin.common.bean.WxJsapiSignature; -import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.StandardSessionManager; import me.chanjar.weixin.common.session.WxSession; import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.common.util.DataUtils; import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.http.RequestExecutor; @@ -21,14 +20,11 @@ import me.chanjar.weixin.cp.api.*; import me.chanjar.weixin.cp.bean.*; import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.util.List; public abstract class WxCpServiceAbstractImpl implements WxCpService, RequestHttp { protected final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -39,6 +35,7 @@ public abstract class WxCpServiceAbstractImpl implements WxCpService, Requ private WxCpMenuService menuService = new WxCpMenuServiceImpl(this); private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this); private WxCpTagService tagService = new WxCpTagServiceImpl(this); + private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); /** * 全局的是否正在刷新access token的锁 @@ -138,188 +135,6 @@ public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorExce return WxCpMessageSendResult.fromJson(this.post(url, message.toJson())); } - @Override - @Deprecated - public void menuCreate(WxMenu menu) throws WxErrorException { - this.getMenuService().create(menu); - } - - @Override - @Deprecated - public void menuCreate(Integer agentId, WxMenu menu) throws WxErrorException { - this.getMenuService().create(agentId, menu); - } - - @Override - @Deprecated - public void menuDelete() throws WxErrorException { - this.getMenuService().delete(); - } - - @Override - @Deprecated - public void menuDelete(Integer agentId) throws WxErrorException { - this.getMenuService().delete(agentId); - } - - @Override - @Deprecated - public WxMenu menuGet() throws WxErrorException { - return this.getMenuService().get(); - } - - @Override - @Deprecated - public WxMenu menuGet(Integer agentId) throws WxErrorException { - return this.getMenuService().get(agentId); - } - - @Override - @Deprecated - public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) - throws WxErrorException, IOException { - return this.getMediaService().upload(mediaType, fileType, inputStream); - } - - @Override - @Deprecated - public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { - return this.getMediaService().upload(mediaType, file); - } - - @Override - @Deprecated - public File mediaDownload(String mediaId) throws WxErrorException { - return this.getMediaService().download(mediaId); - } - - @Override - @Deprecated - public void userAuthenticated(String userId) throws WxErrorException { - this.getUserService().authenticate(userId); - } - - @Override - @Deprecated - public void userCreate(WxCpUser user) throws WxErrorException { - this.getUserService().create(user); - } - - @Override - @Deprecated - public void userUpdate(WxCpUser user) throws WxErrorException { - this.getUserService().update(user); - } - - @Override - @Deprecated - public void userDelete(String userid) throws WxErrorException { - this.getUserService().delete(userid); - } - - @Override - @Deprecated - public void userDelete(String[] userids) throws WxErrorException { - this.getUserService().delete(userids); - } - - @Override - @Deprecated - public WxCpUser userGet(String userid) throws WxErrorException { - return this.getUserService().getById(userid); - } - - @Override - @Deprecated - public List userList(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException { - return this.getUserService().listByDepartment(departId, fetchChild, status); - } - - @Override - @Deprecated - public List departGetUsers(Integer departId, Boolean fetchChild, Integer status) throws WxErrorException { - return this.getUserService().listSimpleByDepartment(departId, fetchChild, status); - } - - @Override - @Deprecated - public String tagCreate(String tagName) throws WxErrorException { - return this.getTagService().create(tagName); - } - - @Override - @Deprecated - public void tagUpdate(String tagId, String tagName) throws WxErrorException { - this.getTagService().update(tagId, tagName); - } - - @Override - @Deprecated - public void tagDelete(String tagId) throws WxErrorException { - this.getTagService().delete(tagId); - } - - @Override - @Deprecated - public List tagGet() throws WxErrorException { - return this.getTagService().listAll(); - } - - @Override - @Deprecated - public List tagGetUsers(String tagId) throws WxErrorException { - return this.getTagService().listUsersByTagId(tagId); - } - - @Override - @Deprecated - public void tagAddUsers(String tagId, List userIds, List partyIds) throws WxErrorException { - this.getTagService().addUsers2Tag(tagId, userIds, partyIds); - } - - @Override - @Deprecated - public void tagRemoveUsers(String tagId, List userIds) throws WxErrorException { - this.getTagService().removeUsersFromTag(tagId, userIds); - } - - @Override - @Deprecated - public String oauth2buildAuthorizationUrl(String state) { - return this.getOauth2Service().buildAuthorizationUrl(state); - } - - @Override - @Deprecated - public String oauth2buildAuthorizationUrl(String redirectUri, String state) { - return this.getOauth2Service().buildAuthorizationUrl(redirectUri, state); - } - - @Override - @Deprecated - public String[] oauth2getUserInfo(String code) throws WxErrorException { - return this.getOauth2Service().getUserInfo(code); - } - - @Override - @Deprecated - public String[] oauth2getUserInfo(Integer agentId, String code) throws WxErrorException { - return this.getOauth2Service().getUserInfo(agentId, code); - } - - @Override - public int invite(String userId, String inviteTips) throws WxErrorException { - String url = "https://qyapi.weixin.qq.com/cgi-bin/invite/send"; - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("userid", userId); - if (StringUtils.isNotEmpty(inviteTips)) { - jsonObject.addProperty("invite_tips", inviteTips); - } - String responseContent = post(url, jsonObject.toString()); - JsonElement tmpJsonElement = new JsonParser().parse(responseContent); - return tmpJsonElement.getAsJsonObject().get("type").getAsInt(); - } - @Override public String[] getCallbackIp() throws WxErrorException { String url = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip"; @@ -381,7 +196,9 @@ public T execute(RequestExecutor executor, String uri, E data) thro throw new RuntimeException("微信服务端异常,超出重试次数"); } - protected synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + protected T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + E dataForLog = DataUtils.handleDataWithSecret(data); + if (uri.contains("access_token=")) { throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); } @@ -391,7 +208,7 @@ protected synchronized T executeInternal(RequestExecutor executor, try { T result = executor.execute(uriWithAccessToken, data); - this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); + this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); return result; } catch (WxErrorException e) { WxError error = e.getError(); @@ -408,12 +225,12 @@ protected synchronized T executeInternal(RequestExecutor executor, } if (error.getErrorCode() != 0) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); throw new WxErrorException(error, e); } return null; } catch (IOException e) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); throw new RuntimeException(e); } } @@ -516,30 +333,6 @@ public WxCpUserService getUserService() { return userService; } - @Override - @Deprecated - public Integer departCreate(WxCpDepart depart) throws WxErrorException { - return this.getDepartmentService().create(depart); - } - - @Override - @Deprecated - public void departUpdate(WxCpDepart depart) throws WxErrorException { - this.getDepartmentService().update(depart); - } - - @Override - @Deprecated - public void departDelete(Integer departId) throws WxErrorException { - this.getDepartmentService().delete(departId); - } - - @Override - @Deprecated - public List departGet() throws WxErrorException { - return this.getDepartmentService().listAll(); - } - @Override public RequestHttp getRequestHttp() { return this; @@ -574,4 +367,13 @@ public void setOauth2Service(WxCpOAuth2Service oauth2Service) { public void setTagService(WxCpTagService tagService) { this.tagService = tagService; } + + @Override + public WxCpAgentService getAgentService() { + return agentService; + } + + public void setAgentService(WxCpAgentService agentService) { + this.agentService = agentService; + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java index af32f5fb5d..7081272793 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java @@ -1,9 +1,10 @@ package me.chanjar.weixin.cp.api.impl; +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; @@ -58,7 +59,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { } finally { httpGet.releaseConnection(); } - WxError error = WxError.fromJson(resultContent); + WxError error = WxError.fromJson(resultContent, WxType.CP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java index ff8e149c77..a7538c6ead 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java @@ -4,8 +4,9 @@ *
  *  默认接口实现类,使用apache httpclient实现
  * Created by Binary Wang on 2017-5-27.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl { } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java index 3e7c4bc5b8..2d7e1b1c29 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java @@ -1,9 +1,10 @@ package me.chanjar.weixin.cp.api.impl; import jodd.http.*; +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.cp.config.WxCpConfigStorage; @@ -44,7 +45,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { HttpResponse response = request.send(); String resultContent = response.bodyText(); - WxError error = WxError.fromJson(resultContent); + WxError error = WxError.fromJson(resultContent, WxType.CP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java index f8476ff5af..34c978cd4f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java @@ -1,20 +1,17 @@ package me.chanjar.weixin.cp.api.impl; +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; import me.chanjar.weixin.cp.config.WxCpConfigStorage; import okhttp3.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - protected OkHttpClient httpClient; protected OkHttpProxyInfo httpProxy; @@ -36,7 +33,7 @@ public HttpType getRequestType() { @Override public String getAccessToken(boolean forceRefresh) throws WxErrorException { - logger.debug("WxCpServiceOkHttpImpl is running"); + this.log.debug("WxCpServiceOkHttpImpl is running"); if (this.configStorage.isAccessTokenExpired() || forceRefresh) { synchronized (this.globalAccessTokenRefreshLock) { if (this.configStorage.isAccessTokenExpired()) { @@ -47,19 +44,15 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { OkHttpClient client = getRequestHttpClient(); //请求的request Request request = new Request.Builder().url(url).get().build(); - Response response = null; - try { - response = client.newCall(request).execute(); - } catch (IOException e) { - e.printStackTrace(); - } String resultContent = null; try { + Response response = client.newCall(request).execute(); resultContent = response.body().string(); } catch (IOException e) { - e.printStackTrace(); + this.log.error(e.getMessage(), e); } - WxError error = WxError.fromJson(resultContent); + + WxError error = WxError.fromJson(resultContent, WxType.CP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } @@ -74,9 +67,16 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { @Override public void initHttp() { - logger.debug("WxCpServiceOkHttpImpl initHttp"); - OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); + this.log.debug("WxCpServiceOkHttpImpl initHttp"); //设置代理 + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(), + configStorage.getHttpProxyPort(), + configStorage.getHttpProxyUsername(), + configStorage.getHttpProxyPassword()); + } + + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); if (httpProxy != null) { clientBuilder.proxy(getRequestHttpProxy().getProxy()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java index ff995d9724..aa8260b14e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImpl.java @@ -2,11 +2,12 @@ import com.google.gson.*; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.api.WxCpTagService; import me.chanjar.weixin.cp.bean.WxCpTag; import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult; +import me.chanjar.weixin.cp.bean.WxCpTagGetResult; import me.chanjar.weixin.cp.bean.WxCpUser; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; @@ -82,6 +83,22 @@ public WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List use String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers"; JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("tagid", tagId); + this.addUserIdsAndPartyIdsToJson(userIds, partyIds, jsonObject); + + return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); + } + + @Override + public WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List userIds, List partyIds) throws WxErrorException { + String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers"; + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("tagid", tagId); + this.addUserIdsAndPartyIdsToJson(userIds, partyIds, jsonObject); + + return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); + } + + private void addUserIdsAndPartyIdsToJson(List userIds, List partyIds, JsonObject jsonObject) { if (userIds != null) { JsonArray jsonArray = new JsonArray(); for (String userId : userIds) { @@ -89,6 +106,7 @@ public WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List use } jsonObject.add("userlist", jsonArray); } + if (partyIds != null) { JsonArray jsonArray = new JsonArray(); for (String userId : partyIds) { @@ -96,21 +114,19 @@ public WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List use } jsonObject.add("partylist", jsonArray); } - - return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); } @Override - public WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List userIds) throws WxErrorException { - String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers"; - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("tagid", tagId); - JsonArray jsonArray = new JsonArray(); - for (String userId : userIds) { - jsonArray.add(new JsonPrimitive(userId)); + public WxCpTagGetResult get(String tagId) throws WxErrorException { + String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get"; + if (tagId != null) { + url += "?tagId=" + tagId; + } else { + throw new IllegalArgumentException("缺少tagId参数"); } - jsonObject.add("userlist", jsonArray); - return WxCpTagAddOrRemoveUsersResult.fromJson(this.mainService.post(url, jsonObject.toString())); + String responseContent = this.mainService.get(url, null); + + return WxCpTagGetResult.fromJson(responseContent); } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java index 13009427c6..68224b1eb9 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImpl.java @@ -1,15 +1,23 @@ package me.chanjar.weixin.cp.api.impl; -import com.google.gson.*; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.Maps; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.api.WxCpUserService; +import me.chanjar.weixin.cp.bean.WxCpInviteResult; import me.chanjar.weixin.cp.bean.WxCpUser; +import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import java.util.List; - /** *
  *  Created by BinaryWang on 2017/6/24.
@@ -112,4 +120,74 @@ public List listSimpleByDepartment(Integer departId, Boolean fetchChil
       );
   }
 
+  @Override
+  public WxCpInviteResult invite(List userIds, List partyIds, List tagIds) throws WxErrorException {
+    String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/invite";
+    JsonObject jsonObject = new JsonObject();
+    if (userIds != null) {
+      JsonArray jsonArray = new JsonArray();
+      for (String userId : userIds) {
+        jsonArray.add(new JsonPrimitive(userId));
+      }
+      jsonObject.add("user", jsonArray);
+    }
+
+    if (partyIds != null) {
+      JsonArray jsonArray = new JsonArray();
+      for (String userId : partyIds) {
+        jsonArray.add(new JsonPrimitive(userId));
+      }
+      jsonObject.add("party", jsonArray);
+    }
+
+    if (tagIds != null) {
+      JsonArray jsonArray = new JsonArray();
+      for (String tagId : tagIds) {
+        jsonArray.add(new JsonPrimitive(tagId));
+      }
+      jsonObject.add("tag", jsonArray);
+    }
+
+    return WxCpInviteResult.fromJson(this.mainService.post(url, jsonObject.toString()));
+  }
+
+  @Override
+  public Map userId2Openid(String userId, Integer agentId) throws WxErrorException {
+    String url = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid";
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("userid", userId);
+    if (agentId != null) {
+      jsonObject.addProperty("agentid", agentId);
+    }
+
+    String responseContent = this.mainService.post(url, jsonObject.toString());
+    JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
+    Map result = Maps.newHashMap();
+    if (tmpJsonElement.getAsJsonObject().get("openid") != null) {
+      result.put("openid", tmpJsonElement.getAsJsonObject().get("openid").getAsString());
+    }
+
+    if (tmpJsonElement.getAsJsonObject().get("appid") != null) {
+      result.put("appid", tmpJsonElement.getAsJsonObject().get("appid").getAsString());
+    }
+
+    return result;
+  }
+
+  @Override
+  public String openid2UserId(String openid) throws WxErrorException {
+    String url = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_userid";
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("openid", openid);
+    String responseContent = this.mainService.post(url, jsonObject.toString());
+    JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
+    return tmpJsonElement.getAsJsonObject().get("userid").getAsString();
+  }
+
+  @Override
+  public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException {
+    String url = "https://qyapi.weixin.qq.com/cgi-bin/crm/get_external_contact?external_userid=" + userId;
+    String responseContent = this.mainService.get(url, null);
+    return WxCpUserExternalContactInfo.fromJson(responseContent);
+  }
 }
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/Gender.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/Gender.java
new file mode 100644
index 0000000000..2b6e26efde
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/Gender.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.cp.bean;
+
+/**
+ * 
+ *  性别枚举
+ *  Created by BinaryWang on 2018/4/22.
+ * 
+ * + * @author Binary Wang + */ +public enum Gender { + /** + * 男 + */ + MALE("男", "1"), + /** + * 女 + */ + FEMALE("女", "2"); + + private String genderName; + private String code; + + Gender(String genderName, String code) { + this.genderName = genderName; + this.code = code; + } + + public String getGenderName() { + return this.genderName; + } + + public String getCode() { + return this.code; + } + + public static Gender fromCode(String code) { + if ("1".equals(code)) { + return Gender.MALE; + } + if ("2".equals(code)) { + return Gender.FEMALE; + } + + return null; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgent.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgent.java new file mode 100644 index 0000000000..b70571f075 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAgent.java @@ -0,0 +1,105 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 企业号应用信息.
+ * Created by huansinho on 2018/4/13.
+ * 
+ * + * @author huansinho + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class WxCpAgent implements Serializable { + private static final long serialVersionUID = 5002894979081127234L; + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("agentid") + private Integer agentId; + + @SerializedName("name") + private String name; + + @SerializedName("square_logo_url") + private String squareLogoUrl; + + @SerializedName("logo_mediaid") + private String logoMediaId; + + @SerializedName("description") + private String description; + + @SerializedName("allow_userinfos") + private Users allowUserInfos; + + @SerializedName("allow_partys") + private Parties allowParties; + + @SerializedName("allow_tags") + private Tags allowTags; + + @SerializedName("close") + private Integer close; + + @SerializedName("redirect_domain") + private String redirectDomain; + + @SerializedName("report_location_flag") + private Integer reportLocationFlag; + + @SerializedName("isreportenter") + private Integer isReportEnter; + + @SerializedName("home_url") + private String homeUrl; + + public static WxCpAgent fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpAgent.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + @Data + public static class Users implements Serializable { + @SerializedName("user") + private List users; + } + + @Data + public class User implements Serializable { + @SerializedName("userid") + private String userId; + } + + @Data + public class Parties { + @SerializedName("partyid") + private List partyIds = null; + } + + @Data + public class Tags { + @SerializedName("tagid") + private List tagIds = null; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java index 118c500488..2890ce61eb 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java @@ -1,69 +1,30 @@ package me.chanjar.weixin.cp.bean; +import lombok.Data; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import java.io.Serializable; /** - * 微信部门 + * 微信部门. * * @author Daniel Qian */ +@Data public class WxCpDepart implements Serializable { private static final long serialVersionUID = -5028321625140879571L; private Integer id; private String name; private Integer parentId; - private Integer order; + private Long order; public static WxCpDepart fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class); } - public Integer getId() { - return this.id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getParentId() { - return this.parentId; - } - - public void setParentId(Integer parentId) { - this.parentId = parentId; - } - - public Integer getOrder() { - return this.order; - } - - public void setOrder(Integer order) { - this.order = order; - } - public String toJson() { return WxCpGsonBuilder.create().toJson(this); } - @Override - public String toString() { - return "WxCpDepart{" + - "id=" + this.id + - ", name='" + this.name + '\'' + - ", parentId=" + this.parentId + - ", order=" + this.order + - '}'; - } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpInviteResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpInviteResult.java new file mode 100644 index 0000000000..f6ff46348e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpInviteResult.java @@ -0,0 +1,62 @@ +package me.chanjar.weixin.cp.bean; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.common.base.Splitter; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + * 邀请成员的结果对象类. + * Created by Binary Wang on 2018-5-13. + * + * @author Binary Wang + */ +@Data +public class WxCpInviteResult implements Serializable { + private static final long serialVersionUID = 1420065684270213578L; + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + public static WxCpInviteResult fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpInviteResult.class); + } + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("invaliduser") + private String invalidUsers; + + @SerializedName("invalidparty") + private String[] invalidParties; + + @SerializedName("invalidtag") + private String[] invalidTags; + + public List getInvalidUserList() { + return this.content2List(this.invalidUsers); + } + + private List content2List(String content) { + if (StringUtils.isBlank(content)) { + return Collections.emptyList(); + } + + return Splitter.on("|").splitToList(content); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java index c59ca87e1f..58fc983063 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.cp.bean; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; import me.chanjar.weixin.cp.bean.messagebuilder.*; @@ -10,13 +12,14 @@ import java.util.List; /** - * 消息 + * 消息. * * @author Daniel Qian */ +@Data public class WxCpMessage implements Serializable { - private static final long serialVersionUID = -2082278303476631708L; + private String toUser; private String toParty; private String toTag; @@ -31,119 +34,77 @@ public class WxCpMessage implements Serializable { private String hqMusicUrl; private String safe; private String url; + private String btnTxt; private List articles = new ArrayList<>(); private List mpnewsArticles = new ArrayList<>(); /** - * 获得文本消息builder + * 获得文本消息builder. */ public static TextBuilder TEXT() { return new TextBuilder(); } /** - * 获得文本卡片消息builder + * 获得文本卡片消息builder. */ public static TextCardBuilder TEXTCARD() { return new TextCardBuilder(); } /** - * 获得图片消息builder + * 获得图片消息builder. */ public static ImageBuilder IMAGE() { return new ImageBuilder(); } /** - * 获得语音消息builder + * 获得语音消息builder. */ public static VoiceBuilder VOICE() { return new VoiceBuilder(); } /** - * 获得视频消息builder + * 获得视频消息builder. */ public static VideoBuilder VIDEO() { return new VideoBuilder(); } /** - * 获得图文消息builder + * 获得图文消息builder. */ public static NewsBuilder NEWS() { return new NewsBuilder(); } /** - * 获得mpnews图文消息builder + * 获得mpnews图文消息builder. */ public static MpnewsBuilder MPNEWS() { return new MpnewsBuilder(); } /** - * 获得文件消息builder + * 获得文件消息builder. */ public static FileBuilder FILE() { return new FileBuilder(); } - public List getMpnewsArticles() { - return mpnewsArticles; - } - - public void setMpnewsArticles(List mpnewsArticles) { - this.mpnewsArticles = mpnewsArticles; - } - - public String getToUser() { - return this.toUser; - } - - public void setToUser(String toUser) { - this.toUser = toUser; - } - - public String getToParty() { - return this.toParty; - } - - public void setToParty(String toParty) { - this.toParty = toParty; - } - - public String getToTag() { - return this.toTag; - } - - public void setToTag(String toTag) { - this.toTag = toTag; - } - - public Integer getAgentId() { - return this.agentId; - } - - public void setAgentId(Integer agentId) { - this.agentId = agentId; - } - - public String getMsgType() { - return this.msgType; - } /** *
    * 请使用
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VOICE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MUSIC}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_NEWS}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MPNEWS}
+   * {@link WxConsts.KefuMsgType#TEXT}
+   * {@link WxConsts.KefuMsgType#IMAGE}
+   * {@link WxConsts.KefuMsgType#VOICE}
+   * {@link WxConsts.KefuMsgType#MUSIC}
+   * {@link WxConsts.KefuMsgType#VIDEO}
+   * {@link WxConsts.KefuMsgType#NEWS}
+   * {@link WxConsts.KefuMsgType#MPNEWS}
    * 
* * @param msgType 消息类型 @@ -152,87 +113,8 @@ public void setMsgType(String msgType) { this.msgType = msgType; } - public String getSafe() { - return this.safe; - } - - public void setSafe(String safe) { - this.safe = safe; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getThumbMediaId() { - return this.thumbMediaId; - } - - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getMusicUrl() { - return this.musicUrl; - } - - public void setMusicUrl(String musicUrl) { - this.musicUrl = musicUrl; - } - - public String getHqMusicUrl() { - return this.hqMusicUrl; - } - - public void setHqMusicUrl(String hqMusicUrl) { - this.hqMusicUrl = hqMusicUrl; - } - - public List getArticles() { - return this.articles; - } - - public void setArticles(List articles) { - this.articles = articles; - } - public String toJson() { return WxCpGsonBuilder.INSTANCE.create().toJson(this); } - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java index 6989c4988f..9d0a85b6b9 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java @@ -1,25 +1,31 @@ package me.chanjar.weixin.cp.bean; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.common.base.Splitter; import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import org.apache.commons.lang3.StringUtils; - -import java.util.Collections; -import java.util.List; /** - *
- * 消息发送结果对象类
+ * 消息发送结果对象类.
  * Created by Binary Wang on 2017-6-22.
+ *
  * @author Binary Wang
- * 
*/ -public class WxCpMessageSendResult { +@Data +public class WxCpMessageSendResult implements Serializable { + private static final long serialVersionUID = 916455987193190004L; + @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public static WxCpMessageSendResult fromJson(String json) { @@ -41,52 +47,13 @@ public static WxCpMessageSendResult fromJson(String json) { @SerializedName("invalidtag") private String invalidTag; - public Integer getErrCode() { - return this.errCode; - } - - public void setErrCode(Integer errCode) { - this.errCode = errCode; - } - - public String getErrMsg() { - return this.errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } - - public String getInvalidUser() { - return this.invalidUser; - } - - public void setInvalidUser(String invalidUser) { - this.invalidUser = invalidUser; - } - - public String getInvalidParty() { - return this.invalidParty; - } - - public void setInvalidParty(String invalidParty) { - this.invalidParty = invalidParty; - } - - public String getInvalidTag() { - return this.invalidTag; - } - - public void setInvalidTag(String invalidTag) { - this.invalidTag = invalidTag; - } public List getInvalidUserList() { return this.content2List(this.invalidUser); } private List content2List(String content) { - if(StringUtils.isBlank(content)){ + if (StringUtils.isBlank(content)) { return Collections.emptyList(); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java index 79ec3f1321..360ddd28be 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java @@ -1,50 +1,30 @@ package me.chanjar.weixin.cp.bean; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import java.io.Serializable; /** - * Created by Daniel Qian + * Created by Daniel Qian. */ +@Data +@AllArgsConstructor +@NoArgsConstructor public class WxCpTag implements Serializable { - private static final long serialVersionUID = -7243320279646928402L; private String id; private String name; - public WxCpTag() { - super(); - } - - public WxCpTag(String id, String name) { - super(); - this.id = id; - this.name = name; - } public static WxCpTag fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class); } - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getId() { - return this.id; - } - - public void setId(String id) { - this.id = id; - } - public String toJson() { return WxCpGsonBuilder.create().toJson(this); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java index c216ae46a6..67d90978ba 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java @@ -1,25 +1,31 @@ package me.chanjar.weixin.cp.bean; +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.common.base.Splitter; import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import org.apache.commons.lang3.StringUtils; - -import java.util.Collections; -import java.util.List; /** - *
- * 为标签添加或移除用户结果对象类
+ * 为标签添加或移除用户结果对象类.
  * Created by Binary Wang on 2017-6-22.
+ *
  * @author Binary Wang
- * 
*/ -public class WxCpTagAddOrRemoveUsersResult { +@Data +public class WxCpTagAddOrRemoveUsersResult implements Serializable { + private static final long serialVersionUID = 1420065684270213578L; + @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public static WxCpTagAddOrRemoveUsersResult fromJson(String json) { @@ -38,44 +44,12 @@ public static WxCpTagAddOrRemoveUsersResult fromJson(String json) { @SerializedName("invalidparty") private String[] invalidParty; - public Integer getErrCode() { - return this.errCode; - } - - public void setErrCode(Integer errCode) { - this.errCode = errCode; - } - - public String getErrMsg() { - return this.errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } - - public String getInvalidUser() { - return this.invalidUsers; - } - - public void setInvalidUser(String invalidUser) { - this.invalidUsers = invalidUser; - } - - public String[] getInvalidParty() { - return this.invalidParty; - } - - public void setInvalidParty(String[] invalidParty) { - this.invalidParty = invalidParty; - } - public List getInvalidUserList() { return this.content2List(this.invalidUsers); } private List content2List(String content) { - if(StringUtils.isBlank(content)){ + if (StringUtils.isBlank(content)) { return Collections.emptyList(); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagGetResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagGetResult.java new file mode 100644 index 0000000000..28cc4807a1 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagGetResult.java @@ -0,0 +1,57 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ *  管理企业号应用-测试
+ *  Created by huansinho on 2018/4/16.
+ * 
+ * + * @author huansinho + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class WxCpTagGetResult implements Serializable { + + @SerializedName("errcode") + private Integer errcode; + + @SerializedName("errmsg") + private String errmsg; + + /** + * 用户列表 + */ + @SerializedName("userlist") + private List userlist; + + /** + * 部门列表 + */ + @SerializedName("partylist") + private List partylist; + + /** + * 标签名称 + */ + @SerializedName("tagname") + private String tagname; + + public static WxCpTagGetResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTagGetResult.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java index 647a4e6ba2..f3d5aa2282 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java @@ -1,50 +1,22 @@ package me.chanjar.weixin.cp.bean; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + /** - * 微信用户信息 + * 微信用户信息. * * @author Daniel Qian */ +@Data public class WxCpUser implements Serializable { - - public enum Gender { - MALE("男", "1"), - FEMAIL("女", "2"); - - private String genderName; - private String code; - - Gender(String genderName, String code) { - this.genderName = genderName; - this.code = code; - } - - public String getGenderName() { - return this.genderName; - } - - public String getCode() { - return this.code; - } - - public static Gender fromCode(String code) { - if ("1".equals(code)) { - return Gender.MALE; - } - if ("2".equals(code)) { - return Gender.FEMAIL; - } - - return null; - } - } - private static final long serialVersionUID = -5696099236344075582L; private String userId; private String name; @@ -54,6 +26,7 @@ public static Gender fromCode(String code) { private Gender gender; private String email; private String avatar; + private String avatarMediaId; private Integer status; private Integer enable; private Integer isLeader; @@ -61,160 +34,69 @@ public static Gender fromCode(String code) { private Integer hideMobile; private String englishName; private String telephone; + private String qrCode; + private Boolean toInvite; + /** + * 成员对外信息. + */ + private List externalAttrs = new ArrayList<>(); - public static WxCpUser fromJson(String json) { - return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); - } - - public String getUserId() { - return this.userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer[] getDepartIds() { - return this.departIds; - } - - public void setDepartIds(Integer[] departIds) { - this.departIds = departIds; - } - - public Gender getGender() { - return this.gender; - } - - public void setGender(Gender gender) { - this.gender = gender; - } - - public String getPosition() { - return this.position; - } - - public void setPosition(String position) { - this.position = position; - } - - public String getMobile() { - return this.mobile; - } - - public void setMobile(String mobile) { - this.mobile = mobile; - } - - public String getTelephone() { - return this.telephone; - } - - public void setTelephone(String telephone) { - this.telephone = telephone; - } - - public String getEmail() { - return this.email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getAvatar() { - return this.avatar; - } - - public void setAvatar(String avatar) { - this.avatar = avatar; - } - - public Integer getStatus() { - return this.status; - } - - public void setStatus(Integer status) { - this.status = status; - } - - public Integer getEnable() { - return this.enable; - } - - public void setEnable(Integer enable) { - this.enable = enable; + public void addExternalAttr(ExternalAttribute externalAttr) { + this.externalAttrs.add(externalAttr); } public void addExtAttr(String name, String value) { this.extAttrs.add(new Attr(name, value)); } - public List getExtAttrs() { - return this.extAttrs; - } - - public Integer getIsLeader() { - return isLeader; - } - - public void setIsLeader(Integer isLeader) { - this.isLeader = isLeader; - } - - public Integer getHideMobile() { - return hideMobile; - } - - public void setHideMobile(Integer hideMobile) { - this.hideMobile = hideMobile; - } - - public String getEnglishName() { - return englishName; - } - - public void setEnglishName(String englishName) { - this.englishName = englishName; + public static WxCpUser fromJson(String json) { + return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class); } public String toJson() { return WxCpGsonBuilder.INSTANCE.create().toJson(this); } + @Data + @AllArgsConstructor public static class Attr { private String name; private String value; - - public Attr(String name, String value) { - this.name = name; - this.value = value; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getValue() { - return this.value; - } - - public void setValue(String value) { - this.value = value; - } - } + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ExternalAttribute { + /** + * 属性类型: 0-本文 1-网页 2-小程序. + */ + private int type; + /** + * 属性名称: 需要先确保在管理端有创建改属性,否则会忽略. + */ + private String name; + /** + * 文本属性内容,长度限制12个UTF8字符. + */ + private String value; + /** + * 网页的url,必须包含http或者https头. + */ + private String url; + /** + * 小程序的展示标题,长度限制12个UTF8字符. + * 或者 网页的展示标题,长度限制12个UTF8字符 + */ + private String title; + /** + * 小程序appid,必须是有在本企业安装授权的小程序,否则会被忽略. + */ + private String appid; + /** + * 小程序的页面路径. + */ + private String pagePath; + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserDetail.java new file mode 100644 index 0000000000..1d40e94ae0 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserDetail.java @@ -0,0 +1,54 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +/** + *
+ *  使用user_ticket获取成员详情接口返回类.
+ *  Created by BinaryWang on 2018/4/22.
+ * 
+ * + * @author Binary Wang + */ +@Data +public class WxCpUserDetail { + + /** + * 成员UserID + */ + @SerializedName("userid") + private String userId; + + /** + * 成员姓名 + */ + private String name; + + /** + * 成员手机号,仅在用户同意snsapi_privateinfo授权时返回 + */ + private String mobile; + + /** + * 性别。0表示未定义,1表示男性,2表示女性 + */ + private String gender; + + /** + * 成员邮箱,仅在用户同意snsapi_privateinfo授权时返回 + */ + private String email; + + /** + * 头像url。注:如果要获取小图将url最后的”/0”改成”/100”即可。仅在用户同意snsapi_privateinfo授权时返回 + */ + private String avatar; + + /** + * 员工个人二维码(扫描可添加为外部联系人),仅在用户同意snsapi_privateinfo授权时返回 + */ + @SerializedName("qr_code") + private String qrCode; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java new file mode 100644 index 0000000000..466eac4a6e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java @@ -0,0 +1,126 @@ +package me.chanjar.weixin.cp.bean; + +import java.util.List; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +/** + *
+ * 外部联系人详情
+ * Created by Binary Wang on 2018/9/16.
+ * 参考文档:https://work.weixin.qq.com/api/doc#13878
+ * 
+ * + * @author Binary Wang + */ +@Getter +@Setter +public class WxCpUserExternalContactInfo { + @SerializedName("external_contact") + private ExternalContact externalContact; + + @SerializedName("follow_user") + private List followedUsers; + + @Getter + @Setter + public static class ExternalContact { + @SerializedName("external_userid") + private String externalUserId; + + @SerializedName("position") + private String position; + + @SerializedName("name") + private String name; + + @SerializedName("avatar") + private String avatar; + + @SerializedName("corp_name") + private String corpName; + + @SerializedName("corp_full_name") + private String corpFullName; + + @SerializedName("type") + private Integer type; + + @SerializedName("gender") + private Integer gender; + + @SerializedName("unionid") + private String unionId; + + @SerializedName("external_profile") + private ExternalProfile externalProfile; + } + + @Setter + @Getter + public static class ExternalProfile { + @SerializedName("external_attr") + private List externalAttrs; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ExternalAttribute { + @Setter + @Getter + public static class Text { + private String value; + } + + @Setter + @Getter + public static class Web { + private String title; + private String url; + } + + @Setter + @Getter + public static class MiniProgram { + @SerializedName("pagepath") + private String pagePath; + private String appid; + private String title; + } + + private int type; + + private String name; + + private Text text; + + private Web web; + + @SerializedName("miniprogram") + private MiniProgram miniProgram; + } + + @Setter + @Getter + public static class FollowedUser { + @SerializedName("userid") + private String userId; + private String remark; + private String description; + @SerializedName("createtime") + private Long createTime; + } + + public static WxCpUserExternalContactInfo fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalContactInfo.class); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java index 117cf4115b..abb880d2e8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java @@ -1,30 +1,37 @@ package me.chanjar.weixin.cp.bean; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; import me.chanjar.weixin.cp.util.xml.XStreamTransformer; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; /** *
  * 微信推送过来的消息,也是同步回复给用户的消息,xml格式
  * 相关字段的解释看微信开发者文档:
- * http://mp.weixin.qq.com/wiki/index.php?title=接收普通消息
- * http://mp.weixin.qq.com/wiki/index.php?title=接收事件推送
- * http://mp.weixin.qq.com/wiki/index.php?title=接收语音识别结果
+ * https://work.weixin.qq.com/api/doc#12973
+ * https://work.weixin.qq.com/api/doc#12974
  * 
* * @author Daniel Qian */ +@Data +@Slf4j @XStreamAlias("xml") public class WxCpXmlMessage implements Serializable { private static final long serialVersionUID = -1042994982179476410L; @@ -47,6 +54,24 @@ public class WxCpXmlMessage implements Serializable { @XStreamAlias("CreateTime") private Long createTime; + /** + *
+   * 当接受用户消息时,可能会获得以下值:
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#LOCATION}
+   * {@link WxConsts.XmlMsgType#LINK}
+   * {@link WxConsts.XmlMsgType#EVENT}
+   * 当发送消息的时候使用:
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#NEWS}
+   * 
+ */ @XStreamAlias("MsgType") @XStreamConverter(value = XStreamCDataConverter.class) private String msgType; @@ -124,32 +149,190 @@ public class WxCpXmlMessage implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) private String recognition; + /** + * 通讯录变更事件. + * 请参考常量 me.chanjar.weixin.cp.WxCpConsts.ContactChangeType + */ + @XStreamAlias("ChangeType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String changeType; + + /** + * 变更信息的成员UserID. + */ + @XStreamAlias("UserID") + @XStreamConverter(value = XStreamCDataConverter.class) + private String userId; + + /** + * 新的UserID,变更时推送(userid由系统生成时可更改一次). + */ + @XStreamAlias("NewUserID") + @XStreamConverter(value = XStreamCDataConverter.class) + private String newUserId; + + /** + * 成员名称. + * 或者部门名称 + */ + @XStreamAlias("Name") + @XStreamConverter(value = XStreamCDataConverter.class) + private String name; + + /** + * 成员部门列表. + */ + @XStreamAlias("Department") + @XStreamConverter(value = XStreamCDataConverter.class) + private String department; + + /** + * 手机号码. + */ + @XStreamAlias("Mobile") + @XStreamConverter(value = XStreamCDataConverter.class) + private String mobile; + + /** + * 职位信息。长度为0~64个字节. + */ + @XStreamAlias("Position") + @XStreamConverter(value = XStreamCDataConverter.class) + private String position; + + /** + * 性别,1表示男性,2表示女性. + */ + @XStreamAlias("Gender") + private Integer gender; + + /** + * 邮箱. + */ + @XStreamAlias("Email") + @XStreamConverter(value = XStreamCDataConverter.class) + private String email; + + /** + * 头像url。注:如果要获取小图将url最后的”/0”改成”/100”即可. + */ + @XStreamAlias("Avatar") + @XStreamConverter(value = XStreamCDataConverter.class) + private String avatar; + + /** + * 英文名. + */ + @XStreamAlias("EnglishName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String englishName; + + /** + * 上级字段,标识是否为上级。0表示普通成员,1表示上级. + */ + @XStreamAlias("IsLeader") + private Integer isLeader; + + /** + * 座机. + */ + @XStreamAlias("Telephone") + @XStreamConverter(value = XStreamCDataConverter.class) + private String telephone; + + /** + * 扩展属性. + */ + @XStreamAlias("ExtAttr") + private ExtAttr extAttrs = new ExtAttr(); + + /** + * 部门Id. + */ + @XStreamAlias("Id") + private Integer id; + + /** + * 父部门id. + */ + @XStreamAlias("ParentId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String parentId; + + /** + * 部门排序. + */ + @XStreamAlias("Order") + @XStreamConverter(value = XStreamCDataConverter.class) + private String order; + + /** + * 标签Id. + */ + @XStreamAlias("TagId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String tagId; + + /** + * 标签中新增的成员userid列表,用逗号分隔. + */ + @XStreamAlias("AddUserItems") + @XStreamConverter(value = XStreamCDataConverter.class) + private String addUserItems; + + /** + * 标签中删除的成员userid列表,用逗号分隔. + */ + @XStreamAlias("DelUserItems") + @XStreamConverter(value = XStreamCDataConverter.class) + private String delUserItems; + + /** + * 标签中新增的部门id列表,用逗号分隔. + */ + @XStreamAlias("AddPartyItems") + @XStreamConverter(value = XStreamCDataConverter.class) + private String addPartyItems; + + /** + * 标签中删除的部门id列表,用逗号分隔. + */ + @XStreamAlias("DelPartyItems") + @XStreamConverter(value = XStreamCDataConverter.class) + private String delPartyItems; + + /////////////////////////////////////// // 群发消息返回的结果 /////////////////////////////////////// /** - * 群发的结果 + * 多个时间共用字段. + * 1. 群发的结果. + * 2. 通讯录变更事件 + * 激活状态:1=已激活 2=已禁用 4=未激活 已激活代表已激活企业微信或已关注微工作台(原企业号). */ @XStreamAlias("Status") @XStreamConverter(value = XStreamCDataConverter.class) private String status; + /** - * group_id下粉丝数;或者openid_list中的粉丝数 + * group_id下粉丝数;或者openid_list中的粉丝数. */ @XStreamAlias("TotalCount") private Integer totalCount; /** - * 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount + * 过滤. + * (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount */ @XStreamAlias("FilterCount") private Integer filterCount; /** - * 发送成功的粉丝数 + * 发送成功的粉丝数. */ @XStreamAlias("SentCount") private Integer sentCount; /** - * 发送失败的粉丝数 + * 发送失败的粉丝数. */ @XStreamAlias("ErrorCount") private Integer errorCount; @@ -174,27 +357,18 @@ protected static WxCpXmlMessage fromXml(InputStream is) { } /** - * 从加密字符串转换 - * - * @param encryptedXml - * @param wxCpConfigStorage - * @param timestamp - * @param nonce - * @param msgSignature + * 从加密字符串转换. */ - public static WxCpXmlMessage fromEncryptedXml( - String encryptedXml, - WxCpConfigStorage wxCpConfigStorage, - String timestamp, String nonce, String msgSignature) { + public static WxCpXmlMessage fromEncryptedXml(String encryptedXml, WxCpConfigStorage wxCpConfigStorage, + String timestamp, String nonce, String msgSignature) { WxCpCryptUtil cryptUtil = new WxCpCryptUtil(wxCpConfigStorage); String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml); + log.debug("解密后的原始xml消息内容:{}", plainText); return fromXml(plainText); } - public static WxCpXmlMessage fromEncryptedXml( - InputStream is, - WxCpConfigStorage wxCpConfigStorage, - String timestamp, String nonce, String msgSignature) { + public static WxCpXmlMessage fromEncryptedXml(InputStream is, WxCpConfigStorage wxCpConfigStorage, + String timestamp, String nonce, String msgSignature) { try { return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxCpConfigStorage, timestamp, nonce, msgSignature); } catch (IOException e) { @@ -202,406 +376,66 @@ public static WxCpXmlMessage fromEncryptedXml( } } - public Integer getAgentId() { - return this.agentId; - } - - public void setAgentId(Integer agentId) { - this.agentId = agentId; - } - - public String getToUserName() { - return this.toUserName; - } - - public void setToUserName(String toUserName) { - this.toUserName = toUserName; - } - - public Long getCreateTime() { - return this.createTime; - } - - public void setCreateTime(Long createTime) { - this.createTime = createTime; - } - - /** - *
-   * 当接受用户消息时,可能会获得以下值:
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LOCATION}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LINK}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_EVENT}
-   * 
- */ - public String getMsgType() { - return this.msgType; - } - - /** - *
-   * 当发送消息的时候使用:
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_NEWS}
-   * 
- * - * @param msgType - */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public Long getMsgId() { - return this.msgId; - } - - public void setMsgId(Long msgId) { - this.msgId = msgId; - } - - public String getPicUrl() { - return this.picUrl; - } - - public void setPicUrl(String picUrl) { - this.picUrl = picUrl; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getFormat() { - return this.format; - } - - public void setFormat(String format) { - this.format = format; - } - - public String getThumbMediaId() { - return this.thumbMediaId; - } - - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } - - public Double getLocationX() { - return this.locationX; - } - - public void setLocationX(Double locationX) { - this.locationX = locationX; - } - - public Double getLocationY() { - return this.locationY; - } - - public void setLocationY(Double locationY) { - this.locationY = locationY; - } - - public Double getScale() { - return this.scale; - } - - public void setScale(Double scale) { - this.scale = scale; - } - - public String getLabel() { - return this.label; - } - - public void setLabel(String label) { - this.label = label; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getEvent() { - return this.event; - } - - public void setEvent(String event) { - this.event = event; - } - - public String getEventKey() { - return this.eventKey; - } - - public void setEventKey(String eventKey) { - this.eventKey = eventKey; - } - - public String getTicket() { - return this.ticket; - } - - public void setTicket(String ticket) { - this.ticket = ticket; - } - - public Double getLatitude() { - return this.latitude; - } - - public void setLatitude(Double latitude) { - this.latitude = latitude; - } - - public Double getLongitude() { - return this.longitude; - } - - public void setLongitude(Double longitude) { - this.longitude = longitude; - } - - public Double getPrecision() { - return this.precision; - } - - public void setPrecision(Double precision) { - this.precision = precision; - } - - public String getRecognition() { - return this.recognition; - } - - public void setRecognition(String recognition) { - this.recognition = recognition; - } - - public String getFromUserName() { - return this.fromUserName; - } - - public void setFromUserName(String fromUserName) { - this.fromUserName = fromUserName; - } - - public String getStatus() { - return this.status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Integer getTotalCount() { - return this.totalCount; - } - - public void setTotalCount(Integer totalCount) { - this.totalCount = totalCount; - } - - public Integer getFilterCount() { - return this.filterCount; - } - - public void setFilterCount(Integer filterCount) { - this.filterCount = filterCount; - } - - public Integer getSentCount() { - return this.sentCount; - } - - public void setSentCount(Integer sentCount) { - this.sentCount = sentCount; - } - - public Integer getErrorCount() { - return this.errorCount; - } - - public void setErrorCount(Integer errorCount) { - this.errorCount = errorCount; - } - - public WxCpXmlMessage.ScanCodeInfo getScanCodeInfo() { - return this.scanCodeInfo; - } - - public void setScanCodeInfo(WxCpXmlMessage.ScanCodeInfo scanCodeInfo) { - this.scanCodeInfo = scanCodeInfo; - } - - public WxCpXmlMessage.SendPicsInfo getSendPicsInfo() { - return this.sendPicsInfo; - } - - public void setSendPicsInfo(WxCpXmlMessage.SendPicsInfo sendPicsInfo) { - this.sendPicsInfo = sendPicsInfo; - } - - public WxCpXmlMessage.SendLocationInfo getSendLocationInfo() { - return this.sendLocationInfo; - } - - public void setSendLocationInfo(WxCpXmlMessage.SendLocationInfo sendLocationInfo) { - this.sendLocationInfo = sendLocationInfo; - } - @Override public String toString() { - return "WxCpXmlMessage{" + - "agentId=" + this.agentId + - ", toUserName='" + this.toUserName + '\'' + - ", fromUserName='" + this.fromUserName + '\'' + - ", createTime=" + this.createTime + - ", msgType='" + this.msgType + '\'' + - ", content='" + this.content + '\'' + - ", msgId=" + this.msgId + - ", picUrl='" + this.picUrl + '\'' + - ", mediaId='" + this.mediaId + '\'' + - ", format='" + this.format + '\'' + - ", thumbMediaId='" + this.thumbMediaId + '\'' + - ", locationX=" + this.locationX + - ", locationY=" + this.locationY + - ", scale=" + this.scale + - ", label='" + this.label + '\'' + - ", title='" + this.title + '\'' + - ", description='" + this.description + '\'' + - ", url='" + this.url + '\'' + - ", event='" + this.event + '\'' + - ", eventKey='" + this.eventKey + '\'' + - ", ticket='" + this.ticket + '\'' + - ", latitude=" + this.latitude + - ", longitude=" + this.longitude + - ", precision=" + this.precision + - ", recognition='" + this.recognition + '\'' + - ", status='" + this.status + '\'' + - ", totalCount=" + this.totalCount + - ", filterCount=" + this.filterCount + - ", sentCount=" + this.sentCount + - ", errorCount=" + this.errorCount + - ", scanCodeInfo=" + this.scanCodeInfo + - ", sendPicsInfo=" + this.sendPicsInfo + - ", sendLocationInfo=" + this.sendLocationInfo + - '}'; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } + @Data @XStreamAlias("ScanCodeInfo") public static class ScanCodeInfo { + /** + * 扫描类型,一般是qrcode. + */ @XStreamAlias("ScanType") @XStreamConverter(value = XStreamCDataConverter.class) private String scanType; + /** + * 扫描结果,即二维码对应的字符串信息. + */ @XStreamAlias("ScanResult") @XStreamConverter(value = XStreamCDataConverter.class) private String scanResult; + } - /** - * 扫描类型,一般是qrcode - */ - public String getScanType() { - - return this.scanType; - } - - public void setScanType(String scanType) { - this.scanType = scanType; - } + @Data + public static class ExtAttr { + @XStreamAlias("Item") + protected final List items = new ArrayList<>(); - /** - * 扫描结果,即二维码对应的字符串信息 - */ - public String getScanResult() { - return this.scanResult; - } + @Data + public static class Item { + @XStreamAlias("Name") + @XStreamConverter(value = XStreamCDataConverter.class) + private String name; - public void setScanResult(String scanResult) { - this.scanResult = scanResult; + @XStreamAlias("Value") + @XStreamConverter(value = XStreamCDataConverter.class) + private String value; } - } + @Data @XStreamAlias("SendPicsInfo") public static class SendPicsInfo { - @XStreamAlias("PicList") protected final List picList = new ArrayList<>(); + @XStreamAlias("Count") private Long count; - public Long getCount() { - return this.count; - } - - public void setCount(Long count) { - this.count = count; - } - - public List getPicList() { - return this.picList; - } - @XStreamAlias("item") + @Data public static class Item { - @XStreamAlias("PicMd5Sum") @XStreamConverter(value = XStreamCDataConverter.class) - private String PicMd5Sum; - - public String getPicMd5Sum() { - return this.PicMd5Sum; - } - - public void setPicMd5Sum(String picMd5Sum) { - this.PicMd5Sum = picMd5Sum; - } + private String picMd5Sum; } } + @Data @XStreamAlias("SendLocationInfo") public static class SendLocationInfo { @@ -623,47 +457,8 @@ public static class SendLocationInfo { @XStreamAlias("Poiname") @XStreamConverter(value = XStreamCDataConverter.class) - private String poiname; + private String poiName; - public String getLocationX() { - return this.locationX; - } - - public void setLocationX(String locationX) { - this.locationX = locationX; - } - - public String getLocationY() { - return this.locationY; - } - - public void setLocationY(String locationY) { - this.locationY = locationY; - } - - public String getScale() { - return this.scale; - } - - public void setScale(String scale) { - this.scale = scale; - } - - public String getLabel() { - return this.label; - } - - public void setLabel(String label) { - this.label = label; - } - - public String getPoiname() { - return this.poiname; - } - - public void setPoiname(String poiname) { - this.poiname = poiname; - } } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java index 2ddb78afc9..cbef3f8766 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = false) public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { private static final long serialVersionUID = -1099446240667237313L; @@ -14,15 +18,7 @@ public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage { private String mediaId; public WxCpXmlOutImageMessage() { - this.msgType = WxConsts.XML_MSG_IMAGE; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; + this.msgType = WxConsts.XmlMsgType.IMAGE; } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java index d69703502f..a053a5460e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java @@ -1,18 +1,29 @@ package me.chanjar.weixin.cp.bean; +import java.io.Serializable; + import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import me.chanjar.weixin.cp.bean.outxmlbuilder.ImageBuilder; +import me.chanjar.weixin.cp.bean.outxmlbuilder.NewsBuilder; +import me.chanjar.weixin.cp.bean.outxmlbuilder.TextBuilder; +import me.chanjar.weixin.cp.bean.outxmlbuilder.VideoBuilder; +import me.chanjar.weixin.cp.bean.outxmlbuilder.VoiceBuilder; import me.chanjar.weixin.cp.config.WxCpConfigStorage; -import me.chanjar.weixin.cp.bean.outxmlbuilder.*; import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; import me.chanjar.weixin.cp.util.xml.XStreamTransformer; -import java.io.Serializable; - +/** + * 被动回复消息. + * https://work.weixin.qq.com/api/doc#12975 + * + * @author Daniel Qian + */ @XStreamAlias("xml") +@Data public abstract class WxCpXmlOutMessage implements Serializable { - private static final long serialVersionUID = 1418629839964153110L; @XStreamAlias("ToUserName") @@ -31,78 +42,46 @@ public abstract class WxCpXmlOutMessage implements Serializable { protected String msgType; /** - * 获得文本消息builder + * 获得文本消息builder. */ public static TextBuilder TEXT() { return new TextBuilder(); } /** - * 获得图片消息builder + * 获得图片消息builder. */ public static ImageBuilder IMAGE() { return new ImageBuilder(); } /** - * 获得语音消息builder + * 获得语音消息builder. */ public static VoiceBuilder VOICE() { return new VoiceBuilder(); } /** - * 获得视频消息builder + * 获得视频消息builder. */ public static VideoBuilder VIDEO() { return new VideoBuilder(); } /** - * 获得图文消息builder + * 获得图文消息builder. */ public static NewsBuilder NEWS() { return new NewsBuilder(); } - public String getToUserName() { - return this.toUserName; - } - - public void setToUserName(String toUserName) { - this.toUserName = toUserName; - } - - public String getFromUserName() { - return this.fromUserName; - } - - public void setFromUserName(String fromUserName) { - this.fromUserName = fromUserName; - } - - public Long getCreateTime() { - return this.createTime; - } - - public void setCreateTime(Long createTime) { - this.createTime = createTime; - } - - public String getMsgType() { - return this.msgType; - } - - public void setMsgType(String msgType) { - this.msgType = msgType; - } - protected String toXml() { return XStreamTransformer.toXml((Class) this.getClass(), this); } /** - * 转换成加密的xml格式 + * 转换成加密的xml格式. */ public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) { String plainXml = toXml(); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java index 0997841081..c8149cabfa 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java @@ -2,6 +2,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; @@ -9,84 +11,47 @@ import java.util.List; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { private static final long serialVersionUID = -5796178637883178826L; @XStreamAlias("Articles") protected final List articles = new ArrayList<>(); + @XStreamAlias("ArticleCount") protected int articleCount; public WxCpXmlOutNewsMessage() { - this.msgType = WxConsts.XML_MSG_NEWS; + this.msgType = WxConsts.XmlMsgType.NEWS; } - public int getArticleCount() { - return this.articleCount; - } public void addArticle(Item item) { this.articles.add(item); this.articleCount = this.articles.size(); } - public List getArticles() { - return this.articles; - } - - @XStreamAlias("item") + @Data public static class Item { @XStreamAlias("Title") @XStreamConverter(value = XStreamCDataConverter.class) - private String Title; + private String title; @XStreamAlias("Description") @XStreamConverter(value = XStreamCDataConverter.class) - private String Description; + private String description; @XStreamAlias("PicUrl") @XStreamConverter(value = XStreamCDataConverter.class) - private String PicUrl; + private String picUrl; @XStreamAlias("Url") @XStreamConverter(value = XStreamCDataConverter.class) - private String Url; - - public String getTitle() { - return this.Title; - } - - public void setTitle(String title) { - this.Title = title; - } - - public String getDescription() { - return this.Description; - } - - public void setDescription(String description) { - this.Description = description; - } - - public String getPicUrl() { - return this.PicUrl; - } - - public void setPicUrl(String picUrl) { - this.PicUrl = picUrl; - } - - public String getUrl() { - return this.Url; - } - - public void setUrl(String url) { - this.Url = url; - } + private String url; } - } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java index 5f09abf485..6589b0b3b6 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = false) public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { private static final long serialVersionUID = 2569239617185930232L; @@ -14,16 +18,7 @@ public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage { private String content; public WxCpXmlOutTextMessage() { - this.msgType = WxConsts.XML_MSG_TEXT; + this.msgType = WxConsts.XmlMsgType.TEXT; } - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java index 46dae31c3f..f4aabd182b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = false) public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { private static final long serialVersionUID = -8672761162722733622L; @@ -13,7 +17,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage { protected final Video video = new Video(); public WxCpXmlOutVideoMessage() { - this.msgType = WxConsts.XML_MSG_VIDEO; + this.msgType = WxConsts.XmlMsgType.VIDEO; } public String getMediaId() { @@ -40,7 +44,7 @@ public void setDescription(String description) { this.video.setDescription(description); } - + @Data @XStreamAlias("Video") public static class Video { @@ -56,30 +60,6 @@ public static class Video { @XStreamConverter(value = XStreamCDataConverter.class) private String description; - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java index b1827706dd..efe4a86fcf 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = false) public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { private static final long serialVersionUID = -7947384031546099340L; @@ -14,15 +18,7 @@ public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage { private String mediaId; public WxCpXmlOutVoiceMessage() { - this.msgType = WxConsts.XML_MSG_VOICE; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; + this.msgType = WxConsts.XmlMsgType.VOICE; } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java index b3f4acf402..af622fefd8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java @@ -1,5 +1,8 @@ package me.chanjar.weixin.cp.bean.article; +import lombok.Builder; +import lombok.Data; + import java.io.Serializable; /** @@ -9,6 +12,8 @@ * * @author Binary Wang */ +@Data +@Builder(builderMethodName = "newBuilder") public class MpnewsArticle implements Serializable { private static final long serialVersionUID = 6985871812170756481L; @@ -20,125 +25,4 @@ public class MpnewsArticle implements Serializable { private String digest; private String showCoverPic; - private MpnewsArticle(Builder builder) { - setTitle(builder.title); - setThumbMediaId(builder.thumbMediaId); - setAuthor(builder.author); - setContentSourceUrl(builder.contentSourceUrl); - setContent(builder.content); - setDigest(builder.digest); - setShowCoverPic(builder.showCoverPic); - } - - public static Builder newBuilder() { - return new Builder(); - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getThumbMediaId() { - return thumbMediaId; - } - - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getContentSourceUrl() { - return contentSourceUrl; - } - - public void setContentSourceUrl(String contentSourceUrl) { - this.contentSourceUrl = contentSourceUrl; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getDigest() { - return digest; - } - - public void setDigest(String digest) { - this.digest = digest; - } - - public String getShowCoverPic() { - return showCoverPic; - } - - public void setShowCoverPic(String showCoverPic) { - this.showCoverPic = showCoverPic; - } - - public static final class Builder { - private String title; - private String thumbMediaId; - private String author; - private String contentSourceUrl; - private String content; - private String digest; - private String showCoverPic; - - private Builder() { - } - - public Builder title(String title) { - this.title = title; - return this; - } - - public Builder thumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - return this; - } - - public Builder author(String author) { - this.author = author; - return this; - } - - public Builder contentSourceUrl(String contentSourceUrl) { - this.contentSourceUrl = contentSourceUrl; - return this; - } - - public Builder content(String content) { - this.content = content; - return this; - } - - public Builder digest(String digest) { - this.digest = digest; - return this; - } - - public Builder showCoverPic(String showCoverPic) { - this.showCoverPic = showCoverPic; - return this; - } - - public MpnewsArticle build() { - return new MpnewsArticle(this); - } - } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java index 02b0b1086f..7f10d363b4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.cp.bean.article; +import lombok.Data; + import java.io.Serializable; /** @@ -9,6 +11,7 @@ * * @author Binary Wang */ +@Data public class NewArticle implements Serializable { private static final long serialVersionUID = 4087852055781140659L; @@ -17,36 +20,4 @@ public class NewArticle implements Serializable { private String url; private String picUrl; - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getPicUrl() { - return this.picUrl; - } - - public void setPicUrl(String picUrl) { - this.picUrl = picUrl; - } - } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java index 784de9a769..1064f00526 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java @@ -44,7 +44,7 @@ public WxCpMessage build() { m.setToUser(this.toUser); m.setToParty(this.toParty); m.setToTag(this.toTag); - m.setSafe(StringUtils.defaultIfBlank(this.safe, WxConsts.CUSTOM_MSG_SAFE_NO)); + m.setSafe(StringUtils.defaultIfBlank(this.safe, WxConsts.KefuMsgSafe.NO)); return m; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java index 1da7816926..f67cf6e50d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java @@ -15,7 +15,7 @@ public final class FileBuilder extends BaseBuilder { private String mediaId; public FileBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_FILE; + this.msgType = WxConsts.KefuMsgType.FILE; } public FileBuilder mediaId(String media_id) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java index a74f5016e4..ddf3b7373b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java @@ -15,7 +15,7 @@ public final class ImageBuilder extends BaseBuilder { private String mediaId; public ImageBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_IMAGE; + this.msgType = WxConsts.KefuMsgType.IMAGE; } public ImageBuilder mediaId(String media_id) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java index 55ed20abab..75739803f4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java @@ -23,7 +23,7 @@ public final class MpnewsBuilder extends BaseBuilder { private String mediaId; public MpnewsBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_MPNEWS; + this.msgType = WxConsts.KefuMsgType.MPNEWS; } public MpnewsBuilder mediaId(String mediaId) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java index dd23941244..9d0d2f603a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java @@ -22,7 +22,7 @@ public final class NewsBuilder extends BaseBuilder { private List articles = new ArrayList<>(); public NewsBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_NEWS; + this.msgType = WxConsts.KefuMsgType.NEWS; } public NewsBuilder addArticle(NewArticle... articles) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java index 8c1ee1d014..5079b5f846 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java @@ -15,7 +15,7 @@ public final class TextBuilder extends BaseBuilder { private String content; public TextBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_TEXT; + this.msgType = WxConsts.KefuMsgType.TEXT; } public TextBuilder content(String content) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java index a30b9d4059..6cae763d19 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java @@ -16,9 +16,10 @@ public class TextCardBuilder extends BaseBuilder { private String title; private String description; private String url; + private String btnTxt; public TextCardBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_TEXTCARD; + this.msgType = WxConsts.KefuMsgType.TEXTCARD; } public TextCardBuilder title(String title) { @@ -36,12 +37,18 @@ public TextCardBuilder url(String url) { return this; } + public TextCardBuilder btnTxt(String btnTxt) { + this.btnTxt = btnTxt; + return this; + } + @Override public WxCpMessage build() { WxCpMessage m = super.build(); m.setTitle(this.title); m.setDescription(this.description); m.setUrl(this.url); + m.setBtnTxt(this.btnTxt); return m; } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java index 52cba28703..8d47399407 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java @@ -24,7 +24,7 @@ public final class VideoBuilder extends BaseBuilder { private String thumbMediaId; public VideoBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_VIDEO; + this.msgType = WxConsts.KefuMsgType.VIDEO; } public VideoBuilder mediaId(String mediaId) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java index 0960fe8f0c..33c36abcbe 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java @@ -15,7 +15,7 @@ public final class VoiceBuilder extends BaseBuilder { private String mediaId; public VoiceBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_VOICE; + this.msgType = WxConsts.KefuMsgType.VOICE; } public VoiceBuilder mediaId(String media_id) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java index 03eb8f544a..303ed3c46a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java @@ -23,7 +23,7 @@ public BuilderType fromUser(String fromusername) { public void setCommon(WxCpXmlOutMessage m) { m.setToUserName(this.toUserName); m.setFromUserName(this.fromUserName); - m.setCreateTime(System.currentTimeMillis() / 1000l); + m.setCreateTime(System.currentTimeMillis() / 1000L); } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java index 1b57f83bf8..707188a27d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java @@ -1,11 +1,13 @@ package me.chanjar.weixin.cp.config; +import java.io.File; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.util.ToStringUtils; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; -import java.io.File; - /** * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 * @@ -63,7 +65,7 @@ public synchronized void updateAccessToken(WxAccessToken accessToken) { @Override public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { this.accessToken = accessToken; - this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; + this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; } @Override @@ -92,7 +94,7 @@ public boolean isJsapiTicketExpired() { public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { this.jsapiTicket = jsapiTicket; // 预留200秒的时间 - this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; + this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; } @Override @@ -201,7 +203,7 @@ public void setHttpProxyPassword(String httpProxyPassword) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } @Override diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java index 39b2ae5023..6ae48f0e64 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java @@ -9,18 +9,26 @@ import java.io.File; /** - * Jedis client implementor for wechat config storage + * Jedis client implementor for wechat config storage. + *
+ *    使用说明:本实现仅供参考,并不完整,
+ *    比如为减少项目依赖,未加入redis分布式锁的实现,如有需要请自行实现。
+ * 
* * @author gaigeshen */ public class WxCpJedisConfigStorage implements WxCpConfigStorage { - /* Redis keys here */ + /** + * Redis keys here + */ private static final String ACCESS_TOKEN_KEY = "WX_CP_ACCESS_TOKEN"; private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME"; private static final String JS_API_TICKET_KEY = "WX_CP_JS_API_TICKET"; private static final String JS_API_TICKET_EXPIRES_TIME_KEY = "WX_CP_JS_API_TICKET_EXPIRES_TIME"; - /* Redis clients pool */ + /** + * Redis clients pool + */ private final JedisPool jedisPool; private volatile String corpId; private volatile String corpSecret; @@ -35,17 +43,24 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage { private volatile File tmpDirFile; private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; + public WxCpJedisConfigStorage(JedisPool jedisPool) { + this.jedisPool = jedisPool; + } + public WxCpJedisConfigStorage(String host, int port) { - this.jedisPool = new JedisPool(host, port); + jedisPool = new JedisPool(host, port); } - public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port) { - this.jedisPool = new JedisPool(poolConfig, host, port); + jedisPool = new JedisPool(poolConfig, host, port); + } + + public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port, int timeout, String password) { + jedisPool = new JedisPool(poolConfig, host, port, timeout, password); } - public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port, int timeout, final String password) { - this.jedisPool = new JedisPool(poolConfig, host, port, timeout, password); + public WxCpJedisConfigStorage(JedisPoolConfig poolConfig, String host, int port, int timeout, String password, int database) { + jedisPool = new JedisPool(poolConfig, host, port, timeout, password, database); } /** @@ -192,8 +207,7 @@ public long getExpiresTime() { String expiresTimeStr = jedis.get(ACCESS_TOKEN_EXPIRES_TIME_KEY); if (expiresTimeStr != null) { - Long expiresTime = Long.parseLong(expiresTimeStr); - return expiresTime; + return Long.parseLong(expiresTimeStr); } return 0L; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java index 615fa8f220..22074d6e70 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.cp.message; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpXmlMessage; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java index 21abb5cdb4..ab4c658e4f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.cp.message; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpXmlMessage; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java index 3c53d26106..99e4fd4573 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java @@ -11,6 +11,7 @@ import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -215,17 +216,19 @@ public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) { } protected boolean isDuplicateMessage(WxCpXmlMessage wxMessage) { - - String messageId = ""; + String messageId; if (wxMessage.getMsgId() == null) { messageId = String.valueOf(wxMessage.getCreateTime()) - + "-" + String.valueOf(wxMessage.getAgentId() == null ? "" : wxMessage.getAgentId()) + + "-" + StringUtils.trimToEmpty(String.valueOf(wxMessage.getAgentId())) + "-" + wxMessage.getFromUserName() - + "-" + String.valueOf(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey()) - + "-" + String.valueOf(wxMessage.getEvent() == null ? "" : wxMessage.getEvent()) + + "-" + StringUtils.trimToEmpty(wxMessage.getEventKey()) + + "-" + StringUtils.trimToEmpty(wxMessage.getEvent()) ; } else { - messageId = String.valueOf(wxMessage.getMsgId()); + messageId = new StringBuilder().append(wxMessage.getMsgId()) + .append("-").append(wxMessage.getCreateTime()) + .append("-").append(wxMessage.getFromUserName()) + .toString(); } return this.messageDuplicateChecker.isDuplicate(messageId); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java index b5912404ce..8f3766a160 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.message; import me.chanjar.weixin.common.api.WxErrorExceptionHandler; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpXmlMessage; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java index 431c38039b..a5a11d24f4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java @@ -49,7 +49,7 @@ public WxCpDepart deserialize(JsonElement json, Type typeOfT, JsonDeserializatio depart.setName(GsonHelper.getAsString(departJson.get("name"))); } if (departJson.get("order") != null && !departJson.get("order").isJsonNull()) { - depart.setOrder(GsonHelper.getAsInteger(departJson.get("order"))); + depart.setOrder(GsonHelper.getAsLong(departJson.get("order"))); } if (departJson.get("parentid") != null && !departJson.get("parentid").isJsonNull()) { depart.setParentId(GsonHelper.getAsInteger(departJson.get("parentid"))); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java index 5efee45ce5..f4dc691ea4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java @@ -3,13 +3,16 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.util.json.WxErrorAdapter; 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; +/** + * @author Daniel Qian + */ public class WxCpGsonBuilder { public static final GsonBuilder INSTANCE = new GsonBuilder(); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java index 67e43c4ccc..7bed435d30 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java @@ -37,33 +37,34 @@ public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializat if (StringUtils.isNotBlank(message.getToTag())) { messageJson.addProperty("totag", message.getToTag()); } - if (WxConsts.CUSTOM_MSG_TEXT.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) { JsonObject text = new JsonObject(); text.addProperty("content", message.getContent()); messageJson.add("text", text); } - if (WxConsts.CUSTOM_MSG_TEXTCARD.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.TEXTCARD.equals(message.getMsgType())) { JsonObject text = new JsonObject(); text.addProperty("title", message.getTitle()); text.addProperty("description", message.getDescription()); text.addProperty("url", message.getUrl()); + text.addProperty("btntxt", message.getBtnTxt()); messageJson.add("textcard", text); } - if (WxConsts.CUSTOM_MSG_IMAGE.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.IMAGE.equals(message.getMsgType())) { JsonObject image = new JsonObject(); image.addProperty("media_id", message.getMediaId()); messageJson.add("image", image); } - if (WxConsts.CUSTOM_MSG_FILE.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.FILE.equals(message.getMsgType())) { JsonObject image = new JsonObject(); image.addProperty("media_id", message.getMediaId()); messageJson.add("file", image); } - if (WxConsts.CUSTOM_MSG_VOICE.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.VOICE.equals(message.getMsgType())) { JsonObject voice = new JsonObject(); voice.addProperty("media_id", message.getMediaId()); messageJson.add("voice", voice); @@ -73,7 +74,7 @@ public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializat messageJson.addProperty("safe", message.getSafe()); } - if (WxConsts.CUSTOM_MSG_VIDEO.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.VIDEO.equals(message.getMsgType())) { JsonObject video = new JsonObject(); video.addProperty("media_id", message.getMediaId()); video.addProperty("thumb_media_id", message.getThumbMediaId()); @@ -82,7 +83,7 @@ public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializat messageJson.add("video", video); } - if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.NEWS.equals(message.getMsgType())) { JsonObject newsJsonObject = new JsonObject(); JsonArray articleJsonArray = new JsonArray(); for (NewArticle article : message.getArticles()) { @@ -97,7 +98,7 @@ public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializat messageJson.add("news", newsJsonObject); } - if (WxConsts.CUSTOM_MSG_MPNEWS.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.MPNEWS.equals(message.getMsgType())) { JsonObject newsJsonObject = new JsonObject(); if (message.getMediaId() != null) { newsJsonObject.addProperty("media_id", message.getMediaId()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java index 6531d07ba9..1dc3f687d5 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java @@ -8,20 +8,30 @@ */ package me.chanjar.weixin.cp.util.json; -import com.google.gson.*; +import java.lang.reflect.Type; + +import com.google.gson.JsonArray; +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.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.cp.bean.Gender; import me.chanjar.weixin.cp.bean.WxCpUser; -import java.lang.reflect.Type; - /** * @author Daniel Qian */ public class WxCpUserGsonAdapter implements JsonDeserializer, JsonSerializer { + private static final String EXTERNAL_PROFILE = "external_profile"; + private static final String EXTERNAL_ATTR = "external_attr"; @Override - public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject o = json.getAsJsonObject(); WxCpUser user = new WxCpUser(); @@ -39,15 +49,18 @@ public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationC user.setName(GsonHelper.getString(o, "name")); user.setPosition(GsonHelper.getString(o, "position")); user.setMobile(GsonHelper.getString(o, "mobile")); - user.setGender(WxCpUser.Gender.fromCode(GsonHelper.getString(o, "gender"))); + user.setGender(Gender.fromCode(GsonHelper.getString(o, "gender"))); user.setEmail(GsonHelper.getString(o, "email")); user.setAvatar(GsonHelper.getString(o, "avatar")); + user.setAvatarMediaId(GsonHelper.getString(o, "avatar_mediaid")); user.setStatus(GsonHelper.getInteger(o, "status")); user.setEnable(GsonHelper.getInteger(o, "enable")); user.setIsLeader(GsonHelper.getInteger(o, "isleader")); user.setHideMobile(GsonHelper.getInteger(o, "hide_mobile")); user.setEnglishName(GsonHelper.getString(o, "english_name")); user.setTelephone(GsonHelper.getString(o, "telephone")); + user.setQrCode(GsonHelper.getString(o, "qr_code")); + user.setToInvite(GsonHelper.getBoolean(o, "to_invite")); if (GsonHelper.isNotNull(o.get("extattr"))) { JsonArray attrJsonElements = o.get("extattr").getAsJsonObject().get("attrs").getAsJsonArray(); @@ -59,6 +72,53 @@ public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationC user.getExtAttrs().add(attr); } } + + if (GsonHelper.isNotNull(o.get(EXTERNAL_PROFILE))) { + JsonArray attrJsonElements = o.get(EXTERNAL_PROFILE).getAsJsonObject().get(EXTERNAL_ATTR).getAsJsonArray(); + for (JsonElement element : attrJsonElements) { + final Integer type = GsonHelper.getInteger(element.getAsJsonObject(), "type"); + final String name = GsonHelper.getString(element.getAsJsonObject(), "name"); + + switch (type) { + case 0: { + user.getExternalAttrs() + .add(WxCpUser.ExternalAttribute.builder() + .type(type) + .name(name) + .value(GsonHelper.getString(element.getAsJsonObject().get("text").getAsJsonObject(), "value")) + .build() + ); + break; + } + case 1: { + final JsonObject web = element.getAsJsonObject().get("web").getAsJsonObject(); + user.getExternalAttrs() + .add(WxCpUser.ExternalAttribute.builder() + .type(type) + .name(name) + .url(GsonHelper.getString(web, "url")) + .title(GsonHelper.getString(web, "title")) + .build() + ); + break; + } + case 2: { + final JsonObject miniprogram = element.getAsJsonObject().get("miniprogram").getAsJsonObject(); + user.getExternalAttrs() + .add(WxCpUser.ExternalAttribute.builder() + .type(type) + .name(name) + .appid(GsonHelper.getString(miniprogram, "appid")) + .pagePath(GsonHelper.getString(miniprogram, "pagepath")) + .title(GsonHelper.getString(miniprogram, "title")) + .build() + ); + break; + } + default://ignored + } + } + } return user; } @@ -93,6 +153,9 @@ public JsonElement serialize(WxCpUser user, Type typeOfSrc, JsonSerializationCon if (user.getAvatar() != null) { o.addProperty("avatar", user.getAvatar()); } + if (user.getAvatarMediaId() != null) { + o.addProperty("avatar_mediaid", user.getAvatarMediaId()); + } if (user.getStatus() != null) { o.addProperty("status", user.getStatus()); } @@ -111,6 +174,13 @@ public JsonElement serialize(WxCpUser user, Type typeOfSrc, JsonSerializationCon if (user.getTelephone() != null) { o.addProperty("telephone", user.getTelephone()); } + if (user.getQrCode() != null) { + o.addProperty("qr_code", user.getQrCode()); + } + if (user.getToInvite() != null) { + o.addProperty("to_invite", user.getToInvite()); + } + if (user.getExtAttrs().size() > 0) { JsonArray attrsJsonArray = new JsonArray(); for (WxCpUser.Attr attr : user.getExtAttrs()) { @@ -123,6 +193,45 @@ public JsonElement serialize(WxCpUser user, Type typeOfSrc, JsonSerializationCon attrsJson.add("attrs", attrsJsonArray); o.add("extattr", attrsJson); } + + if (user.getExternalAttrs().size() > 0) { + JsonArray attrsJsonArray = new JsonArray(); + for (WxCpUser.ExternalAttribute attr : user.getExternalAttrs()) { + JsonObject attrJson = new JsonObject(); + attrJson.addProperty("type",attr.getType()); + attrJson.addProperty("name", attr.getName()); + switch (attr.getType()) { + case 0: { + JsonObject text = new JsonObject(); + text.addProperty("value", attr.getValue()); + attrJson.add("text", text); + break; + } + case 1: { + JsonObject web = new JsonObject(); + web.addProperty("url", attr.getUrl()); + web.addProperty("title", attr.getTitle()); + attrJson.add("web", web); + break; + } + case 2: { + JsonObject miniprogram = new JsonObject(); + miniprogram.addProperty("appid", attr.getAppid()); + miniprogram.addProperty("pagepath", attr.getPagePath()); + miniprogram.addProperty("title", attr.getTitle()); + attrJson.add("miniprogram", miniprogram); + break; + } + default://忽略 + } + attrsJsonArray.add(attrJson); + } + + JsonObject attrsJson = new JsonObject(); + attrsJson.add(EXTERNAL_ATTR, attrsJsonArray); + o.add(EXTERNAL_PROFILE, attrsJson); + } + return o; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java index 6b58063062..5ef1503df1 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java @@ -1,13 +1,19 @@ 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; +import com.thoughtworks.xstream.XStream; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; +import me.chanjar.weixin.cp.bean.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage; +import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage; +import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; +import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage; +import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage; + public class XStreamTransformer { protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance(); @@ -28,7 +34,7 @@ public static T fromXml(Class clazz, InputStream is) { } /** - * 注册扩展消息的解析器 + * 注册扩展消息的解析器. * * @param clz 类型 * @param xStream xml解析器 @@ -38,7 +44,7 @@ public static void register(Class clz, XStream xStream) { } /** - * pojo -> xml + * pojo -> xml. */ public static String toXml(Class clazz, T object) { return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); @@ -46,17 +52,18 @@ public static String toXml(Class clazz, T object) { private static Map configXStreamInstance() { Map map = new HashMap<>(); - 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()); + map.put(WxCpXmlMessage.class, configWxCpXmlMessage()); + map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage()); + map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage()); + map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage()); + map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage()); + map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage()); return map; } - private static XStream config_WxCpXmlMessage() { + private static XStream configWxCpXmlMessage() { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(WxCpXmlMessage.class); xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class); xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class); @@ -65,38 +72,43 @@ private static XStream config_WxCpXmlMessage() { return xstream; } - private static XStream config_WxCpXmlOutImageMessage() { + private static XStream configWxCpXmlOutImageMessage() { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(WxCpXmlOutMessage.class); xstream.processAnnotations(WxCpXmlOutImageMessage.class); return xstream; } - private static XStream config_WxCpXmlOutNewsMessage() { + private static XStream configWxCpXmlOutNewsMessage() { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(WxCpXmlOutMessage.class); xstream.processAnnotations(WxCpXmlOutNewsMessage.class); xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class); return xstream; } - private static XStream config_WxCpXmlOutTextMessage() { + private static XStream configWxCpXmlOutTextMessage() { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(WxCpXmlOutMessage.class); xstream.processAnnotations(WxCpXmlOutTextMessage.class); return xstream; } - private static XStream config_WxCpXmlOutVideoMessage() { + private static XStream configWxCpXmlOutVideoMessage() { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(WxCpXmlOutMessage.class); xstream.processAnnotations(WxCpXmlOutVideoMessage.class); xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class); return xstream; } - private static XStream config_WxCpXmlOutVoiceMessage() { + private static XStream configWxCpXmlOutVoiceMessage() { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(WxCpXmlOutMessage.class); xstream.processAnnotations(WxCpXmlOutVoiceMessage.class); return xstream; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java index 179086f739..c87b6455ac 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java @@ -1,20 +1,24 @@ package me.chanjar.weixin.cp.api; +import java.io.IOException; +import java.io.InputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.inject.Binder; import com.google.inject.Module; 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.impl.WxCpServiceImpl; -import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage; -import java.io.IOException; -import java.io.InputStream; - public class ApiTestModule implements Module { + private final Logger log = LoggerFactory.getLogger(this.getClass()); + private static final String TEST_CONFIG_XML = "test-config.xml"; - public static T fromXml(Class clazz, InputStream is) { + private static T fromXml(Class clazz, InputStream is) { XStream xstream = XStreamInitializer.getInstance(); xstream.alias("xml", clazz); xstream.processAnnotations(clazz); @@ -23,17 +27,19 @@ public static T fromXml(Class clazz, InputStream is) { @Override public void configure(Binder binder) { - try (InputStream is1 = ClassLoader - .getSystemResourceAsStream("test-config.xml")) { - WxXmlCpInMemoryConfigStorage config = fromXml( - WxXmlCpInMemoryConfigStorage.class, is1); + try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(TEST_CONFIG_XML)) { + if (inputStream == null) { + throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成"); + } + + WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream); WxCpService wxService = new WxCpServiceImpl(); wxService.setWxCpConfigStorage(config); binder.bind(WxCpService.class).toInstance(wxService); binder.bind(WxXmlCpInMemoryConfigStorage.class).toInstance(config); } catch (IOException e) { - e.printStackTrace(); + this.log.error(e.getMessage(), e); } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java index b535634a45..58ba1a9791 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.api; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; import me.chanjar.weixin.cp.config.WxCpConfigStorage; import org.apache.commons.lang3.StringUtils; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java index 2c964d309c..2e89e5e79d 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.api; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; import org.testng.annotations.DataProvider; @@ -24,9 +24,7 @@ public synchronized T executeInternal( RequestExecutor executor, String uri, E data) throws WxErrorException { this.log.info("Executed"); - WxError error = new WxError(); - error.setErrorCode(-1); - throw new WxErrorException(error); + throw new WxErrorException(WxError.builder().errorCode(-1).build()); } }; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java index 0cecc01588..640bbad17d 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java @@ -2,8 +2,7 @@ import com.google.inject.Inject; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.bean.WxCpMessage; import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; import org.testng.annotations.*; @@ -32,7 +31,7 @@ public void setup() { public void testSendMessage() throws WxErrorException { WxCpMessage message = new WxCpMessage(); // message.setAgentId(configStorage.getAgentId()); - message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); + message.setMsgType(WxConsts.KefuMsgType.TEXT); message.setToUser(configStorage.getUserId()); message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java index e52101f508..a213488953 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java @@ -27,21 +27,21 @@ public void prepare(boolean async, StringBuffer sb, WxCpMessageRouter router) { router .rule() .async(async) - .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1") + .msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1").content("CONTENT_1") .handler(new WxEchoCpMessageHandler(sb, "COMBINE_4")) .end() .rule() .async(async) - .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1") + .msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1") .handler(new WxEchoCpMessageHandler(sb, "COMBINE_3")) .end() .rule() .async(async) - .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK) + .msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK) .handler(new WxEchoCpMessageHandler(sb, "COMBINE_2")) .end() - .rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end() - .rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EVT_CLICK)).end() + .rule().async(async).msgType(WxConsts.XmlMsgType.TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XmlMsgType.TEXT)).end() + .rule().async(async).event(WxConsts.EventType.CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EventType.CLICK)).end() .rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end() .rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end() .rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end() @@ -69,7 +69,7 @@ public void testAsync(WxCpXmlMessage message, String expected) throws Interrupte WxCpMessageRouter router = new WxCpMessageRouter(null); prepare(true, sb, router); router.route(message); - Thread.sleep(500l); + Thread.sleep(500); Assert.assertEquals(sb.toString(), expected); } @@ -89,7 +89,7 @@ public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map co public void run() { router.route(m); try { - Thread.sleep(1000l); + Thread.sleep(1000); } catch (InterruptedException e) { } } @@ -98,16 +98,16 @@ public void run() { new Thread(r).start(); } - Thread.sleep(1000l * 2); + Thread.sleep(2000); } @DataProvider(name = "messages-1") public Object[][] messages2() { WxCpXmlMessage message1 = new WxCpXmlMessage(); - message1.setMsgType(WxConsts.XML_MSG_TEXT); + message1.setMsgType(WxConsts.XmlMsgType.TEXT); WxCpXmlMessage message2 = new WxCpXmlMessage(); - message2.setEvent(WxConsts.EVT_CLICK); + message2.setEvent(WxConsts.EventType.CLICK); WxCpXmlMessage message3 = new WxCpXmlMessage(); message3.setEventKey("KEY_1"); @@ -125,24 +125,24 @@ public Object[][] messages2() { message7.setFormat("strangeformat"); WxCpXmlMessage c2 = new WxCpXmlMessage(); - c2.setMsgType(WxConsts.XML_MSG_TEXT); - c2.setEvent(WxConsts.EVT_CLICK); + c2.setMsgType(WxConsts.XmlMsgType.TEXT); + c2.setEvent(WxConsts.EventType.CLICK); WxCpXmlMessage c3 = new WxCpXmlMessage(); - c3.setMsgType(WxConsts.XML_MSG_TEXT); - c3.setEvent(WxConsts.EVT_CLICK); + c3.setMsgType(WxConsts.XmlMsgType.TEXT); + c3.setEvent(WxConsts.EventType.CLICK); c3.setEventKey("KEY_1"); WxCpXmlMessage c4 = new WxCpXmlMessage(); - c4.setMsgType(WxConsts.XML_MSG_TEXT); - c4.setEvent(WxConsts.EVT_CLICK); + c4.setMsgType(WxConsts.XmlMsgType.TEXT); + c4.setEvent(WxConsts.EventType.CLICK); c4.setEventKey("KEY_1"); c4.setContent("CONTENT_1"); return new Object[][]{ - new Object[]{message1, WxConsts.XML_MSG_TEXT + ","}, - new Object[]{message2, WxConsts.EVT_CLICK + ","}, + new Object[]{message1, WxConsts.XmlMsgType.TEXT + ","}, + new Object[]{message2, WxConsts.EventType.CLICK + ","}, new Object[]{message3, "KEY_1,"}, new Object[]{message4, "CONTENT_1,"}, new Object[]{message5, "ALL,"}, @@ -184,7 +184,7 @@ public void testSessionClean1(StandardSessionManager ism) throws InterruptedExce msg.setFromUserName("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -204,7 +204,7 @@ public void testSessionClean2(StandardSessionManager ism) throws InterruptedExce msg.setFromUserName("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } { @@ -218,7 +218,7 @@ public void testSessionClean2(StandardSessionManager ism) throws InterruptedExce msg.setFromUserName("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -238,7 +238,7 @@ public void testSessionClean3(StandardSessionManager ism) throws InterruptedExce msg.setFromUserName("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -257,7 +257,7 @@ public void testSessionClean4(StandardSessionManager ism) throws InterruptedExce msg.setFromUserName("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -271,7 +271,7 @@ public void testSessionClean4(StandardSessionManager ism) throws InterruptedExce msg.setFromUserName("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImplTest.java new file mode 100644 index 0000000000..4ce497243d --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImplTest.java @@ -0,0 +1,90 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.ApiTestModule; +import me.chanjar.weixin.cp.api.WxCpAgentService; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpAgent; +import org.testng.Assert; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; + + +/** + *
+ *  管理企业号应用-测试
+ *  Created by huansinho on 2018/4/13.
+ * 
+ * + * @author huansinho + */ +@Guice(modules = ApiTestModule.class) +public class WxCpAgentServiceImplTest { + @Inject + private WxCpService wxCpService; + + @Test + public void testGet() throws Exception { + final Integer agentId = this.wxCpService.getWxCpConfigStorage().getAgentId(); + WxCpAgent wxCpAgent = this.wxCpService.getAgentService().get(agentId); + + assertThat(wxCpAgent.getAgentId()).isEqualTo(agentId); + + assertThat(wxCpAgent.getAllowUserInfos().getUsers().toArray()).isNotEmpty(); + assertThat(wxCpAgent.getAllowParties().getPartyIds().toArray()).isNotEmpty(); + assertThat(wxCpAgent.getAllowTags().getTagIds().toArray()).isNotEmpty(); + } + + @Test + public void testSet() throws WxErrorException { + final Integer agentId = this.wxCpService.getWxCpConfigStorage().getAgentId(); + + this.wxCpService.getAgentService().set(WxCpAgent.builder() + .description("abcddd") + .logoMediaId("aaaaaaaaaaaaaa") + .agentId(agentId) + .build()); + } + + @Test + public void testList() throws WxErrorException { + List list = this.wxCpService.getAgentService().list(); + + assertThat(list).isNotEmpty(); + + assertThat(list.get(0).getAgentId()).isNotNull(); + assertThat(list.get(0).getName()).isNotEmpty(); + assertThat(list.get(0).getSquareLogoUrl()).isNotEmpty(); + } + + public static class MockTest { + private WxCpService wxService = mock(WxCpService.class); + + @Test + public void testGet() throws Exception { + String returnJson = "{\"errcode\": 0,\"errmsg\": \"ok\",\"agentid\": 9,\"name\": \"测试应用\",\"square_logo_url\": \"http://wx.qlogo.cn/mmhead/alksjf;lasdjf;lasjfuodiuj3rj2o34j/0\",\"description\": \"这是一个企业号应用\",\"allow_userinfos\": {\"user\": [{\"userid\": \"0009854\"}, {\"userid\": \"1723\"}, {\"userid\": \"5625\"}]},\"allow_partys\": {\"partyid\": [42762742]},\"allow_tags\": {\"tagid\": [23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7]},\"close\": 0,\"redirect_domain\": \"weixin.com.cn\",\"report_location_flag\": 0,\"isreportenter\": 0,\"home_url\": \"\"}"; + when(wxService.get("https://qyapi.weixin.qq.com/cgi-bin/agent/get?agentid=9", null)).thenReturn(returnJson); + when(wxService.getAgentService()).thenReturn(new WxCpAgentServiceImpl(wxService)); + + WxCpAgentService wxAgentService = this.wxService.getAgentService(); + WxCpAgent wxCpAgent = wxAgentService.get(9); + + assertEquals(9, wxCpAgent.getAgentId().intValue()); + + assertEquals(new Integer[]{42762742}, wxCpAgent.getAllowParties().getPartyIds().toArray()); + + assertEquals(new Integer[]{23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7}, wxCpAgent.getAllowTags().getTagIds().toArray()); + + } + + } + +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java index 685f37444f..9a19564cd2 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java @@ -1,15 +1,14 @@ package me.chanjar.weixin.cp.api.impl; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.cp.api.ApiTestModule; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpDepart; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; +import org.testng.annotations.*; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.*; /** @@ -31,25 +30,33 @@ public void testCreate() throws Exception { WxCpDepart cpDepart = new WxCpDepart(); cpDepart.setName("子部门" + System.currentTimeMillis()); cpDepart.setParentId(1); - cpDepart.setOrder(1); + cpDepart.setOrder(1L); Integer departId = this.wxCpService.getDepartmentService().create(cpDepart); System.out.println(departId); } - @Test - public void testListAll() throws Exception { + @DataProvider + public Object[][] departIds(){ + return new Object[][]{ + {null}, + {1}, + {5} + }; + } + + @Test(dataProvider = "departIds") + public void testList(Integer id) throws Exception { System.out.println("=================获取部门"); - List departList = this.wxCpService.getDepartmentService().listAll(); - assertNotNull(departList); - assertTrue(departList.size() > 0); + List departList = this.wxCpService.getDepartmentService().list(id); + assertThat(departList).isNotEmpty(); for (WxCpDepart g : departList) { this.depart = g; System.out.println(this.depart.getId() + ":" + this.depart.getName()); - assertNotNull(g.getName()); + assertThat(g.getName()).isNotBlank(); } } - @Test(dependsOnMethods = {"testListAll", "testCreate"}) + @Test(dependsOnMethods = {"testList", "testCreate"}) public void testUpdate() throws Exception { System.out.println("=================更新部门"); this.depart.setName("子部门改名" + System.currentTimeMillis()); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImplTest.java index 4bdb73413d..d7242a7703 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImplTest.java @@ -1,28 +1,29 @@ package me.chanjar.weixin.cp.api.impl; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import org.testng.annotations.*; + 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.common.error.WxErrorException; import me.chanjar.weixin.cp.api.ApiTestModule; import me.chanjar.weixin.cp.api.TestConstants; import me.chanjar.weixin.cp.api.WxCpService; -import org.testng.annotations.*; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.*; /** - *
- *
  * Created by Binary Wang on 2017-6-25.
+ *
  * @author Binary Wang
- * 
*/ @Guice(modules = ApiTestModule.class) public class WxCpMediaServiceImplTest { @@ -34,11 +35,11 @@ public class WxCpMediaServiceImplTest { @DataProvider public Object[][] mediaData() { return new Object[][]{ - new Object[]{WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, - new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, "mm.mp3"}, - new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_AMR, "mm.amr"},//{"errcode":301017,"errmsg":"voice file only support amr like myvoice.amr"} - new Object[]{WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, - new Object[]{WxConsts.MEDIA_FILE, TestConstants.FILE_JPG, "mm.jpeg"} + new Object[]{WxConsts.MediaFileType.IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, + new Object[]{WxConsts.MediaFileType.VOICE, TestConstants.FILE_MP3, "mm.mp3"},//{"errcode":301017,"errmsg":"voice file only support amr like myvoice.amr"} + new Object[]{WxConsts.MediaFileType.VOICE, TestConstants.FILE_AMR, "mm.amr"}, + new Object[]{WxConsts.MediaFileType.VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, + new Object[]{WxConsts.MediaFileType.FILE, TestConstants.FILE_JPG, "mm.jpeg"} }; } @@ -75,4 +76,10 @@ public void testDownloadMedia(String media_id) throws WxErrorException { System.out.println(file); } + @Test + public void testUploadImg() throws WxErrorException { + URL url = ClassLoader.getSystemResource("mm.jpeg"); + String res = this.wxService.getMediaService().uploadImg(new File(url.getFile())); + assertThat(res).isNotEmpty(); + } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImplTest.java index def6419820..b9dbbd3aa1 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImplTest.java @@ -26,12 +26,12 @@ public class WxCpMenuServiceImplTest { public Object[][] menuData() { WxMenu menu = new WxMenu(); WxMenuButton button1 = new WxMenuButton(); - button1.setType(WxConsts.BUTTON_CLICK); + button1.setType(WxConsts.MenuButtonType.CLICK); button1.setName("今日歌曲"); button1.setKey("V1001_TODAY_MUSIC"); WxMenuButton button2 = new WxMenuButton(); - button2.setType(WxConsts.BUTTON_CLICK); + button2.setType(WxConsts.MenuButtonType.CLICK); button2.setName("歌手简介"); button2.setKey("V1001_TODAY_SINGER"); @@ -43,17 +43,17 @@ public Object[][] menuData() { menu.getButtons().add(button3); WxMenuButton button31 = new WxMenuButton(); - button31.setType(WxConsts.BUTTON_VIEW); + button31.setType(WxConsts.MenuButtonType.VIEW); button31.setName("搜索"); button31.setUrl("http://www.soso.com/"); WxMenuButton button32 = new WxMenuButton(); - button32.setType(WxConsts.BUTTON_VIEW); + button32.setType(WxConsts.MenuButtonType.VIEW); button32.setName("视频"); button32.setUrl("http://v.qq.com/"); WxMenuButton button33 = new WxMenuButton(); - button33.setType(WxConsts.BUTTON_CLICK); + button33.setType(WxConsts.MenuButtonType.CLICK); button33.setName("赞一下我们"); button33.setKey("V1001_GOOD"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImplTest.java new file mode 100644 index 0000000000..21801e4b42 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAuth2ServiceImplTest.java @@ -0,0 +1,33 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.ApiTestModule; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpUserDetail; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +/** + *
+ *  Created by BinaryWang on 2018/4/22.
+ * 
+ * + * @author Binary Wang + */ +@Guice(modules = ApiTestModule.class) +public class WxCpOAuth2ServiceImplTest { + @Inject + private WxCpService wxService; + + @Test + public void testGetUserDetail() throws WxErrorException { + WxCpUserDetail userDetail = this.wxService.getOauth2Service().getUserDetail("b"); + System.out.println(userDetail); + } + + @Test + public void testGetUserInfo() throws WxErrorException { + this.wxService.getOauth2Service().getUserInfo("abc"); + } +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java index 94ac3b09db..5a6e8ccabd 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTagServiceImplTest.java @@ -2,16 +2,23 @@ import com.google.common.base.Splitter; import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.ApiTestModule; import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.api.WxCpTagService; import me.chanjar.weixin.cp.bean.WxCpTag; import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult; +import me.chanjar.weixin.cp.bean.WxCpTagGetResult; import me.chanjar.weixin.cp.bean.WxCpUser; -import org.testng.annotations.*; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; import java.util.List; -import static org.testng.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; /** *
@@ -63,7 +70,7 @@ public void testListUsersByTagId() throws Exception {
   @Test(dependsOnMethods = {"testListUsersByTagId", "testAddUsers2Tag", "testListAll", "testUpdate", "testCreate"})
   public void testRemoveUsersFromTag() throws Exception {
     List userIds = Splitter.on("|").splitToList(this.configStorage.getUserId());
-    WxCpTagAddOrRemoveUsersResult result = this.wxService.getTagService().removeUsersFromTag(this.tagId, userIds);
+    WxCpTagAddOrRemoveUsersResult result = this.wxService.getTagService().removeUsersFromTag(this.tagId, userIds, null);
     assertEquals(result.getErrCode(), Integer.valueOf(0));
   }
 
@@ -72,4 +79,24 @@ public void testDelete() throws Exception {
     this.wxService.getTagService().delete(this.tagId);
   }
 
+  @Test
+  public void testGet() throws WxErrorException {
+    String apiResultJson = "{\"errcode\": 0,\"errmsg\": \"ok\",\"userlist\": [{\"userid\": \"0124035\",\"name\": \"王五\"},{\"userid\": \"0114035\",\"name\": \"梦雪\"}],\"partylist\": [9576,9567,9566],\"tagname\": \"测试标签-001\"}";
+    WxCpService wxService = mock(WxCpService.class);
+    when(wxService.get("https://qyapi.weixin.qq.com/cgi-bin/tag/get?tagId=150", null)).thenReturn(apiResultJson);
+    when(wxService.getTagService()).thenReturn(new WxCpTagServiceImpl(wxService));
+
+    WxCpTagService wxCpTagService = wxService.getTagService();
+
+    WxCpTagGetResult wxCpTagGetResult = wxCpTagService.get(String.valueOf(150));
+
+    assertEquals(0, wxCpTagGetResult.getErrcode().intValue());
+
+    assertEquals(2, wxCpTagGetResult.getUserlist().size());
+    assertEquals(3, wxCpTagGetResult.getPartylist().size());
+    assertEquals("测试标签-001", wxCpTagGetResult.getTagname());
+
+
+  }
+
 }
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java
index a01f03436e..6b67112095 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java
@@ -1,14 +1,21 @@
 package me.chanjar.weixin.cp.api.impl;
 
-import com.google.inject.Inject;
-import me.chanjar.weixin.cp.api.ApiTestModule;
-import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpUser;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import org.testng.annotations.*;
 
-import java.util.List;
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.ApiTestModule;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.Gender;
+import me.chanjar.weixin.cp.bean.WxCpInviteResult;
+import me.chanjar.weixin.cp.bean.WxCpUser;
+import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
 
 import static org.testng.Assert.*;
 
@@ -37,7 +44,7 @@ public void testCreate() throws Exception {
     user.setName("Some Woman");
     user.setDepartIds(new Integer[]{2});
     user.setEmail("none@none.com");
-    user.setGender(WxCpUser.Gender.FEMAIL);
+    user.setGender(Gender.FEMALE);
     user.setMobile("13560084979");
     user.setPosition("woman");
     user.setTelephone("3300393");
@@ -83,4 +90,31 @@ public void testListSimpleByDepartment() throws Exception {
     }
   }
 
+  @Test
+  public void testInvite() throws Exception {
+    WxCpInviteResult result = this.wxCpService.getUserService().invite(
+      Lists.newArrayList(userId), null,null);
+    System.out.println(result);
+  }
+
+  @Test
+  public void testUserId2Openid() throws Exception {
+    Map result = this.wxCpService.getUserService().userId2Openid(userId, null);
+    System.out.println(result);
+    assertNotNull(result);
+  }
+
+  @Test
+  public void testOpenid2UserId() throws Exception {
+    String result = this.wxCpService.getUserService().openid2UserId(userId);
+    System.out.println(result);
+    assertNotNull(result);
+  }
+
+  @Test
+  public void testGetExternalContact() throws WxErrorException {
+    WxCpUserExternalContactInfo result = this.wxCpService.getUserService().getExternalContact(userId);
+    System.out.println(result);
+    assertNotNull(result);
+  }
 }
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpAgentTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpAgentTest.java
new file mode 100644
index 0000000000..74b8269d3d
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpAgentTest.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.cp.bean;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Created by huansinho on 2018/4/13.
+ */
+@Test
+public class WxCpAgentTest {
+
+  public void testDeserialize() {
+    String json = "{\"errcode\": 0,\"errmsg\": \"ok\",\"agentid\": 9,\"name\": \"测试应用\",\"square_logo_url\": \"http://wx.qlogo.cn/mmhead/alksjf;lasdjf;lasjfuodiuj3rj2o34j/0\",\"description\": \"这是一个企业号应用\",\"allow_userinfos\": {\"user\": [{\"userid\": \"0009854\"}, {\"userid\": \"1723\"}, {\"userid\": \"5625\"}]},\"allow_partys\": {\"partyid\": [42762742]},\"allow_tags\": {\"tagid\": [23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7]},\"close\": 0,\"redirect_domain\": \"weixin.com.cn\",\"report_location_flag\": 0,\"isreportenter\": 0,\"home_url\": \"\"}";
+
+    WxCpAgent wxCpAgent = WxCpAgent.fromJson(json);
+
+    Assert.assertEquals(9, wxCpAgent.getAgentId().intValue());
+
+    Assert.assertEquals(new Integer[]{42762742}, wxCpAgent.getAllowParties().getPartyIds().toArray());
+
+    Assert.assertEquals(new Integer[]{23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7}, wxCpAgent.getAllowTags().getTagIds().toArray());
+
+  }
+
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
index e02cc6672d..0af121a835 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
@@ -2,39 +2,47 @@
 
 import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
 import me.chanjar.weixin.cp.bean.article.NewArticle;
-import org.testng.annotations.*;
+import org.testng.annotations.Test;
 
-import static org.testng.Assert.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.testng.Assert.assertEquals;
 
 @Test
 public class WxCpMessageTest {
 
   public void testTextBuild() {
     WxCpMessage reply = WxCpMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build();
-    assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"},\"safe\":\"0\"}");
+    assertThat(reply.toJson())
+      .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"},\"safe\":\"0\"}");
   }
 
   public void testTextCardBuild() {
     WxCpMessage reply = WxCpMessage.TEXTCARD().toUser("OPENID")
       .title("领奖通知")
-      .description( "
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") - .url("http://www.qq.com").build(); - assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"textcard\",\"textcard\":{\"title\":\"领奖通知\",\"description\":\"
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
\",\"url\":\"http://www.qq.com\"},\"safe\":\"0\"}"); + .description("
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") + .url("http://www.qq.com") + .btnTxt("更多") + .build(); + assertThat(reply.toJson()) + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"textcard\",\"textcard\":{\"title\":\"领奖通知\",\"description\":\"
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
\",\"url\":\"http://www.qq.com\",\"btntxt\":\"更多\"},\"safe\":\"0\"}"); } public void testImageBuild() { WxCpMessage reply = WxCpMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build(); - assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); + assertThat(reply.toJson()) + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); } public void testVoiceBuild() { WxCpMessage reply = WxCpMessage.VOICE().toUser("OPENID").mediaId("MEDIA_ID").build(); - assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); + assertThat(reply.toJson()) + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"},\"safe\":\"0\"}"); } public void testVideoBuild() { WxCpMessage reply = WxCpMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); - assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"safe\":\"0\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); + assertThat(reply.toJson()) + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"safe\":\"0\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); } public void testNewsBuild() { @@ -52,7 +60,8 @@ public void testNewsBuild() { WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); - assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"safe\":\"0\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); + assertThat(reply.toJson()) + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"safe\":\"0\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); } public void testMpnewsBuild_with_articles() { @@ -78,14 +87,15 @@ public void testMpnewsBuild_with_articles() { WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1, article2).build(); - assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"},{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); + assertThat(reply.toJson()) + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"},{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); } public void testMpnewsBuild_with_media_id() { WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").mediaId("mmm").build(); - assertEquals(reply.toJson(), - "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"media_id\":\"mmm\"}}"); + assertThat(reply.toJson()) + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"media_id\":\"mmm\"}}"); } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfoTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfoTest.java new file mode 100644 index 0000000000..3c1b327cd3 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfoTest.java @@ -0,0 +1,129 @@ +package me.chanjar.weixin.cp.bean; + +import java.util.List; + +import org.testng.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
+ *
+ * Created by Binary Wang on 2018/9/16.
+ * 
+ * + * @author Binary Wang + */ +public class WxCpUserExternalContactInfoTest { + + @Test + public void testFromJson() { + final String json = "{\n" + + " \"errcode\": 0,\n" + + " \"errmsg\": \"ok\",\n" + + " \"external_contact\": {\n" + + " \"external_userid\": \"woAJ2GCAAAXtWyujaWJHDDGi0mACH71w\",\n" + + " \"name\": \"李四\",\n" + + " \"position\": \"Mangaer\",\n" + + " \"avatar\": \"http://p.qlogo.cn/bizmail/IcsdgagqefergqerhewSdage/0\",\n" + + " \"corp_name\": \"腾讯\",\n" + + " \"corp_full_name\": \"腾讯科技有限公司\",\n" + + " \"type\": 2,\n" + + " \"gender\": 1,\n" + + " \"unionid\": \"ozynqsulJFCZ2z1aYeS8h-nuasdfR1\",\n" + + " \"external_profile\": {\n" + + " \"external_attr\": [\n" + + " {\n" + + " \"type\": 0,\n" + + " \"name\": \"文本名称\",\n" + + " \"text\": {\n" + + " \"value\": \"文本\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"type\": 1,\n" + + " \"name\": \"网页名称\",\n" + + " \"web\": {\n" + + " \"url\": \"http://www.test.com\",\n" + + " \"title\": \"标题\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"type\": 2,\n" + + " \"name\": \"测试app\",\n" + + " \"miniprogram\": {\n" + + " \"appid\": \"wx8bd80126147df384\",\n" + + " \"pagepath\": \"/index\",\n" + + " \"title\": \"my miniprogram\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"follow_user\": [\n" + + " {\n" + + " \"userid\": \"rocky\",\n" + + " \"remark\": \"李部长\",\n" + + " \"description\": \"对接采购事物\",\n" + + " \"createtime\": 1525779812\n" + + " },\n" + + " {\n" + + " \"userid\": \"tommy\",\n" + + " \"remark\": \"李总\",\n" + + " \"description\": \"采购问题咨询\",\n" + + " \"createtime\": 1525881637\n" + + " }\n" + + " ]\n" + + "}"; + + final WxCpUserExternalContactInfo contactInfo = WxCpUserExternalContactInfo.fromJson(json); + assertThat(contactInfo).isNotNull(); + assertThat(contactInfo.getExternalContact()).isNotNull(); + + assertThat(contactInfo.getExternalContact().getExternalUserId()).isEqualTo("woAJ2GCAAAXtWyujaWJHDDGi0mACH71w"); + assertThat(contactInfo.getExternalContact().getPosition()).isEqualTo("Mangaer"); + assertThat(contactInfo.getExternalContact().getAvatar()).isEqualTo("http://p.qlogo.cn/bizmail/IcsdgagqefergqerhewSdage/0"); + assertThat(contactInfo.getExternalContact().getCorpName()).isEqualTo("腾讯"); + assertThat(contactInfo.getExternalContact().getCorpFullName()).isEqualTo("腾讯科技有限公司"); + assertThat(contactInfo.getExternalContact().getType()).isEqualTo(2); + assertThat(contactInfo.getExternalContact().getGender()).isEqualTo(1); + assertThat(contactInfo.getExternalContact().getUnionId()).isEqualTo("ozynqsulJFCZ2z1aYeS8h-nuasdfR1"); + assertThat(contactInfo.getExternalContact().getName()).isEqualTo("李四"); + + assertThat(contactInfo.getExternalContact().getExternalProfile()).isNotNull(); + + final List externalAttrs = contactInfo.getExternalContact().getExternalProfile().getExternalAttrs(); + assertThat(externalAttrs).isNotEmpty(); + + final WxCpUserExternalContactInfo.ExternalAttribute externalAttr1 = externalAttrs.get(0); + assertThat(externalAttr1.getType()).isEqualTo(0); + assertThat(externalAttr1.getName()).isEqualTo("文本名称"); + assertThat(externalAttr1.getText().getValue()).isEqualTo("文本"); + + final WxCpUserExternalContactInfo.ExternalAttribute externalAttr2 = externalAttrs.get(1); + assertThat(externalAttr2.getType()).isEqualTo(1); + assertThat(externalAttr2.getName()).isEqualTo("网页名称"); + assertThat(externalAttr2.getWeb().getUrl()).isEqualTo("http://www.test.com"); + assertThat(externalAttr2.getWeb().getTitle()).isEqualTo("标题"); + + final WxCpUserExternalContactInfo.ExternalAttribute externalAttr3 = externalAttrs.get(2); + assertThat(externalAttr3.getType()).isEqualTo(2); + assertThat(externalAttr3.getName()).isEqualTo("测试app"); + assertThat(externalAttr3.getMiniProgram().getAppid()).isEqualTo("wx8bd80126147df384"); + assertThat(externalAttr3.getMiniProgram().getPagePath()).isEqualTo("/index"); + assertThat(externalAttr3.getMiniProgram().getTitle()).isEqualTo("my miniprogram"); + + + List followedUsers = contactInfo.getFollowedUsers(); + assertThat(followedUsers).isNotEmpty(); + assertThat(followedUsers.get(0).getUserId()).isEqualTo("rocky"); + assertThat(followedUsers.get(0).getRemark()).isEqualTo("李部长"); + assertThat(followedUsers.get(0).getDescription()).isEqualTo("对接采购事物"); + assertThat(followedUsers.get(0).getCreateTime()).isEqualTo(1525779812); + + assertThat(followedUsers.get(1).getUserId()).isEqualTo("tommy"); + assertThat(followedUsers.get(1).getRemark()).isEqualTo("李总"); + assertThat(followedUsers.get(1).getDescription()).isEqualTo("采购问题咨询"); + assertThat(followedUsers.get(1).getCreateTime()).isEqualTo(1525881637); + } +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java index 87e16d773a..68c57c3d89 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java @@ -57,10 +57,10 @@ public void testFromXml() { WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); assertEquals(wxMessage.getToUserName(), "toUser"); assertEquals(wxMessage.getFromUserName(), "fromUser"); - assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); - assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); + assertEquals(wxMessage.getCreateTime(), new Long(1348831860)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); assertEquals(wxMessage.getContent(), "this is a test"); - assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); + assertEquals(wxMessage.getMsgId(), new Long(1234567890123456L)); assertEquals(wxMessage.getPicUrl(), "this is a url"); assertEquals(wxMessage.getMediaId(), "media_id"); assertEquals(wxMessage.getFormat(), "Format"); @@ -80,13 +80,13 @@ public void testFromXml() { assertEquals(wxMessage.getPrecision(), 119.385040); assertEquals(wxMessage.getScanCodeInfo().getScanType(), "qrcode"); assertEquals(wxMessage.getScanCodeInfo().getScanResult(), "1"); - assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1l)); + assertEquals(wxMessage.getSendPicsInfo().getCount(), new Long(1)); assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "1b5f7c23b5bf75682a53e7b6d163e185"); assertEquals(wxMessage.getSendLocationInfo().getLocationX(), "23"); assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); - assertEquals(wxMessage.getSendLocationInfo().getPoiname(), "wo de poi"); + assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); } public void testSendPicsInfo() { @@ -108,7 +108,7 @@ public void testSendPicsInfo() { assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9"); assertEquals(wxMessage.getFromUserName(), "xiaohe"); assertEquals(wxMessage.getCreateTime(), new Long(1502012364L)); - assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_EVENT); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004)); assertEquals(wxMessage.getEvent(), "pic_weixin"); assertEquals(wxMessage.getEventKey(), "faceSimilarity"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java index 6f366988eb..87c9454c91 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java @@ -9,7 +9,7 @@ public class WxCpXmlOutImageMessageTest { public void test() { WxCpXmlOutImageMessage m = new WxCpXmlOutImageMessage(); m.setMediaId("ddfefesfsdfef"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("from"); m.setToUserName("to"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java index 71dbf4125d..128bc9a4c6 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java @@ -8,7 +8,7 @@ public class WxCpXmlOutNewsMessageTest { public void test() { WxCpXmlOutNewsMessage m = new WxCpXmlOutNewsMessage(); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("fromUser"); m.setToUserName("toUser"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java index 4d73b27f5b..fd09ed6b92 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java @@ -9,7 +9,7 @@ public class WxCpXmlOutTextMessageTest { public void test() { WxCpXmlOutTextMessage m = new WxCpXmlOutTextMessage(); m.setContent("content"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("from"); m.setToUserName("to"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java index b4124c6130..c5551dec01 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java @@ -11,7 +11,7 @@ public void test() { m.setMediaId("media_id"); m.setTitle("title"); m.setDescription("ddfff"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("fromUser"); m.setToUserName("toUser"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java index f414256a5f..a3c9688c44 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java @@ -9,7 +9,7 @@ public class WxCpXmlOutVoiceMessageTest { public void test() { WxCpXmlOutVoiceMessage m = new WxCpXmlOutVoiceMessage(); m.setMediaId("ddfefesfsdfef"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("from"); m.setToUserName("to"); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java index a9ab309c37..ff204a80f0 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java @@ -1,6 +1,16 @@ package me.chanjar.weixin.cp.demo; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; + +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.WxCpConsts; import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; import me.chanjar.weixin.cp.bean.WxCpXmlMessage; @@ -9,13 +19,6 @@ import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.message.WxCpMessageHandler; import me.chanjar.weixin.cp.message.WxCpMessageRouter; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHandler; -import org.eclipse.jetty.servlet.ServletHolder; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; public class WxCpDemoServer { @@ -78,9 +81,26 @@ public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, }; wxCpMessageRouter = new WxCpMessageRouter(wxCpService); - wxCpMessageRouter.rule().async(false).content("哈哈") // 拦截内容为“哈哈”的消息 - .handler(handler).end().rule().async(false).content("oauth") - .handler(oauth2handler).end(); + wxCpMessageRouter.rule() + .async(false) + .content("哈哈") // 拦截内容为“哈哈”的消息 + .handler(handler) + .end() + .rule() + .async(false) + .content("oauth") + .handler(oauth2handler) + .end() + .rule() + .event(WxCpConsts.EventType.CHANGE_CONTACT) + .handler(new WxCpMessageHandler() { + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService wxCpService, WxSessionManager sessionManager) throws WxErrorException { + System.out.println("通讯录发生变更"); + return null; + } + }) + .end(); } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java index 37c2b7a12f..d652884b64 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.cp.demo; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpService; import javax.servlet.http.HttpServlet; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapterTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapterTest.java new file mode 100644 index 0000000000..ec553f7521 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapterTest.java @@ -0,0 +1,124 @@ +package me.chanjar.weixin.cp.util.json; + +import org.testng.annotations.*; + +import me.chanjar.weixin.cp.bean.WxCpUser; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
+ *
+ * Created by Binary Wang on 2018/9/16.
+ * 
+ * + * @author BinaryWang + */ +public class WxCpUserGsonAdapterTest { + + @Test + public void testDeserialize() { + final String userJson = "{\n" + + " \"errcode\": 0,\n" + + " \"errmsg\": \"ok\",\n" + + " \"userid\": \"zhangsan\",\n" + + " \"name\": \"李四\",\n" + + " \"department\": [1, 2],\n" + + " \"order\": [1, 2],\n" + + " \"position\": \"后台工程师\",\n" + + " \"mobile\": \"15913215421\",\n" + + " \"gender\": \"1\",\n" + + " \"email\": \"zhangsan@gzdev.com\",\n" + + " \"isleader\": 1,\n" + + " \"avatar\": \"http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0\",\n" + + " \"telephone\": \"020-123456\",\n" + + " \"enable\": 1,\n" + + " \"alias\": \"jackzhang\",\n" + + " \"extattr\": {\n" + + " \"attrs\": [{\n" + + " \"name\": \"爱好\",\n" + + " \"value\": \"旅游\"\n" + + " }, {\n" + + " \"name\": \"卡号\",\n" + + " \"value\": \"1234567234\"\n" + + " }]\n" + + " },\n" + + " \"status\": 1,\n" + + " \"qr_code\": \"https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=xxx\",\n" + + " \"external_profile\": {\n" + + " \"external_attr\": [{\n" + + " \"type\": 0,\n" + + " \"name\": \"文本名称\",\n" + + " \"text\": {\n" + + " \"value\": \"文本\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"type\": 1,\n" + + " \"name\": \"网页名称\",\n" + + " \"web\": {\n" + + " \"url\": \"http://www.test.com\",\n" + + " \"title\": \"标题\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"type\": 2,\n" + + " \"name\": \"测试app\",\n" + + " \"miniprogram\": {\n" + + " \"appid\": \"wx8bd80126147df384\",\n" + + " \"pagepath\": \"/index\",\n" + + " \"title\": \"my miniprogram\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + + final WxCpUser user = WxCpUser.fromJson(userJson); + assertThat(user).isNotNull(); + assertThat(user.getExternalAttrs()).isNotEmpty(); + + final WxCpUser.ExternalAttribute externalAttr1 = user.getExternalAttrs().get(0); + assertThat(externalAttr1.getType()).isEqualTo(0); + assertThat(externalAttr1.getName()).isEqualTo("文本名称"); + assertThat(externalAttr1.getValue()).isEqualTo("文本"); + + final WxCpUser.ExternalAttribute externalAttr2 = user.getExternalAttrs().get(1); + assertThat(externalAttr2.getType()).isEqualTo(1); + assertThat(externalAttr2.getName()).isEqualTo("网页名称"); + assertThat(externalAttr2.getUrl()).isEqualTo("http://www.test.com"); + assertThat(externalAttr2.getTitle()).isEqualTo("标题"); + + final WxCpUser.ExternalAttribute externalAttr3 = user.getExternalAttrs().get(2); + assertThat(externalAttr3.getType()).isEqualTo(2); + assertThat(externalAttr3.getName()).isEqualTo("测试app"); + assertThat(externalAttr3.getAppid()).isEqualTo("wx8bd80126147df384"); + assertThat(externalAttr3.getPagePath()).isEqualTo("/index"); + assertThat(externalAttr3.getTitle()).isEqualTo("my miniprogram"); + } + + @Test + public void testSerialize() { + WxCpUser user = new WxCpUser(); + user.addExternalAttr(WxCpUser.ExternalAttribute.builder() + .type(0) + .name("文本名称") + .value("文本") + .build()); + user.addExternalAttr(WxCpUser.ExternalAttribute.builder() + .type(1) + .name("网页名称") + .url("http://www.test.com") + .title("标题") + .build()); + user.addExternalAttr(WxCpUser.ExternalAttribute.builder() + .type(2) + .name("测试app") + .appid("wx8bd80126147df384") + .pagePath("/index") + .title("my miniprogram") + .build()); + + assertThat(user.toJson()).isEqualTo("{\"external_profile\":{\"external_attr\":[{\"type\":0,\"name\":\"文本名称\",\"text\":{\"value\":\"文本\"}},{\"type\":1,\"name\":\"网页名称\",\"web\":{\"url\":\"http://www.test.com\",\"title\":\"标题\"}},{\"type\":2,\"name\":\"测试app\",\"miniprogram\":{\"appid\":\"wx8bd80126147df384\",\"pagepath\":\"/index\",\"title\":\"my miniprogram\"}}]}}"); + } +} diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 3a2614aa59..456147618b 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,10 +7,10 @@ com.github.binarywang weixin-java-parent - 2.8.0 + 3.2.0 weixin-java-miniapp - WeiXin Java Tools - MiniApp + Weixin Java Tools - MiniApp 微信小程序Java SDK @@ -61,10 +61,19 @@ joda-time test + + org.assertj + assertj-guava + test + redis.clients jedis + + org.projectlombok + lombok + diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaAnalysisService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaAnalysisService.java new file mode 100644 index 0000000000..e8273bc402 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaAnalysisService.java @@ -0,0 +1,145 @@ +package cn.binarywang.wx.miniapp.api; + +import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaSummaryTrend; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaUserPortrait; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitDistribution; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitPage; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitTrend; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.Date; +import java.util.List; + +/** + * 小程序数据分析相关接口 + * 文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/analysis.html + * + * @author Charming + * @since 2018-04-28 + */ +public interface WxMaAnalysisService { + String GET_DAILY_SUMMARY_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend"; + String GET_DAILY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend"; + String GET_WEEKLY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyvisittrend"; + String GET_MONTHLY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend"; + String GET_VISIT_DISTRIBUTION_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution"; + String GET_DAILY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo"; + String GET_WEEKLY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo"; + String GET_MONTHLY_RETAIN_INFO_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo"; + String GET_VISIT_PAGE_URL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage"; + String GET_USER_PORTRAIT_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait"; + + /** + * 查询概况趋势 + * 温馨提示:小程序接口目前只能查询一天的数据,即 beginDate 和 endDate 一样 + * + * @param beginDate 开始日期 + * @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 + * @return 概况趋势 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + List getDailySummaryTrend(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 获取日访问趋势 + * 温馨提示:小程序接口目前只能查询一天的数据,即 beginDate 和 endDate 一样 + * + * @param beginDate 开始日期 + * @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 + * @return 日访问趋势 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + List getDailyVisitTrend(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 获取周访问趋势 + * 限定查询一个自然周的数据,时间必须按照自然周的方式输入: 如:20170306(周一), 20170312(周日) + * + * @param beginDate 开始日期,为周一日期 + * @param endDate 结束日期,为周日日期,限定查询一周数据 + * @return 周访问趋势(每项数据都是一个自然周汇总) + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + List getWeeklyVisitTrend(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 获取月访问趋势 + * 限定查询一个自然月的数据,时间必须按照自然月的方式输入: 如:20170201(月初), 20170228(月末) + * + * @param beginDate 开始日期,为自然月第一天 + * @param endDate 结束日期,为自然月最后一天,限定查询一个月数据 + * @return 月访问趋势(每项数据都是一个自然月汇总) + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + List getMonthlyVisitTrend(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 获取访问分布 + * (此接口目前只能查询一天的数据,即 beginDate 和 endDate 一样) + * + * @param beginDate 开始日期,为周一日期 + * @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 + * @return 访问分布 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + WxMaVisitDistribution getVisitDistribution(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 日留存 + * (此接口目前只能查询一天的数据,即 beginDate 和 endDate 一样) + * + * @param beginDate 开始日期,为周一日期 + * @param endDate 结束日期,限定查询 1 天数据,endDate 允许设置的最大值为昨日 + * @return 日留存 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + WxMaRetainInfo getDailyRetainInfo(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 周留存 + * 限定查询一个自然周的数据,时间必须按照自然周的方式输入: 如:20170306(周一), 20170312(周日) + * + * @param beginDate 开始日期,为周一日期 + * @param endDate 结束日期,为周日日期,限定查询一周数据 + * @return 周留存 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + WxMaRetainInfo getWeeklyRetainInfo(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 月留存 + * 限定查询一个自然月的数据,时间必须按照自然月的方式输入: 如:20170201(月初), 20170228(月末) + * + * @param beginDate 开始日期,为自然月第一天 + * @param endDate 结束日期,为自然月最后一天,限定查询一个月数据 + * @return 月留存 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + WxMaRetainInfo getMonthlyRetainInfo(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 获取访问页面数据 + * 温馨提示:此接口目前只能查询一天的数据,即 beginDate 和 endDate 一样 + * + * @param beginDate 开始日期 + * @param endDate 结束日期,限定查询1天数据,end_date允许设置的最大值为昨日 + * @return 访问页面数据 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + List getVisitPage(Date beginDate, Date endDate) throws WxErrorException; + + /** + * 获取小程序新增或活跃用户的画像分布数据 + * 时间范围支持昨天、最近7天、最近30天。 + * 其中,新增用户数为时间范围内首次访问小程序的去重用户数, + * 活跃用户数为时间范围内访问过小程序的去重用户数。 + * 画像属性包括用户年龄、性别、省份、城市、终端类型、机型。 + * + * @param beginDate 开始日期 + * @param endDate 结束日期,开始日期与结束日期相差的天数限定为0/6/29,分别表示查询最近1/7/30天数据,end_date允许设置的最大值为昨日 + * @return 小程序新增或活跃用户的画像分布数据 + * @throws WxErrorException 获取失败时抛出,具体错误码请看文档 + */ + WxMaUserPortrait getUserPortrait(Date beginDate, Date endDate) throws WxErrorException; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCodeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCodeService.java new file mode 100644 index 0000000000..fbe0818493 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCodeService.java @@ -0,0 +1,144 @@ +package cn.binarywang.wx.miniapp.api; + +import java.util.List; + +import cn.binarywang.wx.miniapp.bean.code.WxMaCategory; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeAuditStatus; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeSubmitAuditRequest; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution; +import me.chanjar.weixin.common.error.WxErrorException; + +/** + * 小程序代码管理相关 API(大部分只能是第三方平台调用) + * 文档:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140610_Uavc4&token=&lang=zh_CN + * + * @author Charming + * @since 2018-04-26 19:43 + */ +public interface WxMaCodeService { + /** + * 为授权的小程序帐号上传小程序代码 + */ + String COMMIT_URL = "https://api.weixin.qq.com/wxa/commit"; + String GET_QRCODE_URL = "https://api.weixin.qq.com/wxa/get_qrcode"; + String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxa/get_category"; + String GET_PAGE_URL = "https://api.weixin.qq.com/wxa/get_page"; + String SUBMIT_AUDIT_URL = "https://api.weixin.qq.com/wxa/submit_audit"; + String GET_AUDIT_STATUS_URL = "https://api.weixin.qq.com/wxa/get_auditstatus"; + String GET_LATEST_AUDIT_STATUS_URL = "https://api.weixin.qq.com/wxa/get_latest_auditstatus"; + String RELEASE_URL = "https://api.weixin.qq.com/wxa/release"; + String CHANGE_VISIT_STATUS_URL = "https://api.weixin.qq.com/wxa/change_visitstatus"; + String REVERT_CODE_RELEASE_URL = "https://api.weixin.qq.com/wxa/revertcoderelease"; + String GET_SUPPORT_VERSION_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/getweappsupportversion"; + String SET_SUPPORT_VERSION_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/setweappsupportversion"; + String UNDO_CODE_AUDIT_URL = "https://api.weixin.qq.com/wxa/undocodeaudit"; + + /** + * 为授权的小程序帐号上传小程序代码(仅仅支持第三方开放平台) + * + * @param commitRequest 参数 + * @throws WxErrorException 上传失败时抛出,具体错误码请看类注释文档 + */ + void commit(WxMaCodeCommitRequest commitRequest) throws WxErrorException; + + /** + * 获取体验小程序的体验二维码 + * 文档地址: + * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140610_Uavc4&token=&lang=zh_CN + * + * @param path 指定体验版二维码跳转到某个具体页面(如果不需要的话,则不需要填path参数,可在路径后以“?参数”方式传入参数) + * 具体的路径加参数需要urlencode(方法内部处理),比如page/index?action=1编码后得到page%2Findex%3Faction%3D1 + * @return 二维码 bytes + * @throws WxErrorException 上传失败时抛出,具体错误码请看类注释文档 + */ + byte[] getQrCode(String path) throws WxErrorException; + + /** + * 获取授权小程序帐号的可选类目 + * + * @return List + * @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档 + */ + List getCategory() throws WxErrorException; + + /** + * 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) + * + * @return page_list 页面配置列表 + * @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档 + */ + List getPage() throws WxErrorException; + + /** + * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) + * + * @param auditRequest 提交审核参数 + * @return 审核编号 + * @throws WxErrorException 提交失败时返回,具体错误码请看此接口的注释文档 + */ + long submitAudit(WxMaCodeSubmitAuditRequest auditRequest) throws WxErrorException; + + /** + * 查询某个指定版本的审核状态(仅供第三方代小程序调用) + * + * @param auditId 提交审核时获得的审核id + * @return 审核状态 + * @throws WxErrorException 查询失败时返回,具体错误码请看此接口的注释文档 + */ + WxMaCodeAuditStatus getAuditStatus(long auditId) throws WxErrorException; + + /** + * 查询最新一次提交的审核状态(仅供第三方代小程序调用) + * + * @return 审核状态 + * @throws WxErrorException 查询失败时返回,具体错误码请看此接口的注释文档 + */ + WxMaCodeAuditStatus getLatestAuditStatus() throws WxErrorException; + + /** + * 发布已通过审核的小程序(仅供第三方代小程序调用) + * + * @throws WxErrorException 发布失败时抛出,具体错误码请看此接口的注释文档 + */ + void release() throws WxErrorException; + + /** + * 修改小程序线上代码的可见状态(仅供第三方代小程序调用) + * + * @param action 设置可访问状态,发布后默认可访问,close为不可见,open为可见 + * @throws WxErrorException 发布失败时抛出,具体错误码请看此接口的注释文档 + */ + void changeVisitStatus(String action) throws WxErrorException; + + /** + * 小程序版本回退(仅供第三方代小程序调用) + * + * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 + */ + void revertCodeRelease() throws WxErrorException; + + /** + * 查询当前设置的最低基础库版本及各版本用户占比 (仅供第三方代小程序调用) + * + * @return 小程序版本分布信息 + * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 + */ + WxMaCodeVersionDistribution getSupportVersion() throws WxErrorException; + + /** + * 设置最低基础库版本(仅供第三方代小程序调用) + * + * @param version 版本 + * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 + */ + void setSupportVersion(String version) throws WxErrorException; + + /** + * 小程序审核撤回 + * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次 + * + * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档 + */ + void undoCodeAudit() throws WxErrorException; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaJsapiService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaJsapiService.java new file mode 100644 index 0000000000..156fcbc1ce --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaJsapiService.java @@ -0,0 +1,48 @@ +package cn.binarywang.wx.miniapp.api; + +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; + +/** + *
+ *  jsapi相关接口
+ *  Created by BinaryWang on 2018/8/5.
+ * 
+ * + * @author Binary Wang + */ +public interface WxMaJsapiService { + /** + * 获得jsapi_ticket的url + */ + String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi"; + + /** + * 获得jsapi_ticket,不强制刷新jsapi_ticket + * + * @see #getJsapiTicket(boolean) + */ + String getJsapiTicket() throws WxErrorException; + + /** + *
+   * 获得jsapi_ticket
+   * 获得时会检查jsapiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
+   * 
+ * + * @param forceRefresh 强制刷新 + */ + String getJsapiTicket(boolean forceRefresh) throws WxErrorException; + + /** + *
+   * 创建调用jsapi时所需要的签名
+   *
+   * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN
+   * 
+ */ + WxJsapiSignature createJsapiSignature(String url) throws WxErrorException; + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMediaService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMediaService.java index 09c8aa5b9d..d2c57ca5e4 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMediaService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMediaService.java @@ -1,7 +1,7 @@ package cn.binarywang.wx.miniapp.api; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import java.io.File; import java.io.InputStream; diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java index 65522f4b75..a838417e23 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java @@ -2,7 +2,8 @@ import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import me.chanjar.weixin.common.exception.WxErrorException; +import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; +import me.chanjar.weixin.common.error.WxErrorException; /** *
@@ -14,6 +15,7 @@
 public interface WxMaMsgService {
   String KEFU_MESSAGE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
   String TEMPLATE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send";
+  String UNIFORM_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send";
 
   /**
    * 
@@ -32,4 +34,14 @@ public interface WxMaMsgService {
    * 
*/ void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; + + + /** + *
+   * 下发小程序和公众号统一的服务消息
+   * 详情请见: 下发小程序和公众号统一的服务消息
+   * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
+   * 
+ */ + void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException; } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaQrcodeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaQrcodeService.java index c2222bc93e..2903737486 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaQrcodeService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaQrcodeService.java @@ -1,14 +1,15 @@ package cn.binarywang.wx.miniapp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; +import me.chanjar.weixin.common.error.WxErrorException; import java.io.File; /** *
- * 二维码相关操作接口
+ * 二维码相关操作接口.
  *
- * 接口A(createWxCode)加上接口C(createQrcode),总共生成的码数量限制为100,000,请谨慎调用。
+ * 接口A(createWxaCode)加上接口C(createQrcode),总共生成的码数量限制为100,000,请谨慎调用。
  *
  * 文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
  * 
@@ -16,11 +17,13 @@ * @author Binary Wang */ public interface WxMaQrcodeService { + String CREATE_QRCODE_URL = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode"; + String GET_WXACODE_URL = "https://api.weixin.qq.com/wxa/getwxacode"; + String GET_WXACODE_UNLIMIT_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit"; /** - * 接口C + * 接口C: 获取小程序页面二维码. *
-   * 获取小程序页面二维码
    * 适用于需要的码数量较少的业务场景
    * 通过该接口,仅能生成已发布的小程序的二维码。
    * 可以在开发者工具预览时生成开发版的带参二维码。
@@ -35,79 +38,38 @@ public interface WxMaQrcodeService {
   File createQrcode(String path) throws WxErrorException;
 
   /**
-   * 接口A
-   * 获取小程序码
+   * 接口A: 获取小程序码.
    *
-   * @param path      不能为空,最大长度 128 字节
-   * @param width     默认430 二维码的宽度
-   * @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
-   * @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"}
-   * @return
-   * @throws WxErrorException
+   * @param path       不能为空,最大长度 128 字节
+   * @param width      默认430 二维码的宽度
+   * @param autoColor  默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
+   * @param lineColor  auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"}
+   * @param is_hyaline 是否需要透明底色, is_hyaline 为true时,生成透明底色的小程序码
    */
-  File createWxCode(String path, int width, boolean autoColor, LineColor lineColor) throws WxErrorException;
+  File createWxaCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean is_hyaline) throws WxErrorException;
 
-  File createWxCode(String path, int width) throws WxErrorException;
+  File createWxaCode(String path, int width) throws WxErrorException;
 
-  File createWxCode(String path) throws WxErrorException;
+  File createWxaCode(String path) throws WxErrorException;
 
   /**
-   * 接口B
-   * 获取小程序码(永久有效、数量暂无限制)
-   * 

+ * 接口B: 获取小程序码(永久有效、数量暂无限制). + *

    * 通过该接口生成的小程序码,永久有效,数量暂无限制。
    * 用户扫描该码进入小程序后,将统一打开首页,开发者需在对应页面根据获取的码中 scene 字段的值,再做处理逻辑。
    * 使用如下代码可以获取到二维码中的 scene 字段的值。
    * 调试阶段可以使用开发工具的条件编译自定义参数 scene=xxxx 进行模拟,开发工具模拟时的 scene 的参数值需要进行 urlencode
+   * 
* * @param scene 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式) * @param page 必须是已经发布的小程序页面,例如 "pages/index/index" ,如果不填写这个字段,默认跳主页面 * @param width 默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 * @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 * @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} - * @return - * @throws WxErrorException - */ - File createWxCodeLimit(String scene, String page, int width, boolean autoColor, LineColor lineColor) throws WxErrorException; - - File createWxCodeLimit(String scene, String page) throws WxErrorException; - - /** - * lineColor 包装类 - * 用于描述二维码(小程序码)颜色(RGB参数值),详情请查看文档 + * @param isHyaline 是否需要透明底色, is_hyaline 为true时,生成透明底色的小程序码 */ - public static class LineColor { - - private String r = "0", g = "0", b = "0"; - - public LineColor(String r, String g, String b) { - this.r = r; - this.g = g; - this.b = b; - } - - public String getR() { - return r; - } - - public void setR(String r) { - this.r = r; - } - - public String getG() { - return g; - } - - public void setG(String g) { - this.g = g; - } + File createWxaCodeUnlimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException; - public String getB() { - return b; - } + File createWxaCodeUnlimit(String scene, String page) throws WxErrorException; - public void setB(String b) { - this.b = b; - } - } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java index 9098d4ac48..0904d606c1 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java @@ -1,7 +1,10 @@ package cn.binarywang.wx.miniapp.api; +import java.io.File; + +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.config.WxMaConfig; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; @@ -11,20 +14,40 @@ */ public interface WxMaService { /** - * 获取access_token + * 获取access_token. */ String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; + String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session"; + + String IMG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/img_sec_check"; + + /** + *
+   * 校验一张图片是否含有违法违规内容.
+   * 应用场景举例:1)图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等;2)敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。频率限制:单个 appId 调用上限为 1000 次/分钟,100,000 次/天
+   * 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/imgSecCheck.html
+   * 
+ */ + boolean imgSecCheck(File file) throws WxErrorException; + + /** + * 获取登录后的session信息. + * + * @param jsCode 登录时获取的 code + */ + WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException; + /** *
-   * 验证消息的确来自微信服务器
+   * 验证消息的确来自微信服务器.
    * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319&token=&lang=zh_CN
    * 
*/ boolean checkSignature(String timestamp, String nonce, String signature); /** - * 获取access_token, 不强制刷新access_token + * 获取access_token, 不强制刷新access_token. * * @see #getAccessToken(boolean) */ @@ -32,7 +55,7 @@ public interface WxMaService { /** *
-   * 获取access_token,本方法线程安全
+   * 获取access_token,本方法线程安全.
    * 且在多线程同时刷新时只刷新一次,避免超出2000次/日的调用次数上限
    *
    * 另:本service的所有方法都会在access_token过期是调用此方法
@@ -47,12 +70,12 @@ public interface WxMaService {
   String getAccessToken(boolean forceRefresh) throws WxErrorException;
 
   /**
-   * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求
+   * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求.
    */
   String get(String url, String queryParam) throws WxErrorException;
 
   /**
-   * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求
+   * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求.
    */
   String post(String url, String postData) throws WxErrorException;
 
@@ -67,7 +90,7 @@ public interface WxMaService {
 
   /**
    * 
-   * 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试
+   * 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试.
    * 默认:1000ms
    * 
*/ @@ -75,59 +98,94 @@ public interface WxMaService { /** *
-   * 设置当微信系统响应系统繁忙时,最大重试次数
+   * 设置当微信系统响应系统繁忙时,最大重试次数.
    * 默认:5次
    * 
*/ void setMaxRetryTimes(int maxRetryTimes); /** - * 获取WxMaConfig 对象 + * 获取WxMaConfig 对象. * * @return WxMaConfig */ WxMaConfig getWxMaConfig(); /** - * 注入 {@link WxMaConfig} 的实现 + * 注入 {@link WxMaConfig} 的实现. */ void setWxMaConfig(WxMaConfig wxConfigProvider); /** - * 返回消息(客服消息和模版消息)发送接口方法实现类,以方便调用其各个接口 + * 返回消息(客服消息和模版消息)发送接口方法实现类,以方便调用其各个接口. * * @return WxMaMsgService */ WxMaMsgService getMsgService(); /** - * 返回素材相关接口方法的实现类对象,以方便调用其各个接口 + * 返回素材相关接口方法的实现类对象,以方便调用其各个接口. * * @return WxMaMediaService */ WxMaMediaService getMediaService(); /** - * 返回用户相关接口方法的实现类对象,以方便调用其各个接口 + * 返回用户相关接口方法的实现类对象,以方便调用其各个接口. * * @return WxMaUserService */ WxMaUserService getUserService(); /** - * 返回二维码相关接口方法的实现类对象,以方便调用其各个接口 + * 返回二维码相关接口方法的实现类对象,以方便调用其各个接口. * * @return WxMaQrcodeService */ WxMaQrcodeService getQrcodeService(); /** - * 初始化http请求对象 + * 返回模板配置相关接口方法的实现类对象, 以方便调用其各个接口. + * + * @return WxMaTemplateService + */ + WxMaTemplateService getTemplateService(); + + /** + * 数据分析相关查询服务 + * + * @return WxMaAnalysisService + */ + WxMaAnalysisService getAnalysisService(); + + /** + * 返回代码操作相关的 API + * + * @return WxMaCodeService + */ + WxMaCodeService getCodeService(); + + /** + * 返回jsapi操作相关的 API服务类对象 + * + * @return WxMaJsapiService + */ + WxMaJsapiService getJsapiService(); + + /** + * 小程序修改服务器地址、成员管理 API + * + * @return WxMaSettingService + */ + WxMaSettingService getSettingService(); + + /** + * 初始化http请求对象. */ void initHttp(); /** - * 请求http请求相关信息 + * 请求http请求相关信息. */ RequestHttp getRequestHttp(); diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSettingService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSettingService.java new file mode 100644 index 0000000000..8cc7934988 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSettingService.java @@ -0,0 +1,65 @@ +package cn.binarywang.wx.miniapp.api; + +import cn.binarywang.wx.miniapp.bean.WxMaDomainAction; +import me.chanjar.weixin.common.error.WxErrorException; + +/** + * 小程序修改服务器地址、成员管理 API(大部分只能是第三方平台调用) + * + * @author Charming + * @since 2018-04-27 15:46 + */ +public interface WxMaSettingService { + /** + * 修改服务器地址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489138143_WPbOO&token=&lang=zh_CN + * access_token 为 authorizer_access_token + */ + String MODIFY_DOMAIN_URL = "https://api.weixin.qq.com/wxa/modify_domain"; + String SET_WEB_VIEW_DOMAIN_URL = "https://api.weixin.qq.com/wxa/setwebviewdomain"; + /** + * 小程序成员管理:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140588_nVUgx&token=&lang=zh_CN + * access_token 为 authorizer_access_token + */ + String BIND_TESTER_URL = "https://api.weixin.qq.com/wxa/bind_tester"; + String UNBIND_TESTER_URL = "https://api.weixin.qq.com/wxa/unbind_tester"; + + /** + * 操作服务器域名 + * + * @param domainAction 域名操作参数 + * 除了 webViewDomain,都是有效的 + * @return 以下字段仅在 get 时返回完整字段 + * @throws WxErrorException 操作失败时抛出,具体错误码请看文档 + */ + WxMaDomainAction modifyDomain(WxMaDomainAction domainAction) throws WxErrorException; + + /** + * 设置小程序业务域名(仅供第三方代小程序调用) + * 授权给第三方的小程序,其业务域名只可以为第三方的服务器, + * 当小程序通过第三方发布代码上线后,小程序原先自己配置的业务域名将被删除, + * 只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加业务域名。 + * 提示:需要先将域名登记到第三方平台的小程序业务域名中,才可以调用接口进行配置。 + * + * @param domainAction 域名操作参数 + * 只有 action 和 webViewDomain 是有效的 + * @return 以下字段仅在 get 时返回完整字段 + * @throws WxErrorException 操作失败时抛出,具体错误码请看文档 + */ + WxMaDomainAction setWebViewDomain(WxMaDomainAction domainAction) throws WxErrorException; + + /** + * 绑定微信用户为小程序体验者 + * + * @param wechatId 微信号 + * @throws WxErrorException 失败时抛出,具体错误码请看文档 + */ + void bindTester(String wechatId) throws WxErrorException; + + /** + * 解除绑定小程序的体验者 + * + * @param wechatId 微信号 + * @throws WxErrorException 失败时抛出,具体错误码请看文档 + */ + void unbindTester(String wechatId) throws WxErrorException; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java new file mode 100644 index 0000000000..1dbf052695 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java @@ -0,0 +1,89 @@ +package cn.binarywang.wx.miniapp.api; + +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.List; + +public interface WxMaTemplateService { + + //获取小程序模板库标题列表 + String TEMPLATE_LIBRARY_LIST_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/library/list"; + + //获取模板库某个模板标题下关键词库 + String TEMPLATE_LIBRARY_KEYWORD_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/library/get"; + + //组合模板并添加至帐号下的个人模板库 + String TEMPLATE_ADD_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/add"; + + //获取帐号下已存在的模板列表 + String TEMPLATE_LIST_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/list"; + + //删除帐号下的某个模板 + String TEMPLATE_DEL_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/del"; + + /** + *
+   * 获取小程序模板库标题列表
+   *
+   * 详情请见: 获取小程序模板库标题列表
+   * 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/library/list?access_token=ACCESS_TOKEN
+   * 
+ * @param offset + * @param count + * @return + */ + WxMaTemplateLibraryListResult findTemplateLibraryList(int offset, int count) throws WxErrorException; + + /** + *
+   * 获取模板库某个模板标题下关键词库
+   *
+   * 详情请见: 获取小程序模板库标题列表
+   * 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/library/get?access_token=ACCESS_TOKEN
+   * 
+ * @param id + * @return + */ + WxMaTemplateLibraryGetResult findTemplateLibraryKeywordList(String id) throws WxErrorException; + + /** + *
+   * 组合模板并添加至帐号下的个人模板库
+   *
+   * 详情请见: 获取小程序模板库标题列表
+   * 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/add?access_token=ACCESS_TOKEN
+   * 
+ * @param id + * @param keywordIdList + * @return + */ + WxMaTemplateAddResult addTemplate(String id, List keywordIdList) throws WxErrorException; + + /** + *
+   * 获取帐号下已存在的模板列表
+   *
+   * 详情请见: 获取小程序模板库标题列表
+   * 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/list?access_token=ACCESS_TOKEN
+   * 
+ * @param offset + * @param count + * @return + */ + WxMaTemplateListResult findTemplateList(int offset, int count) throws WxErrorException; + + /** + *
+   * 删除帐号下的某个模板
+   *
+   * 详情请见: 获取小程序模板库标题列表
+   * 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/list?access_token=ACCESS_TOKEN
+   * 
+ * @param templateId + */ + boolean delTemplate(String templateId) throws WxErrorException; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java index 84b17378ca..a4abdc04d4 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaUserService.java @@ -1,26 +1,28 @@ package cn.binarywang.wx.miniapp.api; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.Map; /** - * 用户信息相关操作接口 + * 用户信息相关操作接口. * * @author Binary Wang */ public interface WxMaUserService { - String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session"; /** - * 获取登录后的session信息 + * 获取登录后的session信息. * * @param jsCode 登录时获取的 code */ WxMaJscode2SessionResult getSessionInfo(String jsCode) throws WxErrorException; /** - * 解密用户敏感数据 + * 解密用户敏感数据. * * @param sessionKey 会话密钥 * @param encryptedData 消息密文 @@ -29,7 +31,26 @@ public interface WxMaUserService { WxMaUserInfo getUserInfo(String sessionKey, String encryptedData, String ivStr); /** - * 验证用户信息完整性 + * 上报用户数据后台接口. + *

小游戏可以通过本接口上报key-value数据到用户的CloudStorage。

+ * 文档参考https://developers.weixin.qq.com/minigame/dev/document/open-api/data/setUserStorage.html + * @param kvMap 要上报的数据 + * @param sessionKey 通过wx.login 获得的登录态 + * @param openid + */ + void setUserStorage(Map kvMap, String sessionKey, String openid) throws WxErrorException; + + /** + * 解密用户手机号信息. + * + * @param sessionKey 会话密钥 + * @param encryptedData 消息密文 + * @param ivStr 加密算法的初始向量 + */ + WxMaPhoneNumberInfo getPhoneNoInfo(String sessionKey, String encryptedData, String ivStr); + + /** + * 验证用户信息完整性. * * @param sessionKey 会话密钥 * @param rawData 微信用户基本信息 diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaAnalysisServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaAnalysisServiceImpl.java new file mode 100644 index 0000000000..dc7fe42437 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaAnalysisServiceImpl.java @@ -0,0 +1,126 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaSummaryTrend; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaUserPortrait; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitDistribution; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitPage; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitTrend; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.error.WxErrorException; +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.reflect.Type; +import java.util.Date; +import java.util.List; + +/** + * @author Charming + * @since 2018-04-28 + */ +public class WxMaAnalysisServiceImpl implements WxMaAnalysisService { + private static final JsonParser JSON_PARSER = new JsonParser(); + private WxMaService wxMaService; + + public WxMaAnalysisServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public List getDailySummaryTrend(Date beginDate, Date endDate) throws WxErrorException { + return getAnalysisResultAsList(GET_DAILY_SUMMARY_TREND_URL, beginDate, endDate, + new TypeToken>() { + }.getType()); + } + + @Override + public List getDailyVisitTrend(Date beginDate, Date endDate) throws WxErrorException { + return getAnalysisResultAsList(GET_DAILY_VISIT_TREND_URL, beginDate, endDate, + new TypeToken>() { + }.getType()); + } + + @Override + public List getWeeklyVisitTrend(Date beginDate, Date endDate) throws WxErrorException { + return getAnalysisResultAsList(GET_WEEKLY_VISIT_TREND_URL, beginDate, endDate, + new TypeToken>() { + }.getType()); + } + + @Override + public List getMonthlyVisitTrend(Date beginDate, Date endDate) throws WxErrorException { + return getAnalysisResultAsList(GET_MONTHLY_VISIT_TREND_URL, beginDate, endDate, + new TypeToken>() { + }.getType()); + } + + @Override + public WxMaVisitDistribution getVisitDistribution(Date beginDate, Date endDate) throws WxErrorException { + String responseContent = this.wxMaService.post(GET_VISIT_DISTRIBUTION_URL, toJson(beginDate, endDate)); + return WxMaVisitDistribution.fromJson(responseContent); + } + + @Override + public WxMaRetainInfo getDailyRetainInfo(Date beginDate, Date endDate) throws WxErrorException { + return getRetainInfo(beginDate, endDate, GET_DAILY_RETAIN_INFO_URL); + } + + @Override + public WxMaRetainInfo getWeeklyRetainInfo(Date beginDate, Date endDate) throws WxErrorException { + return getRetainInfo(beginDate, endDate, GET_WEEKLY_RETAIN_INFO_URL); + } + + @Override + public WxMaRetainInfo getMonthlyRetainInfo(Date beginDate, Date endDate) throws WxErrorException { + return getRetainInfo(beginDate, endDate, GET_MONTHLY_RETAIN_INFO_URL); + } + + @Override + public List getVisitPage(Date beginDate, Date endDate) throws WxErrorException { + return getAnalysisResultAsList(GET_VISIT_PAGE_URL, beginDate, endDate, + new TypeToken>() { + }.getType()); + } + + @Override + public WxMaUserPortrait getUserPortrait(Date beginDate, Date endDate) throws WxErrorException { + String responseContent = this.wxMaService.post(GET_USER_PORTRAIT_URL, toJson(beginDate, endDate)); + return WxMaUserPortrait.fromJson(responseContent); + } + + private WxMaRetainInfo getRetainInfo(Date beginDate, Date endDate, String url) throws WxErrorException { + String responseContent = this.wxMaService.post(url, toJson(beginDate, endDate)); + return WxMaRetainInfo.fromJson(responseContent); + } + + /** + * 获取数据分析结果并返回 List,returnType 类型 + * + * @param url 链接 + * @param returnType 返回的类型 + * @param 返回的类型 + * @return List 类型的数据 + */ + private List getAnalysisResultAsList(String url, Date beginDate, Date endDate, Type returnType) throws WxErrorException { + String responseContent = this.wxMaService.post(url, toJson(beginDate, endDate)); + JsonObject response = JSON_PARSER.parse(responseContent).getAsJsonObject(); + boolean hasList = response.has("list"); + if (hasList) { + return WxMaGsonBuilder.create().fromJson(response.getAsJsonArray("list"), returnType); + } else { + return null; + } + } + + private static String toJson(Date beginDate, Date endDate) { + JsonObject param = new JsonObject(); + param.addProperty("begin_date", DateFormatUtils.format(beginDate, "yyyyMMdd")); + param.addProperty("end_date", DateFormatUtils.format(endDate, "yyyyMMdd")); + return param.toString(); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCodeServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCodeServiceImpl.java new file mode 100644 index 0000000000..a460f4a314 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCodeServiceImpl.java @@ -0,0 +1,158 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import java.io.File; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import cn.binarywang.wx.miniapp.api.WxMaCodeService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.code.WxMaCategory; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeAuditStatus; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeSubmitAuditRequest; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.json.GsonHelper; + +/** + * @author Charming + * @since 2018-04-26 20:00 + */ +public class WxMaCodeServiceImpl implements WxMaCodeService { + private static final JsonParser JSON_PARSER = new JsonParser(); + private WxMaService wxMaService; + + public WxMaCodeServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public void commit(WxMaCodeCommitRequest commitRequest) throws WxErrorException { + this.wxMaService.post(COMMIT_URL, commitRequest.toJson()); + } + + @Override + public byte[] getQrCode(String path) throws WxErrorException { + String appId = this.wxMaService.getWxMaConfig().getAppid(); + Path qrCodeFilePath = null; + try { + RequestExecutor executor = BaseMediaDownloadRequestExecutor + .create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("weixin-java-tools-ma-" + appId).toFile()); + + final StringBuilder url = new StringBuilder(GET_QRCODE_URL); + if (StringUtils.isNotBlank(path)) { + url.append("?path=").append(URLEncoder.encode(path, StandardCharsets.UTF_8.name())); + } + + qrCodeFilePath = this.wxMaService.execute(executor, url.toString(), null).toPath(); + return Files.readAllBytes(qrCodeFilePath); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); + } finally { + if (qrCodeFilePath != null) { + try { + // 及时删除二维码文件,避免积压过多缓存文件 + Files.delete(qrCodeFilePath); + } catch (Exception ignored) { + } + } + } + } + + @Override + public List getCategory() throws WxErrorException { + String responseContent = this.wxMaService.get(GET_CATEGORY_URL, null); + JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + boolean hasCategoryList = jsonObject.has("category_list"); + if (hasCategoryList) { + return WxMaGsonBuilder.create().fromJson(jsonObject.getAsJsonArray("category_list"), + new TypeToken>() { + }.getType()); + } else { + return null; + } + } + + @Override + public List getPage() throws WxErrorException { + String responseContent = this.wxMaService.get(GET_PAGE_URL, null); + JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + boolean hasPageList = jsonObject.has("page_list"); + if (hasPageList) { + return WxMaGsonBuilder.create().fromJson(jsonObject.getAsJsonArray("page_list"), + new TypeToken>() { + }.getType()); + } else { + return null; + } + } + + @Override + public long submitAudit(WxMaCodeSubmitAuditRequest auditRequest) throws WxErrorException { + String responseContent = this.wxMaService.post(SUBMIT_AUDIT_URL, auditRequest.toJson()); + JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + return GsonHelper.getLong(jsonObject, "auditid"); + } + + @Override + public WxMaCodeAuditStatus getAuditStatus(long auditId) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("auditid", auditId); + String responseContent = this.wxMaService.post(GET_AUDIT_STATUS_URL, param.toString()); + return WxMaCodeAuditStatus.fromJson(responseContent); + } + + @Override + public WxMaCodeAuditStatus getLatestAuditStatus() throws WxErrorException { + String responseContent = this.wxMaService.get(GET_LATEST_AUDIT_STATUS_URL, null); + return WxMaCodeAuditStatus.fromJson(responseContent); + } + + @Override + public void release() throws WxErrorException { + this.wxMaService.post(RELEASE_URL, "{}"); + } + + @Override + public void changeVisitStatus(String action) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("action", action); + this.wxMaService.post(CHANGE_VISIT_STATUS_URL, param.toString()); + } + + @Override + public void revertCodeRelease() throws WxErrorException { + this.wxMaService.get(REVERT_CODE_RELEASE_URL, null); + } + + @Override + public WxMaCodeVersionDistribution getSupportVersion() throws WxErrorException { + String responseContent = this.wxMaService.post(GET_SUPPORT_VERSION_URL, "{}"); + return WxMaCodeVersionDistribution.fromJson(responseContent); + } + + @Override + public void setSupportVersion(String version) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("version", version); + this.wxMaService.post(SET_SUPPORT_VERSION_URL, param.toString()); + } + + @Override + public void undoCodeAudit() throws WxErrorException { + this.wxMaService.get(UNDO_CODE_AUDIT_URL, null); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java new file mode 100644 index 0000000000..8164db8bb6 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java @@ -0,0 +1,75 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaJsapiService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.RandomUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; + +import java.util.concurrent.locks.Lock; + +/** + *
+ *  Created by BinaryWang on 2018/8/5.
+ * 
+ * + * @author Binary Wang + */ +public class WxMaJsapiServiceImpl implements WxMaJsapiService { + private static final JsonParser JSON_PARSER = new JsonParser(); + + private WxMaService wxMaService; + + public WxMaJsapiServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public String getJsapiTicket() throws WxErrorException { + return getJsapiTicket(false); + } + + @Override + public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { + Lock lock = this.wxMaService.getWxMaConfig().getJsapiTicketLock(); + try { + lock.lock(); + if (forceRefresh) { + this.wxMaService.getWxMaConfig().expireJsapiTicket(); + } + + if (this.wxMaService.getWxMaConfig().isJsapiTicketExpired()) { + String responseContent = this.wxMaService.get(GET_JSAPI_TICKET_URL, null); + JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); + JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); + String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); + int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); + this.wxMaService.getWxMaConfig().updateJsapiTicket(jsapiTicket, expiresInSeconds); + } + } finally { + lock.unlock(); + } + return this.wxMaService.getWxMaConfig().getJsapiTicket(); + } + + @Override + public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { + long timestamp = System.currentTimeMillis() / 1000; + String randomStr = RandomUtils.getRandomStr(); + String jsapiTicket = getJsapiTicket(false); + String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, + "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url); + return WxJsapiSignature + .builder() + .appId(this.wxMaService.getWxMaConfig().getAppid()) + .timestamp(timestamp) + .nonceStr(randomStr) + .url(url) + .signature(signature) + .build(); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java index 66ad3c2a91..695f9578d1 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java @@ -2,15 +2,13 @@ import cn.binarywang.wx.miniapp.api.WxMaMediaService; import cn.binarywang.wx.miniapp.api.WxMaService; -import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; -import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -22,8 +20,6 @@ * @author Binary Wang */ public class WxMaMediaServiceImpl implements WxMaMediaService { - private final Logger log = LoggerFactory.getLogger(this.getClass()); - private WxMaService wxMaService; public WxMaMediaServiceImpl(WxMaService wxMaService) { @@ -35,8 +31,7 @@ public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputS try { return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); } catch (IOException e) { - e.printStackTrace(); - throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build()); + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); } } @@ -49,12 +44,11 @@ public WxMediaUploadResult uploadMedia(String mediaType, File file) throws WxErr @Override public File getMedia(String mediaId) throws WxErrorException { try { - RequestExecutor executor = MediaDownloadRequestExecutor + RequestExecutor executor = BaseMediaDownloadRequestExecutor .create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile()); return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId); } catch (IOException e) { - this.log.error(e.getMessage(), e); - throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build()); + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java index 70a4e50445..e0403a5103 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java @@ -4,10 +4,12 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; +import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; /** * @author Binary Wang @@ -30,7 +32,16 @@ public boolean sendKefuMsg(WxMaKefuMessage message) throws WxErrorException { public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); - if (jsonObject.get("errcode").getAsInt() != 0) { + if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { + throw new WxErrorException(WxError.fromJson(responseContent)); + } + } + + @Override + public void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException { + String responseContent = this.wxMaService.post(UNIFORM_MSG_SEND_URL, uniformMessage.toJson()); + JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { throw new WxErrorException(WxError.fromJson(responseContent)); } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImpl.java index fd58855b3d..277418e752 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImpl.java @@ -2,11 +2,12 @@ import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; import cn.binarywang.wx.miniapp.bean.WxMaQrcode; import cn.binarywang.wx.miniapp.bean.WxMaWxcode; -import cn.binarywang.wx.miniapp.bean.WxMaWxcodeLimit; +import cn.binarywang.wx.miniapp.bean.WxaCodeUnlimit; import cn.binarywang.wx.miniapp.util.http.QrCodeRequestExecutor; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import java.io.File; @@ -22,9 +23,8 @@ public WxMaQrcodeServiceImpl(WxMaService wxMaService) { @Override public File createQrcode(String path, int width) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode"; return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), - url, new WxMaQrcode(path, width)); + CREATE_QRCODE_URL, new WxMaQrcode(path, width)); } @Override @@ -33,43 +33,44 @@ public File createQrcode(String path) throws WxErrorException { } @Override - public File createWxCode(String path, int width, boolean autoColor, LineColor lineColor) throws WxErrorException { - String url = "https://api.weixin.qq.com/wxa/getwxacode"; + public File createWxaCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean isHyaline) throws WxErrorException { WxMaWxcode wxMaWxcode = new WxMaWxcode(); wxMaWxcode.setPath(path); wxMaWxcode.setWidth(width); wxMaWxcode.setAutoColor(autoColor); wxMaWxcode.setLineColor(lineColor); + wxMaWxcode.setHyaline(isHyaline); return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), - url, wxMaWxcode); + GET_WXACODE_URL, wxMaWxcode); } @Override - public File createWxCode(String path, int width) throws WxErrorException { - return this.createWxCode(path, width, true, null); + public File createWxaCode(String path, int width) throws WxErrorException { + return this.createWxaCode(path, width, true, null, false); } @Override - public File createWxCode(String path) throws WxErrorException { - return this.createWxCode(path, 430, true, null); + public File createWxaCode(String path) throws WxErrorException { + return this.createWxaCode(path, 430, true, null, false); } @Override - public File createWxCodeLimit(String scene, String page, int width, boolean autoColor, LineColor lineColor) throws WxErrorException { - String url = "http://api.weixin.qq.com/wxa/getwxacodeunlimit"; - WxMaWxcodeLimit wxMaWxcodeLimit = new WxMaWxcodeLimit(); - wxMaWxcodeLimit.setScene(scene); - wxMaWxcodeLimit.setPage(page); - wxMaWxcodeLimit.setWidth(width); - wxMaWxcodeLimit.setAutoColor(autoColor); - wxMaWxcodeLimit.setLineColor(lineColor); + public File createWxaCodeUnlimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor, boolean isHyaline) + throws WxErrorException { + WxaCodeUnlimit wxaCodeUnlimit = new WxaCodeUnlimit(); + wxaCodeUnlimit.setScene(scene); + wxaCodeUnlimit.setPage(page); + wxaCodeUnlimit.setWidth(width); + wxaCodeUnlimit.setAutoColor(autoColor); + wxaCodeUnlimit.setLineColor(lineColor); + wxaCodeUnlimit.setHyaline(isHyaline); return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()), - url, wxMaWxcodeLimit); + GET_WXACODE_UNLIMIT_URL, wxaCodeUnlimit); } @Override - public File createWxCodeLimit(String scene, String page) throws WxErrorException { - return this.createWxCodeLimit(scene, page, 430, true, null); + public File createWxaCodeUnlimit(String scene, String page) throws WxErrorException { + return this.createWxaCodeUnlimit(scene, page, 430, true, null, false); } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java index 106f020e53..9c8ac82d73 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java @@ -1,15 +1,11 @@ package cn.binarywang.wx.miniapp.api.impl; -import cn.binarywang.wx.miniapp.api.*; -import cn.binarywang.wx.miniapp.config.WxMaConfig; -import com.google.gson.JsonParser; -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.common.util.crypto.SHA1; -import me.chanjar.weixin.common.util.http.*; -import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; -import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.Lock; + import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; @@ -19,14 +15,41 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.concurrent.locks.Lock; +import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; +import cn.binarywang.wx.miniapp.api.WxMaCodeService; +import cn.binarywang.wx.miniapp.api.WxMaJsapiService; +import cn.binarywang.wx.miniapp.api.WxMaMediaService; +import cn.binarywang.wx.miniapp.api.WxMaMsgService; +import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaSettingService; +import cn.binarywang.wx.miniapp.api.WxMaTemplateService; +import cn.binarywang.wx.miniapp.api.WxMaUserService; +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import com.google.common.base.Joiner; +import com.google.gson.Gson; +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.DataUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; + +import static cn.binarywang.wx.miniapp.constant.WxMaConstants.ErrorCode.*; /** * @author Binary Wang */ public class WxMaServiceImpl implements WxMaService, RequestHttp { - private static final JsonParser JSON_PARSER = new JsonParser(); private final Logger log = LoggerFactory.getLogger(this.getClass()); private CloseableHttpClient httpClient; @@ -37,10 +60,17 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp params = new HashMap<>(8); + params.put("appid", config.getAppid()); + params.put("secret", config.getSecret()); + params.put("js_code", jsCode); + params.put("grant_type", "authorization_code"); + + String result = get(JSCODE_TO_SESSION_URL, Joiner.on("&").withKeyValueSeparator("=").join(params)); + return WxMaJscode2SessionResult.fromJson(result); + } + @Override public boolean checkSignature(String timestamp, String nonce, String signature) { try { @@ -147,6 +197,7 @@ public String post(String url, String postData) throws WxErrorException { /** * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 */ + @Override public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { int retryTimes = 0; do { @@ -179,7 +230,9 @@ public T execute(RequestExecutor executor, String uri, E data) thro throw new RuntimeException("微信服务端异常,超出重试次数"); } - public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + private T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + E dataForLog = DataUtils.handleDataWithSecret(data); + if (uri.contains("access_token=")) { throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); } @@ -189,17 +242,16 @@ public synchronized T executeInternal(RequestExecutor executor, Str try { T result = executor.execute(uriWithAccessToken, data); - this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); + this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); return result; } catch (WxErrorException e) { WxError error = e.getError(); /* * 发生以下情况时尝试刷新access_token - * 40001 获取access_token时AppSecret错误,或者access_token无效 - * 42001 access_token超时 - * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期) */ - if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { + if (error.getErrorCode() == ERR_40001 + || error.getErrorCode() == ERR_42001 + || error.getErrorCode() == ERR_40014) { // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token this.getWxMaConfig().expireAccessToken(); if (this.getWxMaConfig().autoRefreshToken()) { @@ -208,12 +260,12 @@ public synchronized T executeInternal(RequestExecutor executor, Str } if (error.getErrorCode() != 0) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); throw new WxErrorException(error, e); } return null; } catch (IOException e) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); throw new RuntimeException(e); } } @@ -258,4 +310,29 @@ public WxMaUserService getUserService() { public WxMaQrcodeService getQrcodeService() { return this.qrCodeService; } + + @Override + public WxMaTemplateService getTemplateService() { + return this.templateService; + } + + @Override + public WxMaAnalysisService getAnalysisService() { + return this.analysisService; + } + + @Override + public WxMaCodeService getCodeService() { + return this.codeService; + } + + @Override + public WxMaJsapiService getJsapiService() { + return this.jsapiService; + } + + @Override + public WxMaSettingService getSettingService() { + return this.settingService; + } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSettingServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSettingServiceImpl.java new file mode 100644 index 0000000000..ac45e6ce31 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSettingServiceImpl.java @@ -0,0 +1,48 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaSettingService; +import cn.binarywang.wx.miniapp.bean.WxMaDomainAction; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Charming + * @since 2018-04-27 15:46 + */ +public class WxMaSettingServiceImpl implements WxMaSettingService { + private WxMaService wxMaService; + + public WxMaSettingServiceImpl(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + @Override + public WxMaDomainAction modifyDomain(WxMaDomainAction domainAction) throws WxErrorException { + String responseContent = this.wxMaService.post(MODIFY_DOMAIN_URL, domainAction.toJson()); + return WxMaDomainAction.fromJson(responseContent); + } + + @Override + public WxMaDomainAction setWebViewDomain(WxMaDomainAction domainAction) throws WxErrorException { + String responseContent = this.wxMaService.post(SET_WEB_VIEW_DOMAIN_URL, domainAction.toJson()); + return WxMaDomainAction.fromJson(responseContent); + } + + @Override + public void bindTester(String wechatId) throws WxErrorException { + Map param = new HashMap<>(1); + param.put("wechatid", wechatId); + this.wxMaService.post(BIND_TESTER_URL, WxMaGsonBuilder.create().toJson(param)); + } + + @Override + public void unbindTester(String wechatId) throws WxErrorException { + Map param = new HashMap<>(1); + param.put("wechatid", wechatId); + this.wxMaService.post(UNBIND_TESTER_URL, WxMaGsonBuilder.create().toJson(param)); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImpl.java new file mode 100644 index 0000000000..9570c07a91 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImpl.java @@ -0,0 +1,101 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaTemplateService; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class WxMaTemplateServiceImpl implements WxMaTemplateService { + + private WxMaService wxMaService; + + public WxMaTemplateServiceImpl(WxMaService wxMaService){ + this.wxMaService = wxMaService; + } + + @Override + public WxMaTemplateLibraryListResult findTemplateLibraryList(int offset, int count) throws WxErrorException { + + Map params = new HashMap<>(); + params.put("offset", offset); + params.put("count", count); + + String responseText = this.wxMaService.post(TEMPLATE_LIBRARY_LIST_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if(wxError.getErrorCode() == 0){ + return WxMaTemplateLibraryListResult.fromJson(responseText); + }else { + throw new WxErrorException(wxError); + } + } + + @Override + public WxMaTemplateLibraryGetResult findTemplateLibraryKeywordList(String id) throws WxErrorException { + + Map params = new HashMap<>(); + params.put("id", id); + + String responseText = this.wxMaService.post(TEMPLATE_LIBRARY_KEYWORD_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if(wxError.getErrorCode() == 0){ + return WxMaTemplateLibraryGetResult.fromJson(responseText); + }else { + throw new WxErrorException(wxError); + } + } + + @Override + public WxMaTemplateAddResult addTemplate(String id, List keywordIdList) throws WxErrorException { + + Map params = new HashMap<>(); + params.put("id", id); + params.put("keyword_id_list", keywordIdList.toArray()); + + String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if(wxError.getErrorCode() == 0){ + return WxMaTemplateAddResult.fromJson(responseText); + }else { + throw new WxErrorException(wxError); + } + } + + @Override + public WxMaTemplateListResult findTemplateList(int offset, int count) throws WxErrorException { + + Map params = new HashMap<>(); + params.put("offset", offset); + params.put("count", count); + + String responseText = this.wxMaService.post(TEMPLATE_LIST_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if(wxError.getErrorCode() == 0){ + return WxMaTemplateListResult.fromJson(responseText); + }else { + throw new WxErrorException(wxError); + } + } + + @Override + public boolean delTemplate(String templateId) throws WxErrorException { + Map params = new HashMap<>(); + params.put("template_id", templateId); + + String responseText = this.wxMaService.post(TEMPLATE_DEL_URL, WxGsonBuilder.create().toJson(params)); + WxError wxError = WxError.fromJson(responseText); + if(wxError.getErrorCode() == 0){ + return true; + }else { + throw new WxErrorException(wxError); + } + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java index e2fdb9dc2b..f8177bf1d6 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java @@ -3,14 +3,22 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.WxMaUserService; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; import cn.binarywang.wx.miniapp.config.WxMaConfig; import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; -import com.google.common.base.Joiner; -import me.chanjar.weixin.common.exception.WxErrorException; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.SignUtils; +import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; -import java.util.HashMap; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.Map; /** @@ -19,21 +27,13 @@ public class WxMaUserServiceImpl implements WxMaUserService { private WxMaService service; - WxMaUserServiceImpl(WxMaService service) { + public WxMaUserServiceImpl(WxMaService service) { this.service = service; } @Override public WxMaJscode2SessionResult getSessionInfo(String jsCode) throws WxErrorException { - final WxMaConfig config = service.getWxMaConfig(); - Map params = new HashMap<>(); - params.put("appid", config.getAppid()); - params.put("secret", config.getSecret()); - params.put("js_code", jsCode); - params.put("grant_type", "authorization_code"); - - String result = this.service.get(JSCODE_TO_SESSION_URL, Joiner.on("&").withKeyValueSeparator("=").join(params)); - return WxMaJscode2SessionResult.fromJson(result); + return service.jsCode2SessionInfo(jsCode); } @Override @@ -41,10 +41,38 @@ public WxMaUserInfo getUserInfo(String sessionKey, String encryptedData, String return WxMaUserInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)); } + @Override + public void setUserStorage(Map kvMap, String sessionKey, String openid) throws WxErrorException { + final WxMaConfig config = this.service.getWxMaConfig(); + JsonObject param = new JsonObject(); + JsonArray array = new JsonArray(); + for (Map.Entry e : kvMap.entrySet()) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("key", e.getKey()); + jsonObject.addProperty("value", e.getValue()); + array.add(jsonObject); + } + param.add("kv_list", array); + String params = param.toString(); + String signature = SignUtils.createHmacSha256Sign(params, sessionKey); + String url = String.format("https://api.weixin.qq.com/wxa/set_user_storage" + + "?appid=%s&signature=%s&openid=%s&sig_method=%s", + config.getAppid(), signature, openid, "hmac_sha256"); + String result = this.service.post(url, params); + WxError error = WxError.fromJson(result); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + } + + @Override + public WxMaPhoneNumberInfo getPhoneNoInfo(String sessionKey, String encryptedData, String ivStr) { + return WxMaPhoneNumberInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)); + } + @Override public boolean checkUserInfo(String sessionKey, String rawData, String signature) { final String generatedSignature = DigestUtils.sha1Hex(rawData + sessionKey); - System.out.println(generatedSignature); return generatedSignature.equals(signature); } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcodeWrapper.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/AbstractWxMaQrcodeWrapper.java similarity index 53% rename from weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcodeWrapper.java rename to weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/AbstractWxMaQrcodeWrapper.java index 37c5c5db88..cb444c94c1 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcodeWrapper.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/AbstractWxMaQrcodeWrapper.java @@ -3,14 +3,17 @@ import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; /** - * 微信二维码(小程序码)包装器 - * Created by Element on 2017/7/27. + * 微信二维码(小程序码)包装器. + * + * @author Element */ -public abstract class WxMaQrcodeWrapper { +public abstract class AbstractWxMaQrcodeWrapper { + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } @Override public String toString() { - return WxMaGsonBuilder.create().toJson(this); + return this.toJson(); } - } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java new file mode 100644 index 0000000000..2afb4c073e --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java @@ -0,0 +1,18 @@ +package cn.binarywang.wx.miniapp.bean; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + *
+ * lineColor 包装类
+ * 用于描述二维码(小程序码)颜色(RGB参数值),
+ * 详情请查看文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
+ * 
+ * @author Element + */ +@Data +@AllArgsConstructor +public class WxMaCodeLineColor { + private String r = "0", g = "0", b = "0"; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaDomainAction.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaDomainAction.java new file mode 100644 index 0000000000..313f6cbed8 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaDomainAction.java @@ -0,0 +1,58 @@ +package cn.binarywang.wx.miniapp.bean; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 域名相关操作 + * + * @author Charming + * @since 2018-04-27 15:45 + */ +@Data +@Builder +public class WxMaDomainAction implements Serializable { + private static final long serialVersionUID = -2898601966852935708L; + /** + * add添加, delete删除, set覆盖, get获取。当参数是get时不需要填四个域名字段 + */ + private String action; + /** + * request合法域名,当action参数是get时不需要此字段。 + */ + @SerializedName("requestdomain") + private List requestDomain; + /** + * socket合法域名,当action参数是get时不需要此字段。 + */ + @SerializedName("wsrequestdomain") + private List wsRequestDomain; + /** + * uploadFile合法域名,当action参数是get时不需要此字段。 + */ + @SerializedName("uploaddomain") + private List uploadDomain; + /** + * downloadFile合法域名,当action参数是get时不需要此字段。 + */ + @SerializedName("downloaddomain") + private List downloadDomain; + /** + * 小程序业务域名,当action参数是get时不需要此字段。 + */ + @SerializedName("webviewdomain") + private List webViewDomain; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + + public static WxMaDomainAction fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaDomainAction.class); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java index 471e6c46ec..85b4767702 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java @@ -2,19 +2,27 @@ import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; /** - * {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"} - * + *
+ * code换取session_key接口的响应
+ * 文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject
+ * 微信返回报文:{"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"}
+ * 
* @author Binary Wang */ -public class WxMaJscode2SessionResult { +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaJscode2SessionResult implements Serializable { + private static final long serialVersionUID = -1060216618475607933L; + @SerializedName("session_key") private String sessionKey; - @SerializedName("expires_in") - private Integer expiresin; - @SerializedName("openid") private String openid; @@ -25,36 +33,4 @@ public static WxMaJscode2SessionResult fromJson(String json) { return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class); } - public String getSessionKey() { - return sessionKey; - } - - public void setSessionKey(String sessionKey) { - this.sessionKey = sessionKey; - } - - public Integer getExpiresin() { - return expiresin; - } - - public void setExpiresin(Integer expiresin) { - this.expiresin = expiresin; - } - - public String getOpenid() { - return openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getUnionid() { - return unionid; - } - - public void setUnionid(String unionid) { - this.unionid = unionid; - } - } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java index d75fbf12ae..ee11476878 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java @@ -1,95 +1,106 @@ package cn.binarywang.wx.miniapp.bean; -import cn.binarywang.wx.miniapp.builder.ImageBuilder; -import cn.binarywang.wx.miniapp.builder.TextBuilder; +import cn.binarywang.wx.miniapp.builder.ImageMessageBuilder; +import cn.binarywang.wx.miniapp.builder.LinkMessageBuilder; +import cn.binarywang.wx.miniapp.builder.MaPageMessageBuilder; +import cn.binarywang.wx.miniapp.builder.TextMessageBuilder; import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; import java.io.Serializable; /** - * 客服消息 + * 客服消息. * * @author Binary Wang */ +@Data public class WxMaKefuMessage implements Serializable { private static final long serialVersionUID = -9196732086954365246L; + @SerializedName("touser") private String toUser; + + @SerializedName("msgtype") private String msgType; - private String content; - private String mediaId; - private String thumbMediaId; - private String title; - private String description; - /** - * 获得文本消息builder - */ - public static TextBuilder TEXT() { - return new TextBuilder(); - } + @SerializedName("text") + private KfText text; - /** - * 获得图片消息builder - */ - public static ImageBuilder IMAGE() { - return new ImageBuilder(); - } + @SerializedName("image") + private KfImage image; - public String getToUser() { - return this.toUser; - } + @SerializedName("link") + private KfLink link; - public void setToUser(String toUser) { - this.toUser = toUser; - } - - public String getMsgType() { - return this.msgType; - } + @SerializedName("miniprogrampage") + private KfMaPage maPage; - public void setMsgType(String msgType) { - this.msgType = msgType; + @Data + @AllArgsConstructor + public static class KfText { + private String content; } - public String getContent() { - return this.content; + @Data + @AllArgsConstructor + public static class KfImage { + @SerializedName("media_id") + private String mediaId; } - public void setContent(String content) { - this.content = content; - } + @Data + @Builder + public static class KfLink { + private String title; + private String description; + private String url; - public String getMediaId() { - return this.mediaId; + @SerializedName("thumb_url") + private String thumbUrl; } - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } + @Data + @Builder + public static class KfMaPage { + private String title; - public String getThumbMediaId() { - return this.thumbMediaId; - } + @SerializedName("pagepath") + private String pagePath; - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; + @SerializedName("thumb_media_id") + private String thumbMediaId; } - public String getTitle() { - return this.title; + /** + * 获得文本消息builder. + */ + public static TextMessageBuilder newTextBuilder() { + return new TextMessageBuilder(); } - public void setTitle(String title) { - this.title = title; + /** + * 获得图片消息builder. + */ + public static ImageMessageBuilder newImageBuilder() { + return new ImageMessageBuilder(); } - public String getDescription() { - return this.description; + /** + * 获得图文链接消息builder. + */ + public static LinkMessageBuilder newLinkBuilder() { + return new LinkMessageBuilder(); } - public void setDescription(String description) { - this.description = description; + /** + * 获得图文链接消息builder. + */ + public static MaPageMessageBuilder newMaPageBuilder() { + return new MaPageMessageBuilder(); } public String toJson() { diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java index 4b201da1cd..d44d155638 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java @@ -1,5 +1,14 @@ package cn.binarywang.wx.miniapp.bean; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import cn.binarywang.wx.miniapp.config.WxMaConfig; import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; @@ -7,19 +16,14 @@ import com.google.gson.annotations.SerializedName; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import org.apache.commons.io.IOUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; /** * @author Binary Wang */ @XStreamAlias("xml") +@Data public class WxMaMessage implements Serializable { private static final long serialVersionUID = -3586245291677274914L; @@ -40,15 +44,18 @@ public class WxMaMessage implements Serializable { @SerializedName("CreateTime") @XStreamAlias("CreateTime") - @XStreamConverter(value = XStreamCDataConverter.class) private Integer createTime; + @SerializedName("MsgType") + @XStreamAlias("MsgType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String msgType; + @SerializedName("MsgDataFormat") @XStreamAlias("MsgDataFormat") @XStreamConverter(value = XStreamCDataConverter.class) - private String msgType; + private String msgDataFormat; - // 文本消息 @SerializedName("Content") @XStreamAlias("Content") @XStreamConverter(value = XStreamCDataConverter.class) @@ -56,10 +63,8 @@ public class WxMaMessage implements Serializable { @SerializedName("MsgId") @XStreamAlias("MsgId") - @XStreamConverter(value = XStreamCDataConverter.class) private Long msgId; - // 图片消息 @SerializedName("PicUrl") @XStreamAlias("PicUrl") @XStreamConverter(value = XStreamCDataConverter.class) @@ -70,12 +75,36 @@ public class WxMaMessage implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) private String mediaId; - // 事件消息 @SerializedName("Event") @XStreamAlias("Event") @XStreamConverter(value = XStreamCDataConverter.class) private String event; + @SerializedName("Title") + @XStreamAlias("Title") + @XStreamConverter(value = XStreamCDataConverter.class) + private String title; + + @SerializedName("AppId") + @XStreamAlias("AppId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String appId; + + @SerializedName("PagePath") + @XStreamAlias("PagePath") + @XStreamConverter(value = XStreamCDataConverter.class) + private String pagePath; + + @SerializedName("ThumbUrl") + @XStreamAlias("ThumbUrl") + @XStreamConverter(value = XStreamCDataConverter.class) + private String thumbUrl; + + @SerializedName("ThumbMediaId") + @XStreamAlias("ThumbMediaId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String thumbMediaId; + @SerializedName("SessionFrom") @XStreamAlias("SessionFrom") @XStreamConverter(value = XStreamCDataConverter.class) @@ -90,7 +119,7 @@ public static WxMaMessage fromXml(InputStream is) { } /** - * 从加密字符串转换 + * 从加密字符串转换. * * @param encryptedXml 密文 * @param wxMaConfig 配置存储器对象 @@ -139,98 +168,11 @@ public static WxMaMessage fromEncryptedJson(InputStream inputStream, WxMaConfig @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public String toJson() { return WxMaGsonBuilder.create().toJson(this); } - public String getToUser() { - return toUser; - } - - public void setToUser(String toUser) { - this.toUser = toUser; - } - - public String getFromUser() { - return fromUser; - } - - public void setFromUser(String fromUser) { - this.fromUser = fromUser; - } - - public Integer getCreateTime() { - return createTime; - } - - public void setCreateTime(Integer createTime) { - this.createTime = createTime; - } - - public String getMsgType() { - return msgType; - } - - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public Long getMsgId() { - return msgId; - } - - public void setMsgId(Long msgId) { - this.msgId = msgId; - } - - public String getPicUrl() { - return picUrl; - } - - public void setPicUrl(String picUrl) { - this.picUrl = picUrl; - } - - public String getMediaId() { - return mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getEvent() { - return event; - } - - public void setEvent(String event) { - this.event = event; - } - - public String getSessionFrom() { - return sessionFrom; - } - - public void setSessionFrom(String sessionFrom) { - this.sessionFrom = sessionFrom; - } - - public String getEncrypt() { - return encrypt; - } - - public void setEncrypt(String encrypt) { - this.encrypt = encrypt; - } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaPhoneNumberInfo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaPhoneNumberInfo.java new file mode 100644 index 0000000000..6b39a3d718 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaPhoneNumberInfo.java @@ -0,0 +1,30 @@ +package cn.binarywang.wx.miniapp.bean; + +import java.io.Serializable; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; + +/** + * 微信用户绑定的手机号相关信息 + * @author Binary Wang + */ +@Data +public class WxMaPhoneNumberInfo implements Serializable { + private static final long serialVersionUID = 6719822331555402137L; + + private String phoneNumber; + private String purePhoneNumber; + private String countryCode; + private Watermark watermark; + + public static WxMaPhoneNumberInfo fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaPhoneNumberInfo.class); + } + + @Data + public static class Watermark { + private String timestamp; + private String appid; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java index a047d7c8b1..5c17cd1e58 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java @@ -1,13 +1,17 @@ package cn.binarywang.wx.miniapp.bean; import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.Data; +import lombok.EqualsAndHashCode; import java.io.Serializable; /** * @author Binary Wang */ -public class WxMaQrcode extends WxMaQrcodeWrapper implements Serializable { +@Data +@EqualsAndHashCode(callSuper = false) +public class WxMaQrcode extends AbstractWxMaQrcodeWrapper implements Serializable { private static final long serialVersionUID = 5777119669111011584L; private String path; private int width = 430; @@ -21,22 +25,6 @@ public static WxMaQrcode fromJson(String json) { return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class); } - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public int getWidth() { - return width; - } - - public void setWidth(int width) { - this.width = width; - } - @Override public String toString() { return WxMaGsonBuilder.create().toJson(this); diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateData.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateData.java new file mode 100644 index 0000000000..5eae34b115 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateData.java @@ -0,0 +1,32 @@ +package cn.binarywang.wx.miniapp.bean; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *
+ *
+ * Created by Binary Wang on 2018/9/23.
+ * 
+ * + * @author Binary Wang + */ +@Data +@NoArgsConstructor +public class WxMaTemplateData { + private String name; + private String value; + private String color; + + public WxMaTemplateData(String name, String value) { + this.name = name; + this.value = value; + } + + public WxMaTemplateData(String name, String value, String color) { + this.name = name; + this.value = value; + this.color = color; + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java index 79f955c6d2..5a67439478 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java @@ -1,20 +1,32 @@ package cn.binarywang.wx.miniapp.bean; -import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + /** + * 模板消息. * 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#接口说明 模板消息部分 * * @author Binary Wang */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder public class WxMaTemplateMessage implements Serializable { private static final long serialVersionUID = 5063374783759519418L; /** + * 接收者(用户)的 openid. *
    * 参数:touser
    * 是否必填: 是
@@ -24,6 +36,7 @@ public class WxMaTemplateMessage implements Serializable {
   private String toUser;
 
   /**
+   * 所需下发的模板消息的id.
    * 
    * 参数:template_id
    * 是否必填: 是
@@ -33,6 +46,7 @@ public class WxMaTemplateMessage implements Serializable {
   private String templateId;
 
   /**
+   * 点击模板卡片后的跳转页面,仅限本小程序内的页面.
    * 
    * 参数:page
    * 是否必填: 否
@@ -42,6 +56,7 @@ public class WxMaTemplateMessage implements Serializable {
   private String page;
 
   /**
+   * 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id.
    * 
    * 参数:form_id
    * 是否必填: 是
@@ -51,15 +66,17 @@ public class WxMaTemplateMessage implements Serializable {
   private String formId;
 
   /**
+   * 模板内容,不填则下发空模板.
    * 
    * 参数:data
    * 是否必填: 是
    * 描述: 模板内容,不填则下发空模板
    * 
*/ - private List data = new ArrayList<>(); + private List data; /** + * 模板内容字体的颜色,不填默认黑色. *
    * 参数:color
    * 是否必填: 否
@@ -69,6 +86,7 @@ public class WxMaTemplateMessage implements Serializable {
   private String color;
 
   /**
+   * 模板需要放大的关键词,不填则默认无放大.
    * 
    * 参数:emphasis_keyword
    * 是否必填: 否
@@ -77,171 +95,17 @@ public class WxMaTemplateMessage implements Serializable {
    */
   private String emphasisKeyword;
 
-  private WxMaTemplateMessage(Builder builder) {
-    setToUser(builder.toUser);
-    setTemplateId(builder.templateId);
-    setPage(builder.page);
-    setFormId(builder.formId);
-    setData(builder.data);
-    setColor(builder.color);
-    setEmphasisKeyword(builder.emphasisKeyword);
-  }
+  public WxMaTemplateMessage addData(WxMaTemplateData datum) {
+    if (this.data == null) {
+      this.data = new ArrayList<>();
+    }
+    this.data.add(datum);
 
-  public static Builder newBuilder() {
-    return new Builder();
+    return this;
   }
 
   public String toJson() {
     return WxMaGsonBuilder.create().toJson(this);
   }
 
-  public String getToUser() {
-    return toUser;
-  }
-
-  public void setToUser(String toUser) {
-    this.toUser = toUser;
-  }
-
-  public String getTemplateId() {
-    return templateId;
-  }
-
-  public void setTemplateId(String templateId) {
-    this.templateId = templateId;
-  }
-
-  public String getPage() {
-    return page;
-  }
-
-  public void setPage(String page) {
-    this.page = page;
-  }
-
-  public String getFormId() {
-    return formId;
-  }
-
-  public void setFormId(String formId) {
-    this.formId = formId;
-  }
-
-  public List getData() {
-    return data;
-  }
-
-  public void setData(List data) {
-    this.data = data;
-  }
-
-  public String getColor() {
-    return color;
-  }
-
-  public void setColor(String color) {
-    this.color = color;
-  }
-
-  public String getEmphasisKeyword() {
-    return emphasisKeyword;
-  }
-
-  public void setEmphasisKeyword(String emphasisKeyword) {
-    this.emphasisKeyword = emphasisKeyword;
-  }
-
-  public static class Data {
-    private String name;
-    private String value;
-    private String color;
-
-    public Data(String name, String value) {
-      this.name = name;
-      this.value = value;
-    }
-
-    public Data(String name, String value, String color) {
-      this.name = name;
-      this.value = value;
-      this.color = color;
-    }
-
-    public String getName() {
-      return this.name;
-    }
-
-    public void setName(String name) {
-      this.name = name;
-    }
-
-    public String getValue() {
-      return this.value;
-    }
-
-    public void setValue(String value) {
-      this.value = value;
-    }
-
-    public String getColor() {
-      return this.color;
-    }
-
-    public void setColor(String color) {
-      this.color = color;
-    }
-
-  }
-
-  public static final class Builder {
-    private String toUser;
-    private String templateId;
-    private String page;
-    private String formId;
-    private List data;
-    private String color;
-    private String emphasisKeyword;
-
-    private Builder() {
-    }
-
-    public Builder toUser(String toUser) {
-      this.toUser = toUser;
-      return this;
-    }
-
-    public Builder templateId(String templateId) {
-      this.templateId = templateId;
-      return this;
-    }
-
-    public Builder page(String page) {
-      this.page = page;
-      return this;
-    }
-
-    public Builder formId(String formId) {
-      this.formId = formId;
-      return this;
-    }
-
-    public Builder data(List data) {
-      this.data = data;
-      return this;
-    }
-
-    public Builder color(String color) {
-      this.color = color;
-      return this;
-    }
-
-    public Builder emphasisKeyword(String emphasisKeyword) {
-      this.emphasisKeyword = emphasisKeyword;
-      return this;
-    }
-
-    public WxMaTemplateMessage build() {
-      return new WxMaTemplateMessage(this);
-    }
-  }
 }
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java
new file mode 100644
index 0000000000..e58ad58a98
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java
@@ -0,0 +1,108 @@
+package cn.binarywang.wx.miniapp.bean;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * 模板消息.
+ * 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#接口说明  模板消息部分
+ *
+ * @author Binary Wang
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class WxMaUniformMessage implements Serializable {
+  private static final long serialVersionUID = 5063374783759519418L;
+
+  /**
+   * 是否发送公众号模版消息,否则发送小程序模版消息.
+   */
+  private boolean isMpTemplateMsg;
+
+  /**
+   * 用户openid.
+   * 可以是小程序的openid,也可以是mp_template_msg.appid对应的公众号的openid
+   */
+  private String toUser;
+
+  /**
+   * 公众号appid,要求与小程序有绑定且同主体.
+   */
+  private String appid;
+
+  /**
+   * 公众号或小程序模板ID.
+   */
+  private String templateId;
+
+  /**
+   * 公众号模板消息所要跳转的url.
+   */
+  private String url;
+
+  /**
+   * 小程序页面路径.
+   */
+  private String page;
+
+  /**
+   * 小程序模板消息formid.
+   */
+  private String formId;
+
+  /**
+   * 公众号模板消息所要跳转的小程序,小程序的必须与公众号具有绑定关系.
+   */
+  private MiniProgram miniProgram;
+
+  /**
+   * 小程序模板数据.
+   */
+  private List data;
+
+  /**
+   * 模板需要放大的关键词,不填则默认无放大.
+   */
+  private String emphasisKeyword;
+
+  public WxMaUniformMessage addData(WxMaTemplateData datum) {
+    if (this.data == null) {
+      this.data = new ArrayList<>();
+    }
+    this.data.add(datum);
+
+    return this;
+  }
+
+  public String toJson() {
+    return WxMaGsonBuilder.create().toJson(this);
+  }
+
+  @Data
+  @NoArgsConstructor
+  @AllArgsConstructor
+  public static class MiniProgram implements Serializable {
+    private static final long serialVersionUID = -7945254706501974849L;
+
+    private String appid;
+    private String pagePath;
+
+    /**
+     * 是否使用path,否则使用pagepath.
+     * 加入此字段是基于微信官方接口变化多端的考虑
+     */
+    private boolean usePath = false;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java
index e3cc69d913..8b0ed8fe6a 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java
@@ -1,13 +1,17 @@
 package cn.binarywang.wx.miniapp.bean;
 
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
+import lombok.Data;
+
+import java.io.Serializable;
 
 /**
  * @author Binary Wang
  */
-public class WxMaUserInfo {
+@Data
+public class WxMaUserInfo implements Serializable {
+  private static final long serialVersionUID = 6719822331555402137L;
+
   private String openId;
   private String nickName;
   private String gender;
@@ -23,109 +27,9 @@ public static WxMaUserInfo fromJson(String json) {
     return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class);
   }
 
-  @Override
-  public String toString() {
-    return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
-  }
-
-  public String getOpenId() {
-    return openId;
-  }
-
-  public void setOpenId(String openId) {
-    this.openId = openId;
-  }
-
-  public String getNickName() {
-    return nickName;
-  }
-
-  public void setNickName(String nickName) {
-    this.nickName = nickName;
-  }
-
-  public String getGender() {
-    return gender;
-  }
-
-  public void setGender(String gender) {
-    this.gender = gender;
-  }
-
-  public String getLanguage() {
-    return language;
-  }
-
-  public void setLanguage(String language) {
-    this.language = language;
-  }
-
-  public String getCity() {
-    return city;
-  }
-
-  public void setCity(String city) {
-    this.city = city;
-  }
-
-  public String getProvince() {
-    return province;
-  }
-
-  public void setProvince(String province) {
-    this.province = province;
-  }
-
-  public String getCountry() {
-    return country;
-  }
-
-  public void setCountry(String country) {
-    this.country = country;
-  }
-
-  public String getAvatarUrl() {
-    return avatarUrl;
-  }
-
-  public void setAvatarUrl(String avatarUrl) {
-    this.avatarUrl = avatarUrl;
-  }
-
-  public String getUnionId() {
-    return unionId;
-  }
-
-  public void setUnionId(String unionId) {
-    this.unionId = unionId;
-  }
-
-  public Watermark getWatermark() {
-    return watermark;
-  }
-
-  public void setWatermark(Watermark watermark) {
-    this.watermark = watermark;
-  }
-
+  @Data
   public static class Watermark {
     private String timestamp;
     private String appid;
-
-    public String getTimestamp() {
-      return timestamp;
-    }
-
-    public void setTimestamp(String timestamp) {
-      this.timestamp = timestamp;
-    }
-
-    public String getAppid() {
-      return appid;
-    }
-
-    public void setAppid(String appid) {
-      this.appid = appid;
-    }
   }
 }
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java
index 9ea674ed98..e538a1bb83 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java
@@ -1,64 +1,36 @@
 package cn.binarywang.wx.miniapp.bean;
 
-import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
 import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 import java.io.Serializable;
 
 /**
- * Created by Element on 2017/7/27.
+ *
+ * @author Element
+ * @date 2017/7/27
  */
-public class WxMaWxcode extends WxMaQrcodeWrapper implements Serializable {
-
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class WxMaWxcode extends AbstractWxMaQrcodeWrapper implements Serializable {
   private static final long serialVersionUID = 1287399621649210322L;
+
   private String path;
   private int width = 430;
 
   @SerializedName("auto_color")
   private boolean autoColor = true;
 
+  @SerializedName("is_hyaline")
+  private boolean isHyaline = false;
+
   @SerializedName("line_color")
-  private WxMaQrcodeService.LineColor lineColor = new WxMaQrcodeService.LineColor("0", "0", "0");
+  private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0");
 
   public static WxMaWxcode fromJson(String json) {
     return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class);
   }
 
-  public static long getSerialVersionUID() {
-    return serialVersionUID;
-  }
-
-  public String getPath() {
-    return path;
-  }
-
-  public void setPath(String path) {
-    this.path = path;
-  }
-
-  public int getWidth() {
-    return width;
-  }
-
-  public void setWidth(int width) {
-    this.width = width;
-  }
-
-  public boolean isAutoColor() {
-    return autoColor;
-  }
-
-  public void setAutoColor(boolean autoColor) {
-    this.autoColor = autoColor;
-  }
-
-  public WxMaQrcodeService.LineColor getLineColor() {
-    return lineColor;
-  }
-
-  public void setLineColor(WxMaQrcodeService.LineColor lineColor) {
-    this.lineColor = lineColor;
-  }
-
 }
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java
deleted file mode 100644
index 7619fe46f2..0000000000
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package cn.binarywang.wx.miniapp.bean;
-
-import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
-import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
-import com.google.gson.annotations.SerializedName;
-
-import java.io.Serializable;
-
-/**
- * Created by Element on 2017/7/27.
- */
-public class WxMaWxcodeLimit extends WxMaQrcodeWrapper implements Serializable {
-  private static final long serialVersionUID = 4782193774524960401L;
-  private String scene;
-  private String page;
-
-  private int width = 430;
-
-  @SerializedName("auto_color")
-  private boolean autoColor = true;
-
-  @SerializedName("line_color")
-  private WxMaQrcodeService.LineColor lineColor = new WxMaQrcodeService.LineColor("0", "0", "0");
-
-  public static WxMaWxcodeLimit fromJson(String json) {
-    return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class);
-  }
-
-  public String getPage() {
-    return page;
-  }
-
-  public void setPage(String page) {
-    this.page = page;
-  }
-
-  public String getScene() {
-    return scene;
-  }
-
-  public void setScene(String scene) {
-    this.scene = scene;
-  }
-
-  public int getWidth() {
-    return width;
-  }
-
-  public void setWidth(int width) {
-    this.width = width;
-  }
-
-  public boolean isAutoColor() {
-    return autoColor;
-  }
-
-  public void setAutoColor(boolean autoColor) {
-    this.autoColor = autoColor;
-  }
-
-  public WxMaQrcodeService.LineColor getLineColor() {
-    return lineColor;
-  }
-
-  public void setLineColor(WxMaQrcodeService.LineColor lineColor) {
-    this.lineColor = lineColor;
-  }
-}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxaCodeUnlimit.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxaCodeUnlimit.java
new file mode 100644
index 0000000000..05bf134c6b
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxaCodeUnlimit.java
@@ -0,0 +1,38 @@
+package cn.binarywang.wx.miniapp.bean;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 小程序码接口B.
+ *
+ * @author Element
+ * @date 2017/7/27
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class WxaCodeUnlimit extends AbstractWxMaQrcodeWrapper implements Serializable {
+  private static final long serialVersionUID = 4782193774524960401L;
+  private String scene;
+  private String page;
+
+  private int width = 430;
+
+  @SerializedName("auto_color")
+  private boolean autoColor = true;
+
+  @SerializedName("is_hyaline")
+  private boolean isHyaline = false;
+
+  @SerializedName("line_color")
+  private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0");
+
+  public static WxaCodeUnlimit fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxaCodeUnlimit.class);
+  }
+
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaRetainInfo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaRetainInfo.java
new file mode 100644
index 0000000000..7021a180e9
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaRetainInfo.java
@@ -0,0 +1,43 @@
+package cn.binarywang.wx.miniapp.bean.analysis;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * 访问留存
+ *
+ * @author Charming
+ * @since 2018-04-28 14:41
+ */
+@Data
+public class WxMaRetainInfo implements Serializable {
+  private static final long serialVersionUID = 8986403173656848413L;
+  /**
+   * 日留存:日期,yyyyMMdd 格式,如 20170313
+   * 周留存:时间,如"20170306-20170312"
+   * 月留存:时间,如"201702"
+   */
+  @SerializedName(value = "refDate", alternate = "ref_date")
+  private String refDate;
+  /**
+   * 新增用户留存
+   * - key:
+   *  - 日留存:标识,0开始,0表示当天,1表示1天后,依此类推,key取值分别是:0,1,2,3,4,5,6,7,14,30
+   *  - 周留存:标识,0开始,0表示当周,1表示1周后,依此类推,key 取值分别是:0,1,2,3,4
+   *  - 月留存:标识,0开始,0表示当月,1表示1月后,key取值分别是:0,1
+   * - value: key对应日期的新增用户数/活跃用户数(key=0时)或留存用户数(k>0时)
+   */
+  private Map visitUvNew;
+  /**
+   * 活跃用户留存
+   */
+  private Map visitUv;
+
+  public static WxMaRetainInfo fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaRetainInfo.class);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaSummaryTrend.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaSummaryTrend.java
new file mode 100644
index 0000000000..f4ceb0ad95
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaSummaryTrend.java
@@ -0,0 +1,37 @@
+package cn.binarywang.wx.miniapp.bean.analysis;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 小程序概况趋势
+ *
+ * @author Charming
+ * @since 2018-04-28
+ */
+@Data
+public class WxMaSummaryTrend implements Serializable {
+  private static final long serialVersionUID = 1379688517709317935L;
+  /**
+   * 日期,yyyyMMdd 格式,如 20170313
+   */
+  @SerializedName(value = "refDate", alternate = "ref_date")
+  private String refDate;
+  /**
+   * 累计用户数
+   */
+  @SerializedName(value = "visitTotal", alternate = "visit_total")
+  private Long visitTotal;
+  /**
+   * 转发次数
+   */
+  @SerializedName(value = "sharePv", alternate = "share_pv")
+  private Long sharePv;
+  /**
+   * 转发人数
+   */
+  @SerializedName(value = "shareUv", alternate = "share_uv")
+  private Long shareUv;
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaUserPortrait.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaUserPortrait.java
new file mode 100644
index 0000000000..5e1164909e
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaUserPortrait.java
@@ -0,0 +1,68 @@
+package cn.binarywang.wx.miniapp.bean.analysis;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * 用户画像
+ *
+ * @author Charming
+ * @since 2018-04-28
+ */
+@Data
+public class WxMaUserPortrait implements Serializable {
+  private static final long serialVersionUID = 5653571047669243178L;
+  /**
+   * 时间范围,如: "20170611-20170617"
+   */
+  private String refDate;
+  /**
+   * 新用户
+   */
+  private Item visitUvNew;
+  /**
+   * 活跃用户
+   */
+  private Item visitUv;
+
+  public static WxMaUserPortrait fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaUserPortrait.class);
+  }
+
+  @Data
+  public static class Item {
+    /**
+     * key: 省份,如北京、广东等
+     * value: 活跃用户数或新用户数
+     */
+    private Map province;
+    /**
+     * key: 城市,如北京、广州等
+     * value: 活跃用户数或新用户数
+     */
+    private Map city;
+    /**
+     * key: 性别,包括男、女、未知
+     * value: 活跃用户数或新用户数
+     */
+    private Map genders;
+    /**
+     * key: 终端类型,包括iPhone, android,其他
+     * value: 活跃用户数或新用户数
+     */
+    private Map platforms;
+    /**
+     * key: 机型,如苹果iPhone6, OPPO R9等
+     * value: 活跃用户数或新用户数
+     */
+    private Map devices;
+    /**
+     * key: 年龄,包括17岁以下、18-24岁等区间
+     * value: 活跃用户数或新用户数
+     */
+    private Map ages;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitDistribution.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitDistribution.java
new file mode 100644
index 0000000000..1655eec286
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitDistribution.java
@@ -0,0 +1,83 @@
+package cn.binarywang.wx.miniapp.bean.analysis;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * 访问分布
+ * 访问来源:(index="access_source_session_cnt")
+ * 1:小程序历史列表
+ * 2:搜索
+ * 3:会话
+ * 4:二维码
+ * 5:公众号主页
+ * 6:聊天顶部
+ * 7:系统桌面
+ * 8:小程序主页
+ * 9:附近的小程序
+ * 10:其他
+ * 11:模板消息
+ * 12:客服消息
+ * 13: 公众号菜单
+ * 14: APP分享
+ * 15: 支付完成页
+ * 16: 长按识别二维码
+ * 17: 相册选取二维码
+ * 18: 公众号文章
+ * 19:钱包
+ * 20:卡包
+ * 21:小程序内卡券
+ * 22:其他小程序
+ * 23:其他小程序返回
+ * 24:卡券适用门店列表
+ * 25:搜索框快捷入口
+ * 26:小程序客服消息
+ * 27:公众号下发
+ * 访问时长:(index="access_staytime_info")
+ * 1: 0-2s
+ * 2: 3-5s
+ * 3: 6-10s
+ * 4: 11-20s
+ * 5: 20-30s
+ * 6: 30-50s
+ * 7: 50-100s
+ * 8: > 100s
+ * 平均访问深度:(index="access_depth_info")
+ * 1: 1页
+ * 2: 2页
+ * 3: 3页
+ * 4: 4页
+ * 5: 5页
+ * 6: 6-10页
+ * 7: >10页
+ *
+ * @author Charming
+ * @since 2018-04-28
+ */
+@Data
+public class WxMaVisitDistribution implements Serializable {
+  private static final long serialVersionUID = 5404250039495926632L;
+  /**
+   * 日期,yyyyMMdd 格式,如 20170313
+   */
+  @SerializedName(value = "refDate", alternate = "ref_date")
+  private String refDate;
+  /**
+   * key: 分布类型
+   * - access_source_session_cnt 访问来源分布
+   * - access_staytime_info 访问时长分布
+   * - access_depth_info 访问深度的分布
+   * value: 场景 ID 下的值
+   * - key: 场景 ID
+   * - value: 场景下的值
+   */
+  private Map> list;
+
+  public static WxMaVisitDistribution fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaVisitDistribution.class);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitPage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitPage.java
new file mode 100644
index 0000000000..705cf6b49e
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitPage.java
@@ -0,0 +1,55 @@
+package cn.binarywang.wx.miniapp.bean.analysis;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Charming
+ * @since 2018-04-28
+ */
+@Data
+public class WxMaVisitPage implements Serializable {
+  private static final long serialVersionUID = -7006334774516877372L;
+  /**
+   * 页面路径
+   */
+  @SerializedName(value = "pagePath", alternate = "page_path")
+  private String pagePath;
+  /**
+   * 访问次数
+   */
+  @SerializedName(value = "pageVisitPv", alternate = "page_visit_pv")
+  private Long pageVisitPv;
+  /**
+   * 访问人数
+   */
+  @SerializedName(value = "pageVisitUv", alternate = "page_visit_uv")
+  private Long pageVisitUv;
+  /**
+   * 次均停留时长
+   */
+  @SerializedName(value = "pageStayTimePv", alternate = "page_staytime_pv")
+  private Float pageStayTimePv;
+  /**
+   * 进入页次数
+   */
+  @SerializedName(value = "entryPagePv", alternate = "entrypage_pv")
+  private Long entryPagePv;
+  /**
+   * 退出页次数
+   */
+  @SerializedName(value = "exitPagePv", alternate = "exitpage_pv")
+  private Long exitPagePv;
+  /**
+   * 转发次数
+   */
+  @SerializedName(value = "pageSharePv", alternate = "page_share_pv")
+  private Long pageSharePv;
+  /**
+   * 转发人数
+   */
+  @SerializedName(value = "pageShareUv", alternate = "page_share_uv")
+  private Long pageShareUv;
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitTrend.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitTrend.java
new file mode 100644
index 0000000000..72223ef618
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitTrend.java
@@ -0,0 +1,59 @@
+package cn.binarywang.wx.miniapp.bean.analysis;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 访问趋势
+ *
+ * @author Charming
+ * @since 2018-04-28
+ */
+@Data
+public class WxMaVisitTrend implements Serializable {
+  private static final long serialVersionUID = 1379688517709317935L;
+  /**
+   * 日留存:日期,yyyyMMdd 格式,如 20170313
+   * 周留存:时间,如"20170306-20170312"
+   * 月留存:时间,如"201702"
+   */
+  @SerializedName(value = "refDate", alternate = "ref_date")
+  private String refDate;
+  /**
+   * 打开次数
+   */
+  @SerializedName(value = "sessionCnt", alternate = "session_cnt")
+  private Long sessionCnt;
+  /**
+   * 访问次数
+   */
+  @SerializedName(value = "visitPv", alternate = "visit_pv")
+  private Long visitPv;
+  /**
+   * 访问人数
+   */
+  @SerializedName(value = "visitUv", alternate = "visit_uv")
+  private Long visitUv;
+  /**
+   * 新用户数
+   */
+  @SerializedName(value = "visitUvNew", alternate = "visit_uv_new")
+  private Long visitUvNew;
+  /**
+   * 人均停留时长 (浮点型,单位:秒)
+   */
+  @SerializedName(value = "stayTimeUv", alternate = "stay_time_uv")
+  private Float stayTimeUv;
+  /**
+   * 人均停留时长 (浮点型,单位:秒)
+   */
+  @SerializedName(value = "stayTimeSession", alternate = "stay_time_session")
+  private Float stayTimeSession;
+  /**
+   * 人均停留时长 (浮点型,单位:秒)
+   */
+  @SerializedName(value = "visitDepth", alternate = "visit_depth")
+  private Float visitDepth;
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/package-info.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/package-info.java
new file mode 100644
index 0000000000..e4e68c7805
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/analysis/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 数据分析
+ *
+ * @author Charming
+ * @since 2018-04-28
+ */
+package cn.binarywang.wx.miniapp.bean.analysis;
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCategory.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCategory.java
new file mode 100644
index 0000000000..32195333eb
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCategory.java
@@ -0,0 +1,62 @@
+package cn.binarywang.wx.miniapp.bean.code;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 小程序帐号的可选类目,其中 address / tag / title 是提交审核会用到的
+ *
+ * @author Charming
+ * @since 2018-04-26 19:44
+ */
+@Data
+@Builder
+public class WxMaCategory implements Serializable {
+  private static final long serialVersionUID = -7663757440028175135L;
+  /**
+   * 一级类目名称
+   */
+  @SerializedName("first_class")
+  private String firstClass;
+  /**
+   * 二级类目名称
+   */
+  @SerializedName("second_class")
+  private String secondClass;
+  /**
+   * 三级类目名称
+   */
+  @SerializedName("third_class")
+  private String thirdClass;
+  /**
+   * 一级类目的ID编号
+   */
+  @SerializedName("first_id")
+  private Long firstId;
+  /**
+   * 二级类目的ID编号
+   */
+  @SerializedName("second_id")
+  private Long secondId;
+  /**
+   * 三级类目的ID编号
+   */
+  @SerializedName("third_id")
+  private Long thirdId;
+
+  /**
+   * 小程序的页面,可通过“获取小程序的第三方提交代码的页面配置”接口获得
+   */
+  private String address;
+  /**
+   * 小程序的标签,多个标签用空格分隔,标签不能多于10个,标签长度不超过20
+   */
+  private String tag;
+  /**
+   * 小程序页面的标题,标题长度不超过32
+   */
+  private String title;
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeAuditStatus.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeAuditStatus.java
new file mode 100644
index 0000000000..36c33eaf1a
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeAuditStatus.java
@@ -0,0 +1,37 @@
+package cn.binarywang.wx.miniapp.bean.code;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import com.google.gson.annotations.SerializedName;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 小程序代码审核状态
+ *
+ * @author Charming
+ * @since 2018-04-26 19:44:39
+ */
+@Data
+@Builder
+public class WxMaCodeAuditStatus implements Serializable {
+  private static final long serialVersionUID = 4655119308692217268L;
+  /**
+   * 审核 ID
+   */
+  @SerializedName(value = "auditId", alternate = {"auditid"})
+  private Long auditId;
+  /**
+   * 审核状态,其中0为审核成功,1为审核失败,2为审核中
+   */
+  private Integer status;
+  /**
+   * 当status=1,审核被拒绝时,返回的拒绝原因
+   */
+  private String reason;
+
+  public static WxMaCodeAuditStatus fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaCodeAuditStatus.class);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeCommitRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeCommitRequest.java
new file mode 100644
index 0000000000..ec64da59a3
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeCommitRequest.java
@@ -0,0 +1,39 @@
+package cn.binarywang.wx.miniapp.bean.code;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 微信代码请求上传参数
+ *
+ * @author Charming
+ * @since 2018-04-26 19:44:47
+ */
+@Data
+@Builder
+public class WxMaCodeCommitRequest implements Serializable {
+  private static final long serialVersionUID = 7495157056049312108L;
+  /**
+   * 代码库中的代码模版ID
+   */
+  private Long templateId;
+  /**
+   * 第三方自定义的配置
+   */
+  private WxMaCodeExtConfig extConfig;
+  /**
+   * 代码版本号,开发者可自定义
+   */
+  private String userVersion;
+  /**
+   * 代码描述,开发者可自定义
+   */
+  private String userDesc;
+
+  public String toJson() {
+    return WxMaGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeExtConfig.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeExtConfig.java
new file mode 100644
index 0000000000..5d0314b2c6
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeExtConfig.java
@@ -0,0 +1,205 @@
+package cn.binarywang.wx.miniapp.bean.code;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 上传代码需要用到的第三方自定义的配置
+ * 详细文档,参考:https://developers.weixin.qq.com/miniprogram/dev/framework/config.html
+ *
+ * @author Charming
+ * @since 2018-04-26 19:44
+ */
+@Data
+@Builder
+public class WxMaCodeExtConfig implements Serializable {
+  private static final long serialVersionUID = -7666911367458178753L;
+  /**
+   * 配置 ext.json 是否生效.
+   * 必填:是
+   */
+  private boolean extEnable;
+  /**
+   * 配置 extAppid.
+   * 必填:是
+   */
+  private String extAppid;
+  /**
+   * 开发自定义的数据字段.
+   * 必填:否
+   */
+  private Object ext;
+  /**
+   * 单独设置每个页面的 json.
+   * 必填:否
+   * key: page 名称,如 pages/logs/logs
+   * value: page 配置
+   */
+  private Map extPages;
+  /**
+   * 是否直接提交到待审核列表.
+   * 必填:否
+   */
+  private Boolean directCommit;
+  /**
+   * 设置页面路径(同 app.json 相同的字段,填写会覆盖 app.json).
+   * 必填:否
+   */
+  private List pages;
+  /**
+   * 设置默认页面的窗口表现(同 app.json 相同的字段,填写会覆盖 app.json)
+   * 必填:否
+   */
+  private PageConfig window;
+  /**
+   * 设置各种网络请求的超时时间(同 app.json 相同的字段,填写会覆盖 app.json)
+   * 必填:否
+   */
+  private NetworkTimeout networkTimeout;
+  /**
+   * 设置是否开启 debug 模式(同 app.json 相同的字段,填写会覆盖 app.json)
+   * 必填:否
+   */
+  private Boolean debug;
+  /**
+   * 底部 tab 栏的表现.
+   * 必填:否
+   */
+  private TabBar tabBar;
+
+  /**
+   * page.json 配置,页面配置
+   * 文档:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html
+   */
+  @Data
+  @Builder
+  public static class PageConfig {
+    /**
+     * 导航栏背景颜色,如"#000000" HexColor.
+     * 默认:#000000
+     */
+    private String navigationBarBackgroundColor;
+    /**
+     * 导航栏标题颜色,仅支持 black/white.
+     * 默认:white
+     */
+    private String navigationBarTextStyle;
+    /**
+     * 导航栏标题文字内容.
+     */
+    private String navigationBarTitleText;
+    /**
+     * 窗口的背景色 HexColor.
+     * 默认:#ffffff
+     */
+    private String backgroundColor;
+    /**
+     * 下拉背景字体、loading 图的样式,仅支持 dark/light.
+     * 默认:dark
+     */
+    private String backgroundTextStyle;
+    /**
+     * 是否开启下拉刷新,详见页面相关事件处理函数.
+     * 默认:false
+     */
+    private String enablePullDownRefresh;
+    /**
+     * 设置为 true 则页面整体不能上下滚动;只在 page.json 中有效,无法在 app.json 中设置该项.
+     * 默认:false
+     */
+    private Boolean disableScroll;
+    /**
+     * 页面上拉触底事件触发时距页面底部距离,单位为px.
+     * 默认:50
+     */
+    private Integer onReachBottomDistance;
+  }
+
+  /**
+   * tabBar 配置.
+   */
+  @Data
+  @Builder
+  public static class TabBar {
+    /**
+     * HexColor, tab 上的文字默认颜色.
+     */
+    private String color;
+    /**
+     * HexColor, tab 上的文字选中时的颜色.
+     */
+    private String selectedColor;
+    /**
+     * HexColor, tab 的背景色.
+     */
+    private String backgroundColor;
+    /**
+     * tabbar 上边框的颜色,仅支持 black/white.
+     */
+    private String borderStyle;
+    /**
+     * tab 的列表,最少2个、最多5个 tab.
+     */
+    private List list;
+    /**
+     * 可选值 bottom、top.
+     */
+    private String position;
+
+    /**
+     * list item.
+     */
+    @Data
+    @Builder
+    public static class Item {
+      /**
+       * 页面路径,必须在 pages 中先定义.
+       */
+      private String pagePath;
+      /**
+       * tab 上按钮文字.
+       */
+      private String text;
+      /**
+       * 图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 postion 为 top 时,此参数无效,不支持网络图片.
+       */
+      private String iconPath;
+      /**
+       * 选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 postion 为 top 时,此参数无效.
+       */
+      private String selectedIconPath;
+    }
+  }
+
+  /**
+   * 各种网络请求的超时时间.
+   */
+  @Data
+  @Builder
+  public static class NetworkTimeout {
+    /**
+     * wx.request的超时时间,单位毫秒,默认为:60000.
+     * 必填:否
+     */
+    private Integer request;
+    /**
+     * wx.connectSocket的超时时间,单位毫秒,默认为:60000.
+     * 必填:否
+     */
+    private Integer connectSocket;
+    /**
+     * wx.uploadFile的超时时间,单位毫秒,默认为:60000.
+     * 必填:否
+     */
+    private Integer uploadFile;
+    /**
+     * wx.downloadFile的超时时间,单位毫秒,默认为:60000.
+     * 必填:否
+     */
+    private Integer downloadFile;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeSubmitAuditRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeSubmitAuditRequest.java
new file mode 100644
index 0000000000..5b784dbded
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeSubmitAuditRequest.java
@@ -0,0 +1,30 @@
+package cn.binarywang.wx.miniapp.bean.code;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import com.google.gson.annotations.SerializedName;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 提交审核的请求
+ *
+ * @author Charming
+ * @since 2018-04-26 19:45
+ */
+@Data
+@Builder
+public class WxMaCodeSubmitAuditRequest implements Serializable {
+  private static final long serialVersionUID = 8854979405505241314L;
+  /**
+   * 提交审核项的一个列表(至少填写1项,至多填写5项)
+   */
+  @SerializedName("item_list")
+  private List itemList;
+
+  public String toJson() {
+    return WxMaGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeVersionDistribution.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeVersionDistribution.java
new file mode 100644
index 0000000000..4c0f09644f
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeVersionDistribution.java
@@ -0,0 +1,30 @@
+package cn.binarywang.wx.miniapp.bean.code;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * 小程序代码版本号分布
+ *
+ * @author Charming
+ * @since 2018-04-26 19:45
+ */
+@Data
+public class WxMaCodeVersionDistribution {
+  /**
+   * 当前版本
+   */
+  private String nowVersion;
+  /**
+   * 受影响用户占比
+   * key: version, 版本号
+   * value: percentage, 受影响比例
+   */
+  private Map uvInfo;
+
+  public static WxMaCodeVersionDistribution fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaCodeVersionDistribution.class);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/package-info.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/package-info.java
new file mode 100644
index 0000000000..01f6496b99
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * 微信小程序代码管理相关的 bean
+ *
+ * @author Charming
+ * @since 2018-04-26 19:44
+ */
+package cn.binarywang.wx.miniapp.bean.code;
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateAddResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateAddResult.java
new file mode 100644
index 0000000000..4b30870d60
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateAddResult.java
@@ -0,0 +1,20 @@
+package cn.binarywang.wx.miniapp.bean.template;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+
+@Data
+public class WxMaTemplateAddResult implements Serializable{
+
+  private static final long serialVersionUID = 872250961973834465L;
+
+  @SerializedName("template_id")
+  private String templateId;
+
+  public static WxMaTemplateAddResult fromJson(String json){
+    return WxGsonBuilder.create().fromJson(json, WxMaTemplateAddResult.class);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateLibraryGetResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateLibraryGetResult.java
new file mode 100644
index 0000000000..e55ed0d563
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateLibraryGetResult.java
@@ -0,0 +1,31 @@
+package cn.binarywang.wx.miniapp.bean.template;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class WxMaTemplateLibraryGetResult implements Serializable{
+
+  private static final long serialVersionUID = -190847592776636744L;
+  private String id;
+  private String title;
+  @SerializedName("keyword_list")
+  private List keywordList;
+
+  @Data
+  public static class KeywordInfo{
+
+    @SerializedName("keyword_id")
+    private int keywordId;
+    private String name;
+    private String example;
+  }
+
+  public static WxMaTemplateLibraryGetResult fromJson(String json){
+    return WxGsonBuilder.create().fromJson(json, WxMaTemplateLibraryGetResult.class);
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateLibraryListResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateLibraryListResult.java
new file mode 100644
index 0000000000..1926971b65
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateLibraryListResult.java
@@ -0,0 +1,28 @@
+package cn.binarywang.wx.miniapp.bean.template;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class WxMaTemplateLibraryListResult implements Serializable{
+  private static final long serialVersionUID = -2780782521447602209L;
+
+  @SerializedName("total_count")
+  private int totalCount;
+  private List list;
+
+  public static WxMaTemplateLibraryListResult fromJson(String json){
+    return WxGsonBuilder.create().fromJson(json, WxMaTemplateLibraryListResult.class);
+  }
+
+  @Data
+  public static class TemplateItem{
+
+    private String id;
+    private String title;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateListResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateListResult.java
new file mode 100644
index 0000000000..0537fefcc5
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaTemplateListResult.java
@@ -0,0 +1,29 @@
+package cn.binarywang.wx.miniapp.bean.template;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class WxMaTemplateListResult implements Serializable{
+
+  private static final long serialVersionUID = -7430535579782184537L;
+  private List list;
+
+  public static WxMaTemplateListResult fromJson(String json){
+    return WxGsonBuilder.create().fromJson(json, WxMaTemplateListResult.class);
+  }
+
+  @Data
+  public static class TemplateInfo{
+
+    @SerializedName("template_id")
+    private String templateId;
+    private String title;
+    private String content;
+    private String example;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/BaseBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/BaseBuilder.java
index 70d7cf4b7c..c353534c3f 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/BaseBuilder.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/BaseBuilder.java
@@ -15,6 +15,9 @@ public T toUser(String toUser) {
     return (T) this;
   }
 
+  /**
+   * 构造器方法.
+   */
   public WxMaKefuMessage build() {
     WxMaKefuMessage m = new WxMaKefuMessage();
     m.setMsgType(this.msgType);
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageBuilder.java
deleted file mode 100644
index a903e97c43..0000000000
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageBuilder.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.binarywang.wx.miniapp.builder;
-
-import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
-import cn.binarywang.wx.miniapp.constant.WxMaConstants;
-
-/**
- * @author Binary Wang
- */
-public final class ImageBuilder extends BaseBuilder {
-  private String mediaId;
-
-  public ImageBuilder() {
-    this.msgType = WxMaConstants.KefuMsgType.IMAGE;
-  }
-
-  public ImageBuilder mediaId(String media_id) {
-    this.mediaId = media_id;
-    return this;
-  }
-
-  @Override
-  public WxMaKefuMessage build() {
-    WxMaKefuMessage m = super.build();
-    m.setMediaId(this.mediaId);
-    return m;
-  }
-}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageMessageBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageMessageBuilder.java
new file mode 100644
index 0000000000..bcd2290f10
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageMessageBuilder.java
@@ -0,0 +1,30 @@
+package cn.binarywang.wx.miniapp.builder;
+
+import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
+
+import static cn.binarywang.wx.miniapp.constant.WxMaConstants.KefuMsgType;
+
+/**
+ * 图片消息builder.
+ *
+ * @author Binary Wang
+ */
+public final class ImageMessageBuilder extends BaseBuilder {
+  private String mediaId;
+
+  public ImageMessageBuilder() {
+    this.msgType = KefuMsgType.IMAGE;
+  }
+
+  public ImageMessageBuilder mediaId(String mediaId) {
+    this.mediaId = mediaId;
+    return this;
+  }
+
+  @Override
+  public WxMaKefuMessage build() {
+    WxMaKefuMessage m = super.build();
+    m.setImage(new WxMaKefuMessage.KfImage(this.mediaId));
+    return m;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/LinkMessageBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/LinkMessageBuilder.java
new file mode 100644
index 0000000000..f4927e16dc
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/LinkMessageBuilder.java
@@ -0,0 +1,53 @@
+package cn.binarywang.wx.miniapp.builder;
+
+import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
+
+import static cn.binarywang.wx.miniapp.constant.WxMaConstants.KefuMsgType;
+
+/**
+ * 图文链接消息builder
+ *
+ * @author Binary Wang
+ */
+public class LinkMessageBuilder extends BaseBuilder {
+  private String title;
+  private String description;
+  private String url;
+  private String thumbUrl;
+
+  public LinkMessageBuilder() {
+    this.msgType = KefuMsgType.LINK;
+  }
+
+  public LinkMessageBuilder title(String title) {
+    this.title = title;
+    return this;
+  }
+
+  public LinkMessageBuilder description(String description) {
+    this.description = description;
+    return this;
+  }
+
+  public LinkMessageBuilder url(String url) {
+    this.url = url;
+    return this;
+  }
+
+  public LinkMessageBuilder thumbUrl(String thumbUrl) {
+    this.thumbUrl = thumbUrl;
+    return this;
+  }
+
+  @Override
+  public WxMaKefuMessage build() {
+    WxMaKefuMessage m = super.build();
+    m.setLink(WxMaKefuMessage.KfLink.builder().title(this.title)
+      .description(this.description)
+      .url(this.url)
+      .thumbUrl(this.thumbUrl)
+      .build()
+    );
+    return m;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/MaPageMessageBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/MaPageMessageBuilder.java
new file mode 100644
index 0000000000..238a60146e
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/MaPageMessageBuilder.java
@@ -0,0 +1,47 @@
+package cn.binarywang.wx.miniapp.builder;
+
+import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
+
+import static cn.binarywang.wx.miniapp.constant.WxMaConstants.KefuMsgType;
+
+/**
+ * 小程序卡片消息builder
+ *
+ * @author Binary Wang
+ */
+public class MaPageMessageBuilder extends BaseBuilder {
+  private String title;
+  private String pagePath;
+  private String thumbMediaId;
+
+  public MaPageMessageBuilder() {
+    this.msgType = KefuMsgType.MA_PAGE;
+  }
+
+  public MaPageMessageBuilder title(String title) {
+    this.title = title;
+    return this;
+  }
+
+  public MaPageMessageBuilder pagePath(String pagePath) {
+    this.pagePath = pagePath;
+    return this;
+  }
+
+  public MaPageMessageBuilder thumbMediaId(String thumbMediaId) {
+    this.thumbMediaId = thumbMediaId;
+    return this;
+  }
+
+  @Override
+  public WxMaKefuMessage build() {
+    WxMaKefuMessage m = super.build();
+    m.setMaPage(WxMaKefuMessage.KfMaPage.builder()
+      .title(this.title)
+      .pagePath(this.pagePath)
+      .thumbMediaId(this.thumbMediaId)
+      .build()
+    );
+    return m;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/TextBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/TextBuilder.java
deleted file mode 100644
index 35c58a67df..0000000000
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/TextBuilder.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.binarywang.wx.miniapp.builder;
-
-import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
-import cn.binarywang.wx.miniapp.constant.WxMaConstants;
-
-/**
- * @author Binary Wang
- */
-public final class TextBuilder extends BaseBuilder {
-  private String content;
-
-  public TextBuilder() {
-    this.msgType = WxMaConstants.KefuMsgType.TEXT;
-  }
-
-  public TextBuilder content(String content) {
-    this.content = content;
-    return this;
-  }
-
-  @Override
-  public WxMaKefuMessage build() {
-    WxMaKefuMessage m = super.build();
-    m.setContent(this.content);
-    return m;
-  }
-}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/TextMessageBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/TextMessageBuilder.java
new file mode 100644
index 0000000000..d0da32573c
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/TextMessageBuilder.java
@@ -0,0 +1,30 @@
+package cn.binarywang.wx.miniapp.builder;
+
+import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
+
+import static cn.binarywang.wx.miniapp.constant.WxMaConstants.KefuMsgType;
+
+/**
+ * 文本消息builder.
+ *
+ * @author Binary Wang
+ */
+public final class TextMessageBuilder extends BaseBuilder {
+  private String content;
+
+  public TextMessageBuilder() {
+    this.msgType = KefuMsgType.TEXT;
+  }
+
+  public TextMessageBuilder content(String content) {
+    this.content = content;
+    return this;
+  }
+
+  @Override
+  public WxMaKefuMessage build() {
+    WxMaKefuMessage m = super.build();
+    m.setText(new WxMaKefuMessage.KfText(this.content));
+    return m;
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java
index df72bb2c7d..915cffdddd 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaConfig.java
@@ -38,6 +38,25 @@ public interface WxMaConfig {
    */
   void updateAccessToken(String accessToken, int expiresInSeconds);
 
+  String getJsapiTicket();
+
+  Lock getJsapiTicketLock();
+
+  boolean isJsapiTicketExpired();
+
+  /**
+   * 强制将jsapi ticket过期掉
+   */
+  void expireJsapiTicket();
+
+  /**
+   * 应该是线程安全的
+   *
+   * @param jsapiTicket      新的jsapi ticket值
+   * @param expiresInSeconds 过期时间,以秒为单位
+   */
+  void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
+
   String getAppid();
 
   String getSecret();
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaInMemoryConfig.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaInMemoryConfig.java
index 735a52b56a..d8e286afec 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaInMemoryConfig.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaInMemoryConfig.java
@@ -1,13 +1,15 @@
 package cn.binarywang.wx.miniapp.config;
 
-import me.chanjar.weixin.common.bean.WxAccessToken;
-import me.chanjar.weixin.common.util.ToStringUtils;
-import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
-
 import java.io.File;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+
 /**
  * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
  *
@@ -27,7 +29,11 @@ public class WxMaInMemoryConfig implements WxMaConfig {
   protected volatile String httpProxyUsername;
   protected volatile String httpProxyPassword;
 
+  protected volatile String jsapiTicket;
+  protected volatile long jsapiTicketExpiresTime;
+
   protected Lock accessTokenLock = new ReentrantLock();
+  protected Lock jsapiTicketLock = new ReentrantLock();
 
   /**
    * 临时文件目录
@@ -70,6 +76,33 @@ public synchronized void updateAccessToken(String accessToken, int expiresInSeco
     this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
   }
 
+  @Override
+  public String getJsapiTicket() {
+    return this.jsapiTicket;
+  }
+
+  @Override
+  public Lock getJsapiTicketLock() {
+    return this.jsapiTicketLock;
+  }
+
+  @Override
+  public boolean isJsapiTicketExpired() {
+    return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
+  }
+
+  @Override
+  public void expireJsapiTicket() {
+    this.jsapiTicketExpiresTime = 0;
+  }
+
+  @Override
+  public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
+    this.jsapiTicket = jsapiTicket;
+    // 预留200秒的时间
+    this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+  }
+
   @Override
   public void expireAccessToken() {
     this.expiresTime = 0;
@@ -158,7 +191,7 @@ public void setHttpProxyPassword(String httpProxyPassword) {
 
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 
   @Override
@@ -175,6 +208,7 @@ public boolean autoRefreshToken() {
     return true;
   }
 
+  @Override
   public String getAppid() {
     return appid;
   }
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java
index 14016fa578..1ea3595e9a 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java
@@ -2,21 +2,29 @@
 
 /**
  * 
- *  小程序常量
+ *  小程序常量.
  * 
* * @author Binary Wang */ public class WxMaConstants { /** - * 素材类型 + * 微信接口返回的参数errcode. + */ + public static final String ERRCODE = "errcode"; + + /** + * 素材类型. */ public static class MediaType { - public static final String IMAGE = "image";//图片 + /** + * 图片. + */ + public static final String IMAGE = "image"; } /** - * 消息格式 + * 消息格式. */ public static class MsgDataFormat { public static final String XML = "XML"; @@ -24,10 +32,41 @@ public static class MsgDataFormat { } /** - * 客服消息的消息类型 + * 客服消息的消息类型. */ public static class KefuMsgType { - public static final String TEXT = "text";//文本消息 - public static final String IMAGE = "image";//图片消息 + /** + * 文本消息. + */ + public static final String TEXT = "text"; + /** + * 图片消息. + */ + public static final String IMAGE = "image"; + /** + * 图文链接. + */ + public static final String LINK = "link"; + /** + * 小程序卡片消息. + */ + public static final String MA_PAGE = "miniprogrampage"; + } + + public static final class ErrorCode { + /** + * 40001 获取access_token时AppSecret错误,或者access_token无效. + */ + public static final int ERR_40001 = 40001; + + /** + * 42001 access_token超时. + */ + public static final int ERR_42001 = 42001; + + /** + * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期). + */ + public static final int ERR_40014 = 40014; } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageHandler.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageHandler.java index 794d60e98a..f60edc1d8a 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageHandler.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageHandler.java @@ -2,7 +2,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaMessage; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import java.util.Map; diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageInterceptor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageInterceptor.java index 3443862fe1..ef0d500a19 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageInterceptor.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageInterceptor.java @@ -2,7 +2,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaMessage; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import java.util.Map; diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouter.java index cbe42b1f26..be3af708bd 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouter.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouter.java @@ -2,6 +2,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaMessage; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import me.chanjar.weixin.common.api.WxErrorExceptionHandler; import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; @@ -17,10 +18,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.*; /** * @author Binary Wang @@ -42,7 +40,9 @@ public class WxMaMessageRouter { public WxMaMessageRouter(WxMaService wxMaService) { this.wxMaService = wxMaService; - this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); + ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("WxMaMessageRouter-pool-%d").build(); + this.executorService = new ThreadPoolExecutor(DEFAULT_THREAD_POOL_SIZE, DEFAULT_THREAD_POOL_SIZE, + 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), namedThreadFactory); this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); this.sessionManager = new StandardSessionManager(); this.exceptionHandler = new LogExceptionHandler(); @@ -159,7 +159,7 @@ public void run() { } public void route(final WxMaMessage wxMessage) { - this.route(wxMessage, new HashMap()); + this.route(wxMessage, new HashMap(2)); } /** diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java index 835eb2894a..2e4906ebf1 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java @@ -3,7 +3,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaMessage; import me.chanjar.weixin.common.api.WxErrorExceptionHandler; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import java.util.ArrayList; @@ -196,7 +196,7 @@ protected void service(WxMaMessage wxMessage, WxSessionManager sessionManager, WxErrorExceptionHandler exceptionHandler) { if (context == null) { - context = new HashMap<>(); + context = new HashMap<>(16); } try { diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/http/QrCodeRequestExecutor.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/http/QrCodeRequestExecutor.java index 3c026f4a18..cb8097db53 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/http/QrCodeRequestExecutor.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/http/QrCodeRequestExecutor.java @@ -1,8 +1,8 @@ package cn.binarywang.wx.miniapp.util.http; -import cn.binarywang.wx.miniapp.bean.WxMaQrcodeWrapper; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import cn.binarywang.wx.miniapp.bean.AbstractWxMaQrcodeWrapper; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; @@ -25,7 +25,7 @@ /** * @author Binary Wang */ -public class QrCodeRequestExecutor implements RequestExecutor { +public class QrCodeRequestExecutor implements RequestExecutor { protected RequestHttp requestHttp; public QrCodeRequestExecutor(RequestHttp requestHttp) { @@ -33,22 +33,21 @@ public QrCodeRequestExecutor(RequestHttp requestHttp) { } @Override - public File execute(String uri, WxMaQrcodeWrapper ticket) throws WxErrorException, IOException { + public File execute(String uri, AbstractWxMaQrcodeWrapper ticket) throws WxErrorException, IOException { HttpPost httpPost = new HttpPost(uri); if (requestHttp.getRequestHttpProxy() != null) { - httpPost - .setConfig(RequestConfig.custom() - .setProxy(requestHttp.getRequestHttpProxy()) - .build() - ); + httpPost.setConfig( + RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build() + ); } - httpPost.setEntity(new StringEntity(ticket.toString())); + httpPost.setEntity(new StringEntity(ticket.toJson())); try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost); InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) { Header[] contentTypeHeader = response.getHeaders("Content-Type"); if (contentTypeHeader != null && contentTypeHeader.length > 0 - && ContentType.APPLICATION_JSON.getMimeType().equals(contentTypeHeader[0].getValue())) { + && ContentType.APPLICATION_JSON.getMimeType() + .equals(ContentType.parse(contentTypeHeader[0].getValue()).getMimeType())) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); throw new WxErrorException(WxError.fromJson(responseContent)); } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaCodeCommitRequestGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaCodeCommitRequestGsonAdapter.java new file mode 100755 index 0000000000..410f86ca1f --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaCodeCommitRequestGsonAdapter.java @@ -0,0 +1,28 @@ +package cn.binarywang.wx.miniapp.util.json; + +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; + +/** + * @author Charming + * @since 2018-04-26 19:47 + */ +public class WxMaCodeCommitRequestGsonAdapter implements JsonSerializer { + + @Override + public JsonElement serialize(WxMaCodeCommitRequest request, Type typeOfSrc, JsonSerializationContext context) { + JsonObject requestJson = new JsonObject(); + requestJson.addProperty("template_id", request.getTemplateId()); + requestJson.addProperty("user_version", request.getUserVersion()); + requestJson.addProperty("user_desc", request.getUserDesc()); + if (request.getExtConfig() != null) { + requestJson.addProperty("ext_json", WxMaGsonBuilder.create().toJson(request.getExtConfig())); + } + return requestJson; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaCodeVersionDistributionGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaCodeVersionDistributionGsonAdapter.java new file mode 100644 index 0000000000..027ca6a959 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaCodeVersionDistributionGsonAdapter.java @@ -0,0 +1,50 @@ +package cn.binarywang.wx.miniapp.util.json; + +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution; +import com.google.gson.JsonArray; +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 me.chanjar.weixin.common.util.json.GsonHelper; + +import java.lang.reflect.Type; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Charming + * @since 2018-04-26 19:47 + */ +public class WxMaCodeVersionDistributionGsonAdapter implements JsonDeserializer { + @Override + public WxMaCodeVersionDistribution deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + if (json == null) { + return null; + } + + WxMaCodeVersionDistribution distribution = new WxMaCodeVersionDistribution(); + JsonObject object = json.getAsJsonObject(); + distribution.setNowVersion(GsonHelper.getString(object, "now_version")); + distribution.setUvInfo(getAsMap(object.getAsJsonObject("uv_info"), "items")); + return distribution; + } + + private Map getAsMap(JsonObject object, String memberName) { + JsonArray array = object.getAsJsonArray(memberName); + if (array != null && array.size() > 0) { + Map map = new LinkedHashMap<>(array.size()); + for (JsonElement element : array) { + JsonObject elementObject = element.getAsJsonObject(); + String version = GsonHelper.getString(elementObject, "version"); + if (version != null) { + Float percentage = GsonHelper.getFloat(elementObject, "percentage"); + map.put(version, percentage); + } + } + return map; + } + return null; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java index 4eb3a8adf0..f01eb33d62 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaGsonBuilder.java @@ -1,7 +1,12 @@ package cn.binarywang.wx.miniapp.util.json; -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; +import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaUserPortrait; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitDistribution; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -13,8 +18,13 @@ public class WxMaGsonBuilder { static { INSTANCE.disableHtmlEscaping(); - INSTANCE.registerTypeAdapter(WxMaKefuMessage.class, new WxMaKefuMessageGsonAdapter()); INSTANCE.registerTypeAdapter(WxMaTemplateMessage.class, new WxMaTemplateMessageGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMaUniformMessage.class, new WxMaUniformMessageGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMaCodeCommitRequest.class, new WxMaCodeCommitRequestGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMaCodeVersionDistribution.class, new WxMaCodeVersionDistributionGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMaVisitDistribution.class, new WxMaVisitDistributionGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMaRetainInfo.class, new WxMaRetainInfoGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMaUserPortrait.class, new WxMaUserPortraitGsonAdapter()); } public static Gson create() { diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaKefuMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaKefuMessageGsonAdapter.java deleted file mode 100644 index 829469f872..0000000000 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaKefuMessageGsonAdapter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ -package cn.binarywang.wx.miniapp.util.json; - -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; -import cn.binarywang.wx.miniapp.constant.WxMaConstants; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -import java.lang.reflect.Type; - -/** - * @author Binary Wang - */ -public class WxMaKefuMessageGsonAdapter implements JsonSerializer { - - @Override - public JsonElement serialize(WxMaKefuMessage message, Type typeOfSrc, JsonSerializationContext context) { - JsonObject messageJson = new JsonObject(); - messageJson.addProperty("touser", message.getToUser()); - messageJson.addProperty("msgtype", message.getMsgType()); - - if (WxMaConstants.KefuMsgType.TEXT.equals(message.getMsgType())) { - JsonObject text = new JsonObject(); - text.addProperty("content", message.getContent()); - messageJson.add("text", text); - } - - if (WxMaConstants.KefuMsgType.IMAGE.equals(message.getMsgType())) { - JsonObject image = new JsonObject(); - image.addProperty("media_id", message.getMediaId()); - messageJson.add("image", image); - } - - return messageJson; - } - -} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaRetainInfoGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaRetainInfoGsonAdapter.java new file mode 100644 index 0000000000..a51972b4bd --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaRetainInfoGsonAdapter.java @@ -0,0 +1,52 @@ +package cn.binarywang.wx.miniapp.util.json; + +import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo; +import com.google.gson.JsonArray; +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 me.chanjar.weixin.common.util.json.GsonHelper; + +import java.lang.reflect.Type; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Charming + * @since 2018-04-28 + */ +public class WxMaRetainInfoGsonAdapter implements JsonDeserializer { + @Override + public WxMaRetainInfo deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + if (json == null) { + return null; + } + + WxMaRetainInfo retainInfo = new WxMaRetainInfo(); + JsonObject object = json.getAsJsonObject(); + String refDate = GsonHelper.getString(object, "ref_date"); + retainInfo.setRefDate(refDate); + retainInfo.setVisitUvNew(getAsMap(object, "visit_uv_new")); + retainInfo.setVisitUv(getAsMap(object, "visit_uv")); + return retainInfo; + } + + private Map getAsMap(JsonObject object, String memberName) { + JsonArray array = object.getAsJsonArray(memberName); + if (array != null && array.size() > 0) { + Map map = new LinkedHashMap<>(array.size()); + for (JsonElement element : array) { + JsonObject elementObject = element.getAsJsonObject(); + Integer key = GsonHelper.getInteger(elementObject, "key"); + if (key != null) { + Integer value = GsonHelper.getInteger(elementObject, "value"); + map.put(key, value); + } + } + return map; + } + return null; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java index 0b4edee286..800a7e5a8e 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java @@ -1,13 +1,14 @@ package cn.binarywang.wx.miniapp.util.json; +import java.lang.reflect.Type; + +import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; -import java.lang.reflect.Type; - /** * @author Binary Wang */ @@ -26,10 +27,6 @@ public JsonElement serialize(WxMaTemplateMessage message, Type typeOfSrc, JsonSe messageJson.addProperty("form_id", message.getFormId()); } - if (message.getPage() != null) { - messageJson.addProperty("page", message.getPage()); - } - if (message.getColor() != null) { messageJson.addProperty("color", message.getColor()); } @@ -45,7 +42,7 @@ public JsonElement serialize(WxMaTemplateMessage message, Type typeOfSrc, JsonSe return messageJson; } - for (WxMaTemplateMessage.Data datum : message.getData()) { + for (WxMaTemplateData datum : message.getData()) { JsonObject dataJson = new JsonObject(); dataJson.addProperty("value", datum.getValue()); if (datum.getColor() != null) { diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java new file mode 100644 index 0000000000..c847bf375b --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java @@ -0,0 +1,98 @@ +package cn.binarywang.wx.miniapp.util.json; + +import java.lang.reflect.Type; + +import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; +import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +/** + * @author Binary Wang + */ +public class WxMaUniformMessageGsonAdapter implements JsonSerializer { + + @Override + public JsonElement serialize(WxMaUniformMessage message, Type typeOfSrc, JsonSerializationContext context) { + JsonObject messageJson = new JsonObject(); + messageJson.addProperty("touser", message.getToUser()); + if (message.isMpTemplateMsg()) { + JsonObject msg = new JsonObject(); + if (message.getAppid() != null) { + msg.addProperty("appid", message.getAppid()); + } + + msg.addProperty("template_id", message.getTemplateId()); + + if (message.getUrl() != null) { + msg.addProperty("url", message.getUrl()); + } + + final WxMaUniformMessage.MiniProgram miniProgram = message.getMiniProgram(); + if (miniProgram != null) { + JsonObject miniProgramJson = new JsonObject(); + miniProgramJson.addProperty("appid", miniProgram.getAppid()); + if (miniProgram.isUsePath()) { + miniProgramJson.addProperty("path", miniProgram.getPagePath()); + } else { + miniProgramJson.addProperty("pagepath", miniProgram.getPagePath()); + } + msg.add("miniprogram", miniProgramJson); + } + + if (message.getData() != null) { + JsonObject data = new JsonObject(); + for (WxMaTemplateData templateData : message.getData()) { + JsonObject dataJson = new JsonObject(); + dataJson.addProperty("value", templateData.getValue()); + if (templateData.getColor() != null) { + dataJson.addProperty("color", templateData.getColor()); + } + data.add(templateData.getName(), dataJson); + } + msg.add("data", data); + } + + + messageJson.add("mp_template_msg", msg); + return messageJson; + } + + //小程序模版消息 + JsonObject msg = new JsonObject(); + msg.addProperty("template_id", message.getTemplateId()); + + if (message.getPage() != null) { + msg.addProperty("page", message.getPage()); + } + + if (message.getFormId() != null) { + msg.addProperty("form_id", message.getFormId()); + } + + JsonObject data = new JsonObject(); + msg.add("data", data); + + if (message.getData() != null) { + for (WxMaTemplateData templateData : message.getData()) { + JsonObject dataJson = new JsonObject(); + dataJson.addProperty("value", templateData.getValue()); + if (templateData.getColor() != null) { + dataJson.addProperty("color", templateData.getColor()); + } + data.add(templateData.getName(), dataJson); + } + } + + if (message.getEmphasisKeyword() != null) { + msg.addProperty("emphasis_keyword", message.getEmphasisKeyword()); + } + + messageJson.add("weapp_template_msg", msg); + + return messageJson; + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUserPortraitGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUserPortraitGsonAdapter.java new file mode 100644 index 0000000000..b8a7c448ff --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUserPortraitGsonAdapter.java @@ -0,0 +1,67 @@ +package cn.binarywang.wx.miniapp.util.json; + +import cn.binarywang.wx.miniapp.bean.analysis.WxMaUserPortrait; +import com.google.gson.JsonArray; +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 me.chanjar.weixin.common.util.json.GsonHelper; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Type; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Charming + * @since 2018-04-28 + */ +public class WxMaUserPortraitGsonAdapter implements JsonDeserializer { + @Override + public WxMaUserPortrait deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + if (json == null) { + return null; + } + + WxMaUserPortrait portrait = new WxMaUserPortrait(); + JsonObject object = json.getAsJsonObject(); + String refDate = GsonHelper.getString(object, "ref_date"); + portrait.setRefDate(refDate); + portrait.setVisitUvNew(getPortraitItem(object.getAsJsonObject("visit_uv_new"))); + portrait.setVisitUv(getPortraitItem(object.getAsJsonObject("visit_uv"))); + return portrait; + } + + private WxMaUserPortrait.Item getPortraitItem(JsonObject object) { + if (object == null) { + return null; + } + WxMaUserPortrait.Item item = new WxMaUserPortrait.Item(); + item.setProvince(getAsMap(object, "province")); + item.setCity(getAsMap(object, "city")); + item.setGenders(getAsMap(object, "genders")); + item.setPlatforms(getAsMap(object, "platforms")); + item.setDevices(getAsMap(object, "devices")); + item.setAges(getAsMap(object, "ages")); + return item; + } + + private Map getAsMap(JsonObject object, String memberName) { + JsonArray array = object.getAsJsonArray(memberName); + if (array != null && array.size() > 0) { + Map map = new LinkedHashMap<>(array.size()); + for (JsonElement element : array) { + JsonObject elementObject = element.getAsJsonObject(); + String name = GsonHelper.getString(elementObject, "name"); + if (StringUtils.isNotBlank(name)) { + Long value = GsonHelper.getLong(elementObject, "value"); + map.put(name, value); + } + } + return map; + } + return null; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaVisitDistributionGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaVisitDistributionGsonAdapter.java new file mode 100644 index 0000000000..45bdbac0ff --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaVisitDistributionGsonAdapter.java @@ -0,0 +1,67 @@ +package cn.binarywang.wx.miniapp.util.json; + +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitDistribution; +import com.google.gson.JsonArray; +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 me.chanjar.weixin.common.util.json.GsonHelper; + +import java.lang.reflect.Type; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Charming + * @since 2018-04-28 + */ +public class WxMaVisitDistributionGsonAdapter implements JsonDeserializer { + @Override + public WxMaVisitDistribution deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + if (json == null) { + return null; + } + + WxMaVisitDistribution distribution = new WxMaVisitDistribution(); + JsonObject object = json.getAsJsonObject(); + String refDate = GsonHelper.getString(object, "ref_date"); + distribution.setRefDate(refDate); + + boolean hasList = object.has("list"); + if (!hasList) { + return distribution; + } + + JsonArray listArray = object.getAsJsonArray("list"); + Map> list = new Hashtable<>(listArray.size()); + for (JsonElement indexElement : listArray) { + JsonObject indexObject = indexElement.getAsJsonObject(); + String index = GsonHelper.getString(indexObject, "index"); + if (index == null) { + continue; + } + + Map itemList = new LinkedHashMap<>(); + JsonArray itemArray = indexObject.getAsJsonArray("item_list"); + if (itemArray == null || itemArray.size() <= 0) { + list.put(index, itemList); + continue; + } + + for (JsonElement itemElement : itemArray) { + JsonObject itemObject = itemElement.getAsJsonObject(); + Integer key = GsonHelper.getInteger(itemObject, "key"); + Integer value = GsonHelper.getInteger(itemObject, "value"); + if (key != null) { + itemList.put(key, value); + } + } + list.put(index, itemList); + } + distribution.setList(list); + return distribution; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java index f85c716acb..95b09713a3 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java @@ -1,12 +1,16 @@ package cn.binarywang.wx.miniapp.util.xml; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import cn.binarywang.wx.miniapp.bean.WxMaMessage; import com.thoughtworks.xstream.XStream; import me.chanjar.weixin.common.util.xml.XStreamInitializer; -import java.io.InputStream; -import java.util.*; - /** * @author Binary Wang */ @@ -18,7 +22,7 @@ public class XStreamTransformer { } /** - * xml -> pojo + * xml -> pojo. */ @SuppressWarnings("unchecked") public static T fromXml(Class clazz, String xml) { @@ -33,29 +37,30 @@ public static T fromXml(Class clazz, InputStream is) { } /** - * pojo -> xml + * pojo -> xml. */ public static String toXml(Class clazz, T object) { return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); } /** - * 注册扩展消息的解析器 + * 注册扩展消息的解析器. * * @param clz 类型 * @param xStream xml解析器 */ - private static void register(Class clz, XStream xStream) { + public static void register(Class clz, XStream xStream) { CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); } /** - * 会自动注册该类及其子类 + * 会自动注册该类及其子类. * * @param clz 要注册的类 */ private static void registerClass(Class clz) { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(clz); xstream.processAnnotations(getInnerClasses(clz)); if (clz.equals(WxMaMessage.class)) { diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaAnalysisServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaAnalysisServiceImplTest.java new file mode 100644 index 0000000000..9c1c2f00e5 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaAnalysisServiceImplTest.java @@ -0,0 +1,155 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaRetainInfo; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaSummaryTrend; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaUserPortrait; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitDistribution; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitPage; +import cn.binarywang.wx.miniapp.bean.analysis.WxMaVisitTrend; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.inject.Inject; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import static org.testng.Assert.*; + +/** + * @author Charming + * @since 2018-04-28 + */ +@Guice(modules = ApiTestModule.class) +public class WxMaAnalysisServiceImplTest { + @Inject + private WxMaService wxMaService; + + @Test + public void testGetDailySummaryTrend() throws Exception { + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + Date twoDaysAgo = DateUtils.addDays(new Date(), -2); + List trends = service.getDailySummaryTrend(twoDaysAgo, twoDaysAgo); + assertEquals(1, trends.size()); + System.out.println(trends); + } + + @Test + public void testGetDailyVisitTrend() throws Exception { + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + Date twoDaysAgo = DateUtils.addDays(new Date(), -2); + List trends = service.getDailyVisitTrend(twoDaysAgo, twoDaysAgo); + assertEquals(1, trends.size()); + System.out.println(trends); + } + + @Test + public void testGetWeeklyVisitTrend() throws Exception { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + Date now = new Date(); + Date lastSunday = calendar.getTime(); + if (DateUtils.isSameDay(lastSunday, now)) { + lastSunday = DateUtils.addDays(lastSunday, -7); + } + Date lastMonday = DateUtils.addDays(lastSunday, -6); + + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + List trends = service.getWeeklyVisitTrend(lastMonday, lastSunday); + assertEquals(1, trends.size()); + System.out.println(trends); + } + + @Test + public void testGetMonthlyVisitTrend() throws Exception { + Date now = new Date(); + Date firstDayOfThisMonth = DateUtils.setDays(now, 1); + Date lastDayOfLastMonth = DateUtils.addDays(firstDayOfThisMonth, -1); + Date firstDayOfLastMonth = DateUtils.addMonths(firstDayOfThisMonth, -1); + + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + List trends = service.getMonthlyVisitTrend(firstDayOfLastMonth, lastDayOfLastMonth); + assertEquals(1, trends.size()); + System.out.println(trends); + } + + @Test + public void testGetVisitDistribution() throws Exception { + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + Date twoDaysAgo = DateUtils.addDays(new Date(), -2); + WxMaVisitDistribution distribution = service.getVisitDistribution(twoDaysAgo, twoDaysAgo); + assertNotNull(distribution); + String date = DateFormatUtils.format(twoDaysAgo, "yyyyMMdd"); + assertEquals(date, distribution.getRefDate()); + assertTrue(distribution.getList().containsKey("access_source_session_cnt")); + assertTrue(distribution.getList().containsKey("access_staytime_info")); + assertTrue(distribution.getList().containsKey("access_depth_info")); + System.out.println(distribution); + } + + @Test + public void testGetDailyRetainInfo() throws Exception { + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + Date twoDaysAgo = DateUtils.addDays(new Date(), -2); + WxMaRetainInfo retainInfo = service.getDailyRetainInfo(twoDaysAgo, twoDaysAgo); + assertNotNull(retainInfo); + System.out.println(retainInfo); + } + + @Test + public void testGetWeeklyRetainInfo() throws Exception { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + Date now = new Date(); + Date lastSunday = calendar.getTime(); + if (DateUtils.isSameDay(lastSunday, now)) { + lastSunday = DateUtils.addDays(lastSunday, -7); + } + Date lastMonday = DateUtils.addDays(lastSunday, -6); + + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + WxMaRetainInfo retainInfo = service.getWeeklyRetainInfo(lastMonday, lastSunday); + assertNotNull(retainInfo); + System.out.println(retainInfo); + } + + @Test + public void testGetMonthlyRetainInfo() throws Exception { + Date now = new Date(); + Date firstDayOfThisMonth = DateUtils.setDays(now, 1); + Date lastDayOfLastMonth = DateUtils.addDays(firstDayOfThisMonth, -1); + Date firstDayOfLastMonth = DateUtils.addMonths(firstDayOfThisMonth, -1); + + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + WxMaRetainInfo retainInfo = service.getMonthlyRetainInfo(firstDayOfLastMonth, lastDayOfLastMonth); + assertNotNull(retainInfo); + System.out.println(retainInfo); + } + + @Test + public void testGetVisitPage() throws Exception { + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + Date twoDaysAgo = DateUtils.addDays(new Date(), -2); + List visitPages = service.getVisitPage(twoDaysAgo, twoDaysAgo); + assertNotNull(visitPages); + System.out.println(visitPages); + System.out.println(visitPages.get(0).getPagePath()); + System.out.println(visitPages.get(0).getPageVisitPv()); + } + + @Test + public void testGetUserPortrait() throws Exception { + Date twoDaysAgo = DateUtils.addDays(new Date(), -2); + Date eightDaysAgo = DateUtils.addDays(new Date(), -8); + + final WxMaAnalysisService service = wxMaService.getAnalysisService(); + WxMaUserPortrait portrait = service.getUserPortrait(eightDaysAgo, twoDaysAgo); + assertNotNull(portrait); + System.out.println(portrait); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaCodeServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaCodeServiceImplTest.java new file mode 100644 index 0000000000..0a4aca45e3 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaCodeServiceImplTest.java @@ -0,0 +1,155 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.testng.annotations.*; + +import cn.binarywang.wx.miniapp.api.WxMaCodeService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.code.WxMaCategory; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeAuditStatus; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeExtConfig; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeSubmitAuditRequest; +import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.inject.Inject; + +import static org.testng.Assert.*; + +/** + * @author Charming + * @since 2018-04-26 20:18 + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaCodeServiceImplTest { + @Inject + private WxMaService wxService; + @Inject + private WxMaConfig wxMaConfig; + + @Test + public void testGetCategory() throws Exception { + List categories = wxService.getCodeService().getCategory(); + System.out.println(String.valueOf(categories)); + } + + @Test + public void testCommit() throws Exception { + String themeColor = "#0074d9"; + String themeFontColor = "#ffffff"; + + Map ext = new HashMap<>(); + ext.put("appName", "xxx"); + ext.put("verified", true); + ext.put("navigationBarBackgroundColor", themeColor); + ext.put("navigationBarTextStyle", themeFontColor); + ext.put("companyId", 4128); + ext.put("companyFullName", "xxx有限公司"); + + WxMaCodeService wxMaCodeService = wxService.getCodeService(); + WxMaCodeCommitRequest commitRequest = WxMaCodeCommitRequest + .builder() + .templateId(6L) + .userVersion("v0.1.0") + .userDesc("init") + .extConfig(WxMaCodeExtConfig.builder() + .extAppid(wxMaConfig.getAppid()) + .extEnable(true) + .ext(ext) + .window( + WxMaCodeExtConfig.PageConfig + .builder() + .navigationBarBackgroundColor(themeColor) + .navigationBarTextStyle(themeFontColor) + .build() + ) + .build()) + .build(); + wxMaCodeService.commit(commitRequest); + } + + @Test + public void testGetQrCode() throws Exception { + byte[] qrCode = wxService.getCodeService().getQrCode(null); + assertTrue(qrCode.length > 0); + } + + @Test + public void testGetPage() throws Exception { + List pageList = wxService.getCodeService().getPage(); + System.out.println(String.valueOf(pageList)); + } + + @Test + public void testSubmitAudit() throws Exception { + WxMaCodeSubmitAuditRequest auditRequest = WxMaCodeSubmitAuditRequest + .builder() + .itemList(Arrays.asList( + WxMaCategory + .builder() + .address("pages/logs/logs") + .tag("工具 效率") + .firstClass("工具") + .firstId(287L) + .secondClass("效率") + .secondId(616L) + .title("日志") + .build() + )).build(); + long auditId = wxService.getCodeService().submitAudit(auditRequest); + assertTrue(auditId > 0); + // 421937937 + System.out.println(auditId); + } + + @Test + public void testGetAuditStatus() throws Exception { + WxMaCodeAuditStatus auditStatus = wxService.getCodeService().getAuditStatus(421937937L); + System.out.println(auditStatus); + assertNotNull(auditStatus); + } + + @Test + public void testGetLatestAuditStatus() throws Exception { + WxMaCodeAuditStatus auditStatus = wxService.getCodeService().getLatestAuditStatus(); + System.out.println(auditStatus); + assertNotNull(auditStatus); + } + + @Test + public void testRelease() throws Exception { + wxService.getCodeService().release(); + } + + @Test + public void testChangeVisitStatus() throws Exception { + wxService.getCodeService().changeVisitStatus("open"); + } + + @Test + public void testRevertCodeRelease() throws Exception { + wxService.getCodeService().revertCodeRelease(); + } + + @Test + public void testGetSupportVersion() throws Exception { + WxMaCodeVersionDistribution distribution = wxService.getCodeService().getSupportVersion(); + System.out.println(distribution); + } + + @Test + public void testSetSupportVersion() throws Exception { + wxService.getCodeService().setSupportVersion("1.2.0"); + } + + @Test + public void testUndoCodeAudit() throws Exception { + + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImplTest.java new file mode 100644 index 0000000000..07f4358db5 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImplTest.java @@ -0,0 +1,45 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.inject.Inject; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
+ *  Created by BinaryWang on 2018/8/5.
+ * 
+ * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaJsapiServiceImplTest { + @Inject + private WxMaService wxService; + @Inject + private WxMaConfig wxMaConfig; + + @Test + public void testGetJsapiTicket() throws WxErrorException { + assertThat(this.wxService.getJsapiService().getJsapiTicket()).isNotBlank(); + } + + @Test + public void testGetJsapiTicket1() throws WxErrorException { + assertThat(this.wxService.getJsapiService().getJsapiTicket(true)).isNotBlank(); + } + + @Test + public void testCreateJsapiSignature() throws WxErrorException { + final WxJsapiSignature jsapiSignature = this.wxService.getJsapiService().createJsapiSignature("http://www.qq.com"); + System.out.println(jsapiSignature); + assertThat(jsapiSignature).isNotNull(); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImplTest.java index 825ad05f76..6c9420be0e 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImplTest.java @@ -4,7 +4,7 @@ import cn.binarywang.wx.miniapp.test.ApiTestModule; import com.google.inject.Inject; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import org.testng.annotations.Guice; import org.testng.annotations.Test; diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java index 37e3608bff..eb671cda61 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java @@ -1,22 +1,23 @@ package cn.binarywang.wx.miniapp.api.impl; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.testng.annotations.*; + import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; +import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; import cn.binarywang.wx.miniapp.test.ApiTestModule; import cn.binarywang.wx.miniapp.test.TestConfig; import com.google.common.collect.Lists; import com.google.inject.Inject; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.exception.WxErrorException; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; - -import java.text.SimpleDateFormat; -import java.util.Date; +import me.chanjar.weixin.common.error.WxErrorException; /** - * 测试客服相关接口 + * 测试消息相关接口 * * @author Binary Wang */ @@ -25,26 +26,14 @@ public class WxMaMsgServiceImplTest { @Inject - protected WxMaService wxService; - - public void testSendKefuMpNewsMessage() throws WxErrorException { - TestConfig configStorage = (TestConfig) this.wxService - .getWxMaConfig(); - WxMaKefuMessage message = new WxMaKefuMessage(); - message.setMsgType(WxConsts.CUSTOM_MSG_MPNEWS); - message.setToUser(configStorage.getOpenid()); - - this.wxService.getMsgService().sendKefuMsg(message); - } + private WxMaService wxService; public void testSendKefuMessage() throws WxErrorException { - TestConfig config = (TestConfig) this.wxService - .getWxMaConfig(); - WxMaKefuMessage message = new WxMaKefuMessage(); - message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); - message.setToUser(config.getOpenid()); - message.setContent( - "欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); + TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); + WxMaKefuMessage message = WxMaKefuMessage.newTextBuilder() + .toUser(config.getOpenid()) + .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World") + .build(); this.wxService.getMsgService().sendKefuMsg(message); } @@ -54,20 +43,38 @@ public void testSendTemplateMsg() throws WxErrorException { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); - WxMaTemplateMessage templateMessage = WxMaTemplateMessage.newBuilder() + WxMaTemplateMessage templateMessage = WxMaTemplateMessage.builder() .toUser(config.getOpenid()) .formId("FORMID") .page("index") .data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), - new WxMaTemplateMessage.Data("keyword2", dateFormat.format(new Date()), "#173177"), - new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), - new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) + new WxMaTemplateData("keyword1", "339208499", "#173177"), + new WxMaTemplateData("keyword2", dateFormat.format(new Date()), "#173177"), + new WxMaTemplateData("keyword3", "粤海喜来登酒店", "#173177"), + new WxMaTemplateData("keyword4", "广州市天河区天河路208号", "#173177"))) .templateId(config.getTemplateId()) .emphasisKeyword("keyword1.DATA") .build(); - + //templateMessage.addData( new WxMaTemplateData("keyword1", "339208499", "#173177")); this.wxService.getMsgService().sendTemplateMsg(templateMessage); } + @Test + public void testSendUniformMsg() throws WxErrorException { + TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); + WxMaUniformMessage message = WxMaUniformMessage.builder() + .isMpTemplateMsg(false) + .toUser(config.getOpenid()) + .page("page/page/index") + .templateId("TEMPLATE_ID") + .formId("FORMID") + .emphasisKeyword("keyword1.DATA") + .build(); + message.addData(new WxMaTemplateData("keyword1", "339208499")) + .addData(new WxMaTemplateData("keyword2", "2015年01月05日 12:30")) + .addData(new WxMaTemplateData("keyword3", "腾讯微信总部")) + .addData(new WxMaTemplateData("keyword4", "广州市海珠区新港中路397号")); + + this.wxService.getMsgService().sendUniformMsg(message); + } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImplTest.java index eba65f7c34..ae2e8d8fed 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImplTest.java @@ -1,12 +1,12 @@ package cn.binarywang.wx.miniapp.api.impl; +import java.io.File; + +import org.testng.annotations.*; + import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.test.ApiTestModule; import com.google.inject.Inject; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; - -import java.io.File; /** * @author Binary Wang @@ -15,7 +15,7 @@ @Guice(modules = ApiTestModule.class) public class WxMaQrcodeServiceImplTest { @Inject - protected WxMaService wxService; + private WxMaService wxService; @Test public void testCreateQrCode() throws Exception { @@ -24,14 +24,14 @@ public void testCreateQrCode() throws Exception { } @Test - public void testCreateWxCode() throws Exception { - final File wxCode = this.wxService.getQrcodeService().createWxCode("111", 122); + public void testCreateWxaCode() throws Exception { + final File wxCode = this.wxService.getQrcodeService().createWxaCode("111", 122); System.out.println(wxCode); } @Test - public void testCreateWxCodeLimit() throws Exception { - final File wxCode = this.wxService.getQrcodeService().createWxCodeLimit("111", null); + public void testCreateWxaCodeUnlimit() throws Exception { + final File wxCode = this.wxService.getQrcodeService().createWxaCodeUnlimit("111", null); System.out.println(wxCode); } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java index 1c99530d36..dcefc68c72 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java @@ -1,16 +1,17 @@ package cn.binarywang.wx.miniapp.api.impl; +import java.io.File; + +import org.apache.commons.lang3.StringUtils; +import org.testng.annotations.*; + import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.config.WxMaConfig; import cn.binarywang.wx.miniapp.test.ApiTestModule; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; -import org.apache.commons.lang3.StringUtils; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; +import me.chanjar.weixin.common.error.WxErrorException; -import static org.testng.Assert.assertNotEquals; -import static org.testng.Assert.assertTrue; +import static org.testng.Assert.*; /** * @author Binary Wang @@ -32,4 +33,9 @@ public void testRefreshAccessToken() throws WxErrorException { assertTrue(StringUtils.isNotBlank(after)); } + @Test + public void testImgSecCheck() throws WxErrorException { + boolean result = this.wxService.imgSecCheck(new File(ClassLoader.getSystemResource("tmp.png").getFile())); + assertTrue(result); + } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSettingServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSettingServiceImplTest.java new file mode 100644 index 0000000000..8da5f19208 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSettingServiceImplTest.java @@ -0,0 +1,54 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaDomainAction; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.inject.Inject; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertNotNull; + +/** + * @author Charming + * @since 2018-04-27 15:38 + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaSettingServiceImplTest { + @Inject + private WxMaService wxService; + + @Test + public void testModifyDomain() throws Exception { + WxMaDomainAction domainAction = wxService.getSettingService().modifyDomain(WxMaDomainAction + .builder() + .action("get") + .build()); + System.out.println(domainAction); + assertNotNull(domainAction); + + domainAction.setAction("set"); + WxMaDomainAction result = wxService.getSettingService().modifyDomain(domainAction); + System.out.println(result); + } + + @Test + public void testBindTester() throws Exception { + wxService.getSettingService().bindTester("WeChatId"); + } + + @Test + public void testUnbindTester() throws Exception { + wxService.getSettingService().unbindTester("WeChatId"); + } + + @Test + public void testSetWebViewDomain() throws Exception { + WxMaDomainAction domainAction = wxService.getSettingService().setWebViewDomain(WxMaDomainAction + .builder() + .action("get") + .build()); + System.out.println(domainAction); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImplTest.java new file mode 100644 index 0000000000..5dfa86a8b0 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImplTest.java @@ -0,0 +1,70 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.inject.Inject; +import org.assertj.core.util.Lists; +import org.testng.Assert; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.List; + +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaTemplateServiceImplTest { + + @Inject + protected WxMaService wxService; + + @Test + public void testFindTemplateLibraryList() throws Exception { + WxMaTemplateLibraryListResult result = this.wxService.getTemplateService().findTemplateLibraryList(0, 20); + Assert.assertEquals(20, result.getList().size()); + } + + @Test + public void testFindTemplateLibraryKeywordList() throws Exception { + WxMaTemplateLibraryGetResult result = this.wxService.getTemplateService().findTemplateLibraryKeywordList("AT0004"); + Assert.assertEquals("AT0004", result.getId()); + Assert.assertEquals("交易提醒", result.getTitle()); + Assert.assertEquals(100, result.getKeywordList().size()); + } + + @Test + public void testAddTemplate() throws Exception{ + List list = Lists.newArrayList(); + list.add(1); + list.add(20); + list.add(84); + + WxMaTemplateAddResult result = this.wxService.getTemplateService().addTemplate("AT0004", list); + Assert.assertNotNull(result.getTemplateId()); + System.out.println(result); + } + + @Test + public void testFindTemplateList() throws Exception{ + WxMaTemplateListResult result = this.wxService.getTemplateService().findTemplateList(0, 20); + System.out.println(result); + } + + @Test + public void testDelTemplate() throws Exception { + + //add + List list = Lists.newArrayList(); + list.add(1); + list.add(20); + list.add(84); + + WxMaTemplateAddResult result = this.wxService.getTemplateService().addTemplate("AT0004", list); + + //delete + this.wxService.getTemplateService().delTemplate(result.getTemplateId()); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java index a19692763b..2c478e8f95 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImplTest.java @@ -1,14 +1,20 @@ package cn.binarywang.wx.miniapp.api.impl; +import cn.binarywang.wx.miniapp.test.TestConfig; +import com.google.common.collect.ImmutableMap; +import jdk.nashorn.internal.ir.annotations.Immutable; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.*; + import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; import cn.binarywang.wx.miniapp.test.ApiTestModule; import com.google.inject.Inject; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; +import javax.management.ImmutableDescriptor; + +import static org.testng.Assert.*; /** * 测试用户相关的接口 @@ -28,7 +34,7 @@ public void testGetSessionKey() throws Exception { } @Test - public void testGetUserInfo() throws Exception { + public void testGetUserInfo() { WxMaUserInfo userInfo = this.wxService.getUserService().getUserInfo("tiihtNczf5v6AKRyjwEUhQ==", "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew==", "r7BXXKkLb8qrSNn05n0qiA=="); @@ -37,10 +43,34 @@ public void testGetUserInfo() throws Exception { } @Test - public void testCheckUserInfo() throws Exception { + public void testCheckUserInfo() { assertTrue(this.wxService.getUserService().checkUserInfo("HyVFkGl5F5OQWJZZaNzBBg==", "{\"nickName\":\"Band\",\"gender\":1,\"language\":\"zh_CN\",\"city\":\"Guangzhou\",\"province\":\"Guangdong\",\"country\":\"CN\",\"avatarUrl\":\"http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0\"}", "75e81ceda165f4ffa64f4068af58c64b8f54b88c")); } + /** + * TODO 测试数据有问题,需要替换为正确的数据 + */ + @Test + public void testGetPhoneNoInfo() { + WxMaPhoneNumberInfo phoneNoInfo = this.wxService.getUserService().getPhoneNoInfo("tiihtNczf5v6AKRyjwEUhQ==", + "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew==", + "r7BXXKkLb8qrSNn05n0qiA=="); + assertNotNull(phoneNoInfo); + System.out.println(phoneNoInfo.toString()); + } + + @Test + public void testGetSessionInfo() { + } + + /** + * TODO 测试数据有问题,需要替换为正确的数据 + */ + @Test + public void testSetUserStorage() throws WxErrorException { + this.wxService.getUserService().setUserStorage(ImmutableMap.of("1","2"), + "r7BXXKkLb8qrSNn05n0qiA",((TestConfig)this.wxService.getWxMaConfig()).getOpenid()); + } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessageTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessageTest.java index f2ef8bfac5..6486c3237f 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessageTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessageTest.java @@ -1,8 +1,8 @@ package cn.binarywang.wx.miniapp.bean; -import me.chanjar.weixin.common.api.WxConsts; -import org.testng.Assert; -import org.testng.annotations.Test; +import org.testng.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Binary Wang @@ -10,31 +10,60 @@ @Test public class WxMaKefuMessageTest { - public void testTextReply() { - WxMaKefuMessage reply = new WxMaKefuMessage(); - reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_TEXT); - reply.setContent("sfsfdsdf"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); + public void testTextBuilder() { + WxMaKefuMessage reply = WxMaKefuMessage.newTextBuilder() + .toUser("OPENID") + .content("sfsfdsdf") + .build(); + assertThat(reply.toJson()) + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); } - public void testTextBuild() { - WxMaKefuMessage reply = WxMaKefuMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); + public void testImageBuilder() { + WxMaKefuMessage reply = WxMaKefuMessage.newImageBuilder() + .toUser("OPENID") + . mediaId("MEDIA_ID") + .build(); + assertThat(reply.toJson()) + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); } - public void testImageReply() { - WxMaKefuMessage reply = new WxMaKefuMessage(); - reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_IMAGE); - reply.setMediaId("MEDIA_ID"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); + public void testLinkBuilder() { + WxMaKefuMessage reply = WxMaKefuMessage.newLinkBuilder() + .toUser("OPENID") + .url("url") + .description("description") + .title("title") + .thumbUrl("thumbUrl") + .build(); + assertThat(reply.toJson()) + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"link\"," + + "\"link\":{\"title\":\"title\",\"description\":\"description\",\"url\":\"url\",\"thumb_url\":\"thumbUrl\"}}"); } - public void testImageBuild() { - WxMaKefuMessage reply = WxMaKefuMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); + public void testMaPageBuilder() { + WxMaKefuMessage reply = WxMaKefuMessage.newMaPageBuilder() + .toUser("OPENID") + .title("title") + .pagePath("pagePath") + .thumbMediaId("thumbMediaId") + .build(); + assertThat(reply.toJson()) + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"miniprogrampage\"," + + "\"miniprogrampage\":{\"title\":\"title\",\"pagepath\":\"pagePath\",\"thumb_media_id\":\"thumbMediaId\"}}"); } + public void testURLEscaped() { + WxMaKefuMessage reply = WxMaKefuMessage.newLinkBuilder() + .toUser("OPENID") + .url("https://mp.weixin.qq.com/s?__biz=MzI0MDA2OTY5NQ==") + .description("description") + .title("title") + .thumbUrl("thumbUrl") + .build(); + assertThat(reply.toJson()) + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"link\"," + + "\"link\":{\"title\":\"title\",\"description\":\"description\",\"url\":\"https://mp.weixin.qq.com/s?__biz=MzI0MDA2OTY5NQ==\",\"thumb_url\":\"thumbUrl\"}}"); + } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java index cdf989a6af..26855b36ef 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaMessageTest.java @@ -12,118 +12,39 @@ public class WxMaMessageTest { public void testFromXml() { - String xml = "" - + "" - + " " - + "1348831860" - + "" - + "" - + "1234567890123456" - + "" - + "" - + "" - + "" - + "23.134521" - + "113.358803" - + "20" - + "" - + "" - + "" - + "<![CDATA[公众平台官网链接]]>" - + "" - + "" - + "" - + "23.137466" - + "113.352425" - + "119.385040" - + "" - + " " - + " " - + "" - + "" - + " 1\n" - + " " - + " " - + " " - + " " - + " " - + "" - + "" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "" - + ""; + String xml = "\n" + + " \n" + + " \n" + + " 1482048670\n" + + " \n" + + " \n" + + " 1234567890123456\n" + + " \n" + + " \n" + + " <![CDATA[Title]]>\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; WxMaMessage wxMessage = WxMaMessage.fromXml(xml); assertEquals(wxMessage.getToUser(), "toUser"); assertEquals(wxMessage.getFromUser(), "fromUser"); - assertEquals(wxMessage.getCreateTime(), new Long(1348831860L)); - assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); + assertEquals(wxMessage.getCreateTime(),new Integer(1482048670)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); assertEquals(wxMessage.getContent(), "this is a test"); assertEquals(wxMessage.getMsgId(), new Long(1234567890123456L)); assertEquals(wxMessage.getPicUrl(), "this is a url"); assertEquals(wxMessage.getMediaId(), "media_id"); - assertEquals(wxMessage.getEvent(), "subscribe"); - } - - public void testFromXml2() { - - String xml = "" - + "" - + " " - + "1348831860" - + "" - + "" - + "1234567890123456" - + "" - + "" - + "" - + "" - + "23.134521" - + "113.358803" - + "20" - + "" - + "" - + "" - + "<![CDATA[公众平台官网链接]]>" - + "" - + "" - + "" - + "23.137466" - + "113.352425" - + "119.385040" - + "" - + " " - + " " - + "" - + "" - + " 1\n" - + " " - + " " - + " " - + " " - + " " - + "" - + "" - + " \n" - + " \n" - + " \n" - + " \n" - + " \n" - + "" - + ""; - WxMaMessage wxMessage = WxMaMessage.fromXml(xml); - assertEquals(wxMessage.getToUser(), "toUser"); - assertEquals(wxMessage.getFromUser(), "fromUser"); - assertEquals(wxMessage.getCreateTime(), new Integer(1348831860)); - assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); - assertEquals(wxMessage.getContent(), "this is a test"); - assertEquals(wxMessage.getMsgId(), new Long(1234567890123456L)); - assertEquals(wxMessage.getPicUrl(), "this is a url"); - assertEquals(wxMessage.getMediaId(), "media_id"); - assertEquals(wxMessage.getEvent(), "subscribe"); + assertEquals(wxMessage.getTitle(), "Title"); + assertEquals(wxMessage.getPagePath(), "PagePath"); + assertEquals(wxMessage.getThumbUrl(), "ThumbUrl"); + assertEquals(wxMessage.getThumbMediaId(), "ThumbMediaId"); + assertEquals(wxMessage.getAppId(), "AppId"); + assertEquals(wxMessage.getEvent(), "user_enter_tempsession"); + assertEquals(wxMessage.getSessionFrom(), "sessionFrom"); } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java index ad6e62c2ca..51eb0e872c 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessageTest.java @@ -1,9 +1,10 @@ package cn.binarywang.wx.miniapp.bean; +import org.testng.annotations.*; + import com.google.common.collect.Lists; -import org.testng.annotations.Test; -import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.*; /** * @author Binary Wang @@ -11,16 +12,16 @@ public class WxMaTemplateMessageTest { @Test public void testToJson() throws Exception { - WxMaTemplateMessage tm = WxMaTemplateMessage.newBuilder() + WxMaTemplateMessage tm = WxMaTemplateMessage.builder() .toUser("OPENID") //.color("aaaaa") .formId("FORMID") .page("index") .data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"), - new WxMaTemplateMessage.Data("keyword2", "2015年01月05日12:30", "#173177"), - new WxMaTemplateMessage.Data("keyword3", "粤海喜来登酒店", "#173177"), - new WxMaTemplateMessage.Data("keyword4", "广州市天河区天河路208号", "#173177"))) + new WxMaTemplateData("keyword1", "339208499", "#173177"), + new WxMaTemplateData("keyword2", "2015年01月05日12:30", "#173177"), + new WxMaTemplateData("keyword3", "粤海喜来登酒店", "#173177"), + new WxMaTemplateData("keyword4", "广州市天河区天河路208号", "#173177"))) .templateId("TEMPLATE_ID") .emphasisKeyword("keyword1.DATA") .build(); diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaRetainInfoTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaRetainInfoTest.java new file mode 100644 index 0000000000..c2fd925e09 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaRetainInfoTest.java @@ -0,0 +1,22 @@ +package cn.binarywang.wx.miniapp.bean.analysis; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +/** + * @author Charming + * @since 2018-04-28 + */ +public class WxMaRetainInfoTest { + @Test + public void testFromJson() throws Exception { + String json = "{\"ref_date\":\"20170313\",\"visit_uv_new\":[{\"key\":0,\"value\":5464}],\"visit_uv\":[{\"key\":0,\"value\":55500}]}\n"; + WxMaRetainInfo retainInfo = WxMaRetainInfo.fromJson(json); + assertNotNull(retainInfo); + assertEquals("20170313", retainInfo.getRefDate()); + assertTrue(retainInfo.getVisitUv().containsKey(0)); + assertTrue(retainInfo.getVisitUvNew().containsKey(0)); + System.out.println(retainInfo); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaUserPortraitTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaUserPortraitTest.java new file mode 100644 index 0000000000..87239bb599 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaUserPortraitTest.java @@ -0,0 +1,19 @@ +package cn.binarywang.wx.miniapp.bean.analysis; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertNotNull; + +/** + * @author Charming + * @since 2018-04-28 + */ +public class WxMaUserPortraitTest { + @Test + public void testFromJson() throws Exception { + String json = "{\"ref_date\":\"20170611\",\"visit_uv_new\":{\"province\":[{\"id\":31,\"name\":\"广东省\",\"value\":215}],\"city\":[{\"id\":3102,\"name\":\"广州\",\"value\":78}],\"genders\":[{\"id\":1,\"name\":\"男\",\"value\":2146}],\"platforms\":[{\"id\":1,\"name\":\"iPhone\",\"value\":27642}],\"devices\":[{\"name\":\"OPPO R9\",\"value\":61}],\"ages\":[{\"id\":1,\"name\":\"17岁以下\",\"value\":151}]},\"visit_uv\":{\"province\":[{\"id\":31,\"name\":\"广东省\",\"value\":1341}],\"city\":[{\"id\":3102,\"name\":\"广州\",\"value\":234}],\"genders\":[{\"id\":1,\"name\":\"男\",\"value\":14534}],\"platforms\":[{\"id\":1,\"name\":\"iPhone\",\"value\":21750}],\"devices\":[{\"name\":\"OPPO R9\",\"value\":617}],\"ages\":[{\"id\":1,\"name\":\"17岁以下\",\"value\":3156}]}}\n"; + WxMaUserPortrait portrait = WxMaUserPortrait.fromJson(json); + System.out.println(portrait); + assertNotNull(portrait); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitDistributionTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitDistributionTest.java new file mode 100644 index 0000000000..2b01b3aad7 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/analysis/WxMaVisitDistributionTest.java @@ -0,0 +1,23 @@ +package cn.binarywang.wx.miniapp.bean.analysis; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +/** + * @author Charming + * @since 2018-04-28 + */ +public class WxMaVisitDistributionTest { + @Test + public void testFromJson() throws Exception { + String json = "{\"ref_date\":\"20170313\",\"list\":[{\"index\":\"access_source_session_cnt\",\"item_list\":[{\"key\":10,\"value\":5},{\"key\":8,\"value\":687},{\"key\":7,\"value\":10740},{\"key\":6,\"value\":1961},{\"key\":5,\"value\":677},{\"key\":4,\"value\":653},{\"key\":3,\"value\":1120},{\"key\":2,\"value\":10243},{\"key\":1,\"value\":116578}]},{\"index\":\"access_staytime_info\",\"item_list\":[{\"key\":8,\"value\":16329},{\"key\":7,\"value\":19322},{\"key\":6,\"value\":21832},{\"key\":5,\"value\":19539},{\"key\":4,\"value\":29670},{\"key\":3,\"value\":19667},{\"key\":2,\"value\":11794},{\"key\":1,\"value\":4511}]},{\"index\":\"access_depth_info\",\"item_list\":[{\"key\":5,\"value\":217},{\"key\":4,\"value\":3259},{\"key\":3,\"value\":32445},{\"key\":2,\"value\":63542},{\"key\":1,\"value\":43201}]}]}\n"; + WxMaVisitDistribution distribution = WxMaVisitDistribution.fromJson(json); + assertNotNull(distribution); + assertEquals("20170313", distribution.getRefDate()); + assertTrue(distribution.getList().containsKey("access_source_session_cnt")); + assertTrue(distribution.getList().containsKey("access_staytime_info")); + assertTrue(distribution.getList().containsKey("access_depth_info")); + System.out.println(distribution); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeCommitRequestTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeCommitRequestTest.java new file mode 100644 index 0000000000..36cf1c4840 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeCommitRequestTest.java @@ -0,0 +1,25 @@ +package cn.binarywang.wx.miniapp.bean.code; + +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +/** + * @author Charming + * @since 2018-04-26 19:54 + */ +public class WxMaCodeCommitRequestTest { + @Test + public void testToJson() { + WxMaCodeCommitRequest commitRequest = WxMaCodeCommitRequest.builder() + .templateId(1L) + .userVersion("v0.1.0") + .userDesc("init") + .extConfig(WxMaCodeExtConfig.builder() + .extAppid("app123") + .extEnable(true) + .build()) + .build(); + assertEquals(commitRequest.toJson(), "{\"template_id\":1,\"user_version\":\"v0.1.0\",\"user_desc\":\"init\",\"ext_json\":\"{\\\"extEnable\\\":true,\\\"extAppid\\\":\\\"app123\\\"}\"}"); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeSubmitAuditRequestTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeSubmitAuditRequestTest.java new file mode 100644 index 0000000000..1f962087dc --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeSubmitAuditRequestTest.java @@ -0,0 +1,30 @@ +package cn.binarywang.wx.miniapp.bean.code; + +import org.testng.annotations.Test; + +import java.util.Arrays; + +/** + * @author Charming + * @since 2018-04-26 19:55 + */ +public class WxMaCodeSubmitAuditRequestTest { + @Test + public void testToJson() { + WxMaCodeSubmitAuditRequest request = WxMaCodeSubmitAuditRequest + .builder() + .itemList(Arrays.asList( + WxMaCategory + .builder() + .address("pages/logs/logs") + .tag("工具 效率") + .firstClass("工具") + .firstId(287L) + .secondClass("效率") + .secondId(616L) + .title("日志") + .build() + )).build(); + System.out.println(request.toJson()); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeVersionDistributionTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeVersionDistributionTest.java new file mode 100644 index 0000000000..da02972e04 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeVersionDistributionTest.java @@ -0,0 +1,15 @@ +package cn.binarywang.wx.miniapp.bean.code; + +import org.testng.annotations.Test; + +/** + * @author Charming + * @since 2018-04-26 19:58 + */ +public class WxMaCodeVersionDistributionTest { + @Test + public void testFromJson() { + String json = "{\"errcode\":0,\"errmsg\":\"ok\",\"now_version\":\"1.2.0\",\"uv_info\":{\"items\":[{\"version\":\"0.0.0\",\"percentage\":0},{\"version\":\"1.0.0\",\"percentage\":0},{\"version\":\"1.0.1\",\"percentage\":0},{\"version\":\"1.1.0\",\"percentage\":0},{\"version\":\"1.1.1\",\"percentage\":0},{\"version\":\"1.2.0\",\"percentage\":0},{\"version\":\"1.2.1\",\"percentage\":0},{\"version\":\"1.2.2\",\"percentage\":0},{\"version\":\"1.2.3\",\"percentage\":0},{\"version\":\"1.2.4\",\"percentage\":0},{\"version\":\"1.2.5\",\"percentage\":0},{\"version\":\"1.2.6\",\"percentage\":0},{\"version\":\"1.3.0\",\"percentage\":0},{\"version\":\"1.4.0\",\"percentage\":0},{\"version\":\"1.4.1\",\"percentage\":0},{\"version\":\"1.4.2\",\"percentage\":0},{\"version\":\"1.4.3\",\"percentage\":0},{\"version\":\"1.4.4\",\"percentage\":0},{\"version\":\"1.5.0\",\"percentage\":0},{\"version\":\"1.5.1\",\"percentage\":0},{\"version\":\"1.5.2\",\"percentage\":0},{\"version\":\"1.5.3\",\"percentage\":0},{\"version\":\"1.5.4\",\"percentage\":0},{\"version\":\"1.5.5\",\"percentage\":0},{\"version\":\"1.5.6\",\"percentage\":0},{\"version\":\"1.5.7\",\"percentage\":0},{\"version\":\"1.5.8\",\"percentage\":0},{\"version\":\"1.6.0\",\"percentage\":0.0132},{\"version\":\"1.6.1\",\"percentage\":0.0132},{\"version\":\"1.6.2\",\"percentage\":0.0132},{\"version\":\"1.6.3\",\"percentage\":0.0132},{\"version\":\"1.6.4\",\"percentage\":0.0132},{\"version\":\"1.6.5\",\"percentage\":0.0132},{\"version\":\"1.6.6\",\"percentage\":0.0132},{\"version\":\"1.6.7\",\"percentage\":0.1711},{\"version\":\"1.6.8\",\"percentage\":0.1711},{\"version\":\"1.7.0\",\"percentage\":0.1842},{\"version\":\"1.7.1\",\"percentage\":0.25},{\"version\":\"1.7.2\",\"percentage\":0.5263},{\"version\":\"1.7.3\",\"percentage\":0.5263},{\"version\":\"1.7.4\",\"percentage\":0.6711}]}}\n"; + System.out.println(WxMaCodeVersionDistribution.fromJson(json)); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java index f6dcbae27b..fe886f4b85 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaDemoServer.java @@ -1,9 +1,20 @@ package cn.binarywang.wx.miniapp.demo; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; + import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; import cn.binarywang.wx.miniapp.bean.WxMaMessage; +import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; import cn.binarywang.wx.miniapp.config.WxMaConfig; import cn.binarywang.wx.miniapp.constant.WxMaConstants; @@ -12,17 +23,8 @@ import cn.binarywang.wx.miniapp.test.TestConfig; import com.google.common.collect.Lists; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHandler; -import org.eclipse.jetty.servlet.ServletHolder; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.concurrent.locks.ReentrantLock; /** * @author Binary Wang @@ -34,7 +36,7 @@ public class WxMaDemoServer { public void handle(WxMaMessage wxMessage, Map context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException { System.out.println("收到消息:" + wxMessage.toString()); - service.getMsgService().sendKefuMsg(WxMaKefuMessage.TEXT().content("收到信息为:" + wxMessage.toJson()) + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson()) .toUser(wxMessage.getFromUser()).build()); } }; @@ -44,7 +46,7 @@ public void handle(WxMaMessage wxMessage, Map context, public void handle(WxMaMessage wxMessage, Map context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - service.getMsgService().sendKefuMsg(WxMaKefuMessage.TEXT().content("回复文本消息") + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息") .toUser(wxMessage.getFromUser()).build()); } @@ -60,7 +62,7 @@ public void handle(WxMaMessage wxMessage, Map context, ClassLoader.getSystemResourceAsStream("tmp.png")); service.getMsgService().sendKefuMsg( WxMaKefuMessage - .IMAGE() + .newImageBuilder() .mediaId(uploadResult.getMediaId()) .toUser(wxMessage.getFromUser()) .build()); @@ -79,7 +81,7 @@ public void handle(WxMaMessage wxMessage, Map context, WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia(WxMaConstants.MediaType.IMAGE, file); service.getMsgService().sendKefuMsg( WxMaKefuMessage - .IMAGE() + .newImageBuilder() .mediaId(uploadResult.getMediaId()) .toUser(wxMessage.getFromUser()) .build()); @@ -94,9 +96,9 @@ public void handle(WxMaMessage wxMessage, Map context, public void handle(WxMaMessage wxMessage, Map context, WxMaService service, WxSessionManager sessionManager) throws WxErrorException { - service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.newBuilder() + service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder() .templateId(templateId).data(Lists.newArrayList( - new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177"))) + new WxMaTemplateData("keyword1", "339208499", "#173177"))) .toUser(wxMessage.getFromUser()) .formId("自己替换可用的formid") .build()); diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/ApiTestModule.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/ApiTestModule.java index 3b569e1b89..267eb70ca3 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/ApiTestModule.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/ApiTestModule.java @@ -1,22 +1,30 @@ package cn.binarywang.wx.miniapp.test; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.locks.ReentrantLock; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.config.WxMaConfig; import com.google.inject.Binder; import com.google.inject.Module; -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.locks.ReentrantLock; - /** * @author Binary Wang */ public class ApiTestModule implements Module { + private final Logger log = LoggerFactory.getLogger(this.getClass()); + private static final String TEST_CONFIG_XML = "test-config.xml"; @Override public void configure(Binder binder) { - try (InputStream inputStream = ClassLoader.getSystemResourceAsStream("test-config.xml")) { + try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(TEST_CONFIG_XML)) { + if (inputStream == null) { + throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成"); + } TestConfig config = TestConfig.fromXml(inputStream); config.setAccessTokenLock(new ReentrantLock()); @@ -26,7 +34,7 @@ public void configure(Binder binder) { binder.bind(WxMaService.class).toInstance(wxService); binder.bind(WxMaConfig.class).toInstance(config); } catch (IOException e) { - e.printStackTrace(); + this.log.error(e.getMessage(), e); } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java index ee941ef349..6cebdeb24b 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/test/TestConfig.java @@ -54,6 +54,7 @@ public void setTemplateId(String templateId) { this.templateId = templateId; } + @Override public void setAccessTokenLock(Lock lock) { super.accessTokenLock = lock; } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapterTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapterTest.java new file mode 100644 index 0000000000..1541879c33 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapterTest.java @@ -0,0 +1,112 @@ +package cn.binarywang.wx.miniapp.util.json; + +import org.testng.annotations.*; + +import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; +import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; +import com.google.gson.JsonParser; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
+ *
+ * Created by Binary Wang on 2018/9/23.
+ * 
+ * + * @author Binary Wang + */ +public class WxMaUniformMessageGsonAdapterTest { + + @Test + public void testSerialize_mp() { + WxMaUniformMessage message = WxMaUniformMessage.builder() + .isMpTemplateMsg(true) + .toUser("OPENID") + .appid("APPID") + .templateId("TEMPLATE_ID") + .url("http://weixin.qq.com/download") + .miniProgram(new WxMaUniformMessage.MiniProgram("xiaochengxuappid12345", "index?foo=bar", false)) + .build(); + message.addData(new WxMaTemplateData("first", "恭喜你购买成功!", "#173177")) + .addData(new WxMaTemplateData("keyword1", "巧克力", "#173177")) + .addData(new WxMaTemplateData("keyword2", "39.8元", "#173177")) + .addData(new WxMaTemplateData("keyword3", "2014年9月22日", "#173177")) + .addData(new WxMaTemplateData("remark", "欢迎再次购买!", "#173177")); + + assertThat(message.toJson()).isEqualTo(new JsonParser().parse("{\n" + + " \"touser\":\"OPENID\",\n" + + " \"mp_template_msg\":{\n" + + " \"appid\":\"APPID\",\n" + + " \"template_id\":\"TEMPLATE_ID\",\n" + + " \"url\":\"http://weixin.qq.com/download\",\n" + + " \"miniprogram\":{\n" + + " \"appid\":\"xiaochengxuappid12345\",\n" + + " \"pagepath\":\"index?foo=bar\"\n" + + " },\n" + + " \"data\":{\n" + + " \"first\":{\n" + + " \"value\":\"恭喜你购买成功!\",\n" + + " \"color\":\"#173177\"\n" + + " },\n" + + " \"keyword1\":{\n" + + " \"value\":\"巧克力\",\n" + + " \"color\":\"#173177\"\n" + + " },\n" + + " \"keyword2\":{\n" + + " \"value\":\"39.8元\",\n" + + " \"color\":\"#173177\"\n" + + " },\n" + + " \"keyword3\":{\n" + + " \"value\":\"2014年9月22日\",\n" + + " \"color\":\"#173177\"\n" + + " },\n" + + " \"remark\":{\n" + + " \"value\":\"欢迎再次购买!\",\n" + + " \"color\":\"#173177\"\n" + + " }\n" + + " }\n" + + " }\n" + + "}").getAsJsonObject().toString()); + } + + @Test + public void testSerialize_ma() { + WxMaUniformMessage message = WxMaUniformMessage.builder() + .isMpTemplateMsg(false) + .toUser("OPENID") + .page("page/page/index") + .templateId("TEMPLATE_ID") + .formId("FORMID") + .emphasisKeyword("keyword1.DATA") + .build(); + message.addData(new WxMaTemplateData("keyword1", "339208499")) + .addData(new WxMaTemplateData("keyword2", "2015年01月05日 12:30")) + .addData(new WxMaTemplateData("keyword3", "腾讯微信总部")) + .addData(new WxMaTemplateData("keyword4", "广州市海珠区新港中路397号")); + + assertThat(message.toJson()).isEqualTo(new JsonParser().parse("{\n" + + " \"touser\":\"OPENID\",\n" + + " \"weapp_template_msg\":{\n" + + " \"template_id\":\"TEMPLATE_ID\",\n" + + " \"page\":\"page/page/index\",\n" + + " \"form_id\":\"FORMID\",\n" + + " \"data\":{\n" + + " \"keyword1\":{\n" + + " \"value\":\"339208499\"\n" + + " },\n" + + " \"keyword2\":{\n" + + " \"value\":\"2015年01月05日 12:30\"\n" + + " },\n" + + " \"keyword3\":{\n" + + " \"value\":\"腾讯微信总部\"\n" + + " },\n" + + " \"keyword4\":{\n" + + " \"value\":\"广州市海珠区新港中路397号\"\n" + + " }\n" + + " },\n" + + " \"emphasis_keyword\":\"keyword1.DATA\"\n" + + " }\n" + + "}").getAsJsonObject().toString()); + } +} diff --git a/weixin-java-miniapp/src/test/resources/test-config.sample.xml b/weixin-java-miniapp/src/test/resources/test-config-sample.xml similarity index 100% rename from weixin-java-miniapp/src/test/resources/test-config.sample.xml rename to weixin-java-miniapp/src/test/resources/test-config-sample.xml diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 81ec2c01ab..8441e4cd0e 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,10 +7,10 @@ com.github.binarywang weixin-java-parent - 2.8.0 + 3.2.0 weixin-java-mp - WeiXin Java Tools - MP + Weixin Java Tools - MP 微信公众号Java SDK @@ -65,6 +65,15 @@ logback-classic test + + org.assertj + assertj-guava + test + + + org.projectlombok + lombok + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/AiLangType.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/AiLangType.java new file mode 100644 index 0000000000..54b61b1e51 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/AiLangType.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.mp; + +import lombok.Getter; + +/** + *
+ *  AI开放接口里的语言类型,目前只支持两种:中文和英文
+ *  Created by BinaryWang on 2018/6/10.
+ * 
+ * + * @author Binary Wang + */ +@Getter +public enum AiLangType { + /** + * 中文 汉语 + */ + zh_CN("zh_CN"), + /** + * 英文 英语 + */ + en_US("en_US"); + + private String code; + + AiLangType(String code) { + this.code = code; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java new file mode 100644 index 0000000000..1e9c8e02f8 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java @@ -0,0 +1,97 @@ +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.AiLangType; + +import java.io.File; + +/** + *
+ * 微信AI开放接口(语音识别,微信翻译).
+ * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=21516712282KzWVE
+ *  Created by BinaryWang on 2018/6/9.
+ * 
+ * + * @author Binary Wang + */ +public interface WxMpAiOpenService { + String VOICE_UPLOAD_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/addvoicetorecofortext?format=%s&voice_id=%s&lang=%s"; + String VOICE_QUERY_RESULT_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/queryrecoresultfortext"; + + /** + *
+   * 提交语音.
+   * 接口调用请求说明
+   *
+   * http请求方式: POST
+   * http://api.weixin.qq.com/cgi-bin/media/voice/addvoicetorecofortext?access_token=ACCESS_TOKEN&format=&voice_id=xxxxxx&lang=zh_CN
+   * 参数说明
+   *
+   * 参数	是否必须	说明
+   * access_token	是	接口调用凭证
+   * format	是	文件格式 (只支持mp3,16k,单声道,最大1M)
+   * voice_id	是	语音唯一标识
+   * lang	否	语言,zh_CN 或 en_US,默认中文
+   * 语音内容放body里或者上传文件的形式
+   * 
+ * + * @param lang 语言,zh_CN 或 en_US,默认中文 + * @param voiceFile 语音文件 + * @param voiceId 语音唯一标识 + */ + void uploadVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException; + + /** + *
+   * 获取语音识别结果.
+   * 接口调用请求说明
+   *
+   * http请求方式: POST
+   * http://api.weixin.qq.com/cgi-bin/media/voice/queryrecoresultfortext?access_token=ACCESS_TOKEN&voice_id=xxxxxx&lang=zh_CN
+   * 请注意,添加完文件之后10s内调用这个接口
+   *
+   * 参数说明
+   *
+   * 参数	是否必须	说明
+   * access_token	是	接口调用凭证
+   * voice_id	是	语音唯一标识
+   * lang	否	语言,zh_CN 或 en_US,默认中文
+   * 
+ * + * @param lang 语言,zh_CN 或 en_US,默认中文 + * @param voiceId 语音唯一标识 + */ + String queryRecognitionResult(String voiceId, AiLangType lang) throws WxErrorException; + + /** + * 识别指定语音文件内容. + * 此方法揉合了前两两个方法:uploadVoice 和 queryRecognitionResult + * + * @param lang 语言,zh_CN 或 en_US,默认中文 + * @param voiceFile 语音文件 + * @param voiceId 语音唯一标识 + */ + String recogniseVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException; + + /** + *
+   * 微信翻译.
+   * 接口调用请求说明
+   *
+   * http请求方式: POST
+   * http://api.weixin.qq.com/cgi-bin/media/voice/translatecontent?access_token=ACCESS_TOKEN&lfrom=xxx<o=xxx
+   * 参数说明
+   *
+   * 参数	是否必须	说明
+   * access_token	是	接口调用凭证
+   * lfrom	是	源语言,zh_CN 或 en_US
+   * lto	是	目标语言,zh_CN 或 en_US
+   * 源内容放body里或者上传文件的形式(utf8格式,最大600Byte)
+   * 
+ * + * @param langFrom 源语言,zh_CN 或 en_US + * @param langTo 目标语言,zh_CN 或 en_US + * @param content 要翻译的文本内容 + */ + String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java index 08ea9a7007..1ad01eea55 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java @@ -1,13 +1,17 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.WxCardApiSignature; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest; +import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult; +import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult; import me.chanjar.weixin.mp.bean.result.WxMpCardResult; /** * 卡券相关接口 * - * @author YuJian(mgcnrx11@hotmail.com) on 01/11/2016 + * @author YuJian(mgcnrx11 @ hotmail.com) on 01/11/2016 + * @author yuanqixun 2018-08-29 */ public interface WxMpCardService { String CARD_GET = "https://api.weixin.qq.com/card/get"; @@ -16,6 +20,13 @@ public interface WxMpCardService { String CARD_CODE_GET = "https://api.weixin.qq.com/card/code/get"; String CARD_CODE_CONSUME = "https://api.weixin.qq.com/card/code/consume"; String CARD_CODE_MARK = "https://api.weixin.qq.com/card/code/mark"; + String CARD_TEST_WHITELIST = "https://api.weixin.qq.com/card/testwhitelist/set"; + String CARD_QRCODE_CREAET = "https://api.weixin.qq.com/card/qrcode/create"; + String CARD_LANDING_PAGE_CREAET = "https://api.weixin.qq.com/card/landingpage/create"; + /** + * 将用户的卡券设置为失效状态 + */ + String CARD_CODE_UNAVAILABLE = "https://api.weixin.qq.com/card/code/unavailable"; /** * 得到WxMpService @@ -122,4 +133,53 @@ void markCardCode(String code, String cardId, String openId, boolean isMark) thr *
可由 com.google.gson.JsonParser#parse 等方法直接取JSON串中的某个字段。 */ String getCardDetail(String cardId) throws WxErrorException; + + /** + * 添加测试白名单 + * + * @param openid 用户的openid + * @return + */ + String addTestWhiteList(String openid) throws WxErrorException; + + /** + * 创建卡券二维码 + * + * @param cardId 卡券编号 + * @param outerStr 二维码标识 + * @return WxMpCardQrcodeCreateResult + */ + WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr) throws WxErrorException; + + /** + * 创建卡券二维码 + * + * @param cardId 卡券编号 + * @param outerStr 二维码标识 + * @param expiresIn 失效时间,单位秒,不填默认365天 + * @return WxMpCardQrcodeCreateResult + */ + WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr, int expiresIn) throws WxErrorException; + + /** + * 创建卡券货架 + * + * @param createRequest 货架创建参数 + * @return + * @throws WxErrorException + */ + WxMpCardLandingPageCreateResult createLandingPage(WxMpCardLandingPageCreateRequest createRequest) throws WxErrorException; + + /** + * 将用户的卡券设置为失效状态 + * 详见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272&anchor=9 + * + * @param cardId 卡券编号 + * @param code 用户会员卡号 + * @param reason 设置为失效的原因 + * @return + * @throws WxErrorException + */ + String unavailableCardCode(String cardId, String code, String reason) throws WxErrorException; + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java index dbff2a7abe..ea21c80b76 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java @@ -85,6 +85,8 @@ public interface WxMpConfigStorage { String getAesKey(); + String getTemplateId(); + long getExpiresTime(); String getOauth2redirectUri(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java index 7610b03d3a..fecceea444 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDataCubeService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.datacube.*; import java.util.Date; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java index 6b3fcd9e39..8a0fb6a58e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpDeviceService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.device.*; /** diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java index e74f518867..eb15cd0f52 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java @@ -1,13 +1,15 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; - import java.io.File; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; + /** * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 * @@ -18,6 +20,7 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected volatile String appId; protected volatile String secret; protected volatile String token; + protected volatile String templateId; protected volatile String accessToken; protected volatile String aesKey; protected volatile long expiresTime; @@ -173,6 +176,15 @@ public void setToken(String token) { this.token = token; } + @Override + public String getTemplateId() { + return this.templateId; + } + + public void setTemplateId(String templateId) { + this.templateId = templateId; + } + @Override public long getExpiresTime() { return this.expiresTime; @@ -238,7 +250,7 @@ public void setHttpProxyPassword(String httpProxyPassword) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } @Override diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java index d22214dfa1..e20d1e3f1f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInRedisConfigStorage.java @@ -1,11 +1,15 @@ package me.chanjar.weixin.mp.api; import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; /** * 基于Redis的微信配置provider - * - * @author lly835 + *
+ *    使用说明:本实现仅供参考,并不完整,
+ *    比如为减少项目依赖,未加入redis分布式锁的实现,如有需要请自行实现。
+ * 
+ * @author nickwong */ @SuppressWarnings("hiding") public class WxMpInRedisConfigStorage extends WxMpInMemoryConfigStorage { @@ -16,75 +20,115 @@ public class WxMpInRedisConfigStorage extends WxMpInMemoryConfigStorage { private final static String CARDAPI_TICKET_KEY = "wechat_cardapi_ticket_"; - protected Jedis jedis; + /** + * 使用连接池保证线程安全 + */ + protected final JedisPool jedisPool; + + private String accessTokenKey; + + private String jsapiTicketKey; + + private String cardapiTicketKey; + + public WxMpInRedisConfigStorage(JedisPool jedisPool) { + this.jedisPool = jedisPool; + } + + /** + * 每个公众号生成独有的存储key + * + * @param appId + */ + @Override + public void setAppId(String appId) { + super.setAppId(appId); + this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); + this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(appId); + this.cardapiTicketKey = CARDAPI_TICKET_KEY.concat(appId); + } @Override public String getAccessToken() { - return jedis.get(ACCESS_TOKEN_KEY.concat(appId)); + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.accessTokenKey); + } } @Override public boolean isAccessTokenExpired() { - return jedis.ttl(ACCESS_TOKEN_KEY.concat(appId)) < 2; + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(accessTokenKey) < 2; + } } @Override public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { - jedis.set(ACCESS_TOKEN_KEY.concat(appId), accessToken); - jedis.expire(ACCESS_TOKEN_KEY.concat(appId), expiresInSeconds - 200); + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(this.accessTokenKey, expiresInSeconds - 200, accessToken); + } } @Override public void expireAccessToken() { - jedis.expire(ACCESS_TOKEN_KEY.concat(appId), 0); + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(this.accessTokenKey, 0); + } } @Override public String getJsapiTicket() { - return jedis.get(JSAPI_TICKET_KEY.concat(appId)); + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.jsapiTicketKey); + } } @Override public boolean isJsapiTicketExpired() { - return jedis.ttl(JSAPI_TICKET_KEY.concat(appId)) < 2; + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(this.jsapiTicketKey) < 2; + } } @Override public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { - jedis.set(JSAPI_TICKET_KEY.concat(appId), jsapiTicket); - jedis.expire(JSAPI_TICKET_KEY.concat(appId), expiresInSeconds - 200); + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(this.jsapiTicketKey, expiresInSeconds - 200, jsapiTicket); + } } @Override public void expireJsapiTicket() { - jedis.expire(JSAPI_TICKET_KEY.concat(appId), 0); + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(this.jsapiTicketKey, 0); + } } - /** - * 卡券api_ticket - */ @Override public String getCardApiTicket() { - return jedis.get(CARDAPI_TICKET_KEY.concat(appId)); + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.cardapiTicketKey); + } } @Override public boolean isCardApiTicketExpired() { - return jedis.ttl(CARDAPI_TICKET_KEY.concat(appId)) < 2; + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(this.cardapiTicketKey) < 2; + } } @Override public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { - jedis.set(CARDAPI_TICKET_KEY.concat(appId), cardApiTicket); - jedis.expire(CARDAPI_TICKET_KEY.concat(appId), expiresInSeconds - 200); + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(this.cardapiTicketKey, expiresInSeconds - 200, cardApiTicket); + } } @Override public void expireCardApiTicket() { - jedis.expire(CARDAPI_TICKET_KEY.concat(appId), 0); - } - - public void setJedis(Jedis jedis) { - this.jedis = jedis; + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(this.cardapiTicketKey, 0); + } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java index 36e13b13c4..99dcaba99b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java @@ -1,16 +1,21 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; -import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; -import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; -import me.chanjar.weixin.mp.bean.kefu.result.*; - import java.io.File; import java.util.Date; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; +import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList; + /** *
- * 客服接口 ,
+ * 客服接口.
  * 注意:命名采用kefu拼音的原因是:其英文CustomerService如果再加上Service后缀显得有点啰嗦,如果不加又显得表意不完整。
  * 
* @@ -30,7 +35,8 @@ public interface WxMpKefuService { String KFSESSION_GET_SESSION = "https://api.weixin.qq.com/customservice/kfsession/getsession?openid=%s"; String KFSESSION_GET_SESSION_LIST = "https://api.weixin.qq.com/customservice/kfsession/getsessionlist?kf_account=%s"; String KFSESSION_GET_WAIT_CASE = "https://api.weixin.qq.com/customservice/kfsession/getwaitcase"; - String MSGRECORD_GET_MSG_LIST = "https://api.weixin.qq.com/customservice/msgrecord/getmsglist"; + String MSG_RECORD_LIST = "https://api.weixin.qq.com/customservice/msgrecord/getmsglist"; + String CUSTOM_TYPING = "https://api.weixin.qq.com/cgi-bin/message/custom/typing"; /** *
@@ -38,6 +44,8 @@ public interface WxMpKefuService {
    * 详情请见: 发送客服消息
    * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
    * 
+ * + * @throws WxErrorException 异常 */ boolean sendKefuMessage(WxMpKefuMessage message) throws WxErrorException; @@ -49,6 +57,8 @@ public interface WxMpKefuService { * 详情请见:客服管理 * 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN *
+ * + * @throws WxErrorException 异常 */ WxMpKfList kfList() throws WxErrorException; @@ -58,6 +68,8 @@ public interface WxMpKefuService { * 详情请见:客服管理 * 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist?access_token=ACCESS_TOKEN *
+ * + * @throws WxErrorException 异常 */ WxMpKfOnlineList kfOnlineList() throws WxErrorException; @@ -67,6 +79,8 @@ public interface WxMpKefuService { * 详情请见:客服管理 * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN *
+ * + * @throws WxErrorException 异常 */ boolean kfAccountAdd(WxMpKfAccountRequest request) throws WxErrorException; @@ -85,6 +99,8 @@ public interface WxMpKefuService { * 详情请见:客服管理 * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/inviteworker?access_token=ACCESS_TOKEN *
+ * + * @throws WxErrorException 异常 */ boolean kfAccountInviteWorker(WxMpKfAccountRequest request) throws WxErrorException; @@ -92,11 +108,12 @@ public interface WxMpKefuService { *
    * 上传客服头像
    * 详情请见:客服管理
-   * 接口url格式:http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
    * 
+ * + * @throws WxErrorException 异常 */ - boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) - throws WxErrorException; + boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) throws WxErrorException; /** *
@@ -104,6 +121,8 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile)
    * 详情请见:客服管理
    * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
    * 
+ * + * @throws WxErrorException 异常 */ boolean kfAccountDel(String kfAccount) throws WxErrorException; @@ -116,6 +135,8 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) * 详情请见:客服会话控制接口 * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/create?access_token=ACCESS_TOKEN *
+ * + * @throws WxErrorException 异常 */ boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException; @@ -126,6 +147,8 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) * 详情请见:客服会话控制接口 * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/close?access_token=ACCESS_TOKEN *
+ * + * @throws WxErrorException 异常 */ boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException; @@ -136,6 +159,8 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) * 详情请见:客服会话控制接口 * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getsession?access_token=ACCESS_TOKEN&openid=OPENID *
+ * + * @throws WxErrorException 异常 */ WxMpKfSessionGetResult kfSessionGet(String openid) throws WxErrorException; @@ -146,6 +171,8 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) * 详情请见:客服会话控制 * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getsessionlist?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT *
+ * + * @throws WxErrorException 异常 */ WxMpKfSessionList kfSessionList(String kfAccount) throws WxErrorException; @@ -156,6 +183,8 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) * 详情请见:客服会话控制 * 接口url格式: https://api.weixin.qq.com/customservice/kfsession/getwaitcase?access_token=ACCESS_TOKEN *
+ * + * @throws WxErrorException 异常 */ WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException; @@ -174,7 +203,7 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) * @param msgId 消息id顺序从小到大,从1开始 * @param number 每次获取条数,最多10000条 * @return 聊天记录对象 - * @throws WxErrorException + * @throws WxErrorException 异常 */ WxMpKfMsgList kfMsgList(Date startTime, Date endTime, Long msgId, Integer number) throws WxErrorException; @@ -189,8 +218,27 @@ boolean kfAccountUploadHeadImg(String kfAccount, File imgFile) * @param startTime 起始时间 * @param endTime 结束时间 * @return 聊天记录对象 - * @throws WxErrorException + * @throws WxErrorException 异常 */ WxMpKfMsgList kfMsgList(Date startTime, Date endTime) throws WxErrorException; + /** + *
+   * 客服输入状态
+   * 开发者可通过调用“客服输入状态”接口,返回客服当前输入状态给用户。
+   * 此接口需要客服消息接口权限。
+   * 如果不满足发送客服消息的触发条件,则无法下发输入状态。
+   * 下发输入状态,需要客服之前30秒内跟用户有过消息交互。
+   * 在输入状态中(持续15s),不可重复下发输入态。
+   * 在输入状态中,如果向用户下发消息,会同时取消输入状态。
+   *
+   * 详情请见:客服输入状态
+   * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/custom/typing?access_token=ACCESS_TOKEN
+   * 
+ * + * @param openid 用户id + * @param command "Typing":对用户下发“正在输入"状态 "CancelTyping":取消对用户的”正在输入"状态 + * @throws WxErrorException 异常 + */ + boolean sendKfTypingState(String openid, String command) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java index 6d1f025728..f3e8db9d10 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMassMessageService.java @@ -1,13 +1,13 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.*; import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; /** *
- * 群发消息服务类
+ * 群发消息服务类.
  * Created by Binary Wang on 2017-8-16.
  * 
* @@ -15,33 +15,33 @@ */ public interface WxMpMassMessageService { /** - * 上传群发用的图文消息 + * 上传群发用的图文消息. */ String MEDIA_UPLOAD_NEWS_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; /** - * 上传群发用的视频 + * 上传群发用的视频. */ String MEDIA_UPLOAD_VIDEO_URL = "https://api.weixin.qq.com/cgi-bin/media/uploadvideo"; /** - * 分组群发消息 + * 分组群发消息. */ String MESSAGE_MASS_SENDALL_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"; /** - * 按openId列表群发消息 + * 按openId列表群发消息. */ String MESSAGE_MASS_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/send"; /** - * 群发消息预览接口 + * 群发消息预览接口. */ String MESSAGE_MASS_PREVIEW_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/preview"; /** - * 删除群发接口 + * 删除群发接口. */ String MESSAGE_MASS_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/message/mass/delete"; /** *
-   * 上传群发用的图文消息,上传后才能群发图文消息
+   * 上传群发用的图文消息,上传后才能群发图文消息.
    *
    * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
    * 
@@ -53,7 +53,7 @@ public interface WxMpMassMessageService { /** *
-   * 上传群发用的视频,上传后才能群发视频消息
+   * 上传群发用的视频,上传后才能群发视频消息.
    * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
    * 
* @@ -64,7 +64,7 @@ public interface WxMpMassMessageService { /** *
-   * 分组群发消息
+   * 分组群发消息.
    * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
    * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
    * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
@@ -74,7 +74,7 @@ public interface WxMpMassMessageService {
 
   /**
    * 
-   * 按openId列表群发消息
+   * 按openId列表群发消息.
    * 如果发送图文消息,必须先使用 {@link #massNewsUpload(WxMpMassNews)} 获得media_id,然后再发送
    * 如果发送视频消息,必须先使用 {@link #massVideoUpload(WxMpMassVideo)} 获得media_id,然后再发送
    * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140549&token=&lang=zh_CN
@@ -84,7 +84,7 @@ public interface WxMpMassMessageService {
 
   /**
    * 
-   * 群发消息预览接口
+   * 群发消息预览接口.
    * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100次),请勿滥用。
    * 接口调用请求说明
    *  http请求方式: POST
@@ -94,11 +94,11 @@ public interface WxMpMassMessageService {
    *
    * @return wxMpMassSendResult
    */
-  WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception;
+  WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException;
 
   /**
    * 
-   * 删除群发
+   * 删除群发.
    * 群发之后,随时可以通过该接口删除群发。
    * 请注意:
    * 1、只有已经发送成功的消息才能删除
@@ -114,6 +114,6 @@ public interface WxMpMassMessageService {
    * @param msgId        发送出去的消息ID
    * @param articleIndex 要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章
    */
-  void delete(Integer msgId, Integer articleIndex) throws Exception;
+  void delete(Long msgId, Integer articleIndex) throws WxErrorException;
 
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
index 05ca87eab7..6d762f1c44 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
@@ -1,12 +1,20 @@
 package me.chanjar.weixin.mp.api;
 
-import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
-import me.chanjar.weixin.common.exception.WxErrorException;
-import me.chanjar.weixin.mp.bean.material.*;
-
 import java.io.File;
 import java.io.InputStream;
 
+import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialArticleUpdate;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialCountResult;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialFileBatchGetResult;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialNewsBatchGetResult;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult;
+import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult;
+
 /**
  * 
  * Created by Binary Wang on 2016/7/21.
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java
index 7cebb8c858..d9bbdfbc6c 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java
@@ -1,29 +1,57 @@
 package me.chanjar.weixin.mp.api;
 
-import me.chanjar.weixin.common.exception.WxErrorException;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateMessage;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult;
-import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.card.MemberCardActivateUserFormRequest;
+import me.chanjar.weixin.mp.bean.card.MemberCardActivateUserFormResult;
+import me.chanjar.weixin.mp.bean.card.WxMpCardCreateResult;
+import me.chanjar.weixin.mp.bean.membercard.*;
 
 /**
  * 会员卡相关接口
  *
- * @author YuJian(mgcnrx11@gmail.com)
+ * @author YuJian(mgcnrx11 @ gmail.com)
+ * @author yuanqixun
  * @version 2017/7/8
+ * @date 2018-08-30
  */
 public interface WxMpMemberCardService {
+  String MEMBER_CARD_CREAET = "https://api.weixin.qq.com/card/create";
+  String MEMBER_CARD_ACTIVATE = "https://api.weixin.qq.com/card/membercard/activate";
+  String MEMBER_CARD_USER_INFO_GET = "https://api.weixin.qq.com/card/membercard/userinfo/get";
+  String MEMBER_CARD_UPDATE_USER = "https://api.weixin.qq.com/card/membercard/updateuser";
+  /**
+   * 会员卡激活之微信开卡接口(wx_activate=true情况调用)
+   */
+  String MEMBER_CARD_ACTIVATEUSERFORM = "https://api.weixin.qq.com/card/membercard/activateuserform/set";
 
   /**
    * 得到WxMpService
    */
   WxMpService getWxMpService();
 
+  /**
+   * 会员卡创建接口
+   *
+   * @param createJson
+   * @return
+   * @throws WxErrorException
+   */
+  WxMpCardCreateResult createMemberCard(String createJson) throws WxErrorException;
+
+  /**
+   * 会员卡创建接口
+   *
+   * @param createMessageMessage
+   * @return WxMpCardCreateResult
+   * @throws WxErrorException
+   */
+  WxMpCardCreateResult createMemberCard(WxMpMemberCardCreateMessage createMessageMessage) throws WxErrorException;
+
   /**
    * 会员卡激活接口
    *
    * @param activatedMessage 激活所需参数
-   * @return 调用返回的JSON字符串。
+   * @return 返回json字符串
    * @throws WxErrorException 接口调用失败抛出的异常
    */
   String activateMemberCard(WxMpMemberCardActivatedMessage activatedMessage) throws WxErrorException;
@@ -32,7 +60,7 @@ public interface WxMpMemberCardService {
    * 拉取会员信息接口
    *
    * @param cardId 会员卡的CardId,微信分配
-   * @param code 领取会员的会员卡Code
+   * @param code   领取会员的会员卡Code
    * @return 会员信息的结果对象
    * @throws WxErrorException 接口调用失败抛出的异常
    */
@@ -40,7 +68,7 @@ public interface WxMpMemberCardService {
 
   /**
    * 当会员持卡消费后,支持开发者调用该接口更新会员信息。会员卡交易后的每次信息变更需通过该接口通知微信,便于后续消息通知及其他扩展功能。
-   *
+   * 

* 1.开发者可以同时传入add_bonus和bonus解决由于同步失败带来的幂等性问题。同时传入add_bonus和bonus时 * add_bonus作为积分变动消息中的变量值,而bonus作为卡面上的总积分额度显示。余额变动同理。 * 2.开发者可以传入is_notify_bonus控制特殊的积分对账变动不发送消息,余额变动同理。 @@ -50,4 +78,14 @@ public interface WxMpMemberCardService { * @throws WxErrorException 接口调用失败抛出的异常 */ WxMpMemberCardUpdateResult updateUserMemberCard(WxMpMemberCardUpdateMessage updateUserMessage) throws WxErrorException; + + /** + * 设置会员卡激活的字段(会员卡设置:wx_activate=true 时需要) + * + * @param userFormRequest + * @return + * @throws WxErrorException + */ + MemberCardActivateUserFormResult setActivateUserForm(MemberCardActivateUserFormRequest userFormRequest) throws WxErrorException; + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java index bfd606175c..f0fe549575 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMenuService.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; import me.chanjar.weixin.mp.bean.menu.WxMpMenu; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java index 5a336bc8d9..474e3e6950 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageHandler.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java index 15223895b9..f377b036d1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageInterceptor.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java index 5acf0040aa..8350593aa2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java @@ -10,6 +10,7 @@ import me.chanjar.weixin.common.util.LogExceptionHandler; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,6 +75,29 @@ public WxMpMessageRouter(WxMpService wxMpService) { this.exceptionHandler = new LogExceptionHandler(); } + /** + *

+   * 使用自定义的 {@link ExecutorService}
+   * 
+ */ + public WxMpMessageRouter(WxMpService wxMpService, ExecutorService executorService) { + this.wxMpService = wxMpService; + this.executorService = executorService; + this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker(); + this.sessionManager = new StandardSessionManager(); + this.exceptionHandler = new LogExceptionHandler(); + } + + /** + *
+   * 如果使用默认的 {@link ExecutorService},则系统退出前,应该调用该方法。
+   * 
+ */ + public void shutDownExecutorService() { + this.executorService.shutdown(); + } + + /** *
    * 设置自定义的 {@link ExecutorService}
@@ -129,6 +153,16 @@ public WxMpMessageRouterRule rule() {
    * 处理微信消息
    */
   public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, final Map context) {
+    return route(wxMessage, context, null);
+  }
+  /**
+   * 处理微信消息
+   */
+  public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, final Map context, WxMpService wxMpService) {
+    if(wxMpService == null){
+      wxMpService = this.wxMpService;
+    }
+    final WxMpService mpService = wxMpService;
     if (isMsgDuplicated(wxMessage)) {
       // 如果是重复消息,那么就不做处理
       return null;
@@ -158,12 +192,12 @@ public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, final Map
    * 验证消息的确来自微信服务器
@@ -82,7 +90,7 @@ public interface WxMpService {
    * 获取access_token,本方法线程安全
    * 且在多线程同时刷新时只刷新一次,避免超出2000次/日的调用次数上限
    *
-   * 另:本service的所有方法都会在access_token过期是调用此方法
+   * 另:本service的所有方法都会在access_token过期时调用此方法
    *
    * 程序员在非必要情况下尽量不要主动调用此方法
    *
@@ -219,6 +227,18 @@ public interface WxMpService {
    */
   WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorException;
 
+  /**
+   * 
+   *  公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零:
+   *  HTTP调用:https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=ACCESS_TOKEN
+   *  接口文档地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592
+   *
+   * 
+ * + * @param appid 公众号的APPID + */ + void clearQuota(String appid) throws WxErrorException; + /** * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 */ @@ -343,6 +363,13 @@ public interface WxMpService { */ WxMpTemplateMsgService getTemplateMsgService(); + /** + * 返回一次性订阅消息相关接口方法的实现类对象,以方便调用其各个接口 + * + * @return WxMpSubscribeMsgService + */ + WxMpSubscribeMsgService getSubscribeMsgService(); + /** * 返回硬件平台相关接口方法的实现类对象,以方便调用其各个接口 * @@ -376,10 +403,25 @@ public interface WxMpService { /** * 返回群发消息相关接口方法的实现类对象,以方便调用其各个接口 + * * @return WxMpMassMessageService */ WxMpMassMessageService getMassMessageService(); + /** + * 返回AI开放接口方法的实现类对象,以方便调用其各个接口 + * + * @return WxMpAiOpenService + */ + WxMpAiOpenService getAiOpenService(); + + /** + * 返回WIFI接口方法的实现类对象,以方便调用其各个接口 + * + * @return WxMpWifiService + */ + WxMpWifiService getWifiService(); + void setKefuService(WxMpKefuService kefuService); void setMaterialService(WxMpMaterialService materialService); @@ -409,4 +451,6 @@ public interface WxMpService { void setMemberCardService(WxMpMemberCardService memberCardService); void setMassMessageService(WxMpMassMessageService massMessageService); + + void setAiOpenService(WxMpAiOpenService aiOpenService); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java index 87a6747af5..1f6c3052e7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpShakeService.java @@ -1,8 +1,10 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; /** * 摇一摇周边的相关接口 @@ -24,4 +26,36 @@ public interface WxMpShakeService { */ WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException; + /** + *
+   * 页面管理
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459246752 + *
+ * @param shakeAroundPageAddQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException; + + /** + *
+   * 配置设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1459301931 + *
+ * @param shakeAroundDeviceBindPageQuery + * @return + * @throws WxErrorException + */ + WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException; + + /** + *
+   * 查询设备与页面的关联关系
+ * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443447914 + *
+ * @param shakeAroundRelationSearchQuery + * @return + * @throws WxErrorException + */ + WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java index 2634c3f36c..7b0913e688 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.store.WxMpStoreBaseInfo; import me.chanjar.weixin.mp.bean.store.WxMpStoreInfo; import me.chanjar.weixin.mp.bean.store.WxMpStoreListResult; @@ -9,11 +9,19 @@ /** * 门店管理的相关接口代码 + *

+ * Created by Binary Wang on 2016-09-23. * - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016-09-23. + * @author Binary Wang */ public interface WxMpStoreService { + String POI_GET_WX_CATEGORY_URL = "https://api.weixin.qq.com/cgi-bin/poi/getwxcategory"; + String POI_UPDATE_URL = "https://api.weixin.qq.com/cgi-bin/poi/updatepoi"; + String POI_LIST_URL = "https://api.weixin.qq.com/cgi-bin/poi/getpoilist"; + String POI_DEL_URL = "https://api.weixin.qq.com/cgi-bin/poi/delpoi"; + String POI_GET_URL = "https://api.weixin.qq.com/cgi-bin/poi/getpoi"; + String POI_ADD_URL = "https://api.weixin.qq.com/cgi-bin/poi/addpoi"; + /** *

    * 创建门店
@@ -22,7 +30,7 @@ public interface WxMpStoreService {
    * 创建门店接口调用成功后会返回errcode 0、errmsg ok,但不会实时返回poi_id。
    * 成功创建后,会生成poi_id,但该id不一定为最终id。门店信息会经过审核,审核通过后方可获取最终poi_id,该id为门店的唯一id,强烈建议自行存储审核通过后的最终poi_id,并为后续调用使用。
    * 详情请见: 微信门店接口
-   * 接口格式: http://api.weixin.qq.com/cgi-bin/poi/addpoi?access_token=TOKEN
+   * 接口格式: https://api.weixin.qq.com/cgi-bin/poi/addpoi?access_token=TOKEN
    * 
*/ void add(WxMpStoreBaseInfo request) throws WxErrorException; @@ -35,11 +43,10 @@ public interface WxMpStoreService { * 最终结果会在5 个工作日内,最终确认是否采纳,并前端生效(但该扩展字段的采纳过程不影响门店的可用性,即available_state仍为审核通过状态) * 注:扩展字段为公共编辑信息(大家都可修改),修改将会审核,并决定是否对修改建议进行采纳,但不会影响该门店的生效可用状态。 * 详情请见: 微信门店接口 - * 接口格式:http://api.weixin.qq.com/cgi-bin/poi/getpoi?access_token=TOKEN + * 接口格式:https://api.weixin.qq.com/cgi-bin/poi/getpoi?access_token=TOKEN *
* * @param poiId 门店Id - * @throws WxErrorException */ WxMpStoreBaseInfo get(String poiId) throws WxErrorException; @@ -48,11 +55,10 @@ public interface WxMpStoreService { * 删除门店 * 商户可以通过该接口,删除已经成功创建的门店。请商户慎重调用该接口。 * 详情请见: 微信门店接口 - * 接口格式:http://api.weixin.qq.com/cgi-bin/poi/delpoi?access_token=TOKEN + * 接口格式:https://api.weixin.qq.com/cgi-bin/poi/delpoi?access_token=TOKEN *
* * @param poiId 门店Id - * @throws WxErrorException */ void delete(String poiId) throws WxErrorException; @@ -61,12 +67,11 @@ public interface WxMpStoreService { * 查询门店列表(指定查询起始位置和个数) * 商户可以通过该接口,批量查询自己名下的门店list,并获取已审核通过的poi_id(所有状态均会返回poi_id,但该poi_id不一定为最终id)、商户自身sid 用于对应、商户名、分店名、地址字段。 * 详情请见: 微信门店接口 - * 接口格式:http://api.weixin.qq.com/cgi-bin/poi/getpoilist?access_token=TOKEN + * 接口格式:https://api.weixin.qq.com/cgi-bin/poi/getpoilist?access_token=TOKEN *
* * @param begin 开始位置,0 即为从第一条开始查询 * @param limit 返回数据条数,最大允许50,默认为20 - * @throws WxErrorException */ WxMpStoreListResult list(int begin, int limit) throws WxErrorException; @@ -75,10 +80,8 @@ public interface WxMpStoreService { * 查询门店列表(所有) * 商户可以通过该接口,批量查询自己名下的门店list,并获取已审核通过的poi_id(所有状态均会返回poi_id,但该poi_id不一定为最终id)、商户自身sid 用于对应、商户名、分店名、地址字段。 * 详情请见: 微信门店接口 - * 接口格式:http://api.weixin.qq.com/cgi-bin/poi/getpoilist?access_token=TOKEN + * 接口格式:https://api.weixin.qq.com/cgi-bin/poi/getpoilist?access_token=TOKEN *
- * - * @throws WxErrorException */ List listAll() throws WxErrorException; @@ -87,10 +90,8 @@ public interface WxMpStoreService { * 修改门店服务信息 * 商户可以通过该接口,修改门店的服务信息,包括:sid、图片列表、营业时间、推荐、特色服务、简介、人均价格、电话8个字段(名称、坐标、地址等不可修改)修改后需要人工审核。 * 详情请见: 微信门店接口 - * 接口格式:http://api.weixin.qq.com/cgi-bin/poi/updatepoi?access_token=TOKEN + * 接口格式:https://api.weixin.qq.com/cgi-bin/poi/updatepoi?access_token=TOKEN *
- * - * @throws WxErrorException */ void update(WxMpStoreBaseInfo info) throws WxErrorException; @@ -99,10 +100,8 @@ public interface WxMpStoreService { * 门店类目表 * 类目名称接口是为商户提供自己门店类型信息的接口。门店类目定位的越规范,能够精准的吸引更多用户,提高曝光率。 * 详情请见: 微信门店接口 - * 接口格式:http://api.weixin.qq.com/cgi-bin/poi/getwxcategory?access_token=TOKEN + * 接口格式:https://api.weixin.qq.com/cgi-bin/poi/getwxcategory?access_token=TOKEN *
- * - * @throws WxErrorException */ List listCategories() throws WxErrorException; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpSubscribeMsgService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpSubscribeMsgService.java new file mode 100644 index 0000000000..1e91d9a2d6 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpSubscribeMsgService.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; + +/** + *
+ * 一次性订阅消息接口
+ * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1500374289_66bvB
+ * 
+ * + * @author Mklaus + * @date 2018-01-22 上午11:07 + */ +public interface WxMpSubscribeMsgService { + + /** + *
+   * 构造用户订阅一条模板消息授权的url连接
+   * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1500374289_66bvB
+   * 
+ * + * @param redirectURI 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode + * @param scene 重定向后会带上scene参数,开发者可以填0-10000的整形值,用来标识订阅场景值 + * @param reserved 用于保持请求和回调的状态,授权请后原样带回给第三方 (最多128字节,要求做urlencode) + * @return url + */ + String subscribeMsgAuthorizationUrl(String redirectURI, int scene, String reserved); + + /** + *
+   * 发送一次性订阅消息
+   * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1500374289_66bvB
+   * 
+ * + * @return 消息Id + */ + boolean sendSubscribeMessage(WxMpSubscribeMessage message) throws WxErrorException; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java index f9203c1644..f57c469c01 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.template.WxMpTemplate; import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; @@ -13,7 +13,7 @@ * http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN * Created by Binary Wang on 2016-10-14. * @author miller.lin - * @author binarywang(Binary Wang) + * @author Binary Wang *
*/ public interface WxMpTemplateMsgService { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserBlacklistService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserBlacklistService.java index d93384f005..e7e2fd84fc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserBlacklistService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserBlacklistService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.result.WxMpUserBlacklistGetResult; import java.util.List; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java index e207e5efc3..7523a9f39e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.WxMpUserQuery; import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.bean.result.WxMpUserList; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java index 4a666eff1b..031585053e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpUserTagService.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.tag.WxTagListUser; import me.chanjar.weixin.mp.bean.tag.WxUserTag; @@ -10,7 +10,7 @@ * 用户标签管理相关接口 * Created by Binary Wang on 2016/9/2. * - * @author binarywang(Binary Wang) + * @author Binary Wang */ public interface WxMpUserTagService { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpWifiService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpWifiService.java new file mode 100644 index 0000000000..9cda53bbb5 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpWifiService.java @@ -0,0 +1,28 @@ +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopListResult; + +/** + *
+ *  微信连接WI-FI接口.
+ *  Created by BinaryWang on 2018/6/10.
+ * 
+ * + * @author Binary Wang + */ +public interface WxMpWifiService { + /** + *
+   * 获取Wi-Fi门店列表.
+   * 通过此接口获取WiFi的门店列表,该列表包括公众平台的门店信息、以及添加设备后的WiFi相关信息。创建门店方法请参考“微信门店接口”。
+   * 注:微信连Wi-Fi下的所有接口中的shop_id,必需先通过此接口获取。
+   *
+   * http请求方式: POST
+   * 请求URL:https://api.weixin.qq.com/bizwifi/shop/list?access_token=ACCESS_TOKEN
+   * 
+ * @param pageIndex 分页下标,默认从1开始 + * @param pageSize 每页的个数,默认10个,最大20个 + */ + WxMpWifiShopListResult listShop(int pageIndex, int pageSize) throws WxErrorException; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java similarity index 85% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index e4482d5aa7..09d21bacff 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceAbstractImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -5,16 +5,20 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import me.chanjar.weixin.common.bean.WxJsapiSignature; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.StandardSessionManager; import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.common.util.DataUtils; import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.http.*; import me.chanjar.weixin.mp.api.*; -import me.chanjar.weixin.mp.bean.*; -import me.chanjar.weixin.mp.bean.result.*; +import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; +import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; +import me.chanjar.weixin.mp.bean.result.WxMpUser; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,13 +26,16 @@ import java.io.IOException; import java.util.concurrent.locks.Lock; -public abstract class WxMpServiceAbstractImpl implements WxMpService, RequestHttp { - +/** + * @author someone + */ +public abstract class BaseWxMpServiceImpl implements WxMpService, RequestHttp { private static final JsonParser JSON_PARSER = new JsonParser(); protected final Logger log = LoggerFactory.getLogger(this.getClass()); + protected WxSessionManager sessionManager = new StandardSessionManager(); - private WxMpConfigStorage wxMpConfigStorage; + protected WxMpConfigStorage wxMpConfigStorage; private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); @@ -40,10 +47,13 @@ public abstract class WxMpServiceAbstractImpl implements WxMpService, Requ private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this); private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); + private WxMpSubscribeMsgService subscribeMsgService = new WxMpSubscribeMsgServiceImpl(this); private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this); private WxMpMassMessageService massMessageService = new WxMpMassMessageServiceImpl(this); + private WxMpAiOpenService aiOpenService = new WxMpAiOpenServiceImpl(this); + private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this); private int retrySleepMillis = 1000; private int maxRetryTimes = 5; @@ -67,7 +77,7 @@ public String getJsapiTicket() throws WxErrorException { @Override public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { - Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); + Lock lock = this.getWxMpConfigStorage().getJsapiTicketLock(); try { lock.lock(); if (forceRefresh) { @@ -91,14 +101,14 @@ public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { @Override public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { long timestamp = System.currentTimeMillis() / 1000; - String noncestr = RandomUtils.getRandomStr(); + String randomStr = RandomUtils.getRandomStr(); String jsapiTicket = getJsapiTicket(false); String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, - "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url); + "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url); WxJsapiSignature jsapiSignature = new WxJsapiSignature(); jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId()); jsapiSignature.setTimestamp(timestamp); - jsapiSignature.setNonceStr(noncestr); + jsapiSignature.setNonceStr(randomStr); jsapiSignature.setUrl(url); jsapiSignature.setSignature(signature); return jsapiSignature; @@ -110,10 +120,10 @@ public String getAccessToken() throws WxErrorException { } @Override - public String shortUrl(String long_url) throws WxErrorException { + public String shortUrl(String longUrl) throws WxErrorException { JsonObject o = new JsonObject(); o.addProperty("action", "long2short"); - o.addProperty("long_url", long_url); + o.addProperty("long_url", longUrl); String responseContent = this.post(WxMpService.SHORTURL_API_URL, o.toString()); JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); @@ -160,12 +170,12 @@ public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throw } @Override - public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException { + public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken token, String lang) throws WxErrorException { if (lang == null) { lang = "zh_CN"; } - String url = String.format(WxMpService.OAUTH2_USERINFO_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId(), lang); + String url = String.format(WxMpService.OAUTH2_USERINFO_URL, token.getAccessToken(), token.getOpenId(), lang); try { RequestExecutor executor = SimpleGetRequestExecutor.create(this); @@ -177,8 +187,8 @@ public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, Strin } @Override - public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) { - String url = String.format(WxMpService.OAUTH2_VALIDATE_TOKEN_URL, oAuth2AccessToken.getAccessToken(), oAuth2AccessToken.getOpenId()); + public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken token) { + String url = String.format(WxMpService.OAUTH2_VALIDATE_TOKEN_URL, token.getAccessToken(), token.getOpenId()); try { SimpleGetRequestExecutor.create(this).execute(url, null); @@ -207,6 +217,13 @@ public WxMpCurrentAutoReplyInfo getCurrentAutoReplyInfo() throws WxErrorExceptio return WxMpCurrentAutoReplyInfo.fromJson(this.get(GET_CURRENT_AUTOREPLY_INFO_URL, null)); } + @Override + public void clearQuota(String appid) throws WxErrorException { + JsonObject o = new JsonObject(); + o.addProperty("appid", appid); + this.post(CLEAR_QUOTA_URL, o.toString()); + } + @Override public String get(String url, String queryParam) throws WxErrorException { return execute(SimpleGetRequestExecutor.create(this), url, queryParam); @@ -218,8 +235,9 @@ public String post(String url, String postData) throws WxErrorException { } /** - * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 + * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求. */ + @Override public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { int retryTimes = 0; do { @@ -252,17 +270,20 @@ public T execute(RequestExecutor executor, String uri, E data) thro throw new RuntimeException("微信服务端异常,超出重试次数"); } - public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + public T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + E dataForLog = DataUtils.handleDataWithSecret(data); + if (uri.contains("access_token=")) { throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); } + String accessToken = getAccessToken(false); String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken; try { T result = executor.execute(uriWithAccessToken, data); - this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, data, result); + this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); return result; } catch (WxErrorException e) { WxError error = e.getError(); @@ -281,13 +302,13 @@ public synchronized T executeInternal(RequestExecutor executor, Str } if (error.getErrorCode() != 0) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, data, error); + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); throw new WxErrorException(error, e); } return null; } catch (IOException e) { - this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, data, e.getMessage()); - throw new RuntimeException(e); + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); } } @@ -367,6 +388,11 @@ public WxMpTemplateMsgService getTemplateMsgService() { return this.templateMsgService; } + @Override + public WxMpSubscribeMsgService getSubscribeMsgService() { + return this.subscribeMsgService; + } + @Override public WxMpDeviceService getDeviceService() { return this.deviceService; @@ -466,4 +492,19 @@ public void setMemberCardService(WxMpMemberCardService memberCardService) { public void setMassMessageService(WxMpMassMessageService massMessageService) { this.massMessageService = massMessageService; } + + @Override + public WxMpAiOpenService getAiOpenService() { + return this.aiOpenService; + } + + @Override + public void setAiOpenService(WxMpAiOpenService aiOpenService) { + this.aiOpenService = aiOpenService; + } + + @Override + public WxMpWifiService getWifiService() { + return this.wifiService; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java new file mode 100644 index 0000000000..f492e4670d --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java @@ -0,0 +1,76 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.AiLangType; +import me.chanjar.weixin.mp.api.WxMpAiOpenService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.util.requestexecuter.voice.VoiceUploadRequestExecutor; + +import java.io.File; + +/** + *
+ *  Created by BinaryWang on 2018/6/9.
+ * 
+ * + * @author Binary Wang + */ +public class WxMpAiOpenServiceImpl implements WxMpAiOpenService { + + private static final JsonParser JSON_PARSER = new JsonParser(); + public static final String TRANSLATE_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/translatecontent?lfrom=%s<o=%s"; + private WxMpService wxMpService; + + public WxMpAiOpenServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public void uploadVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException { + if (lang == null) { + lang = AiLangType.zh_CN; + } + + this.wxMpService.execute(VoiceUploadRequestExecutor.create(this.wxMpService.getRequestHttp()), + String.format(VOICE_UPLOAD_URL, "mp3", voiceId, lang.getCode()), + voiceFile); + } + + @Override + public String recogniseVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException { + this.uploadVoice(voiceId, lang, voiceFile); + return this.queryRecognitionResult(voiceId, lang); + } + + @Override + public String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException { + final String responseContent = this.wxMpService.post(String.format(TRANSLATE_URL, langFrom.getCode(), langTo.getCode()), + content); + final JsonObject jsonObject = new JsonParser().parse(responseContent).getAsJsonObject(); + if (jsonObject.get("errcode") == null || jsonObject.get("errcode").getAsInt() == 0) { + return jsonObject.get("to_content").getAsString(); + } + + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); + } + + @Override + public String queryRecognitionResult(String voiceId, AiLangType lang) throws WxErrorException { + if (lang == null) { + lang = AiLangType.zh_CN; + } + + final String responseContent = this.wxMpService.get(VOICE_QUERY_RESULT_URL, + String.format("voice_id=%s&lang=%s", voiceId, lang.getCode())); + final JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + if (jsonObject.get("errcode") == null || jsonObject.get("errcode").getAsInt() == 0) { + return jsonObject.get("result").getAsString(); + } + + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java index 8ec5945f7b..bc1a07247e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java @@ -1,20 +1,21 @@ package me.chanjar.weixin.mp.api.impl; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; +import com.google.gson.*; import com.google.gson.reflect.TypeToken; import me.chanjar.weixin.common.bean.WxCardApiSignature; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import me.chanjar.weixin.mp.api.WxMpCardService; import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest; +import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult; +import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult; import me.chanjar.weixin.mp.bean.result.WxMpCardResult; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,6 +31,8 @@ public class WxMpCardServiceImpl implements WxMpCardService { private WxMpService wxMpService; + private static final Gson GSON = new Gson(); + public WxMpCardServiceImpl(WxMpService wxMpService) { this.wxMpService = wxMpService; } @@ -213,7 +216,7 @@ public void markCardCode(String code, String cardId, String openId, boolean isMa WxMpCardResult cardResult = WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, new TypeToken() { }.getType()); - if (!cardResult.getErrorCode().equals("0")) { + if (!"0".equals(cardResult.getErrorCode())) { this.log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg()); } } @@ -229,12 +232,97 @@ public String getCardDetail(String cardId) throws WxErrorException { String errcode = json.get("errcode").getAsString(); if (!"0".equals(errcode)) { String errmsg = json.get("errmsg").getAsString(); - WxError error = new WxError(); - error.setErrorCode(Integer.valueOf(errcode)); - error.setErrorMsg(errmsg); - throw new WxErrorException(error); + throw new WxErrorException(WxError.builder() + .errorCode(Integer.valueOf(errcode)).errorMsg(errmsg) + .build()); } return responseContent; } + + /** + * 添加测试白名单 + * + * @param openid 用户的openid + * @return + */ + public String addTestWhiteList(String openid) throws WxErrorException { + JsonArray array = new JsonArray(); + array.add(openid); + JsonObject jsonObject = new JsonObject(); + jsonObject.add("openid", array); + String respone = this.wxMpService.post(CARD_TEST_WHITELIST, GSON.toJson(jsonObject)); + return respone; + } + + /** + * 创建卡券二维码 + * + * @param cardId + * @param outerStr + * @return + */ + public WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr) throws WxErrorException { + return createQrcodeCard(cardId, outerStr, 0); + } + + /** + * 创建卡券二维码 + * + * @param cardId 卡券编号 + * @param outerStr 二维码标识 + * @param expiresIn 失效时间,单位秒,不填默认365天 + * @return + * @throws WxErrorException + */ + public WxMpCardQrcodeCreateResult createQrcodeCard(String cardId, String outerStr, int expiresIn) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("action_name", "QR_CARD"); + if (expiresIn > 0) { + jsonObject.addProperty("expire_seconds", expiresIn); + } + JsonObject actionInfoJson = new JsonObject(); + JsonObject cardJson = new JsonObject(); + cardJson.addProperty("card_id", cardId); + cardJson.addProperty("outer_str", outerStr); + actionInfoJson.add("card", cardJson); + jsonObject.add("action_info", actionInfoJson); + String response = this.wxMpService.post(CARD_QRCODE_CREAET, GSON.toJson(jsonObject)); + return WxMpCardQrcodeCreateResult.fromJson(response); + } + + /** + * 创建卡券货架接口 + * + * @param request + * @return + * @throws WxErrorException + */ + @Override + public WxMpCardLandingPageCreateResult createLandingPage(WxMpCardLandingPageCreateRequest request) throws WxErrorException { + String response = this.wxMpService.post(CARD_LANDING_PAGE_CREAET, GSON.toJson(request)); + return WxMpCardLandingPageCreateResult.fromJson(response); + } + + /** + * 将用户的卡券设置为失效状态 + * 详见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272&anchor=9 + * + * @param cardId 卡券编号 + * @param code 用户会员卡号 + * @param reason 设置为失效的原因 + * @return + * @throws WxErrorException + */ + @Override + public String unavailableCardCode(String cardId, String code, String reason) throws WxErrorException { + if (StringUtils.isAnyBlank(cardId, code, reason)) + throw new WxErrorException(WxError.builder().errorCode(41012).errorMsg("参数不完整").build()); + JsonObject jsonRequest = new JsonObject(); + jsonRequest.addProperty("card_id", cardId); + jsonRequest.addProperty("code", code); + jsonRequest.addProperty("reason", reason); + String response = this.wxMpService.post(CARD_CODE_UNAVAILABLE, GSON.toJson(jsonRequest)); + return response; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java index 25bd3cfaab..bf60892a1b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImpl.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api.impl; import com.google.gson.JsonObject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpDataCubeService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.datacube.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java index 284c0a2966..3fe464a89e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.api.impl; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpDeviceService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.device.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java index 8d98a07a32..7707c567dd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java @@ -1,21 +1,27 @@ package me.chanjar.weixin.mp.api.impl; +import java.io.File; +import java.util.Date; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.gson.JsonObject; -import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.mp.api.WxMpKefuService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest; -import me.chanjar.weixin.mp.bean.kefu.result.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.Date; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList; /** * @author Binary Wang @@ -112,20 +118,20 @@ public WxMpKfSessionWaitCaseList kfSessionGetWaitCase() throws WxErrorException @Override public WxMpKfMsgList kfMsgList(Date startTime, Date endTime, Long msgId, Integer number) throws WxErrorException { if (number > 10000) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("非法参数请求,每次最多查询10000条记录!").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法参数请求,每次最多查询10000条记录!").build()); } if (startTime.after(endTime)) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("起始时间不能晚于结束时间!").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("起始时间不能晚于结束时间!").build()); } JsonObject param = new JsonObject(); - param.addProperty("starttime", startTime.getTime() / 1000); //starttime 起始时间,unix时间戳 - param.addProperty("endtime", endTime.getTime() / 1000); //endtime 结束时间,unix时间戳,每次查询时段不能超过24小时 - param.addProperty("msgid", msgId); //msgid 消息id顺序从小到大,从1开始 - param.addProperty("number", number); //number 每次获取条数,最多10000条 + param.addProperty("starttime", startTime.getTime() / 1000); + param.addProperty("endtime", endTime.getTime() / 1000); + param.addProperty("msgid", msgId); + param.addProperty("number", number); - String responseContent = this.wxMpService.post(MSGRECORD_GET_MSG_LIST, param.toString()); + String responseContent = this.wxMpService.post(MSG_RECORD_LIST, param.toString()); return WxMpKfMsgList.fromJson(responseContent); } @@ -149,4 +155,13 @@ public WxMpKfMsgList kfMsgList(Date startTime, Date endTime) throws WxErrorExcep return result; } + @Override + public boolean sendKfTypingState(String openid, String command) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("touser", openid); + params.addProperty("command", command); + String responseContent = this.wxMpService.post(CUSTOM_TYPING, params.toString()); + return responseContent != null; + } + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java index c54fcc768c..31aa043e93 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImpl.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api.impl; import com.google.gson.JsonObject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpMassMessageService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.*; @@ -51,13 +51,13 @@ public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) } @Override - public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception { + public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws WxErrorException { String responseContent = this.wxMpService.post(MESSAGE_MASS_PREVIEW_URL, wxMpMassPreviewMessage.toJson()); return WxMpMassSendResult.fromJson(responseContent); } @Override - public void delete(Integer msgId, Integer articleIndex) throws Exception { + public void delete(Long msgId, Integer articleIndex) throws WxErrorException { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("msg_id", msgId); jsonObject.addProperty("article_idx", articleIndex); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java index 90594fe031..7929aced0a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java @@ -1,25 +1,39 @@ package me.chanjar.weixin.mp.api.impl; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; -import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; +import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.api.WxMpMaterialService; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.material.*; -import me.chanjar.weixin.mp.util.http.*; +import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; +import me.chanjar.weixin.mp.bean.material.WxMpMaterial; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialArticleUpdate; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialCountResult; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialFileBatchGetResult; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialNewsBatchGetResult; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialDeleteRequestExecutor; +import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialNewsInfoRequestExecutor; +import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialUploadRequestExecutor; +import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialVideoInfoRequestExecutor; +import me.chanjar.weixin.mp.util.requestexecuter.material.MaterialVoiceAndImageDownloadRequestExecutor; +import me.chanjar.weixin.mp.util.requestexecuter.media.MediaImgUploadRequestExecutor; /** * Created by Binary Wang on 2016/7/21. @@ -34,11 +48,16 @@ public WxMpMaterialServiceImpl(WxMpService wxMpService) { @Override public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { + File tmpFile = null; try { - return this.mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); + tmpFile = FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType); + return this.mediaUpload(mediaType, tmpFile); } catch (IOException e) { - e.printStackTrace(); - throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build(), e); + } finally { + if (tmpFile != null) { + tmpFile.delete(); + } } } @@ -51,7 +70,7 @@ public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErr @Override public File mediaDownload(String mediaId) throws WxErrorException { return this.wxMpService.execute( - MediaDownloadRequestExecutor.create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), + BaseMediaDownloadRequestExecutor.create(this.wxMpService.getRequestHttp(), this.wxMpService.getWxMpConfigStorage().getTmpDirFile()), MEDIA_GET_URL, "media_id=" + mediaId); } @@ -95,7 +114,7 @@ public WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException @Override public boolean materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException { String responseText = this.wxMpService.post(NEWS_UPDATE_URL, wxMpMaterialArticleUpdate.toJson()); - WxError wxError = WxError.fromJson(responseText); + WxError wxError = WxError.fromJson(responseText, WxType.MP); if (wxError.getErrorCode() == 0) { return true; } else { @@ -111,7 +130,7 @@ public boolean materialDelete(String mediaId) throws WxErrorException { @Override public WxMpMaterialCountResult materialCount() throws WxErrorException { String responseText = this.wxMpService.get(MATERIAL_GET_COUNT_URL, null); - WxError wxError = WxError.fromJson(responseText); + WxError wxError = WxError.fromJson(responseText, WxType.MP); if (wxError.getErrorCode() == 0) { return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialCountResult.class); } else { @@ -122,11 +141,11 @@ public WxMpMaterialCountResult materialCount() throws WxErrorException { @Override public WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException { Map params = new HashMap<>(); - params.put("type", WxConsts.MATERIAL_NEWS); + params.put("type", WxConsts.MaterialType.NEWS); params.put("offset", offset); params.put("count", count); String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); - WxError wxError = WxError.fromJson(responseText); + WxError wxError = WxError.fromJson(responseText, WxType.MP); if (wxError.getErrorCode() == 0) { return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialNewsBatchGetResult.class); } else { @@ -141,7 +160,7 @@ public WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offs params.put("offset", offset); params.put("count", count); String responseText = this.wxMpService.post(MATERIAL_BATCHGET_URL, WxGsonBuilder.create().toJson(params)); - WxError wxError = WxError.fromJson(responseText); + WxError wxError = WxError.fromJson(responseText, WxType.MP); if (wxError.getErrorCode() == 0) { return WxMpGsonBuilder.create().fromJson(responseText, WxMpMaterialFileBatchGetResult.class); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java index b3a43a765a..3c4d0ab526 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java @@ -5,31 +5,30 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.api.WxMpMemberCardService; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; +import me.chanjar.weixin.mp.bean.card.*; +import me.chanjar.weixin.mp.bean.card.enums.BusinessServiceType; +import me.chanjar.weixin.mp.bean.card.enums.CardColor; +import me.chanjar.weixin.mp.bean.card.enums.DateInfoType; +import me.chanjar.weixin.mp.bean.membercard.*; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 会员卡相关接口的实现类 * - * @author YuJian(mgcnrx11@gmail.com) + * @author YuJian(mgcnrx11 @ gmail.com) * @version 2017/7/8 */ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService { private final Logger log = LoggerFactory.getLogger(WxMpMemberCardServiceImpl.class); - private static final String MEMBER_CARD_ACTIVATE = "https://api.weixin.qq.com/card/membercard/activate"; - private static final String MEMBER_CARD_USER_INFO_GET = "https://api.weixin.qq.com/card/membercard/userinfo/get"; - private static final String MEMBER_CARD_UPDATE_USER = "https://api.weixin.qq.com/card/membercard/updateuser"; - private WxMpService wxMpService; private static final Gson GSON = new Gson(); @@ -46,11 +45,176 @@ public WxMpService getWxMpService() { return this.wxMpService; } + /** + * 会员卡创建接口 + * + * @param createJson 创建json + * @return 调用返回的JSON字符串。 + * @throws WxErrorException 接口调用失败抛出的异常 + */ + @Override + public WxMpCardCreateResult createMemberCard(String createJson) throws WxErrorException { + WxMpMemberCardCreateMessage createMessage = WxGsonBuilder.create().fromJson(createJson, WxMpMemberCardCreateMessage.class); + return createMemberCard(createMessage); + } + + /** + * 会员卡创建接口 + * + * @param createMessageMessage 创建所需参数 + * @return WxMpCardCreateResult。 + * @throws WxErrorException 接口调用失败抛出的异常 + */ + @Override + public WxMpCardCreateResult createMemberCard(WxMpMemberCardCreateMessage createMessageMessage) throws WxErrorException { + //校验请求对象合法性 + WxMpCardCreateResult validResult = validCheck(createMessageMessage); + if (!validResult.isSuccess()) + return validResult; + String response = this.wxMpService.post(MEMBER_CARD_CREAET, GSON.toJson(createMessageMessage)); + return WxMpCardCreateResult.fromJson(response); + } + + private WxMpCardCreateResult validCheck(WxMpMemberCardCreateMessage createMessageMessage) throws WxErrorException { + if (createMessageMessage == null) { + return WxMpCardCreateResult.failure("对象不能为空"); + } + MemberCardCreateRequest cardCreateRequest = createMessageMessage.getCardCreateRequest(); + if (createMessageMessage == null) { + return WxMpCardCreateResult.failure("会员卡对象不能为空"); + } + String cardType = cardCreateRequest.getCardType(); + if (!StringUtils.equals(cardType, "MEMBER_CARD")) { + return WxMpCardCreateResult.failure("卡券类型必须等于MEMBER_CARD"); + } + MemberCard memberCard = cardCreateRequest.getMemberCard(); + + if (StringUtils.isEmpty(memberCard.getPrerogative())) { + return WxMpCardCreateResult.failure("会员卡特权说明不能为空:prerogative"); + } + //卡片激活规则 + if (!memberCard.isAutoActivate() && !memberCard.isWxActivate() && StringUtils.isEmpty(memberCard.getActivateUrl())) { + return WxMpCardCreateResult.failure("会员卡激活方式为接口激活,activate_url不能为空"); + } + + //积分支持 +// if(memberCard.isSupplyBonus() && StringUtils.isEmpty(memberCard.getBonusUrl())){ +// return WxMpCardCreateResult.failure("会员卡支持积分,bonus_url不能为空"); +// } +// if(memberCard.isSupplyBonus() && memberCard.getBonusRule() == null){ +// return WxMpCardCreateResult.failure("会员卡支持积分,bonus_rule不能为空"); +// } + BaseInfo baseInfo = memberCard.getBaseInfo(); + if (baseInfo == null) { + return WxMpCardCreateResult.failure("会员卡基本信息对象base_info不能为空"); + } + + if (StringUtils.isBlank(baseInfo.getLogoUrl())) { + return WxMpCardCreateResult.failure("会员卡基本信息的商户logo:logo_url不能为空"); + } + + if (StringUtils.isBlank(baseInfo.getCodeType())) { + return WxMpCardCreateResult.failure("会员卡基本信息的条码类型:code_type不能为空"); + } + + if (StringUtils.isBlank(baseInfo.getBrandName())) { + return WxMpCardCreateResult.failure("会员卡基本信息的商户名字:brand_name不能为空"); + } + + if (StringUtils.length(baseInfo.getBrandName()) > 12) { + return WxMpCardCreateResult.failure("会员卡基本信息的商户名字:brand_name长度不能大于12个汉字"); + } + + if (StringUtils.isBlank(baseInfo.getTitle())) { + return WxMpCardCreateResult.failure("会员卡基本信息的卡券名称:title不能为空"); + } + + if (StringUtils.length(baseInfo.getTitle()) > 9) { + return WxMpCardCreateResult.failure("会员卡基本信息的卡券名称:title长度不能大于9个汉字"); + } + + if (StringUtils.isBlank(baseInfo.getColor())) { + return WxMpCardCreateResult.failure("会员卡基本信息的卡颜色:color不能为空"); + } + + CardColor cardColor = null; + try { + cardColor = CardColor.valueOf(baseInfo.getColor()); + } catch (IllegalArgumentException ex) { + + } + if (cardColor == null) { + return WxMpCardCreateResult.failure("会员卡基本信息的卡颜色:" + baseInfo.getColor() + "不支持"); + } + + if (StringUtils.isBlank(baseInfo.getNotice())) { + return WxMpCardCreateResult.failure("会员卡基本信息的使用提醒:notice不能为空"); + } + + if (StringUtils.isBlank(baseInfo.getDescription())) { + return WxMpCardCreateResult.failure("会员卡基本信息的使用说明:description不能为空"); + } + + if (baseInfo.getSku() == null) { + return WxMpCardCreateResult.failure("会员卡基本信息的商品信息:sku不能为空"); + } + + DateInfo dateInfo = baseInfo.getDateInfo(); + if (dateInfo == null) { + return WxMpCardCreateResult.failure("会员卡基本信息的使用日期:date_info不能为空"); + } + + DateInfoType dateInfoType = null; + try { + dateInfoType = DateInfoType.valueOf(dateInfo.getType()); + } catch (IllegalArgumentException ex) { + + } + + if (dateInfoType == null) { + return WxMpCardCreateResult.failure("会员卡基本信息的使用日期类型:" + dateInfo.getType() + "不合法"); + } + + //固定时长 + if (dateInfoType == DateInfoType.DATE_TYPE_FIX_TERM && (dateInfo.getFixedTerm() == null || dateInfo.getFixedBeginTerm() == null)) { + return WxMpCardCreateResult.failure("会员卡基本信息的使用日期为:" + dateInfoType.getDescription() + ",fixedTerm和fixedBeginTerm不能为空"); + } + + //固定期限 + if (dateInfoType == DateInfoType.DATE_TYPE_FIX_TIME_RANGE && (dateInfo.getBeginTimestamp() == null || dateInfo.getEndTimestamp() == null)) { + return WxMpCardCreateResult.failure("会员卡基本信息的使用日期为:" + dateInfoType.getDescription() + ",beginTimestamp 和 endTimestamp 不能为空"); + } + if (dateInfoType == DateInfoType.DATE_TYPE_FIX_TIME_RANGE && (dateInfo.getBeginTimestamp() < System.currentTimeMillis() || dateInfo.getEndTimestamp() < System.currentTimeMillis() || dateInfo.getBeginTimestamp() > dateInfo.getEndTimestamp())) { + return WxMpCardCreateResult.failure("会员卡基本信息的使用日期为:" + dateInfoType.getDescription() + ",beginTimestamp和endTimestamp的值不合法,请检查"); + } + + if (!baseInfo.isUseAllLocations() && StringUtils.isBlank(baseInfo.getLocationIdList())) { + return WxMpCardCreateResult.failure("会员卡基本信息的门店使用范围选择指定门店,门店列表:locationIdList不能为空"); + } + + //校验高级信息 + AdvancedInfo advancedInfo = memberCard.getAdvancedInfo(); + if (advancedInfo != null) { + if (advancedInfo.getBusinessServiceList() != null) { + for (String bs : advancedInfo.getBusinessServiceList()) { + BusinessServiceType businessServiceType = null; + try { + businessServiceType = BusinessServiceType.valueOf(bs); + } catch (IllegalArgumentException ex) { + return WxMpCardCreateResult.failure("会员卡高级信息的商户服务:" + bs + " 不合法"); + } + } + } + } + + return WxMpCardCreateResult.success(); + } + /** * 会员卡激活接口 * * @param activatedMessage 激活所需参数 - * @return 调用返回的JSON字符串。 + * @return WxMpCardCreateResult。 * @throws WxErrorException 接口调用失败抛出的异常 */ @Override @@ -70,9 +234,10 @@ public String activateMemberCard(WxMpMemberCardActivatedMessage activatedMessage public WxMpMemberCardUserInfoResult getUserInfo(String cardId, String code) throws WxErrorException { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("card_id", cardId); - jsonObject.addProperty("code",code); + jsonObject.addProperty("code", code); String responseContent = this.getWxMpService().post(MEMBER_CARD_USER_INFO_GET, jsonObject.toString()); + log.debug("{}",responseContent); JsonElement tmpJsonElement = new JsonParser().parse(responseContent); return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, new TypeToken() { @@ -81,7 +246,7 @@ public WxMpMemberCardUserInfoResult getUserInfo(String cardId, String code) thro /** * 当会员持卡消费后,支持开发者调用该接口更新会员信息。会员卡交易后的每次信息变更需通过该接口通知微信,便于后续消息通知及其他扩展功能。 - * + *

* 1.开发者可以同时传入add_bonus和bonus解决由于同步失败带来的幂等性问题。同时传入add_bonus和bonus时 * add_bonus作为积分变动消息中的变量值,而bonus作为卡面上的总积分额度显示。余额变动同理。 * 2.开发者可以传入is_notify_bonus控制特殊的积分对账变动不发送消息,余额变动同理。 @@ -101,4 +266,18 @@ public WxMpMemberCardUpdateResult updateUserMemberCard(WxMpMemberCardUpdateMessa new TypeToken() { }.getType()); } + + /** + * 设置会员卡激活的字段(会员卡设置:wx_activate=true 时需要) + * + * @param userFormRequest + * @return + * @throws WxErrorException + */ + @Override + public MemberCardActivateUserFormResult setActivateUserForm(MemberCardActivateUserFormRequest userFormRequest) throws WxErrorException { + String responseContent = this.getWxMpService().post(MEMBER_CARD_ACTIVATEUSERFORM, GSON.toJson(userFormRequest)); + return MemberCardActivateUserFormResult.fromJson(responseContent); + } + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java index d22f4c82e2..e8dc84766b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImpl.java @@ -3,7 +3,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import me.chanjar.weixin.common.bean.menu.WxMenu; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpMenuService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java index 5f6c3ad54f..5783ce7991 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImpl.java @@ -1,12 +1,12 @@ package me.chanjar.weixin.mp.api.impl; import com.google.gson.JsonObject; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpQrcodeService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; +import me.chanjar.weixin.mp.util.requestexecuter.qrcode.QrCodeRequestExecutor; import org.apache.commons.lang3.StringUtils; import java.io.File; @@ -28,13 +28,13 @@ public WxMpQrcodeServiceImpl(WxMpService wxMpService) { @Override public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds) throws WxErrorException { if (sceneId == 0) { - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("临时二维码场景值不能为0!").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为0!").build()); } //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 if (expireSeconds != null && expireSeconds > 2592000) { - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1) - .setErrorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); } if (expireSeconds == null) { @@ -59,13 +59,13 @@ public WxMpQrCodeTicket qrCodeCreateTmpTicket(int sceneId, Integer expireSeconds @Override public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSeconds) throws WxErrorException { if (StringUtils.isBlank(sceneStr)) { - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("临时二维码场景值不能为空!").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("临时二维码场景值不能为空!").build()); } //expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 if (expireSeconds != null && expireSeconds > 2592000) { - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1) - .setErrorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("临时二维码有效时间最大不能超过2592000(即30天)!").build()); } if (expireSeconds == null) { @@ -90,7 +90,9 @@ public WxMpQrCodeTicket qrCodeCreateTmpTicket(String sceneStr, Integer expireSec @Override public WxMpQrCodeTicket qrCodeCreateLastTicket(int sceneId) throws WxErrorException { if (sceneId < 1 || sceneId > 100000) { - throw new WxErrorException(WxError.newBuilder().setErrorCode(-1).setErrorMsg("永久二维码的场景值目前只支持1--100000!").build()); + throw new WxErrorException(WxError.builder().errorCode(-1) + .errorMsg("永久二维码的场景值目前只支持1--100000!") + .build()); } String url = API_URL_PREFIX + "/create"; @@ -137,9 +139,7 @@ public String qrCodePictureUrl(String ticket, boolean needShortUrl) throws WxErr return resultUrl; } catch (UnsupportedEncodingException e) { - WxError error = WxError.newBuilder().setErrorCode(-1) - .setErrorMsg(e.getMessage()).build(); - throw new WxErrorException(error); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg(e.getMessage()).build()); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceApacheHttpClientImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java similarity index 90% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceApacheHttpClientImpl.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java index dd8aaf6114..3db9e9b149 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceApacheHttpClientImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java @@ -1,8 +1,9 @@ package me.chanjar.weixin.mp.api.impl; +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; @@ -19,9 +20,9 @@ import java.util.concurrent.locks.Lock; /** - * apache-http方式实现 + * apache http client方式实现. */ -public class WxMpServiceApacheHttpClientImpl extends WxMpServiceAbstractImpl { +public class WxMpServiceHttpClientImpl extends BaseWxMpServiceImpl { private CloseableHttpClient httpClient; private HttpHost httpProxy; @@ -76,7 +77,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { } try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) { String resultContent = new BasicResponseHandler().handleResponse(response); - WxError error = WxError.fromJson(resultContent); + WxError error = WxError.fromJson(resultContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java index 4d2017dd63..79c3fad266 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java @@ -4,8 +4,9 @@ *

  * 默认接口实现类,使用apache httpclient实现
  * Created by Binary Wang on 2017-5-27.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ -public class WxMpServiceImpl extends WxMpServiceApacheHttpClientImpl { +public class WxMpServiceImpl extends WxMpServiceHttpClientImpl { } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java index f146c365e8..ee8411ab73 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java @@ -2,9 +2,10 @@ import jodd.http.*; import jodd.http.net.SocketHttpConnectionProvider; +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; @@ -14,7 +15,7 @@ /** * jodd-http方式实现 */ -public class WxMpServiceJoddHttpImpl extends WxMpServiceAbstractImpl { +public class WxMpServiceJoddHttpImpl extends BaseWxMpServiceImpl { private HttpConnectionProvider httpClient; private ProxyInfo httpProxy; @@ -65,7 +66,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { } HttpResponse response = request.send(); String resultContent = response.bodyText(); - WxError error = WxError.fromJson(resultContent); + WxError error = WxError.fromJson(resultContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java index 9066dc8d17..6d3f5bf29a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java @@ -1,23 +1,21 @@ package me.chanjar.weixin.mp.api.impl; +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; import okhttp3.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.concurrent.locks.Lock; -public class WxMpServiceOkHttpImpl extends WxMpServiceAbstractImpl { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - +/** + * okhttp实现 + */ +public class WxMpServiceOkHttpImpl extends BaseWxMpServiceImpl { private OkHttpClient httpClient; private OkHttpProxyInfo httpProxy; @@ -38,7 +36,7 @@ public HttpType getRequestType() { @Override public String getAccessToken(boolean forceRefresh) throws WxErrorException { - logger.debug("WxMpServiceOkHttpImpl is running"); + this.log.debug("WxMpServiceOkHttpImpl is running"); Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); try { lock.lock(); @@ -50,7 +48,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { Request request = new Request.Builder().url(url).get().build(); Response response = getRequestHttpClient().newCall(request).execute(); String resultContent = response.body().string(); - WxError error = WxError.fromJson(resultContent); + WxError error = WxError.fromJson(resultContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } @@ -59,7 +57,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { accessToken.getExpiresIn()); } } catch (IOException e) { - e.printStackTrace(); + this.log.error(e.getMessage(), e); } finally { lock.unlock(); } @@ -68,14 +66,17 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { @Override public void initHttp() { - logger.debug("WxMpServiceOkHttpImpl initHttp"); - WxMpConfigStorage configStorage = this.getWxMpConfigStorage(); + this.log.debug("WxMpServiceOkHttpImpl initHttp"); - if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { - httpProxy = OkHttpProxyInfo.socks5Proxy(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort(), configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword()); + //设置代理 + if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) { + httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(), + wxMpConfigStorage.getHttpProxyPort(), + wxMpConfigStorage.getHttpProxyUsername(), + wxMpConfigStorage.getHttpProxyPassword()); } + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder(); - //设置代理 if (httpProxy != null) { clientBuilder.proxy(getRequestHttpProxy().getProxy()); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java index bee636fd54..6f6beda5ab 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpShakeServiceImpl.java @@ -1,13 +1,17 @@ package me.chanjar.weixin.mp.api.impl; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpShakeService; import me.chanjar.weixin.mp.bean.WxMpShakeInfoResult; import me.chanjar.weixin.mp.bean.WxMpShakeQuery; +import me.chanjar.weixin.mp.bean.shake.*; /** * Created by rememberber on 2017/6/5. + * * @author rememberber */ public class WxMpShakeServiceImpl implements WxMpShakeService { @@ -27,7 +31,7 @@ public WxMpShakeServiceImpl(WxMpService wxMpService) { * 接口地址:https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=ACCESS_TOKE *
* - * @param wxMpShakeQuery 查询参数 + * @param wxMpShakeQuery 查询参数 */ @Override public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws WxErrorException { @@ -36,4 +40,28 @@ public WxMpShakeInfoResult getShakeInfo(WxMpShakeQuery wxMpShakeQuery) throws Wx String responseContent = this.wxMpService.post(url, postData); return WxMpShakeInfoResult.fromJson(responseContent); } + + @Override + public WxMpShakeAroundPageAddResult pageAdd(WxMpShakeAroundPageAddQuery shakeAroundPageAddQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/page/add"; + String postData = shakeAroundPageAddQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundPageAddResult.fromJson(responseContent); + } + + @Override + public WxError deviceBindPageQuery(WxMpShakeAroundDeviceBindPageQuery shakeAroundDeviceBindPageQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/device/bindpage"; + String postData = shakeAroundDeviceBindPageQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxError.fromJson(responseContent, WxType.MP); + } + + @Override + public WxMpShakeAroundRelationSearchResult relationSearch(WxMpShakeAroundRelationSearchQuery shakeAroundRelationSearchQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/shakearound/relation/search"; + String postData = shakeAroundRelationSearchQuery.toJsonString(); + String responseContent = this.wxMpService.post(url, postData); + return WxMpShakeAroundRelationSearchResult.fromJson(responseContent); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java index 5f1b5f2a82..402102064c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java @@ -3,8 +3,9 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.BeanUtils; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpStoreService; @@ -21,8 +22,6 @@ * @author binarywang (https://github.com/binarywang) */ public class WxMpStoreServiceImpl implements WxMpStoreService { - private static final String API_BASE_URL = "http://api.weixin.qq.com/cgi-bin/poi"; - private WxMpService wxMpService; public WxMpStoreServiceImpl(WxMpService wxMpService) { @@ -33,9 +32,8 @@ public WxMpStoreServiceImpl(WxMpService wxMpService) { public void add(WxMpStoreBaseInfo request) throws WxErrorException { BeanUtils.checkRequiredFields(request); - String url = API_BASE_URL + "/addpoi"; - String response = this.wxMpService.post(url, request.toJson()); - WxError wxError = WxError.fromJson(response); + String response = this.wxMpService.post(POI_ADD_URL, request.toJson()); + WxError wxError = WxError.fromJson(response, WxType.MP); if (wxError.getErrorCode() != 0) { throw new WxErrorException(wxError); } @@ -43,11 +41,10 @@ public void add(WxMpStoreBaseInfo request) throws WxErrorException { @Override public WxMpStoreBaseInfo get(String poiId) throws WxErrorException { - String url = API_BASE_URL + "/getpoi"; JsonObject paramObject = new JsonObject(); paramObject.addProperty("poi_id", poiId); - String response = this.wxMpService.post(url, paramObject.toString()); - WxError wxError = WxError.fromJson(response); + String response = this.wxMpService.post(POI_GET_URL, paramObject.toString()); + WxError wxError = WxError.fromJson(response, WxType.MP); if (wxError.getErrorCode() != 0) { throw new WxErrorException(wxError); } @@ -57,11 +54,10 @@ public WxMpStoreBaseInfo get(String poiId) throws WxErrorException { @Override public void delete(String poiId) throws WxErrorException { - String url = API_BASE_URL + "/delpoi"; JsonObject paramObject = new JsonObject(); paramObject.addProperty("poi_id", poiId); - String response = this.wxMpService.post(url, paramObject.toString()); - WxError wxError = WxError.fromJson(response); + String response = this.wxMpService.post(POI_DEL_URL, paramObject.toString()); + WxError wxError = WxError.fromJson(response, WxType.MP); if (wxError.getErrorCode() != 0) { throw new WxErrorException(wxError); } @@ -70,13 +66,12 @@ public void delete(String poiId) throws WxErrorException { @Override public WxMpStoreListResult list(int begin, int limit) throws WxErrorException { - String url = API_BASE_URL + "/getpoilist"; JsonObject params = new JsonObject(); params.addProperty("begin", begin); params.addProperty("limit", limit); - String response = this.wxMpService.post(url, params.toString()); + String response = this.wxMpService.post(POI_LIST_URL, params.toString()); - WxError wxError = WxError.fromJson(response); + WxError wxError = WxError.fromJson(response, WxType.MP); if (wxError.getErrorCode() != 0) { throw new WxErrorException(wxError); } @@ -107,9 +102,8 @@ public List listAll() throws WxErrorException { @Override public void update(WxMpStoreBaseInfo request) throws WxErrorException { - String url = API_BASE_URL + "/updatepoi"; - String response = this.wxMpService.post(url, request.toJson()); - WxError wxError = WxError.fromJson(response); + String response = this.wxMpService.post(POI_UPDATE_URL, request.toJson()); + WxError wxError = WxError.fromJson(response, WxType.MP); if (wxError.getErrorCode() != 0) { throw new WxErrorException(wxError); } @@ -117,9 +111,8 @@ public void update(WxMpStoreBaseInfo request) throws WxErrorException { @Override public List listCategories() throws WxErrorException { - String url = API_BASE_URL + "/getwxcategory"; - String response = this.wxMpService.get(url, null); - WxError wxError = WxError.fromJson(response); + String response = this.wxMpService.get(POI_GET_WX_CATEGORY_URL, null); + WxError wxError = WxError.fromJson(response, WxType.MP); if (wxError.getErrorCode() != 0) { throw new WxErrorException(wxError); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImpl.java new file mode 100644 index 0000000000..fe1cfb306c --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImpl.java @@ -0,0 +1,42 @@ +package me.chanjar.weixin.mp.api.impl; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.URIUtil; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpSubscribeMsgService; +import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; + +/** + * @author Mklaus + * @date 2018-01-22 上午11:19 + */ +public class WxMpSubscribeMsgServiceImpl implements WxMpSubscribeMsgService { + private static final String SUBSCRIBE_MESSAGE_AUTHORIZE_URL = + "https://mp.weixin.qq.com/mp/subscribemsg?action=get_confirm&appid=%s&scene=%d&template_id=%s&redirect_url=%s&reserved=%s#wechat_redirect"; + private static final String SEND_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/subscribe"; + + + private WxMpService wxMpService; + + public WxMpSubscribeMsgServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public String subscribeMsgAuthorizationUrl(String redirectURI, int scene, String reserved) { + WxMpConfigStorage storage = this.wxMpService.getWxMpConfigStorage(); + return String.format(SUBSCRIBE_MESSAGE_AUTHORIZE_URL, + storage.getAppId(), scene, storage.getTemplateId(), URIUtil.encodeURIComponent(redirectURI), reserved); + } + + @Override + public boolean sendSubscribeMessage(WxMpSubscribeMessage message) throws WxErrorException { + if (message.getTemplateId() == null) { + message.setTemplateId(this.wxMpService.getWxMpConfigStorage().getTemplateId()); + } + + String responseContent = this.wxMpService.post(SEND_MESSAGE_URL, message.toJson()); + return responseContent != null; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java index 82ce829cdd..472cd0fe8c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java @@ -2,8 +2,9 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpTemplateMsgService; import me.chanjar.weixin.mp.bean.template.WxMpTemplate; @@ -15,8 +16,9 @@ /** *
  * Created by Binary Wang on 2016-10-14.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ public class WxMpTemplateMsgServiceImpl implements WxMpTemplateMsgService { public static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/template"; @@ -36,7 +38,7 @@ public String sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErro if (jsonObject.get("errcode").getAsInt() == 0) { return jsonObject.get("msgid").getAsString(); } - throw new WxErrorException(WxError.fromJson(responseContent)); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); } @Override @@ -69,7 +71,7 @@ public String addTemplate(String shortTemplateId) throws WxErrorException { return result.get("template_id").getAsString(); } - throw new WxErrorException(WxError.fromJson(responseContent)); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); } @Override @@ -84,7 +86,7 @@ public boolean delPrivateTemplate(String templateId) throws WxErrorException { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("template_id", templateId); String responseContent = this.wxMpService.post(url, jsonObject.toString()); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() == 0) { return true; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java index 4e3f78140a..561d7c04f1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserBlacklistServiceImpl.java @@ -2,7 +2,7 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpUserBlacklistService; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java index ba74f0e4a7..def801e4e9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImpl.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api.impl; import com.google.gson.JsonObject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpUserService; import me.chanjar.weixin.mp.bean.WxMpUserQuery; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java index 99f271065c..6a37741b84 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java @@ -4,8 +4,9 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.WxMpUserTagService; import me.chanjar.weixin.mp.bean.tag.WxTagListUser; @@ -16,8 +17,9 @@ import java.util.List; /** - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016/9/2. + * Created by Binary Wang on 2016/9/2. + * + * @author Binary Wang */ public class WxMpUserTagServiceImpl implements WxMpUserTagService { private static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/tags"; @@ -59,7 +61,7 @@ public Boolean tagUpdate(Long id, String name) throws WxErrorException { json.add("tag", tagJson); String responseContent = this.wxMpService.post(url, json.toString()); - WxError wxError = WxError.fromJson(responseContent); + WxError wxError = WxError.fromJson(responseContent, WxType.MP); if (wxError.getErrorCode() == 0) { return true; } @@ -77,7 +79,7 @@ public Boolean tagDelete(Long id) throws WxErrorException { json.add("tag", tagJson); String responseContent = this.wxMpService.post(url, json.toString()); - WxError wxError = WxError.fromJson(responseContent); + WxError wxError = WxError.fromJson(responseContent, WxType.MP); if (wxError.getErrorCode() == 0) { return true; } @@ -112,7 +114,7 @@ public boolean batchTagging(Long tagId, String[] openids) json.add("openid_list", openidArrayJson); String responseContent = this.wxMpService.post(url, json.toString()); - WxError wxError = WxError.fromJson(responseContent); + WxError wxError = WxError.fromJson(responseContent, WxType.MP); if (wxError.getErrorCode() == 0) { return true; } @@ -134,7 +136,7 @@ public boolean batchUntagging(Long tagId, String[] openids) json.add("openid_list", openidArrayJson); String responseContent = this.wxMpService.post(url, json.toString()); - WxError wxError = WxError.fromJson(responseContent); + WxError wxError = WxError.fromJson(responseContent, WxType.MP); if (wxError.getErrorCode() == 0) { return true; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImpl.java new file mode 100644 index 0000000000..f87c784b89 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImpl.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpWifiService; +import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopListResult; + +/** + *
+ *  Created by BinaryWang on 2018/6/10.
+ * 
+ * + * @author Binary Wang + */ +public class WxMpWifiServiceImpl implements WxMpWifiService { + private WxMpService wxMpService; + + public WxMpWifiServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public WxMpWifiShopListResult listShop(int pageIndex, int pageSize) throws WxErrorException { + JsonObject json = new JsonObject(); + json.addProperty("pageindex", pageIndex); + json.addProperty("pagesize", pageSize); + final String result = this.wxMpService.post("https://api.weixin.qq.com/bizwifi/shop/list", json.toString()); + return WxMpWifiShopListResult.fromJson(result); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java index 76fc4a6451..622dca9e73 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java @@ -1,16 +1,20 @@ package me.chanjar.weixin.mp.bean; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; + /** * 微信卡券 * * @author YuJian * @version 15/11/11 */ +@Data public class WxMpCard implements Serializable{ private static final long serialVersionUID = 9214301870017772921L; @@ -24,48 +28,8 @@ public class WxMpCard implements Serializable{ private Boolean canConsume; - public String getCardId() { - return this.cardId; - } - - public void setCardId(String cardId) { - this.cardId = cardId; - } - - public Long getBeginTime() { - return this.beginTime; - } - - public void setBeginTime(Long beginTime) { - this.beginTime = beginTime; - } - - public Long getEndTime() { - return this.endTime; - } - - public void setEndTime(Long endTime) { - this.endTime = endTime; - } - - public String getUserCardStatus() { - return this.userCardStatus; - } - - public void setUserCardStatus(String userCardStatus) { - this.userCardStatus = userCardStatus; - } - - public Boolean getCanConsume() { - return this.canConsume; - } - - public void setCanConsume(Boolean canConsume) { - this.canConsume = canConsume; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassNews.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassNews.java index bb19f0e79e..5dd8c2ad9d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassNews.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassNews.java @@ -1,26 +1,26 @@ package me.chanjar.weixin.mp.bean; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** - * 群发时用到的图文消息素材 + * 群发时用到的图文消息素材. * * @author chanjarster */ +@Data public class WxMpMassNews implements Serializable { private static final long serialVersionUID = 565937155013581016L; private List articles = new ArrayList<>(); - public List getArticles() { - return this.articles; - } - public void addArticle(WxMpMassNewsArticle article) { this.articles.add(article); } @@ -35,12 +35,12 @@ public boolean isEmpty() { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } /** *
-   * 群发图文消息article
+   * 群发图文消息article.
    * 1. thumbMediaId  (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得
    * 2. author          图文消息的作者
    * 3. title           (必填) 图文消息的标题
@@ -52,95 +52,40 @@ public String toString() {
    *
    * @author chanjarster
    */
+  @Data
   public static class WxMpMassNewsArticle {
     /**
-     * (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得
+     * (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得.
      */
     private String thumbMediaId;
     /**
-     * 图文消息的作者
+     * 图文消息的作者.
      */
     private String author;
     /**
-     * (必填) 图文消息的标题
+     * (必填) 图文消息的标题.
      */
     private String title;
     /**
-     * 在图文消息页面点击“阅读原文”后的页面链接
+     * 在图文消息页面点击“阅读原文”后的页面链接.
      */
     private String contentSourceUrl;
     /**
-     * (必填) 图文消息页面的内容,支持HTML标签
+     * (必填) 图文消息页面的内容,支持HTML标签.
      */
     private String content;
     /**
-     * 图文消息的描述
+     * 图文消息的描述.
      */
     private String digest;
     /**
-     * 是否显示封面,true为显示,false为不显示
+     * 是否显示封面,true为显示,false为不显示.
      */
     private boolean showCoverPic;
 
-    public String getThumbMediaId() {
-      return this.thumbMediaId;
-    }
-
-    public void setThumbMediaId(String thumbMediaId) {
-      this.thumbMediaId = thumbMediaId;
-    }
-
-    public String getAuthor() {
-      return this.author;
-    }
-
-    public void setAuthor(String author) {
-      this.author = author;
-    }
-
-    public String getTitle() {
-      return this.title;
-    }
-
-    public void setTitle(String title) {
-      this.title = title;
-    }
-
-    public String getContentSourceUrl() {
-      return this.contentSourceUrl;
-    }
-
-    public void setContentSourceUrl(String contentSourceUrl) {
-      this.contentSourceUrl = contentSourceUrl;
-    }
-
-    public String getContent() {
-      return this.content;
-    }
-
-    public void setContent(String content) {
-      this.content = content;
-    }
-
-    public String getDigest() {
-      return this.digest;
-    }
-
-    public void setDigest(String digest) {
-      this.digest = digest;
-    }
-
-    public boolean isShowCoverPic() {
-      return this.showCoverPic;
-    }
-
-    public void setShowCoverPic(boolean showCoverPic) {
-      this.showCoverPic = showCoverPic;
-    }
-
     @Override
     public String toString() {
-      return ToStringUtils.toSimpleString(this);
+      return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
     }
   }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java
index 73b6c9e241..742b016590 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassOpenIdsMessage.java
@@ -1,5 +1,7 @@
 package me.chanjar.weixin.mp.bean;
 
+import lombok.Data;
+import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
 
 import java.io.Serializable;
@@ -11,93 +13,52 @@
  *
  * @author chanjarster
  */
+@Data
 public class WxMpMassOpenIdsMessage implements Serializable {
   private static final long serialVersionUID = -8022910911104788999L;
 
+  /**
+   * openid列表,最多支持10,000个
+   */
   private List toUsers = new ArrayList<>();
-  private String msgType;
-  private String content;
-  private String mediaId;
-  private boolean sendIgnoreReprint = false;
-
-  public WxMpMassOpenIdsMessage() {
-    super();
-  }
-
-  public String getMsgType() {
-    return this.msgType;
-  }
 
   /**
    * 
    * 请使用
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_NEWS}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_VOICE}
+   * {@link WxConsts.MassMsgType#IMAGE}
+   * {@link WxConsts.MassMsgType#MPNEWS}
+   * {@link WxConsts.MassMsgType#TEXT}
+   * {@link WxConsts.MassMsgType#MPVIDEO}
+   * {@link WxConsts.MassMsgType#VOICE}
    * 如果msgtype和media_id不匹配的话,会返回系统繁忙的错误
    * 
- * - * @param msgType */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } + private String msgType; + private String content; + private String mediaId; + /** + * 文章被判定为转载时,是否继续进行群发操作。 + */ + private boolean sendIgnoreReprint = false; - public String getMediaId() { - return this.mediaId; - } + /** + * 开发者侧群发msgid,长度限制64字节,如不填,则后台默认以群发范围和群发内容的摘要值做为clientmsgid + */ + private String clientMsgId; - public void setMediaId(String mediaId) { - this.mediaId = mediaId; + public WxMpMassOpenIdsMessage() { + super(); } public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } - /** - * openid列表,最多支持10,000个 - */ - public List getToUsers() { - return this.toUsers; - } - - /** - * 提供set方法,方便客户端直接设置所有群发对象的openid列表 - * - * @param toUsers - */ - public void setToUsers(List toUsers) { - this.toUsers = toUsers; - } - /** * 添加openid,最多支持10,000个 - * - * @param openid */ public void addUser(String openid) { this.toUsers.add(openid); } - public boolean isSendIgnoreReprint() { - return sendIgnoreReprint; - } - - /** - * @param sendIgnoreReprint 文章被判定为转载时,是否继续进行群发操作。 - */ - public void setSendIgnoreReprint(boolean sendIgnoreReprint) { - this.sendIgnoreReprint = sendIgnoreReprint; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java index 503bdec43b..512c454c47 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassPreviewMessage.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.mp.bean; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -7,70 +9,30 @@ /** * @author miller */ +@Data public class WxMpMassPreviewMessage implements Serializable { private static final long serialVersionUID = 9095211638358424020L; private String toWxUserName; private String toWxUserOpenid; - private String msgType; - private String content; - private String mediaId; - - public WxMpMassPreviewMessage() { - super(); - } - - public String getToWxUserName() { - return this.toWxUserName; - } - - public void setToWxUserName(String toWxUserName) { - this.toWxUserName = toWxUserName; - } - - public String getMsgType() { - return this.msgType; - } - /** *
+   * 消息类型
    * 请使用
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_NEWS}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_VOICE}
+   * {@link WxConsts.MassMsgType#IMAGE}
+   * {@link WxConsts.MassMsgType#MPNEWS}
+   * {@link WxConsts.MassMsgType#TEXT}
+   * {@link WxConsts.MassMsgType#MPVIDEO}
+   * {@link WxConsts.MassMsgType#VOICE}
    * 如果msgtype和media_id不匹配的话,会返回系统繁忙的错误
    * 
- * - * @param msgType 消息类型 */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getToWxUserOpenid() { - return this.toWxUserOpenid; - } + private String msgType; + private String content; + private String mediaId; - public void setToWxUserOpenid(String toWxUserOpenid) { - this.toWxUserOpenid = toWxUserOpenid; + public WxMpMassPreviewMessage() { + super(); } public String toJson() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java index acf9d0f4c1..9487124c86 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassTagMessage.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.mp.bean; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -9,90 +11,50 @@ * * @author chanjarster */ +@Data public class WxMpMassTagMessage implements Serializable { private static final long serialVersionUID = -6625914040986749286L; + /** + * 标签id,如果不设置则就意味着发给所有用户 + */ private Long tagId; - private String msgType; - private String content; - private String mediaId; - private boolean isSendAll = false; - private boolean sendIgnoreReprint = false; - - public WxMpMassTagMessage() { - super(); - } - - public String getMsgType() { - return this.msgType; - } - /** *
+   * 消息类型
    * 请使用
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_NEWS}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#MASS_MSG_VOICE}
+   * {@link WxConsts.MassMsgType#IMAGE}
+   * {@link WxConsts.MassMsgType#MPNEWS}
+   * {@link WxConsts.MassMsgType#TEXT}
+   * {@link WxConsts.MassMsgType#MPVIDEO}
+   * {@link WxConsts.MassMsgType#VOICE}
    * 如果msgtype和media_id不匹配的话,会返回系统繁忙的错误
    * 
- * - * @param msgType 消息类型 */ - public void setMsgType(String msgType) { - this.msgType = msgType; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String toJson() { - return WxMpGsonBuilder.INSTANCE.create().toJson(this); - } - - public Long getTagId() { - return this.tagId; - } - + private String msgType; + private String content; + private String mediaId; /** - * 如果不设置则就意味着发给所有用户 - * - * @param tagId 标签id + * 是否群发给所有用户 */ - public void setTagId(Long tagId) { - this.tagId = tagId; - } - - public boolean isSendIgnoreReprint() { - return sendIgnoreReprint; - } + private boolean isSendAll = false; /** - * @param sendIgnoreReprint 文章被判定为转载时,是否继续进行群发操作。 + * 文章被判定为转载时,是否继续进行群发操作。 */ - public void setSendIgnoreReprint(boolean sendIgnoreReprint) { - this.sendIgnoreReprint = sendIgnoreReprint; - } + private boolean sendIgnoreReprint = false; /** - * 是否群发给所有用户 + * 开发者侧群发msgid,长度限制64字节,如不填,则后台默认以群发范围和群发内容的摘要值做为clientmsgid */ - public boolean isSendAll() { - return isSendAll; + private String clientMsgId; + + public WxMpMassTagMessage() { + super(); + } + + public String toJson() { + return WxMpGsonBuilder.INSTANCE.create().toJson(this); } public void setSendAll(boolean sendAll) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassVideo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassVideo.java index 1683be5bdf..d536ff989f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassVideo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpMassVideo.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -9,6 +10,7 @@ * * @author chanjarster */ +@Data public class WxMpMassVideo implements Serializable { private static final long serialVersionUID = 9153925016061915637L; @@ -16,30 +18,6 @@ public class WxMpMassVideo implements Serializable { private String title; private String description; - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java index 8c18a6a9ea..f9de30f552 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -11,6 +12,7 @@ * * @author Daniel Qian */ +@Data public class WxMpSemanticQuery implements Serializable { private static final long serialVersionUID = 7685873048199870690L; @@ -23,70 +25,6 @@ public class WxMpSemanticQuery implements Serializable { private String appid; private String uid; - public String getQuery() { - return this.query; - } - - public void setQuery(String query) { - this.query = query; - } - - public String getCategory() { - return this.category; - } - - public void setCategory(String category) { - this.category = category; - } - - public Float getLatitude() { - return this.latitude; - } - - public void setLatitude(Float latitude) { - this.latitude = latitude; - } - - public Float getLongitude() { - return this.longitude; - } - - public void setLongitude(Float longitude) { - this.longitude = longitude; - } - - public String getCity() { - return this.city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getRegion() { - return this.region; - } - - public void setRegion(String region) { - this.region = region; - } - - public String getAppid() { - return this.appid; - } - - public void setAppid(String appid) { - this.appid = appid; - } - - public String getUid() { - return this.uid; - } - - public void setUid(String uid) { - this.uid = uid; - } - public String toJson() { return WxMpGsonBuilder.create().toJson(this); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeInfoResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeInfoResult.java index 5fb2ab1735..313cfaba84 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeInfoResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeInfoResult.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -10,6 +11,7 @@ * * @author rememberber */ +@Data public class WxMpShakeInfoResult implements Serializable { private static final long serialVersionUID = -1604561297395395468L; @@ -17,13 +19,15 @@ public class WxMpShakeInfoResult implements Serializable { private String errmsg; - private Data data; + private ShakeInfoData data; public static WxMpShakeInfoResult fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeInfoResult.class); } - public class Data { + @Data + public class ShakeInfoData implements Serializable { + private static final long serialVersionUID = -4828142206067489488L; private String page_id; @@ -35,7 +39,9 @@ public class Data { private BeaconInfo beacon_info; - public class BeaconInfo { + @Data + public class BeaconInfo implements Serializable { + private static final long serialVersionUID = -8995733049982933362L; private double distance; @@ -48,118 +54,7 @@ public class BeaconInfo { private Integer rssi; private String uuid; - - public double getDistance() { - return distance; - } - - public void setDistance(double distance) { - this.distance = distance; - } - - public Integer getMajor() { - return major; - } - - public void setMajor(Integer major) { - this.major = major; - } - - public Integer getMeasure_power() { - return measure_power; - } - - public void setMeasure_power(Integer measure_power) { - this.measure_power = measure_power; - } - - public Integer getMinor() { - return minor; - } - - public void setMinor(Integer minor) { - this.minor = minor; - } - - public Integer getRssi() { - return rssi; - } - - public void setRssi(Integer rssi) { - this.rssi = rssi; - } - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - } - - public String getPage_id() { - return page_id; - } - - public void setPage_id(String page_id) { - this.page_id = page_id; - } - - public String getOpenid() { - return openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getPoi_id() { - return poi_id; - } - - public void setPoi_id(String poi_id) { - this.poi_id = poi_id; - } - - public BeaconInfo getBeacon_info() { - return beacon_info; - } - - public void setBeacon_info(BeaconInfo beacon_info) { - this.beacon_info = beacon_info; - } - - public String getBrand_userame() { - return brand_userame; - } - - public void setBrand_userame(String brand_userame) { - this.brand_userame = brand_userame; } } - public Integer getErrcode() { - return errcode; - } - - public void setErrcode(Integer errcode) { - this.errcode = errcode; - } - - public String getErrmsg() { - return errmsg; - } - - public void setErrmsg(String errmsg) { - this.errmsg = errmsg; - } - - public Data getData() { - return data; - } - - public void setData(Data data) { - this.data = data; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeQuery.java index 0f4aeadd19..709e59e50f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpShakeQuery.java @@ -1,6 +1,7 @@ package me.chanjar.weixin.mp.bean; import com.google.gson.Gson; +import lombok.Data; import java.io.Serializable; import java.util.HashMap; @@ -11,6 +12,7 @@ * * @author rememberber */ +@Data public class WxMpShakeQuery implements Serializable { private static final long serialVersionUID = 4316527352035275412L; @@ -25,19 +27,4 @@ public String toJsonString() { return new Gson().toJson(map); } - public String getTicket() { - return ticket; - } - - public void setTicket(String ticket) { - this.ticket = ticket; - } - - public int getNeedPoi() { - return needPoi; - } - - public void setNeedPoi(int needPoi) { - this.needPoi = needPoi; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java index 243163c28b..9e73b46159 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpUserQuery.java @@ -1,6 +1,7 @@ package me.chanjar.weixin.mp.bean; import com.google.gson.Gson; +import lombok.Data; import java.io.Serializable; import java.util.ArrayList; @@ -14,6 +15,7 @@ * * @author LiuJunGuang */ +@Data public class WxMpUserQuery implements Serializable { private static final long serialVersionUID = -1344224837373149313L; @@ -110,19 +112,18 @@ public String toJsonString() { } // 查询参数封装 + @Data public class WxMpUserQueryParam implements Serializable { private static final long serialVersionUID = -6863571795702385319L; private String openid; private String lang; public WxMpUserQueryParam(String openid, String lang) { - super(); this.openid = openid; this.lang = lang; } public WxMpUserQueryParam(String openid) { - super(); this.openid = openid; this.lang = "zh_CN"; } @@ -131,56 +132,6 @@ public WxMpUserQueryParam() { super(); } - public String getOpenid() { - return this.openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getLang() { - return this.lang; - } - - public void setLang(String lang) { - this.lang = lang; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getOuterType().hashCode(); - result = prime * result + ((this.lang == null) ? 0 : this.lang.hashCode()); - result = prime * result + ((this.openid == null) ? 0 : this.openid.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - WxMpUserQueryParam other = (WxMpUserQueryParam) obj; - if (!getOuterType().equals(other.getOuterType())) - return false; - if (this.lang == null) { - if (other.lang != null) - return false; - } else if (!this.lang.equals(other.lang)) - return false; - if (this.openid == null) { - if (other.openid != null) - return false; - } else if (!this.openid.equals(other.openid)) - return false; - return true; - } - private WxMpUserQuery getOuterType() { return WxMpUserQuery.this; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Abstract.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Abstract.java new file mode 100644 index 0000000000..985cdb0a9a --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Abstract.java @@ -0,0 +1,33 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 封面摘要 + * author:yuanqixun + * date:2018-08-25 00:35 + */ +@Data +public class Abstract implements Serializable { + + /** + * 摘要 + */ + @SerializedName("abstract") + private String abstractInfo; + + /** + * 封面图片列表,仅支持填入一 个封面图片链接, 上传图片接口 上传获取图片获得链接,填写 非CDN链接会报错,并在此填入。 建议图片尺寸像素850*350 + */ + @SerializedName("icon_url_list") + private String iconUrlList; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java new file mode 100644 index 0000000000..73fd01353e --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java @@ -0,0 +1,76 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.bean.card.enums.BusinessServiceType; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +//子对象列表 + +/** + * 微信会员卡高级字段信息 + * author:yuanqixun + * date:2018-08-25 00:36 + */ +@Data +public class AdvancedInfo implements Serializable { + +// public AdvancedInfo(){ +// useCondition = new UseCondition(); +// abstractInfo = new Abstract(); +// textImageList = new ArrayList<>(); +// timeLimit = new TimeLimit(); +// } + + /** + * 使用门槛(条件),若不填写使用条件则在券面拼写 :无最低消费限制,全场通用,不限品类;并在使用说明显示: 可与其他优惠共享 + */ + @SerializedName("use_condition") + private UseCondition useCondition; + + /** + * 封面摘要 + */ + @SerializedName("abstract") + private Abstract abstractInfo; + + /** + * 图文列表,显示在详情内页 ,优惠券券开发者须至少传入 一组图文列表 + */ + @SerializedName("text_image_list") + private List textImageList; + + /** + * 商家服务类型,数组类型:BIZ_SERVICE_DELIVER 外卖服务; BIZ_SERVICE_FREE_PARK 停车位; BIZ_SERVICE_WITH_PET 可带宠物; BIZ_SERVICE_FREE_WIFI 免费wifi, 可多选 + */ + @SerializedName("business_service") + private List businessServiceList; + + /** + * 使用时段限制 + */ + @SerializedName("time_limit") + private TimeLimit timeLimit; + + /** + * 是否可以分享朋友 + */ + @SerializedName("share_friends") + private Boolean shareFriends; + + public void addBusinessService(BusinessServiceType businessServiceType) { + if (businessServiceType != null) { + if (businessServiceList == null) + businessServiceList = new ArrayList(); + businessServiceList.add(businessServiceType.name()); + } + } + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseInfo.java new file mode 100644 index 0000000000..bdd0b359cb --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseInfo.java @@ -0,0 +1,196 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +//子对象列表 + +/** + * 微信会员卡基本信息 + * author:yuanqixun + * date:2018-08-25 00:36 + */ +@Data +public class BaseInfo implements Serializable { + + /** + * 卡券的商户logo,建议像素为300*300。 + */ + @SerializedName("logo_url") + private String logoUrl; + + /** + * Code展示类型,"CODE_TYPE_TEXT" 文本 "CODE_TYPE_BARCODE" 一维码 "CODE_TYPE_QRCODE" 二维码 "CODE_TYPE_ONLY_QRCODE" 仅显示二维码 "CODE_TYPE_ONLY_BARCODE" 仅显示一维码 "CODE_TYPE_NONE" 不显示任何码型 + */ + @SerializedName("code_type") + private String codeType = "CODE_TYPE_QRCODE"; + + /** + * 支付功能结构体,swipe_card结构 + */ + @SerializedName("pay_info") + private PayInfo payInfo; + + /** + * 是否设置该会员卡中部的按钮同时支持微信支付刷卡和会员卡二维码 + */ + @SerializedName("is_pay_and_qrcode") + private boolean isPayAndQrcode; + + /** + * 商户名字,字数上限为12个汉字 + */ + @SerializedName("brand_name") + private String brandName; + + /** + * 卡券名,字数上限为9个汉字 (建议涵盖卡券属性、服务及金额)。 + */ + @SerializedName("title") + private String title; + + /** + * 券颜色,按色彩规范标注填写Color010-Color100 + */ + @SerializedName("color") + private String color; + + /** + * 卡券使用提醒,字数上限为16个汉字 + */ + @SerializedName("notice") + private String notice; + + /** + * 卡券使用说明,字数上限为1024个汉字。 + */ + @SerializedName("description") + private String description; + + /** + * 商品信息 + */ + @SerializedName("sku") + private Sku sku; + + /** + * 使用日期,有效期的信息。 + */ + @SerializedName("date_info") + private DateInfo dateInfo; + + /** + * 是否自定义Code码,填写true或false,默认为false 通常自有优惠码系统的开发者选择自定义Code码,详情见 是否自定义code + */ + @SerializedName("use_custom_code") + private boolean useCustomCode; + + /** + * 是否指定用户领取,填写true或false。默认为false + */ + @SerializedName("bind_openid") + private boolean bindOpenid; + + /** + * 客服电话 + */ + @SerializedName("service_phone") + private String servicePhone; + + /** + * 门店位置ID,调用 POI门店管理接口 获取门店位置ID。 + */ + @SerializedName("location_id_list") + private String locationIdList; + + /** + * 会员卡是否支持全部门店,填写后商户门店更新时会自动同步至卡券 + */ + @SerializedName("use_all_locations") + private boolean useAllLocations = true; + + /** + * 卡券中部居中的按钮,仅在卡券激活后且可用状态 时显示 + */ + @SerializedName("center_title") + private String centerTitle; + + /** + * 显示在入口下方的提示语,仅在卡券激活后且可用状态时显示 + */ + @SerializedName("center_sub_title") + private String centerSubTitle; + + /** + * 顶部居中的url,仅在卡券激活后且可用状态时显示 + */ + @SerializedName("center_url") + private String centerUrl; + + /** + * 自定义跳转外链的入口名字 + */ + @SerializedName("custom_url_name") + private String customUrlName; + + /** + * 自定义跳转的URL + */ + @SerializedName("custom_url") + private String customUrl; + + /** + * 显示在入口右侧的提示语 + */ + @SerializedName("custom_url_sub_title") + private String customUrlSubTitle; + + /** + * 营销场景的自定义入口名称 + */ + @SerializedName("promotion_url_name") + private String promotionUrlName; + + /** + * 入口跳转外链的地址链接 + */ + @SerializedName("promotion_url") + private String promotionUrl; + + /** + * 显示在营销入口右侧的提示语 + */ + @SerializedName("promotion_url_sub_title") + private String promotionUrlSubTitle; + + /** + * 每人可领券的数量限制,建议会员卡每人限领一张 + */ + @SerializedName("get_limit") + private Integer getLimit = 1; + + /** + * 卡券领取页面是否可分享,默认为true + */ + @SerializedName("can_share") + private boolean canShare; + + /** + * 卡券是否可转赠,默认为true + */ + @SerializedName("can_give_friend") + private boolean canGiveFriend; + + /** + * 用户点击进入会员卡时推送事件,填写true为用户点击进入会员卡时推送事件,默认为false。详情见 进入会员卡事件推送 + */ + @SerializedName("need_push_on_view") + private boolean needPushOnView; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BonusRule.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BonusRule.java new file mode 100644 index 0000000000..9b12d59719 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BonusRule.java @@ -0,0 +1,69 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 积分规则 + * author:yuanqixun + * date:2018-08-25 00:33 + */ +@Data +public class BonusRule implements Serializable { + + /** + * 消费金额,以分为单位。 + */ + @SerializedName("cost_money_unit") + private Integer costMoneyUnit; + + /** + * 对应增加的积分 + */ + @SerializedName("increase_bonus") + private Integer increaseBonus; + + /** + * 用户单次可获取的积分上限 + */ + @SerializedName("max_increase_bonus") + private Integer maxIncreaseBonus; + + /** + * 初始设置积分 + */ + @SerializedName("init_increase_bonus") + private Integer initIncreaseBonus; + + /** + * 每使用积分 + */ + @SerializedName("cost_bonus_unit") + private Integer costBonusUnit; + + /** + * 抵扣xx元,这里以分为单位) + */ + @SerializedName("reduce_money") + private Integer reduceMoney; + + /** + * 抵扣条件,满xx元(这里以分为单位)可用。 + */ + @SerializedName("least_moneyto_use_bonus") + private Integer leastMoneytoUseBonus; + + /** + * 抵扣条件,单笔最多使用xx积分。 + */ + @SerializedName("max_reduce_bonus") + private Integer maxReduceBonus; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomCell1.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomCell1.java new file mode 100644 index 0000000000..bfacd07921 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomCell1.java @@ -0,0 +1,39 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 自定义会员信息类目 + * author:yuanqixun + * date:2018-08-25 00:34 + */ +@Data +public class CustomCell1 implements Serializable { + + /** + * 入口名称 + */ + @SerializedName("name") + private String name; + + /** + * 入口右侧提示语,6个汉字内。 + */ + @SerializedName("tips") + private String tips; + + /** + * 入口跳转链接。 + */ + @SerializedName("url") + private String url; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomField.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomField.java new file mode 100644 index 0000000000..da7df64bc6 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CustomField.java @@ -0,0 +1,43 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 自定义会员信息类目 + * author:yuanqixun + * date:2018-08-25 00:34 + */ +@Data +public class CustomField implements Serializable { + + /** + * 半自定义名称,当开发者变更这类类目信息的value值时 可以选择触发系统模板消息通知用户。 FIELD_NAME_TYPE_LEVEL 等级 FIELD_NAME_TYPE_COUPON 优惠券 FIELD_NAME_TYPE_STAMP 印花 FIELD_NAME_TYPE_DISCOUNT 折扣 FIELD_NAME_TYPE_ACHIEVEMEN 成就 FIELD_NAME_TYPE_MILEAGE 里程 FIELD_NAME_TYPE_SET_POINTS 集点 FIELD_NAME_TYPE_TIMS 次数 + */ + @SerializedName("name_type") + private String nameType; + + /** + * 自定义名称,当开发者变更这类类目信息的value值时 不会触发系统模板消息通知用户 + */ + @SerializedName("name") + private String name; + + /** + * 点击类目跳转外链url + */ + @SerializedName("url") + private String url; + + public String getNameType() { + return nameType; + } + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DateInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DateInfo.java new file mode 100644 index 0000000000..a429665035 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DateInfo.java @@ -0,0 +1,51 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 使用日期,有效期的信息 + * author:yuanqixun + * date:2018-08-25 00:31 + */ +@Data +public class DateInfo implements Serializable { + + /** + * 使用时间的类型,支持固定时长有效类型 固定日期有效类型 永久有效类型:DATE_TYPE_FIX_TERM_RANGE、DATE_TYPE_FIX_TERM 、DATE_TYPE_PERMANENT + */ + @SerializedName("type") + private String type = "DATE_TYPE_PERMANENT"; + + /** + * 起用时间,type为DATE_TYPE_FIX_TIME_RANGE时专用, 表示起用时间。从1970年1月1日00:00:00至起用时间的秒数 ( 东八区时间,UTC+8,单位为秒 ) + */ + @SerializedName("begin_timestamp") + private Long beginTimestamp; + + /** + * 结束时间,type为DATE_TYPE_FIX_TERM_RANGE时专用,表示结束时间 ( 东八区时间,UTC+8,单位为秒 ) + */ + @SerializedName("end_timestamp") + private Long endTimestamp; + + /** + * 自领取后多少天内有效,type为DATE_TYPE_FIX_TERM时专用,表示自领取后多少天内有效,领取后当天有效填写0(单位为天) + */ + @SerializedName("fixed_term") + private Integer fixedTerm; + + /** + * 自领取后多少天开始生效,type为DATE_TYPE_FIX_TERM时专用,表示自领取后多少天开始生效。(单位为天) + */ + @SerializedName("fixed_begin_term") + private Integer fixedBeginTerm; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java new file mode 100644 index 0000000000..48e28efffa --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java @@ -0,0 +1,152 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public final class MemberCard implements Serializable { + + /** + * 会员卡背景图 + */ + @SerializedName("background_pic_url") + private String backgroundPicUrl; + + /** + * 基本信息 + */ + @SerializedName("base_info") + private BaseInfo baseInfo; + + /** + * 特权说明 + */ + @SerializedName("prerogative") + private String prerogative; + + /** + * 自动激活 + */ + @SerializedName("auto_activate") + private boolean autoActivate; + + /** + * 是否一键开卡 + */ + @SerializedName("wx_activate") + private boolean wxActivate; + + /** + * 显示积分 + */ + @SerializedName("supply_bonus") + private boolean supplyBonus; + + /** + * 查看积分外链,设置跳转外链查看积分详情。仅适用于积分无法通过激活接口同步的情况下使用该字段。 + */ + @SerializedName("bonus_url") + private String bonusUrl; + + /** + * 支持储值 + */ + @SerializedName("supply_balance") + private boolean supplyBalance; + + /** + * 余额外链,仅适用于余额无法通过激活接口同步的情况下使用该字段。 + */ + @SerializedName("balance_url") + private String balanceUrl; + + /** + * 自定义会员类目1,会员卡激活后显示 + */ + @SerializedName("custom_field1") + private CustomField customField1; + + /** + * 自定义会员类目2 + */ + @SerializedName("custom_field2") + private CustomField customField2; + + /** + * 自定义会员类目3 + */ + @SerializedName("custom_field3") + private CustomField customField3; + + /** + * 积分清零规则 + */ + @SerializedName("bonus_cleared") + private String bonusCleared; + + /** + * 积分规则 + */ + @SerializedName("bonus_rules") + private String bonusRules; + + /** + * 储值规则 + */ + @SerializedName("balance_rules") + private String balanceRules; + + /** + * 激活会员卡的url + */ + @SerializedName("activate_url") + private String activateUrl; + + /** + * 激活会原卡url对应的小程序user_name,仅可跳转该公众号绑定的小程序 + */ + @SerializedName("activate_app_brand_user_name") + private String activateAppBrandUserName; + + /** + * 激活会原卡url对应的小程序path + */ + @SerializedName("activate_app_brand_pass") + private String activateAppBrandPass; + + /** + * 自定义会员信息类目,会员卡激活后显示。 + */ + @SerializedName("custom_cell1") + private CustomCell1 customCell1; + + /** + * 积分规则,JSON结构积分规则 。 + */ + @SerializedName("bonus_rule") + private BonusRule bonusRule; + + /** + * 折扣,该会员卡享受的折扣优惠,填10就是九折。 + */ + private Integer discount; + + /** + * 创建优惠券特有的高级字段 + */ + @SerializedName("advanced_info") + private AdvancedInfo advancedInfo; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + public static MemberCard fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, MemberCard.class); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardActivateUserFormRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardActivateUserFormRequest.java new file mode 100644 index 0000000000..3d9a968765 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardActivateUserFormRequest.java @@ -0,0 +1,70 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; + +/** + * 会员卡激活,用户字段提交请求 + * + * @author yuanqixun + * @date 2018-08-30 + */ +@Data +public class MemberCardActivateUserFormRequest implements Serializable { + @SerializedName("card_id") + private String cardId; + + @SerializedName("service_statement") + private JsonObject serviceStatement; + + @SerializedName("bind_old_card") + private JsonObject bindOldCard; + + /** + * 必填项 + */ + @SerializedName("required_form") + private MemberCardUserForm requiredForm; + + /** + * 可选项 + */ + @SerializedName("optional_form") + private MemberCardUserForm optionalForm; + + /** + * 绑定老会员卡信息 + * + * @param name + * @param url + */ + public void setBindOldCard(String name, String url) { + if (StringUtils.isAnyEmpty(name, url)) { + return; + } + if (bindOldCard == null) + bindOldCard = new JsonObject(); + bindOldCard.addProperty("name", name); + bindOldCard.addProperty("url", url); + } + + /** + * 设置服务声明,用于放置商户会员卡守则 + * + * @param name + * @param url + */ + public void setServiceStatement(String name, String url) { + if (StringUtils.isAnyEmpty(name, url)) { + return; + } + if (serviceStatement == null) + serviceStatement = new JsonObject(); + serviceStatement.addProperty("name", name); + serviceStatement.addProperty("url", url); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardActivateUserFormResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardActivateUserFormResult.java new file mode 100644 index 0000000000..c961676dda --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardActivateUserFormResult.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.mp.bean.card; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public class MemberCardActivateUserFormResult implements Serializable { + private Integer errcode; + private String errmsg; + + public boolean isSuccess() { + return 0 == errcode; + } + + public static MemberCardActivateUserFormResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, MemberCardActivateUserFormResult.class); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java new file mode 100644 index 0000000000..7e4139cb32 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public class MemberCardCreateRequest implements Serializable { + @SerializedName("card_type") + private String cardType = "MEMBER_CARD"; + + @SerializedName("member_card") + private MemberCard memberCard; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUserForm.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUserForm.java new file mode 100644 index 0000000000..14ef9f37a1 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUserForm.java @@ -0,0 +1,92 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.bean.card.enums.CardWechatFieldType; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 用户表单对象 + * + * @author yuanqixun + * @date 2018-08-30 + */ +@Data +public class MemberCardUserForm implements Serializable { + + /** + * 当前结构(required_form或者optional_form )内的字段是否允许用户激活后再次修改, + * 商户设置为true 时,需要接收相应事件通知处理修改事件 + */ + @SerializedName("can_modify") + private boolean canModify; + + /** + * 富文本类型字段列表 + */ + @SerializedName("rich_field_list") + List richFieldList; + + /** + * 文本选项类型列表 + */ + @SerializedName("custom_field_list") + private List customFieldList; + + + /** + * 微信格式化的选项类型 + */ + @SerializedName("common_field_id_list") + private List wechatFieldIdList; + + /** + * 添加富文本类型字段 + * + * @param fieldType + */ + public void addRichField(MemberCardUserFormRichField field) { + if (field == null) + return; + if (richFieldList == null) + richFieldList = new ArrayList<>(); + richFieldList.add(field); + } + + /** + * 添加微信选项类型字段 + * + * @param fieldType + */ + public void addWechatField(CardWechatFieldType fieldType) { + if (fieldType == null) + return; + if (wechatFieldIdList == null) + wechatFieldIdList = new ArrayList<>(); + wechatFieldIdList.add(fieldType.name()); + } + + /** + * 添加文本类型字段 + * + * @param fieldType + */ + public void addCustomField(String field) { + if (StringUtils.isBlank(field)) + return; + if (customFieldList == null) + customFieldList = new ArrayList<>(); + customFieldList.add(field); + } + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUserFormRichField.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUserFormRichField.java new file mode 100644 index 0000000000..6605f9b64b --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUserFormRichField.java @@ -0,0 +1,42 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.bean.card.enums.CardRichFieldType; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.ArrayList; +import java.util.List; + +/** + * 富文本字段 + * + * @author yuanqixun + * @date 2018-08-30 + */ +@Data +public class MemberCardUserFormRichField { + + /** + * 富文本类型 + */ + @SerializedName("type") + private CardRichFieldType type; + + @SerializedName("name") + private String name; + + @SerializedName("values") + private List valueList; + + public void add(String value) { + if (valueList == null) + valueList = new ArrayList(); + valueList.add(value); + } + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/PayInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/PayInfo.java new file mode 100644 index 0000000000..61fa8ccd52 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/PayInfo.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 支付功能 + * author:yuanqixun + * date:2018-08-25 00:33 + */ +@Data +public class PayInfo implements Serializable { + + /** + * 刷卡功能 + */ + @SerializedName("swipe_card") + private SwipeCard swipeCard; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Sku.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Sku.java new file mode 100644 index 0000000000..12db088df7 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Sku.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 商品信息 + * author:yuanqixun + * date:2018-08-25 00:32 + */ +@Data +public class Sku implements Serializable { + + /** + * 卡券库存的数量,不支持填写0,上限为100000000。 + */ + @SerializedName("quantity") + private Integer quantity = 100000000; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/SwipeCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/SwipeCard.java new file mode 100644 index 0000000000..fa1769422e --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/SwipeCard.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 刷卡功能 + * author:yuanqixun + * date:2018-08-25 00:33 + */ +@Data +public class SwipeCard implements Serializable { + + /** + * 是否设置该会员卡支持拉出微信支付刷卡界面 + */ + @SerializedName("is_swipe_card") + private boolean isSwipeCard; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TextImageList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TextImageList.java new file mode 100644 index 0000000000..5836d956b2 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TextImageList.java @@ -0,0 +1,33 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 图文列表 + * author:yuanqixun + * date:2018-08-25 00:35 + */ +@Data +public class TextImageList implements Serializable { + + /** + * 图片链接,必须调用 上传图片接口 上传图片获得链接,并在此填入, 否则报错 + */ + @SerializedName("image_url") + private String imageUrl; + + /** + * 图文描述 + */ + @SerializedName("text") + private String text; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TimeLimit.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TimeLimit.java new file mode 100644 index 0000000000..4c0d17d544 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/TimeLimit.java @@ -0,0 +1,52 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +//子对象列表 + +/** + * 使用时段限制 + * author:yuanqixun + * date:2018-08-25 00:34 + */ +@Data +public class TimeLimit implements Serializable { + + /** + * 限制类型枚举值,支持填入 MONDAY 周一 TUESDAY 周二 WEDNESDAY 周三 THURSDAY 周四 FRIDAY 周五 SATURDAY 周六 SUNDAY 周日 此处只控制显示, 不控制实际使用逻辑,不填默认不显示 + */ + @SerializedName("type") + private String type; + + /** + * 起始时间(小时),当前type类型下的起始时间(小时) ,如当前结构体内填写了MONDAY, 此处填写了10,则此处表示周一 10:00可用 + */ + @SerializedName("begin_hour") + private Integer beginHour; + + /** + * 起始时间(分钟),如当前结构体内填写了MONDAY, begin_hour填写10,此处填写了59, 则此处表示周一 10:59可用 + */ + @SerializedName("begin_minute") + private Integer beginMinute; + + /** + * 结束时间(小时),如当前结构体内填写了MONDAY, 此处填写了20, 则此处表示周一 10:00-20:00可用 + */ + @SerializedName("end_hour") + private Integer endHour; + + /** + * 结束时间(分钟),如当前结构体内填写了MONDAY, begin_hour填写10,此处填写了59, 则此处表示周一 10:59-00:59可用 + */ + @SerializedName("end_minute") + private Integer endMinute; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UseCondition.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UseCondition.java new file mode 100644 index 0000000000..ff8fa830d3 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UseCondition.java @@ -0,0 +1,52 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +//子对象列表 + +/** + * 使用门槛 + * author:yuanqixun + * date:2018-08-25 00:35 + */ +@Data +public class UseCondition implements Serializable { + + /** + * 指定可用的商品类目,仅用于代金券类型 ,填入后将在券面拼写适用于xxx + */ + @SerializedName("accept_category") + private String acceptCategory; + + /** + * 指定不可用的商品类目,仅用于代金券类型 ,填入后将在券面拼写不适用于xxxx + */ + @SerializedName("reject_category") + private String rejectCategory; + + /** + * 满减门槛字段,可用于兑换券和代金券 ,填入后将在全面拼写消费满xx元可用 + */ + @SerializedName("least_cost") + private Integer leastCost; + + /** + * 购买xx可用类型门槛,仅用于兑换 ,填入后自动拼写购买xxx可用 + */ + @SerializedName("object_use_for") + private String objectUseFor; + + /** + * 不可以与其他类型共享门槛,填写false时系统将在使用须知里 拼写“不可与其他优惠共享”, 填写true时系统将在使用须知里 拼写“可与其他优惠共享”, 默认为true + */ + @SerializedName("can_use_with_other_discount") + private boolean canUseWithOtherDiscount; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateResult.java new file mode 100644 index 0000000000..24875d4eb9 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateResult.java @@ -0,0 +1,47 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public class WxMpCardCreateResult implements Serializable { + private static final long serialVersionUID = -128818731449449537L; + @SerializedName("card_id") + private String cardId; + private Integer errcode; + private String errmsg; + + public boolean isSuccess() { + return 0 == errcode; + } + + public static WxMpCardCreateResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpCardCreateResult.class); + } + + public static WxMpCardCreateResult failure(String errmsg) { + WxMpCardCreateResult result = new WxMpCardCreateResult(); + result.setErrcode(500); + result.setErrmsg(errmsg); + return result; + } + + public static WxMpCardCreateResult success() { + WxMpCardCreateResult result = new WxMpCardCreateResult(); + result.setErrcode(0); + result.setErrmsg("ok"); + return result; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateRequest.java new file mode 100644 index 0000000000..6a55a26a0a --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateRequest.java @@ -0,0 +1,67 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public class WxMpCardLandingPageCreateRequest implements Serializable { + + /** + * 页面的banner图片链接,须调用,建议尺寸为640*300。 + */ + private String banner; + + /** + * 页面的title + */ + @SerializedName("page_title") + private String title; + + @SerializedName("can_share") + private boolean canShare; + + /** + * 投放页面的场景值; + * SCENE_NEAR_BY 附近 + * SCENE_MENU 自定义菜单 + * SCENE_QRCODE 二维码 + * SCENE_ARTICLE 公众号文章 + * SCENE_H5 h5页面 + * SCENE_IVR 自动回复 + * SCENE_CARD_CUSTOM_CELL 卡券自定义cell + */ + private String scene; + + @SerializedName("card_list") + private JsonArray cardList; + + public void addCard(String cardId, String thumbUrl) { + if (StringUtils.isNoneBlank(cardId, thumbUrl)) { + if (cardList == null) + cardList = new JsonArray(); + JsonObject cardJson = new JsonObject(); + cardJson.addProperty("card_id", cardId); + cardJson.addProperty("thumb_url", thumbUrl); + cardList.add(cardJson); + } + } + + public static WxMpCardLandingPageCreateRequest fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpCardLandingPageCreateRequest.class); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateResult.java new file mode 100644 index 0000000000..f99b5f186f --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardLandingPageCreateResult.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public class WxMpCardLandingPageCreateResult implements Serializable { + private Integer errcode; + private String errmsg; + + /** + * 货架链接。 + */ + private String url; + /** + * 货架ID。货架的唯一标识 + */ + @SerializedName("page_id") + private Integer pageId; + + public boolean isSuccess() { + return 0 == errcode; + } + + public static WxMpCardLandingPageCreateResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpCardLandingPageCreateResult.class); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardQrcodeCreateResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardQrcodeCreateResult.java new file mode 100644 index 0000000000..46fb6323bc --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardQrcodeCreateResult.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.mp.bean.card; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public class WxMpCardQrcodeCreateResult implements Serializable { + private static final long serialVersionUID = -128818731449449537L; + private Integer errcode; + private String errmsg; + private String ticket; + + @SerializedName("expire_seconds") + private Integer expireSeconds; + + private String url; + + @SerializedName("show_qrcode_url") + private String showQrcodeUrl; + + public boolean isSuccess() { + return 0 == errcode; + } + + public static WxMpCardQrcodeCreateResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpCardQrcodeCreateResult.class); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/BusinessServiceType.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/BusinessServiceType.java new file mode 100644 index 0000000000..3ae9cf8937 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/BusinessServiceType.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.mp.bean.card.enums; + +/** + * 商户提供服务类型 + */ +public enum BusinessServiceType { + BIZ_SERVICE_DELIVER("外卖服务"), + BIZ_SERVICE_FREE_PARK("停车位"), + BIZ_SERVICE_WITH_PET("可带宠物"), + BIZ_SERVICE_FREE_WIFI("可带宠物"); + + private String description; + + BusinessServiceType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardColor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardColor.java new file mode 100644 index 0000000000..0977cc9239 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardColor.java @@ -0,0 +1,35 @@ +package me.chanjar.weixin.mp.bean.card.enums; + +/** + * 会员卡颜色 + * + * @author yuanqixun + * @date 2018-08-29 + */ +public enum CardColor { + Color010("#63b359"), + Color020("#2c9f67"), + Color030("#509fc9"), + Color040("#5885cf"), + Color050("#9062c0"), + Color060("#d09a45"), + Color070("#e4b138"), + Color080("#ee903c"), + Color081("#f08500"), + Color082("#a9d92d"), + Color090("#dd6549"), + Color100("#cc463d"), + Color101("#cf3e36"), + Color102("#5E6671"); + + private String type; + + CardColor(String type) { + this.type = type; + } + + public String getValue() { + return type; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardFieldType.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardFieldType.java new file mode 100644 index 0000000000..4134f3e543 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardFieldType.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.card.enums; + +/** + * 微信卡券激活字段类型 + * + * @author yuanqixun + * @date 2018-08-30 + */ +public enum CardFieldType { + COMMON_FIELD("微信选项"), + CUSTOM_FIELD("自定义选项"), + RICH_FIELD("自定义富文本类型"); + + private String description; + + CardFieldType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardRichFieldType.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardRichFieldType.java new file mode 100644 index 0000000000..40d4b79fac --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardRichFieldType.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.card.enums; + +/** + * 会员卡富文本字段类型 + * + * @author yuanqixun + * @date 2018-08-30 + */ +public enum CardRichFieldType { + FORM_FIELD_RADIO("自定义单选"), + FORM_FIELD_SELECT("自定义选择项"), + FORM_FIELD_CHECK_BOX("自定义多选"); + + private String description; + + CardRichFieldType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardSceneType.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardSceneType.java new file mode 100644 index 0000000000..ec5b9fcfbc --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardSceneType.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.mp.bean.card.enums; + +public enum CardSceneType { + SCENE_NEAR_BY("附近"), + SCENE_MENU("自定义菜单"), + SCENE_QRCODE("二维码"), + SCENE_ARTICLE("公众号文章"), + SCENE_H5("H5"), + SCENE_IVR("自动回复"), + SCENE_CARD_CUSTOM_CELL("卡券自定义cell"); + + private String description; + + CardSceneType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardWechatFieldType.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardWechatFieldType.java new file mode 100644 index 0000000000..3a62c6f49d --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/CardWechatFieldType.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.mp.bean.card.enums; + +/** + * 微信卡券激活字段类型 + * + * @author yuanqixun + * @date 2018-08-30 + */ +public enum CardWechatFieldType { + USER_FORM_INFO_FLAG_MOBILE("手机号"), + USER_FORM_INFO_FLAG_SEX("性别"), + USER_FORM_INFO_FLAG_NAME("姓名"), + USER_FORM_INFO_FLAG_BIRTHDAY("生日"), + USER_FORM_INFO_FLAG_IDCARD("身份证"), + USER_FORM_INFO_FLAG_EMAIL("邮箱"), + USER_FORM_INFO_FLAG_LOCATION("详细地址"), + USER_FORM_INFO_FLAG_EDUCATION_BACKGRO("教育背景"), + USER_FORM_INFO_FLAG_INDUSTRY("行业"), + USER_FORM_INFO_FLAG_INCOME("收入"), + USER_FORM_INFO_FLAG_HABIT("兴趣爱好"); + + private String description; + + CardWechatFieldType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/DateInfoType.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/DateInfoType.java new file mode 100644 index 0000000000..bd8a23551c --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/enums/DateInfoType.java @@ -0,0 +1,17 @@ +package me.chanjar.weixin.mp.bean.card.enums; + +public enum DateInfoType { + DATE_TYPE_PERMANENT("永久有效类型"), + DATE_TYPE_FIX_TIME_RANGE("固定日期"), + DATE_TYPE_FIX_TERM("固定时长"); + + private String description; + + DateInfoType(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java index e6518064bb..3901c61fbc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleResult.java @@ -1,18 +1,22 @@ package me.chanjar.weixin.mp.bean.datacube; -import com.google.gson.JsonParser; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.util.List; /** * 图文分析数据接口返回结果对象 + *

+ * Created by Binary Wang on 2016/8/24. * - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016/8/24. + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) public class WxDataCubeArticleResult extends WxDataCubeBaseResult { private static final long serialVersionUID = -9222452497954511765L; @@ -116,107 +120,4 @@ public static List fromJson(String json) { }.getType()); } - public Integer getRefHour() { - return this.refHour; - } - - public void setRefHour(Integer refHour) { - this.refHour = refHour; - } - - public String getMsgId() { - return this.msgId; - } - - public void setMsgId(String msgId) { - this.msgId = msgId; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Integer getIntPageReadUser() { - return this.intPageReadUser; - } - - public void setIntPageReadUser(Integer intPageReadUser) { - this.intPageReadUser = intPageReadUser; - } - - public Integer getIntPageReadCount() { - return this.intPageReadCount; - } - - public void setIntPageReadCount(Integer intPageReadCount) { - this.intPageReadCount = intPageReadCount; - } - - public Integer getOriPageReadUser() { - return this.oriPageReadUser; - } - - public void setOriPageReadUser(Integer oriPageReadUser) { - this.oriPageReadUser = oriPageReadUser; - } - - public Integer getOriPageReadCount() { - return this.oriPageReadCount; - } - - public void setOriPageReadCount(Integer oriPageReadCount) { - this.oriPageReadCount = oriPageReadCount; - } - - public Integer getShareScene() { - return this.shareScene; - } - - public void setShareScene(Integer shareScene) { - this.shareScene = shareScene; - } - - public Integer getShareUser() { - return this.shareUser; - } - - public void setShareUser(Integer shareUser) { - this.shareUser = shareUser; - } - - public Integer getShareCount() { - return this.shareCount; - } - - public void setShareCount(Integer shareCount) { - this.shareCount = shareCount; - } - - public Integer getAddToFavUser() { - return this.addToFavUser; - } - - public void setAddToFavUser(Integer addToFavUser) { - this.addToFavUser = addToFavUser; - } - - public Integer getAddToFavCount() { - return this.addToFavCount; - } - - public void setAddToFavCount(Integer addToFavCount) { - this.addToFavCount = addToFavCount; - } - - public Integer getUserSource() { - return this.userSource; - } - - public void setUserSource(Integer userSource) { - this.userSource = userSource; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java index a059c45f3b..bef0e66d15 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotal.java @@ -1,37 +1,40 @@ package me.chanjar.weixin.mp.bean.datacube; -import com.google.gson.JsonParser; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.util.List; /** - * 图文分析数据接口返回结果对象 + * 图文分析数据接口返回结果对象. + * Created by Binary Wang on 2016/8/24. * - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016/8/24. + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) public class WxDataCubeArticleTotal extends WxDataCubeBaseResult { private static final long serialVersionUID = -7634365687303052699L; /** - * msgid + * msgid. * 请注意:这里的msgid实际上是由msgid(图文消息id,这也就是群发接口调用后返回的msg_data_id)和index(消息次序索引)组成, 例如12003_3, 其中12003是msgid,即一次群发的消息的id; 3为index,假设该次群发的图文消息共5个文章(因为可能为多图文),3表示5个中的第3个 */ @SerializedName("msgid") private String msgId; /** - * title + * title. * 图文消息的标题 */ @SerializedName("title") private String title; /** - * details + * details. * 详细信息 */ @SerializedName("details") @@ -44,27 +47,4 @@ public static List fromJson(String json) { }.getType()); } - public String getMsgId() { - return this.msgId; - } - - public void setMsgId(String msgId) { - this.msgId = msgId; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public List getDetails() { - return this.details; - } - - public void setDetails(List details) { - this.details = details; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java index 86897427d1..0c3bf2916c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeArticleTotalDetail.java @@ -1,16 +1,19 @@ package me.chanjar.weixin.mp.bean.datacube; import com.google.gson.annotations.SerializedName; +import lombok.Data; import java.io.Serializable; /** * 获取图文群发总数据接口(getarticletotal)中的详细字段 + *

+ * Created by Binary Wang on 2016/8/24. * - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016/8/24. + * @author Binary Wang */ -public class WxDataCubeArticleTotalDetail implements Serializable{ +@Data +public class WxDataCubeArticleTotalDetail implements Serializable { private static final long serialVersionUID = -5136169129771430052L; /** @@ -195,215 +198,4 @@ public class WxDataCubeArticleTotalDetail implements Serializable{ @SerializedName("feed_share_from_other_cnt") private Integer feedShareFromOtherCnt; - public String getStatDate() { - return this.statDate; - } - - public void setStatDate(String statDate) { - this.statDate = statDate; - } - - public Integer getTargetUser() { - return this.targetUser; - } - - public void setTargetUser(Integer targetUser) { - this.targetUser = targetUser; - } - - public Integer getIntPageReadUser() { - return this.intPageReadUser; - } - - public void setIntPageReadUser(Integer intPageReadUser) { - this.intPageReadUser = intPageReadUser; - } - - public Integer getIntPageReadCount() { - return this.intPageReadCount; - } - - public void setIntPageReadCount(Integer intPageReadCount) { - this.intPageReadCount = intPageReadCount; - } - - public Integer getOriPageReadUser() { - return this.oriPageReadUser; - } - - public void setOriPageReadUser(Integer oriPageReadUser) { - this.oriPageReadUser = oriPageReadUser; - } - - public Integer getOriPageReadCount() { - return this.oriPageReadCount; - } - - public void setOriPageReadCount(Integer oriPageReadCount) { - this.oriPageReadCount = oriPageReadCount; - } - - public Integer getShareUser() { - return this.shareUser; - } - - public void setShareUser(Integer shareUser) { - this.shareUser = shareUser; - } - - public Integer getShareCount() { - return this.shareCount; - } - - public void setShareCount(Integer shareCount) { - this.shareCount = shareCount; - } - - public Integer getAddToFavUser() { - return this.addToFavUser; - } - - public void setAddToFavUser(Integer addToFavUser) { - this.addToFavUser = addToFavUser; - } - - public Integer getAddToFavCount() { - return this.addToFavCount; - } - - public void setAddToFavCount(Integer addToFavCount) { - this.addToFavCount = addToFavCount; - } - - public Integer getIntPageFromSessionReadUser() { - return this.intPageFromSessionReadUser; - } - - public void setIntPageFromSessionReadUser(Integer intPageFromSessionReadUser) { - this.intPageFromSessionReadUser = intPageFromSessionReadUser; - } - - public Integer getIntPageFromSessionReadCount() { - return this.intPageFromSessionReadCount; - } - - public void setIntPageFromSessionReadCount( - Integer intPageFromSessionReadCount) { - this.intPageFromSessionReadCount = intPageFromSessionReadCount; - } - - public Integer getIntPageFromHistMsgReadUser() { - return this.intPageFromHistMsgReadUser; - } - - public void setIntPageFromHistMsgReadUser(Integer intPageFromHistMsgReadUser) { - this.intPageFromHistMsgReadUser = intPageFromHistMsgReadUser; - } - - public Integer getIntPageFromHistMsgReadCount() { - return this.intPageFromHistMsgReadCount; - } - - public void setIntPageFromHistMsgReadCount( - Integer intPageFromHistMsgReadCount) { - this.intPageFromHistMsgReadCount = intPageFromHistMsgReadCount; - } - - public Integer getIntPageFromFeedReadUser() { - return this.intPageFromFeedReadUser; - } - - public void setIntPageFromFeedReadUser(Integer intPageFromFeedReadUser) { - this.intPageFromFeedReadUser = intPageFromFeedReadUser; - } - - public Integer getIntPageFromFeedReadCount() { - return this.intPageFromFeedReadCount; - } - - public void setIntPageFromFeedReadCount(Integer intPageFromFeedReadCount) { - this.intPageFromFeedReadCount = intPageFromFeedReadCount; - } - - public Integer getIntPageFromFriendsReadUser() { - return this.intPageFromFriendsReadUser; - } - - public void setIntPageFromFriendsReadUser(Integer intPageFromFriendsReadUser) { - this.intPageFromFriendsReadUser = intPageFromFriendsReadUser; - } - - public Integer getIntPageFromFriendsReadCount() { - return this.intPageFromFriendsReadCount; - } - - public void setIntPageFromFriendsReadCount( - Integer intPageFromFriendsReadCount) { - this.intPageFromFriendsReadCount = intPageFromFriendsReadCount; - } - - public Integer getIntPageFromOtherReadUser() { - return this.intPageFromOtherReadUser; - } - - public void setIntPageFromOtherReadUser(Integer intPageFromOtherReadUser) { - this.intPageFromOtherReadUser = intPageFromOtherReadUser; - } - - public Integer getIntPageFromOtherReadCount() { - return this.intPageFromOtherReadCount; - } - - public void setIntPageFromOtherReadCount(Integer intPageFromOtherReadCount) { - this.intPageFromOtherReadCount = intPageFromOtherReadCount; - } - - public Integer getFeedShareFromSessionUser() { - return this.feedShareFromSessionUser; - } - - public void setFeedShareFromSessionUser(Integer feedShareFromSessionUser) { - this.feedShareFromSessionUser = feedShareFromSessionUser; - } - - public Integer getFeedShareFromSessionCnt() { - return this.feedShareFromSessionCnt; - } - - public void setFeedShareFromSessionCnt(Integer feedShareFromSessionCnt) { - this.feedShareFromSessionCnt = feedShareFromSessionCnt; - } - - public Integer getFeedShareFromFeedUser() { - return this.feedShareFromFeedUser; - } - - public void setFeedShareFromFeedUser(Integer feedShareFromFeedUser) { - this.feedShareFromFeedUser = feedShareFromFeedUser; - } - - public Integer getFeedShareFromFeedCnt() { - return this.feedShareFromFeedCnt; - } - - public void setFeedShareFromFeedCnt(Integer feedShareFromFeedCnt) { - this.feedShareFromFeedCnt = feedShareFromFeedCnt; - } - - public Integer getFeedShareFromOtherUser() { - return this.feedShareFromOtherUser; - } - - public void setFeedShareFromOtherUser(Integer feedShareFromOtherUser) { - this.feedShareFromOtherUser = feedShareFromOtherUser; - } - - public Integer getFeedShareFromOtherCnt() { - return this.feedShareFromOtherCnt; - } - - public void setFeedShareFromOtherCnt(Integer feedShareFromOtherCnt) { - this.feedShareFromOtherCnt = feedShareFromOtherCnt; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java index cfc8636143..ee2a7d9349 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeBaseResult.java @@ -1,25 +1,29 @@ package me.chanjar.weixin.mp.bean.datacube; +import java.io.Serializable; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.JsonParser; import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; +import lombok.Data; /** *

- *  统计接口的共用属性类
+ *  统计接口的共用属性类.
  *  Created by Binary Wang on 2016/8/25.
  * 
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data public abstract class WxDataCubeBaseResult implements Serializable { private static final long serialVersionUID = 8780389911053297600L; protected static final JsonParser JSON_PARSER = new JsonParser(); /** - * ref_date + * ref_date. * 数据的日期,需在begin_date和end_date之间 */ @SerializedName("ref_date") @@ -27,15 +31,7 @@ public abstract class WxDataCubeBaseResult implements Serializable { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getRefDate() { - return this.refDate; - } - - public void setRefDate(String refDate) { - this.refDate = refDate; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java index fce9fc2018..b151c0089f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeInterfaceResult.java @@ -1,18 +1,22 @@ package me.chanjar.weixin.mp.bean.datacube; -import com.google.gson.JsonParser; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.util.List; /** * 接口分析数据接口返回结果对象 + *

+ * Created by Binary Wang on 2016/8/30. * - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016/8/30. + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) public class WxDataCubeInterfaceResult extends WxDataCubeBaseResult { private static final long serialVersionUID = 597734329161281398L; @@ -58,44 +62,4 @@ public static List fromJson(String json) { }.getType()); } - public Integer getRefHour() { - return this.refHour; - } - - public void setRefHour(Integer refHour) { - this.refHour = refHour; - } - - public Integer getCallbackCount() { - return this.callbackCount; - } - - public void setCallbackCount(Integer callbackCount) { - this.callbackCount = callbackCount; - } - - public Integer getFailCount() { - return this.failCount; - } - - public void setFailCount(Integer failCount) { - this.failCount = failCount; - } - - public Integer getTotalTimeCost() { - return this.totalTimeCost; - } - - public void setTotalTimeCost(Integer totalTimeCost) { - this.totalTimeCost = totalTimeCost; - } - - public Integer getMaxTimeCost() { - return this.maxTimeCost; - } - - public void setMaxTimeCost(Integer maxTimeCost) { - this.maxTimeCost = maxTimeCost; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java index 4800c9c422..1e7e1f58c2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeMsgResult.java @@ -1,51 +1,54 @@ package me.chanjar.weixin.mp.bean.datacube; -import com.google.gson.JsonParser; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.util.List; /** - * 消息分析数据接口返回结果对象 + * 消息分析数据接口返回结果对象. + * Created by Binary Wang on 2016/8/29. * - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016/8/29. + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) public class WxDataCubeMsgResult extends WxDataCubeBaseResult { private static final long serialVersionUID = 6932121822150573659L; /** - * ref_hour + * ref_hour. * 数据的小时,包括从000到2300,分别代表的是[000,100)到[2300,2400),即每日的第1小时和最后1小时 */ @SerializedName("ref_hour") private Integer refHour; /** - * msg_type + * msg_type. * 消息类型,代表含义如下:1代表文字 2代表图片 3代表语音 4代表视频 6代表第三方应用消息(链接消息) */ @SerializedName("msg_type") private Integer msgType; /** - * msg_user + * msg_user. * 上行发送了(向公众号发送了)消息的用户数 */ @SerializedName("msg_user") private Integer msgUser; /** - * msg_count + * msg_count. * 上行发送了消息的消息总数 */ @SerializedName("msg_count") private Integer msgCount; /** - * count_interval + * count_interval. * 当日发送消息量分布的区间,0代表 “0”,1代表“1-5”,2代表“6-10”,3代表“10次以上” */ @SerializedName("count_interval") @@ -59,7 +62,7 @@ public class WxDataCubeMsgResult extends WxDataCubeBaseResult { private Integer intPageReadCount; /** - * ori_page_read_user + * ori_page_read_user. * 原文页(点击图文页“阅读原文”进入的页面)的阅读人数,无原文页时此处数据为0 */ @SerializedName("ori_page_read_user") @@ -72,60 +75,4 @@ public static List fromJson(String json) { }.getType()); } - public Integer getRefHour() { - return this.refHour; - } - - public void setRefHour(Integer refHour) { - this.refHour = refHour; - } - - public Integer getMsgType() { - return this.msgType; - } - - public void setMsgType(Integer msgType) { - this.msgType = msgType; - } - - public Integer getMsgUser() { - return this.msgUser; - } - - public void setMsgUser(Integer msgUser) { - this.msgUser = msgUser; - } - - public Integer getMsgCount() { - return this.msgCount; - } - - public void setMsgCount(Integer msgCount) { - this.msgCount = msgCount; - } - - public Integer getCountInterval() { - return this.countInterval; - } - - public void setCountInterval(Integer countInterval) { - this.countInterval = countInterval; - } - - public Integer getIntPageReadCount() { - return this.intPageReadCount; - } - - public void setIntPageReadCount(Integer intPageReadCount) { - this.intPageReadCount = intPageReadCount; - } - - public Integer getOriPageReadUser() { - return this.oriPageReadUser; - } - - public void setOriPageReadUser(Integer oriPageReadUser) { - this.oriPageReadUser = oriPageReadUser; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserCumulate.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserCumulate.java index d3237a3b6e..5275e140dc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserCumulate.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserCumulate.java @@ -1,20 +1,26 @@ package me.chanjar.weixin.mp.bean.datacube; -import com.google.gson.JsonParser; -import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.Date; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** *

  * 累计用户数据接口的返回JSON数据包
  * 详情查看文档:用户分析数据接口
  * 
+ * + * @author BinaryWang */ +@Data public class WxDataCubeUserCumulate implements Serializable { private static final JsonParser JSON_PARSER = new JsonParser(); @@ -31,24 +37,8 @@ public static List fromJson(String json) { }.getType()); } - public Date getRefDate() { - return this.refDate; - } - - public void setRefDate(Date refDate) { - this.refDate = refDate; - } - - public Integer getCumulateUser() { - return this.cumulateUser; - } - - public void setCumulateUser(Integer cumulateUser) { - this.cumulateUser = cumulateUser; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserSummary.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserSummary.java index 3b76725cc2..06d938214f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserSummary.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/datacube/WxDataCubeUserSummary.java @@ -1,20 +1,24 @@ package me.chanjar.weixin.mp.bean.datacube; -import com.google.gson.JsonParser; -import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.Date; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** *
  * 用户增减数据接口的返回JSON数据包
  * 详情查看文档:用户分析数据接口
  * 
*/ +@Data public class WxDataCubeUserSummary implements Serializable { private static final long serialVersionUID = -2336654489906694173L; @@ -35,40 +39,8 @@ public static List fromJson(String json) { }.getType()); } - public Date getRefDate() { - return this.refDate; - } - - public void setRefDate(Date refDate) { - this.refDate = refDate; - } - - public Integer getUserSource() { - return this.userSource; - } - - public void setUserSource(Integer userSource) { - this.userSource = userSource; - } - - public Integer getNewUser() { - return this.newUser; - } - - public void setNewUser(Integer newUser) { - this.newUser = newUser; - } - - public Integer getCancelUser() { - return this.cancelUser; - } - - public void setCancelUser(Integer cancelUser) { - this.cancelUser = cancelUser; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/AbstractDeviceBean.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/AbstractDeviceBean.java index 4aef452270..d49999c504 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/AbstractDeviceBean.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/AbstractDeviceBean.java @@ -5,9 +5,12 @@ import java.io.Serializable; /** - * Created by keungtung on 14/12/2016. + * 设备抽象类. + * + * @author keungtung + * @date 14/12/2016 */ -public abstract class AbstractDeviceBean implements Serializable{ +public abstract class AbstractDeviceBean implements Serializable { private static final long serialVersionUID = 4359729626772515385L; public String toJson() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java index 7d1fd8aa77..5c66b0cd60 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/BaseResp.java @@ -1,10 +1,15 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; /** - * Created by keungtung on 10/12/2016. + * @author keungtung. + * @date 10/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class BaseResp extends AbstractDeviceBean { private static final long serialVersionUID = 4252655933699659073L; @@ -15,50 +20,12 @@ public class BaseResp extends AbstractDeviceBean { @SerializedName("errmsg") private String errMsg; - public Integer getErrCode() { - return errCode; - } - - public void setErrCode(Integer errCode) { - this.errCode = errCode; - } - - public BaseInfo getBaseInfo() { - return baseInfo; - } - - public void setBaseInfo(BaseInfo baseInfo) { - this.baseInfo = baseInfo; - } - - public String getErrMsg() { - return errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } - + @Data private class BaseInfo { @SerializedName("device_type") private String deviceType; + @SerializedName("device_id") private String deviceId; - - public String getDeviceType() { - return deviceType; - } - - public void setDeviceType(String deviceType) { - this.deviceType = deviceType; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java index 9c62d36f93..601f848223 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/RespMsg.java @@ -1,11 +1,16 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; /** - * Created by keungtung on 10/12/2016. + * + * @author keungtung. + * @date 10/12/2016 */ - +@Data +@EqualsAndHashCode(callSuper = false) public class RespMsg extends AbstractDeviceBean { private static final long serialVersionUID = -4241272701707684136L; @@ -13,20 +18,4 @@ public class RespMsg extends AbstractDeviceBean { private Integer retCode; @SerializedName("error_info") private String errorInfo; - - public Integer getRetCode() { - return retCode; - } - - public void setRetCode(Integer retCode) { - this.retCode = retCode; - } - - public String getErrorInfo() { - return errorInfo; - } - - public void setErrorInfo(String errorInfo) { - this.errorInfo = errorInfo; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java index 1572da75ac..f2b35da5ea 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/TransMsgResp.java @@ -1,11 +1,17 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.util.json.WxGsonBuilder; /** - * Created by keungtung on 14/12/2016. + * + * @author keungtung. + * @date 14/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class TransMsgResp extends AbstractDeviceBean { private static final long serialVersionUID = 5386954916622816491L; @@ -20,36 +26,4 @@ public class TransMsgResp extends AbstractDeviceBean { public static TransMsgResp fromJson(String json) { return WxGsonBuilder.create().fromJson(json, TransMsgResp.class); } - - public Integer getRet() { - return ret; - } - - public void setRet(Integer ret) { - this.ret = ret; - } - - public String getRetInfo() { - return retInfo; - } - - public void setRetInfo(String retInfo) { - this.retInfo = retInfo; - } - - public Integer getErrCode() { - return errCode; - } - - public void setErrCode(Integer errCode) { - this.errCode = errCode; - } - - public String getErrMsg() { - return errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDevice.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDevice.java index 4527d368d2..84c5b2d66d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDevice.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDevice.java @@ -1,12 +1,15 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; import java.io.Serializable; /** - * Created by keungtung on 10/12/2016. + * @author keungtung + * @date 10/12/2016 */ +@Data public class WxDevice implements Serializable { private static final long serialVersionUID = -3284819760735456195L; @@ -30,92 +33,4 @@ public class WxDevice implements Serializable { private String serMacPos; @SerializedName("ble_simple_protocol") private String bleSimpleProtocol; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getMac() { - return mac; - } - - public void setMac(String mac) { - this.mac = mac; - } - - public String getConnectProtocol() { - return connectProtocol; - } - - public void setConnectProtocol(String connectProtocol) { - this.connectProtocol = connectProtocol; - } - - public String getAuthKey() { - return authKey; - } - - public void setAuthKey(String authKey) { - this.authKey = authKey; - } - - public String getCloseStrategy() { - return closeStrategy; - } - - public void setCloseStrategy(String closeStrategy) { - this.closeStrategy = closeStrategy; - } - - public String getConnStrategy() { - return connStrategy; - } - - public void setConnStrategy(String connStrategy) { - this.connStrategy = connStrategy; - } - - public String getCryptMethod() { - return cryptMethod; - } - - public void setCryptMethod(String cryptMethod) { - this.cryptMethod = cryptMethod; - } - - public String getAuthVer() { - return authVer; - } - - public void setAuthVer(String authVer) { - this.authVer = authVer; - } - - public String getManuMacPos() { - return manuMacPos; - } - - public void setManuMacPos(String manuMacPos) { - this.manuMacPos = manuMacPos; - } - - public String getSerMacPos() { - return serMacPos; - } - - public void setSerMacPos(String serMacPos) { - this.serMacPos = serMacPos; - } - - public String getBleSimpleProtocol() { - return bleSimpleProtocol; - } - - public void setBleSimpleProtocol(String bleSimpleProtocol) { - this.bleSimpleProtocol = bleSimpleProtocol; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java index 055e41c879..5e00c4faea 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorize.java @@ -1,14 +1,19 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** - * Created by keungtung on 10/12/2016. + * @author keungtung + * @date 10/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceAuthorize extends AbstractDeviceBean { private static final long serialVersionUID = 8786321356569903887L; @@ -21,38 +26,6 @@ public class WxDeviceAuthorize extends AbstractDeviceBean { @SerializedName("device_list") private List deviceList = new LinkedList<>(); - public String getDeviceNum() { - return deviceNum; - } - - public void setDeviceNum(String deviceNum) { - this.deviceNum = deviceNum; - } - - public String getOpType() { - return opType; - } - - public void setOpType(String opType) { - this.opType = opType; - } - - public String getProductId() { - return productId; - } - - public void setProductId(String productId) { - this.productId = productId; - } - - public List getDeviceList() { - return deviceList; - } - - public void setDeviceList(List deviceList) { - this.deviceList = deviceList; - } - public void addDevice(WxDevice... devices) { this.deviceList.addAll(Arrays.asList(devices)); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java index 560f5498bb..9608452ce1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceAuthorizeResult.java @@ -1,12 +1,17 @@ package me.chanjar.weixin.mp.bean.device; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import java.util.List; /** - * Created by keungtung on 10/12/2016. + * @author keungtung. + * @date 10/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceAuthorizeResult extends AbstractDeviceBean { private static final long serialVersionUID = 9105294570912249811L; @@ -16,11 +21,4 @@ public static WxDeviceAuthorizeResult fromJson(String response) { return WxGsonBuilder.create().fromJson(response, WxDeviceAuthorizeResult.class); } - public List getResp() { - return resp; - } - - public void setResp(List resp) { - this.resp = resp; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java index 4945cfbbf2..aeb7f819ce 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBind.java @@ -1,10 +1,15 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; /** - * Created by keungtung on 10/12/2016. + * @author keungtung. + * @date 10/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceBind extends AbstractDeviceBean { private static final long serialVersionUID = 467559769037590880L; @@ -14,27 +19,4 @@ public class WxDeviceBind extends AbstractDeviceBean { @SerializedName("openid") private String openId; - public String getTicket() { - return ticket; - } - - public void setTicket(String ticket) { - this.ticket = ticket; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getOpenId() { - return openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java index 52c5f45609..ec032e8617 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindDeviceResult.java @@ -1,13 +1,18 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.util.List; /** - * Created by keungtung on 16/12/2016. + * @author keungtung. + * @date 16/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceBindDeviceResult extends AbstractDeviceBean { private static final long serialVersionUID = 725870295905935355L; @@ -22,27 +27,13 @@ public static WxDeviceBindDeviceResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindDeviceResult.class); } + @Data private class Device { @SerializedName("device_type") private String deviceType; @SerializedName("device_id") private String deviceId; - public String getDeviceType() { - return deviceType; - } - - public void setDeviceType(String deviceType) { - this.deviceType = deviceType; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java index c26e9c85d1..f6c702aa29 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceBindResult.java @@ -1,11 +1,16 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** - * Created by keungtung on 10/12/2016. + * @author keungtung. + * @date 10/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceBindResult extends AbstractDeviceBean { private static final long serialVersionUID = 4687725146279339359L; @@ -16,11 +21,4 @@ public static WxDeviceBindResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxDeviceBindResult.class); } - public BaseResp getBaseResp() { - return baseResp; - } - - public void setBaseResp(BaseResp baseResp) { - this.baseResp = baseResp; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java index 182cb27241..9e12a5bb6d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceMsg.java @@ -1,11 +1,18 @@ package me.chanjar.weixin.mp.bean.device; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; +import lombok.EqualsAndHashCode; /** - * Created by keungtung on 10/12/2016. + * @author keungtung. + * @date 10/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceMsg extends AbstractDeviceBean { private static final long serialVersionUID = -5567110858455277963L; @@ -19,38 +26,6 @@ public class WxDeviceMsg extends AbstractDeviceBean { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getDeviceType() { - return deviceType; - } - - public void setDeviceType(String deviceType) { - this.deviceType = deviceType; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getOpenId() { - return openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java index a2ea56c080..95cf2a94ff 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceOpenIdResult.java @@ -1,13 +1,18 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.util.List; /** - * Created by keungtung on 16/12/2016. + * @author keungtung. + * @date 16/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceOpenIdResult extends AbstractDeviceBean { private static final long serialVersionUID = 4980885167833836220L; @@ -24,35 +29,4 @@ public static WxDeviceOpenIdResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxDeviceOpenIdResult.class); } - public Integer getErrCode() { - return errCode; - } - - public void setErrCode(Integer errCode) { - this.errCode = errCode; - } - - public String getErrMsg() { - return errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } - - public List getOpenIds() { - return openIds; - } - - public void setOpenIds(List openIds) { - this.openIds = openIds; - } - - public RespMsg getRespMsg() { - return respMsg; - } - - public void setRespMsg(RespMsg respMsg) { - this.respMsg = respMsg; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java index 8d6efac90b..0e0d96f419 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/device/WxDeviceQrCodeResult.java @@ -1,11 +1,16 @@ package me.chanjar.weixin.mp.bean.device; import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** - * Created by keungtung on 10/12/2016. + * @author keungtung. + * @date 10/12/2016 */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxDeviceQrCodeResult extends AbstractDeviceBean { private static final long serialVersionUID = -4312858303060918266L; @@ -22,35 +27,4 @@ public static WxDeviceQrCodeResult fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxDeviceQrCodeResult.class); } - public String getDeviceLicence() { - return deviceLicence; - } - - public void setDeviceLicence(String deviceLicence) { - this.deviceLicence = deviceLicence; - } - - public BaseResp getBaseResp() { - return baseResp; - } - - public void setBaseResp(BaseResp baseResp) { - this.baseResp = baseResp; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getQrTicket() { - return qrTicket; - } - - public void setQrTicket(String qrTicket) { - this.qrTicket = qrTicket; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java index 2c02a6207d..2b24325211 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java @@ -1,5 +1,7 @@ package me.chanjar.weixin.mp.bean.kefu; +import lombok.Data; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.builder.kefu.*; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; @@ -12,6 +14,7 @@ * * @author chanjarster */ +@Data public class WxMpKefuMessage implements Serializable { private static final long serialVersionUID = -9196732086954365246L; @@ -27,6 +30,8 @@ public class WxMpKefuMessage implements Serializable { private String kfAccount; private String cardId; private String mpNewsMediaId; + private String miniProgramAppId; + private String miniProgramPagePath; private List articles = new ArrayList<>(); /** @@ -85,166 +90,43 @@ public static WxCardBuilder WXCARD() { return new WxCardBuilder(); } - public String getToUser() { - return this.toUser; - } - - public void setToUser(String toUser) { - this.toUser = toUser; - } - - public String getMsgType() { - return this.msgType; + /** + * 小程序卡片 + */ + public static MiniProgramPageBuilder MINIPROGRAMPAGE() { + return new MiniProgramPageBuilder(); } /** *
    * 请使用
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VOICE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MUSIC}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_NEWS}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MPNEWS}
-   * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_WXCARD}
+   * {@link WxConsts.KefuMsgType#TEXT}
+   * {@link WxConsts.KefuMsgType#IMAGE}
+   * {@link WxConsts.KefuMsgType#VOICE}
+   * {@link WxConsts.KefuMsgType#MUSIC}
+   * {@link WxConsts.KefuMsgType#VIDEO}
+   * {@link WxConsts.KefuMsgType#NEWS}
+   * {@link WxConsts.KefuMsgType#MPNEWS}
+   * {@link WxConsts.KefuMsgType#WXCARD}
+   * {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE}
    * 
* - * @param msgType */ public void setMsgType(String msgType) { this.msgType = msgType; } - public String getMpNewsMediaId() { - return this.mpNewsMediaId; - } - - public void setMpNewsMediaId(String mpNewsMediaId) { - this.mpNewsMediaId = mpNewsMediaId; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getThumbMediaId() { - return this.thumbMediaId; - } - - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getMusicUrl() { - return this.musicUrl; - } - - public void setMusicUrl(String musicUrl) { - this.musicUrl = musicUrl; - } - - public String getHqMusicUrl() { - return this.hqMusicUrl; - } - - public void setHqMusicUrl(String hqMusicUrl) { - this.hqMusicUrl = hqMusicUrl; - } - - public String getCardId() { - return this.cardId; - } - - public void setCardId(String cardId) { - this.cardId = cardId; - } - - public List getArticles() { - return this.articles; - } - - public void setArticles(List articles) { - this.articles = articles; - } - public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } - public String getKfAccount() { - return this.kfAccount; - } + @Data + public static class WxArticle implements Serializable { + private static final long serialVersionUID = 5145137235440507379L; - public void setKfAccount(String kfAccount) { - this.kfAccount = kfAccount; - } - - public static class WxArticle { private String title; private String description; private String url; private String picUrl; - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getPicUrl() { - return this.picUrl; - } - - public void setPicUrl(String picUrl) { - this.picUrl = picUrl; - } - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfAccountRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfAccountRequest.java index 85cdfe5507..f20c34d7e8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfAccountRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfAccountRequest.java @@ -1,36 +1,42 @@ package me.chanjar.weixin.mp.bean.kefu.request; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import java.io.Serializable; + import org.apache.commons.lang3.builder.ToStringBuilder; -import java.io.Serializable; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +@Data +@Builder +@AllArgsConstructor public class WxMpKfAccountRequest implements Serializable { private static final long serialVersionUID = -5451863610674856927L; /** - * kf_account 完整客服账号,格式为:账号前缀@公众号微信号 + * kf_account. + * 完整客服账号,格式为:账号前缀@公众号微信号 */ @SerializedName("kf_account") private String kfAccount; /** - * nickname 客服昵称,最长6个汉字或12个英文字符 + * nickname. + * 客服昵称,最长6个汉字或12个英文字符 */ @SerializedName("nickname") private String nickName; /** - * invite_wx 接收绑定邀请的客服微信号 + * invite_wx. + * 接收绑定邀请的客服微信号 */ @SerializedName("invite_wx") private String inviteWx; - public static Builder builder() { - return new Builder(); - } - @Override public String toString() { return ToStringBuilder.reflectionToString(this); @@ -40,64 +46,4 @@ public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } - public String getKfAccount() { - return this.kfAccount; - } - - public void setKfAccount(String kfAccount) { - this.kfAccount = kfAccount; - } - - public String getNickName() { - return this.nickName; - } - - public void setNickName(String nickName) { - this.nickName = nickName; - } - - public String getInviteWx() { - return this.inviteWx; - } - - public void setInviteWx(String inviteWx) { - this.inviteWx = inviteWx; - } - - public static class Builder { - private String kfAccount; - private String nickName; - private String inviteWx; - - public Builder kfAccount(String kfAccount) { - this.kfAccount = kfAccount; - return this; - } - - public Builder nickName(String nickName) { - this.nickName = nickName; - return this; - } - - public Builder inviteWx(String inviteWx) { - this.inviteWx = inviteWx; - return this; - } - - public Builder from(WxMpKfAccountRequest origin) { - this.kfAccount(origin.kfAccount); - this.nickName(origin.nickName); - this.inviteWx(origin.inviteWx); - return this; - } - - public WxMpKfAccountRequest build() { - WxMpKfAccountRequest m = new WxMpKfAccountRequest(); - m.kfAccount = this.kfAccount; - m.nickName = this.nickName; - m.inviteWx = this.inviteWx; - return m; - } - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfSessionRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfSessionRequest.java index ac59e3238e..6cc00f5c7b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfSessionRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/request/WxMpKfSessionRequest.java @@ -1,11 +1,15 @@ package me.chanjar.weixin.mp.bean.kefu.request; +import java.io.Serializable; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; - +@Data public class WxMpKfSessionRequest implements Serializable { private static final long serialVersionUID = -5451863610674856927L; @@ -28,19 +32,11 @@ public WxMpKfSessionRequest(String kfAccount, String openid) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } - public String getKfAccount() { - return this.kfAccount; - } - - public void setKfAccount(String kfAccount) { - this.kfAccount = kfAccount; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfInfo.java index c879e9f63a..76f25d9bc0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfInfo.java @@ -1,16 +1,20 @@ package me.chanjar.weixin.mp.bean.kefu.result; +import java.io.Serializable; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; - -import java.io.Serializable; +import lombok.Data; /** * 客服基本信息以及客服在线状态信息 * * @author Binary Wang */ +@Data public class WxMpKfInfo implements Serializable { private static final long serialVersionUID = -5877300750666022290L; @@ -75,88 +79,9 @@ public class WxMpKfInfo implements Serializable { @SerializedName("accepted_case") private Integer acceptedCase; - public Integer getStatus() { - return this.status; - } - - public void setStatus(Integer status) { - this.status = status; - } - - public Integer getAcceptedCase() { - return this.acceptedCase; - } - - public void setAcceptedCase(Integer acceptedCase) { - this.acceptedCase = acceptedCase; - } - - public String getAccount() { - return this.account; - } - - public void setAccount(String account) { - this.account = account; - } - - public String getHeadImgUrl() { - return this.headImgUrl; - } - - public void setHeadImgUrl(String headImgUrl) { - this.headImgUrl = headImgUrl; - } - - public String getId() { - return this.id; - } - - public void setId(String id) { - this.id = id; - } - - public String getNick() { - return this.nick; - } - - public void setNick(String nick) { - this.nick = nick; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getWxAccount() { - return this.wxAccount; - } - - public void setWxAccount(String wxAccount) { - this.wxAccount = wxAccount; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public String getInviteWx() { - return this.inviteWx; - } - - public void setInviteWx(String inviteWx) { - this.inviteWx = inviteWx; - } - - public Long getInviteExpireTime() { - return this.inviteExpireTime; - } - - public void setInviteExpireTime(Long inviteExpireTime) { - this.inviteExpireTime = inviteExpireTime; - } - - public String getInviteStatus() { - return this.inviteStatus; - } - - public void setInviteStatus(String inviteStatus) { - this.inviteStatus = inviteStatus; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfList.java index 5cce093dfc..d7ac204339 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfList.java @@ -1,15 +1,19 @@ package me.chanjar.weixin.mp.bean.kefu.result; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** * @author Binary Wang */ +@Data public class WxMpKfList implements Serializable { private static final long serialVersionUID = -8194193505173564894L; @@ -22,14 +26,7 @@ public static WxMpKfList fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public List getKfList() { - return this.kfList; - } - - public void setKfList(List kfList) { - this.kfList = kfList; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgList.java index 253652a883..01b262ddd9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgList.java @@ -1,15 +1,21 @@ package me.chanjar.weixin.mp.bean.kefu.result; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** - * Created by Binary Wang on 2016/7/15. + * + * @author Binary Wang + * @date 2016/7/15 */ +@Data public class WxMpKfMsgList implements Serializable { private static final long serialVersionUID = 4524296707435188202L; @@ -26,32 +32,8 @@ public static WxMpKfMsgList fromJson(String responseContent) { return WxMpGsonBuilder.INSTANCE.create().fromJson(responseContent, WxMpKfMsgList.class); } - public List getRecords() { - return this.records; - } - - public void setRecords(List records) { - this.records = records; - } - - public Integer getNumber() { - return this.number; - } - - public void setNumber(Integer number) { - this.number = number; - } - - public Long getMsgId() { - return this.msgId; - } - - public void setMsgId(Long msgId) { - this.msgId = msgId; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgRecord.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgRecord.java index 1b32164879..fc3a1471fd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgRecord.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfMsgRecord.java @@ -1,13 +1,19 @@ package me.chanjar.weixin.mp.bean.kefu.result; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + /** - * Created by Binary Wang on 2016/7/18. + * + * @author Binary Wang + * @date 2016/7/18 */ +@Data public class WxMpKfMsgRecord implements Serializable { private static final long serialVersionUID = -280692188908528688L; @@ -43,7 +49,7 @@ public class WxMpKfMsgRecord implements Serializable { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public String getWorker() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfOnlineList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfOnlineList.java index 6778520c2b..e1e8c298f4 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfOnlineList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfOnlineList.java @@ -1,15 +1,19 @@ package me.chanjar.weixin.mp.bean.kefu.result; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** * @author Binary Wang */ +@Data public class WxMpKfOnlineList implements Serializable { private static final long serialVersionUID = -6154705288500854617L; @@ -22,14 +26,7 @@ public static WxMpKfOnlineList fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public List getKfOnlineList() { - return this.kfOnlineList; - } - - public void setKfOnlineList(List kfOnlineList) { - this.kfOnlineList = kfOnlineList; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSession.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSession.java index b36edb9f2d..c5e9b02a59 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSession.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSession.java @@ -1,13 +1,17 @@ package me.chanjar.weixin.mp.bean.kefu.result; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + /** * @author Binary Wang */ +@Data public class WxMpKfSession implements Serializable { private static final long serialVersionUID = 7804332813164994062L; @@ -39,38 +43,7 @@ public class WxMpKfSession implements Serializable { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getKfAccount() { - return this.kfAccount; - } - - public void setKfAccount(String kfAccount) { - this.kfAccount = kfAccount; - } - - public long getCreateTime() { - return this.createTime; - } - - public void setCreateTime(long createTime) { - this.createTime = createTime; - } - - public String getOpenid() { - return this.openid; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public void setOpenid(String openid) { - this.openid = openid; - } - - public long getLatestTime() { - return this.latestTime; - } - - public void setLatestTime(long latestTime) { - this.latestTime = latestTime; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionGetResult.java index d6ed763e9f..628bd7c400 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionGetResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionGetResult.java @@ -1,14 +1,18 @@ package me.chanjar.weixin.mp.bean.kefu.result; +import java.io.Serializable; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; - /** * @author Binary Wang */ +@Data public class WxMpKfSessionGetResult implements Serializable { private static final long serialVersionUID = 8474846575200033152L; @@ -30,23 +34,7 @@ public static WxMpKfSessionGetResult fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getKfAccount() { - return this.kfAccount; - } - - public void setKfAccount(String kfAccount) { - this.kfAccount = kfAccount; - } - - public long getCreateTime() { - return this.createTime; - } - - public void setCreateTime(long createTime) { - this.createTime = createTime; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionList.java index f1eb4dd7cb..4aacdd1e65 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionList.java @@ -1,15 +1,19 @@ package me.chanjar.weixin.mp.bean.kefu.result; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** * @author Binary Wang */ +@Data public class WxMpKfSessionList implements Serializable { private static final long serialVersionUID = -7680371346226640206L; @@ -26,14 +30,7 @@ public static WxMpKfSessionList fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public List getKfSessionList() { - return this.kfSessionList; - } - - public void setKfSessionList(List kfSessionList) { - this.kfSessionList = kfSessionList; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionWaitCaseList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionWaitCaseList.java index 7dd8def8cf..69b5b91574 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionWaitCaseList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/result/WxMpKfSessionWaitCaseList.java @@ -1,15 +1,19 @@ package me.chanjar.weixin.mp.bean.kefu.result; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** * @author Binary Wang */ +@Data public class WxMpKfSessionWaitCaseList implements Serializable { private static final long serialVersionUID = 2432132626631361922L; @@ -32,15 +36,7 @@ public static WxMpKfSessionWaitCaseList fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public List getKfSessionWaitCaseList() { - return this.kfSessionWaitCaseList; - } - - public void setKfSessionWaitCaseList(List kfSessionWaitCaseList) { - this.kfSessionWaitCaseList = kfSessionWaitCaseList; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMediaImgUploadResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMediaImgUploadResult.java index 1110a1f16b..b60b2791c8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMediaImgUploadResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMediaImgUploadResult.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean.material; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -7,6 +8,7 @@ /** * @author miller */ +@Data public class WxMediaImgUploadResult implements Serializable { private static final long serialVersionUID = 1996392453428768829L; private String url; @@ -15,11 +17,4 @@ public static WxMediaImgUploadResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxMediaImgUploadResult.class); } - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterial.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterial.java index e176620f43..a554834d01 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterial.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterial.java @@ -1,10 +1,13 @@ package me.chanjar.weixin.mp.bean.material; +import lombok.Data; + import java.io.File; import java.io.Serializable; import java.util.HashMap; import java.util.Map; +@Data public class WxMpMaterial implements Serializable { private static final long serialVersionUID = -1651816949780969485L; @@ -29,41 +32,4 @@ public Map getForm() { form.put("introduction", this.videoIntroduction); return form; } - - public String getVideoTitle() { - return this.videoTitle; - } - - public void setVideoTitle(String videoTitle) { - this.videoTitle = videoTitle; - } - - public String getVideoIntroduction() { - return this.videoIntroduction; - } - - public void setVideoIntroduction(String videoIntroduction) { - this.videoIntroduction = videoIntroduction; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public File getFile() { - return this.file; - } - - public void setFile(File file) { - this.file = file; - } - - @Override - public String toString() { - return "WxMpMaterial [" + "name=" + this.name + ", file=" + this.file + ", videoTitle=" + this.videoTitle + ", videoIntroduction=" + this.videoIntroduction + "]"; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialArticleUpdate.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialArticleUpdate.java index f2f7aa1201..13e7701bb7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialArticleUpdate.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialArticleUpdate.java @@ -1,9 +1,11 @@ package me.chanjar.weixin.mp.bean.material; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; +@Data public class WxMpMaterialArticleUpdate implements Serializable { private static final long serialVersionUID = -7611963949517780270L; @@ -11,36 +13,7 @@ public class WxMpMaterialArticleUpdate implements Serializable { private int index; private WxMpMaterialNews.WxMpMaterialNewsArticle articles; - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public int getIndex() { - return this.index; - } - - public void setIndex(int index) { - this.index = index; - } - - public WxMpMaterialNews.WxMpMaterialNewsArticle getArticles() { - return this.articles; - } - - public void setArticles(WxMpMaterialNews.WxMpMaterialNewsArticle articles) { - this.articles = articles; - } - public String toJson() { return WxMpGsonBuilder.create().toJson(this); } - - @Override - public String toString() { - return "WxMpMaterialArticleUpdate [" + "mediaId=" + this.mediaId + ", index=" + this.index + ", articles=" + this.articles + "]"; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialCountResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialCountResult.java index 4a74b6b64b..ba457e799c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialCountResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialCountResult.java @@ -1,9 +1,16 @@ package me.chanjar.weixin.mp.bean.material; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; + +/** + * @author codepiano + */ +@Data public class WxMpMaterialCountResult implements Serializable { private static final long serialVersionUID = -5568772662085874138L; @@ -12,41 +19,9 @@ public class WxMpMaterialCountResult implements Serializable { private int imageCount; private int newsCount; - public int getVoiceCount() { - return this.voiceCount; - } - - public void setVoiceCount(int voiceCount) { - this.voiceCount = voiceCount; - } - - public int getVideoCount() { - return this.videoCount; - } - - public void setVideoCount(int videoCount) { - this.videoCount = videoCount; - } - - public int getImageCount() { - return this.imageCount; - } - - public void setImageCount(int imageCount) { - this.imageCount = imageCount; - } - - public int getNewsCount() { - return this.newsCount; - } - - public void setNewsCount(int newsCount) { - this.newsCount = newsCount; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialFileBatchGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialFileBatchGetResult.java index b08a0ce3c4..3d6e9353bc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialFileBatchGetResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialFileBatchGetResult.java @@ -1,11 +1,18 @@ package me.chanjar.weixin.mp.bean.material; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; import java.util.Date; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; + +/** + * @author codepiano + */ +@Data public class WxMpMaterialFileBatchGetResult implements Serializable { private static final long serialVersionUID = -560388368297267884L; @@ -13,76 +20,21 @@ public class WxMpMaterialFileBatchGetResult implements Serializable { private int itemCount; private List items; - public int getTotalCount() { - return this.totalCount; - } - - public void setTotalCount(int totalCount) { - this.totalCount = totalCount; - } - - public int getItemCount() { - return this.itemCount; - } - - public void setItemCount(int itemCount) { - this.itemCount = itemCount; - } - - public List getItems() { - return this.items; - } - - public void setItems(List items) { - this.items = items; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } + @Data public static class WxMaterialFileBatchGetNewsItem { private String mediaId; private Date updateTime; private String name; private String url; - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public Date getUpdateTime() { - return this.updateTime; - } - - public void setUpdateTime(Date updateTime) { - this.updateTime = updateTime; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java index 51f2d0c6bd..16f787a3f5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNews.java @@ -1,13 +1,20 @@ package me.chanjar.weixin.mp.bean.material; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; -import java.util.Date; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * @author codepiano + */ +@Data public class WxMpMaterialNews implements Serializable { private static final long serialVersionUID = -3283203652013494976L; @@ -32,22 +39,6 @@ public boolean isEmpty() { return this.articles == null || this.articles.isEmpty(); } - public Date getCreatedTime() { - return this.createdTime; - } - - public void setCreatedTime(Date createdTime) { - this.createdTime = createdTime; - } - - public Date getUpdatedTime() { - return this.updatedTime; - } - - public void setUpdatedTime(Date updatedTime) { - this.updatedTime = updatedTime; - } - @Override public String toString() { return this.toJson(); @@ -70,6 +61,7 @@ public String toString() { * * @author chanjarster */ + @Data public static class WxMpMaterialNewsArticle { /** * (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得 @@ -121,97 +113,9 @@ public static class WxMpMaterialNewsArticle { */ private Boolean onlyFansCanComment; - public String getThumbMediaId() { - return this.thumbMediaId; - } - - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } - - public String getAuthor() { - return this.author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getContentSourceUrl() { - return this.contentSourceUrl; - } - - public void setContentSourceUrl(String contentSourceUrl) { - this.contentSourceUrl = contentSourceUrl; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getDigest() { - return this.digest; - } - - public void setDigest(String digest) { - this.digest = digest; - } - - public boolean isShowCoverPic() { - return this.showCoverPic; - } - - public void setShowCoverPic(boolean showCoverPic) { - this.showCoverPic = showCoverPic; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getThumbUrl() { - return this.thumbUrl; - } - - public void setThumbUrl(String thumbUrl) { - this.thumbUrl = thumbUrl; - } - - public Boolean getNeedOpenComment() { - return this.needOpenComment; - } - - public void setNeedOpenComment(Boolean needOpenComment) { - this.needOpenComment = needOpenComment; - } - - public Boolean getOnlyFansCanComment() { - return this.onlyFansCanComment; - } - - public void setOnlyFansCanComment(Boolean onlyFansCanComment) { - this.onlyFansCanComment = onlyFansCanComment; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNewsBatchGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNewsBatchGetResult.java index 03f0a6d854..47e6cb5365 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNewsBatchGetResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialNewsBatchGetResult.java @@ -1,11 +1,15 @@ package me.chanjar.weixin.mp.bean.material; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; import java.util.Date; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; + +@Data public class WxMpMaterialNewsBatchGetResult implements Serializable { private static final long serialVersionUID = -1617952797921001666L; @@ -13,67 +17,20 @@ public class WxMpMaterialNewsBatchGetResult implements Serializable { private int itemCount; private List items; - public int getTotalCount() { - return this.totalCount; - } - - public void setTotalCount(int totalCount) { - this.totalCount = totalCount; - } - - public int getItemCount() { - return this.itemCount; - } - - public void setItemCount(int itemCount) { - this.itemCount = itemCount; - } - - public List getItems() { - return this.items; - } - - public void setItems(List items) { - this.items = items; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } + @Data public static class WxMaterialNewsBatchGetNewsItem { private String mediaId; private Date updateTime; private WxMpMaterialNews content; - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public Date getUpdateTime() { - return this.updateTime; - } - - public void setUpdateTime(Date updateTime) { - this.updateTime = updateTime; - } - - public WxMpMaterialNews getContent() { - return this.content; - } - - public void setContent(WxMpMaterialNews content) { - this.content = content; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialUploadResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialUploadResult.java index 0e5546b9aa..15744ce59c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialUploadResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialUploadResult.java @@ -1,10 +1,14 @@ package me.chanjar.weixin.mp.bean.material; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +@Data public class WxMpMaterialUploadResult implements Serializable { private static final long serialVersionUID = -128818731449449537L; private String mediaId; @@ -16,41 +20,9 @@ public static WxMpMaterialUploadResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxMpMaterialUploadResult.class); } - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public Integer getErrCode() { - return this.errCode; - } - - public void setErrCode(Integer errCode) { - this.errCode = errCode; - } - - public String getErrMsg() { - return this.errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialVideoInfoResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialVideoInfoResult.java index e0558cc888..8a783e6809 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialVideoInfoResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/material/WxMpMaterialVideoInfoResult.java @@ -1,9 +1,11 @@ package me.chanjar.weixin.mp.bean.material; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; +@Data public class WxMpMaterialVideoInfoResult implements Serializable { private static final long serialVersionUID = 1269131745333792202L; @@ -15,33 +17,4 @@ public static WxMpMaterialVideoInfoResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxMpMaterialVideoInfoResult.class); } - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getDownUrl() { - return this.downUrl; - } - - public void setDownUrl(String downUrl) { - this.downUrl = downUrl; - } - - @Override - public String toString() { - return "WxMpMaterialVideoInfoResult [title=" + this.title + ", description=" + this.description + ", downUrl=" + this.downUrl + "]"; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/MemberCardUserInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/MemberCardUserInfo.java index b9c771c487..c039d72a15 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/MemberCardUserInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/MemberCardUserInfo.java @@ -1,10 +1,14 @@ package me.chanjar.weixin.mp.bean.membercard; +import lombok.Data; + import java.io.Serializable; /** - * Created by YuJian on 2017/7/11. + * @author YuJian + * @date 2017/7/11 */ +@Data public class MemberCardUserInfo implements Serializable { private static final long serialVersionUID = -4259196162619282129L; @@ -12,19 +16,4 @@ public class MemberCardUserInfo implements Serializable { private NameValues[] customFieldList; - public NameValues[] getCommonFieldList() { - return commonFieldList; - } - - public void setCommonFieldList(NameValues[] commonFieldList) { - this.commonFieldList = commonFieldList; - } - - public NameValues[] getCustomFieldList() { - return customFieldList; - } - - public void setCustomFieldList(NameValues[] customFieldList) { - this.customFieldList = customFieldList; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NameValues.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NameValues.java index a5c62e5e6a..f285855535 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NameValues.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NameValues.java @@ -1,10 +1,15 @@ package me.chanjar.weixin.mp.bean.membercard; +import lombok.Data; + import java.io.Serializable; /** - * Created by YuJian on 2017/7/11. + * + * @author YuJian + * @date 2017/7/11 */ +@Data public class NameValues implements Serializable{ private static final long serialVersionUID = -8529369702944594330L; @@ -14,27 +19,4 @@ public class NameValues implements Serializable{ private String[] valueList; - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String[] getValueList() { - return valueList; - } - - public void setValueList(String[] valueList) { - this.valueList = valueList; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NotifyOptional.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NotifyOptional.java index e44ec4b5ac..c4d25c97e8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NotifyOptional.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/NotifyOptional.java @@ -1,6 +1,7 @@ package me.chanjar.weixin.mp.bean.membercard; import com.google.gson.annotations.SerializedName; +import lombok.Data; import java.io.Serializable; @@ -15,6 +16,7 @@ * @author YuJian(mgcnrx11@gmail.com) * @version 2017/7/15 */ +@Data public class NotifyOptional implements Serializable { private static final long serialVersionUID = 4488842021504939176L; @@ -41,44 +43,4 @@ public class NotifyOptional implements Serializable { @SerializedName("is_notify_custom_field3") private Boolean isNotifyCustomField3; - - public Boolean getNotifyBonus() { - return isNotifyBonus; - } - - public void setNotifyBonus(Boolean notifyBonus) { - isNotifyBonus = notifyBonus; - } - - public Boolean getNotifyBalance() { - return isNotifyBalance; - } - - public void setNotifyBalance(Boolean notifyBalance) { - isNotifyBalance = notifyBalance; - } - - public Boolean getNotifyCustomField1() { - return isNotifyCustomField1; - } - - public void setNotifyCustomField1(Boolean notifyCustomField1) { - isNotifyCustomField1 = notifyCustomField1; - } - - public Boolean getNotifyCustomField2() { - return isNotifyCustomField2; - } - - public void setNotifyCustomField2(Boolean notifyCustomField2) { - isNotifyCustomField2 = notifyCustomField2; - } - - public Boolean getNotifyCustomField3() { - return isNotifyCustomField3; - } - - public void setNotifyCustomField3(Boolean notifyCustomField3) { - isNotifyCustomField3 = notifyCustomField3; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivatedMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivatedMessage.java index 0c782e3c51..9b1ac647cc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivatedMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivatedMessage.java @@ -1,6 +1,7 @@ package me.chanjar.weixin.mp.bean.membercard; import com.google.gson.annotations.SerializedName; +import lombok.Data; import java.io.Serializable; @@ -10,6 +11,7 @@ * @author YuJian(mgcnrx11@hotmail.com) * @version 2017/7/8 */ +@Data public class WxMpMemberCardActivatedMessage implements Serializable { private static final long serialVersionUID = -5972713484594266480L; @@ -56,7 +58,7 @@ public class WxMpMemberCardActivatedMessage implements Serializable { * 初始余额,不填为0。 */ @SerializedName("init_balance") - private Integer initBalance; + private Double initBalance; /** * 创建时字段custom_field1定义类型的初始值,限制为4个汉字,12字节。 */ @@ -73,99 +75,4 @@ public class WxMpMemberCardActivatedMessage implements Serializable { @SerializedName("init_custom_field_value3") private String initCustomFieldValue3; - public String getMembershipNumber() { - return membershipNumber; - } - - public void setMembershipNumber(String membershipNumber) { - this.membershipNumber = membershipNumber; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getCardId() { - return cardId; - } - - public void setCardId(String cardId) { - this.cardId = cardId; - } - - public String getBackgroundPicUrl() { - return backgroundPicUrl; - } - - public void setBackgroundPicUrl(String backgroundPicUrl) { - this.backgroundPicUrl = backgroundPicUrl; - } - - public Integer getActivateBeginTime() { - return activateBeginTime; - } - - public void setActivateBeginTime(Integer activateBeginTime) { - this.activateBeginTime = activateBeginTime; - } - - public Integer getActivateEndTime() { - return activateEndTime; - } - - public void setActivateEndTime(Integer activateEndTime) { - this.activateEndTime = activateEndTime; - } - - public Integer getInitBonus() { - return initBonus; - } - - public void setInitBonus(Integer initBonus) { - this.initBonus = initBonus; - } - - public String getInitBonusRecord() { - return initBonusRecord; - } - - public void setInitBonusRecord(String initBonusRecord) { - this.initBonusRecord = initBonusRecord; - } - - public Integer getInitBalance() { - return initBalance; - } - - public void setInitBalance(Integer initBalance) { - this.initBalance = initBalance; - } - - public String getInitCustomFieldValue1() { - return initCustomFieldValue1; - } - - public void setInitCustomFieldValue1(String initCustomFieldValue1) { - this.initCustomFieldValue1 = initCustomFieldValue1; - } - - public String getInitCustomFieldValue2() { - return initCustomFieldValue2; - } - - public void setInitCustomFieldValue2(String initCustomFieldValue2) { - this.initCustomFieldValue2 = initCustomFieldValue2; - } - - public String getInitCustomFieldValue3() { - return initCustomFieldValue3; - } - - public void setInitCustomFieldValue3(String initCustomFieldValue3) { - this.initCustomFieldValue3 = initCustomFieldValue3; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardCreateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardCreateMessage.java new file mode 100644 index 0000000000..bd8fccb423 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardCreateMessage.java @@ -0,0 +1,25 @@ +package me.chanjar.weixin.mp.bean.membercard; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.bean.card.MemberCardCreateRequest; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +@Data +public final class WxMpMemberCardCreateMessage implements Serializable { + + @SerializedName("card") + private MemberCardCreateRequest cardCreateRequest; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + public static WxMpMemberCardCreateMessage fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpMemberCardCreateMessage.class); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateMessage.java index 313ba66282..d4323e0996 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateMessage.java @@ -1,6 +1,7 @@ package me.chanjar.weixin.mp.bean.membercard; import com.google.gson.annotations.SerializedName; +import lombok.Data; import java.io.Serializable; @@ -16,6 +17,7 @@ * @author YuJian(mgcnrx11@gmail.com) * @version 2017/7/15 */ +@Data public class WxMpMemberCardUpdateMessage implements Serializable { private static final long serialVersionUID = 4953923160718911058L; @@ -50,12 +52,12 @@ public class WxMpMemberCardUpdateMessage implements Serializable { /** * 需要设置的余额全量值,传入的数值会直接显示在卡面 */ - private Integer balance; + private Double balance; /** * 本次余额变动值,传负数代表减少 */ @SerializedName("add_balance") - private Integer addBalance; + private Double addBalance; /** * 商家自定义金额消耗记录,不超过14个汉字。 */ @@ -75,107 +77,4 @@ public class WxMpMemberCardUpdateMessage implements Serializable { @SerializedName("notify_optional") private NotifyOptional notifyOptional; - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getCardId() { - return cardId; - } - - public void setCardId(String cardId) { - this.cardId = cardId; - } - - public String getBackgroundPicUrl() { - return backgroundPicUrl; - } - - public void setBackgroundPicUrl(String backgroundPicUrl) { - this.backgroundPicUrl = backgroundPicUrl; - } - - public Integer getBonus() { - return bonus; - } - - public void setBonus(Integer bonus) { - this.bonus = bonus; - } - - public Integer getAddBounus() { - return addBounus; - } - - public void setAddBounus(Integer addBounus) { - this.addBounus = addBounus; - } - - public String getRecordBonus() { - return recordBonus; - } - - public void setRecordBonus(String recordBonus) { - this.recordBonus = recordBonus; - } - - public Integer getBalance() { - return balance; - } - - public void setBalance(Integer balance) { - this.balance = balance; - } - - public Integer getAddBalance() { - return addBalance; - } - - public void setAddBalance(Integer addBalance) { - this.addBalance = addBalance; - } - - public String getRecordBalance() { - return recordBalance; - } - - public void setRecordBalance(String recordBalance) { - this.recordBalance = recordBalance; - } - - public String getCustomFieldValue1() { - return customFieldValue1; - } - - public void setCustomFieldValue1(String customFieldValue1) { - this.customFieldValue1 = customFieldValue1; - } - - public String getCustomFieldValue2() { - return customFieldValue2; - } - - public void setCustomFieldValue2(String customFieldValue2) { - this.customFieldValue2 = customFieldValue2; - } - - public String getCustomFieldValue3() { - return customFieldValue3; - } - - public void setCustomFieldValue3(String customFieldValue3) { - this.customFieldValue3 = customFieldValue3; - } - - public NotifyOptional getNotifyOptional() { - return notifyOptional; - } - - public void setNotifyOptional(NotifyOptional notifyOptional) { - this.notifyOptional = notifyOptional; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateResult.java index 2cbe2efb2f..96b8212d66 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUpdateResult.java @@ -1,10 +1,13 @@ package me.chanjar.weixin.mp.bean.membercard; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** *
  * 用于 `7 更新会员信息` 的接口调用后的返回结果
@@ -14,6 +17,7 @@
  * @author YuJian(mgcnrx11@gmail.com)
  * @version 2017/7/15
  */
+@Data
 public class WxMpMemberCardUpdateResult implements Serializable {
 
   private static final long serialVersionUID = 9084886191442098311L;
@@ -26,51 +30,11 @@ public class WxMpMemberCardUpdateResult implements Serializable {
 
   private Integer resultBonus;
 
-  private Integer resultBalance;
-
-  public String getErrorCode() {
-    return errorCode;
-  }
-
-  public void setErrorCode(String errorCode) {
-    this.errorCode = errorCode;
-  }
-
-  public String getErrorMsg() {
-    return errorMsg;
-  }
-
-  public void setErrorMsg(String errorMsg) {
-    this.errorMsg = errorMsg;
-  }
-
-  public String getOpenId() {
-    return openId;
-  }
-
-  public void setOpenId(String openId) {
-    this.openId = openId;
-  }
-
-  public Integer getResultBonus() {
-    return resultBonus;
-  }
-
-  public void setResultBonus(Integer resultBonus) {
-    this.resultBonus = resultBonus;
-  }
-
-  public Integer getResultBalance() {
-    return resultBalance;
-  }
-
-  public void setResultBalance(Integer resultBalance) {
-    this.resultBalance = resultBalance;
-  }
+  private Double resultBalance;
 
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 
   public static WxMpMemberCardUpdateResult fromJson(String json) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUserInfoResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUserInfoResult.java
index 82a24cd297..705dba7895 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUserInfoResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardUserInfoResult.java
@@ -1,10 +1,13 @@
 package me.chanjar.weixin.mp.bean.membercard;
 
-import me.chanjar.weixin.common.util.ToStringUtils;
-import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-
 import java.io.Serializable;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
 /**
  * 
  * 拉取会员信息返回的结果
@@ -15,6 +18,7 @@
  * @author YuJian
  * @version 2017/7/9
  */
+@Data
 public class WxMpMemberCardUserInfoResult implements Serializable {
 
   private static final long serialVersionUID = 9084777967442098311L;
@@ -31,6 +35,8 @@ public class WxMpMemberCardUserInfoResult implements Serializable {
 
   private Integer bonus;
 
+  private Double balance;
+
   private String sex;
 
   private MemberCardUserInfo userInfo;
@@ -39,93 +45,9 @@ public class WxMpMemberCardUserInfoResult implements Serializable {
 
   private Boolean hasActive;
 
-  public static long getSerialVersionUID() {
-    return serialVersionUID;
-  }
-
-  public String getErrorCode() {
-    return errorCode;
-  }
-
-  public void setErrorCode(String errorCode) {
-    this.errorCode = errorCode;
-  }
-
-  public String getErrorMsg() {
-    return errorMsg;
-  }
-
-  public void setErrorMsg(String errorMsg) {
-    this.errorMsg = errorMsg;
-  }
-
-  public String getOpenId() {
-    return openId;
-  }
-
-  public void setOpenId(String openId) {
-    this.openId = openId;
-  }
-
-  public String getNickname() {
-    return nickname;
-  }
-
-  public void setNickname(String nickname) {
-    this.nickname = nickname;
-  }
-
-  public String getMembershipNumber() {
-    return membershipNumber;
-  }
-
-  public void setMembershipNumber(String membershipNumber) {
-    this.membershipNumber = membershipNumber;
-  }
-
-  public Integer getBonus() {
-    return bonus;
-  }
-
-  public void setBonus(Integer bonus) {
-    this.bonus = bonus;
-  }
-
-  public String getSex() {
-    return sex;
-  }
-
-  public void setSex(String sex) {
-    this.sex = sex;
-  }
-
-  public MemberCardUserInfo getUserInfo() {
-    return userInfo;
-  }
-
-  public void setUserInfo(MemberCardUserInfo userInfo) {
-    this.userInfo = userInfo;
-  }
-
-  public String getUserCardStatus() {
-    return userCardStatus;
-  }
-
-  public void setUserCardStatus(String userCardStatus) {
-    this.userCardStatus = userCardStatus;
-  }
-
-  public Boolean getHasActive() {
-    return hasActive;
-  }
-
-  public void setHasActive(Boolean hasActive) {
-    this.hasActive = hasActive;
-  }
-
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 
   public static WxMpMemberCardUserInfoResult fromJson(String json) {
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResult.java
index 295a782696..2c370eaf34 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpGetSelfMenuInfoResult.java
@@ -1,17 +1,22 @@
 package me.chanjar.weixin.mp.bean.menu;
 
+import java.io.Serializable;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
 import com.google.gson.annotations.SerializedName;
-import me.chanjar.weixin.common.util.ToStringUtils;
+import lombok.Data;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 
-import java.io.Serializable;
-
 /**
  * 
  * Created by Binary Wang on 2016-11-25.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ +@Data public class WxMpGetSelfMenuInfoResult implements Serializable { private static final long serialVersionUID = -5612495636936835166L; @@ -27,22 +32,7 @@ public static WxMpGetSelfMenuInfoResult fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public WxMpSelfMenuInfo getSelfMenuInfo() { - return selfMenuInfo; - } - - public void setSelfMenuInfo(WxMpSelfMenuInfo selfMenuInfo) { - this.selfMenuInfo = selfMenuInfo; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public Integer getIsMenuOpen() { - return isMenuOpen; - } - - public void setIsMenuOpen(Integer isMenuOpen) { - this.isMenuOpen = isMenuOpen; - } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpMenu.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpMenu.java index 5e93d7e0d6..e36a2b2387 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpMenu.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpMenu.java @@ -1,21 +1,26 @@ package me.chanjar.weixin.mp.bean.menu; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.annotations.SerializedName; +import lombok.Data; import me.chanjar.weixin.common.bean.menu.WxMenuButton; import me.chanjar.weixin.common.bean.menu.WxMenuRule; -import me.chanjar.weixin.common.util.ToStringUtils; import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import java.io.Serializable; -import java.util.List; - /** *
  *   公众号专用的菜单类,可能包含个性化菜单
  * Created by Binary Wang on 2017-1-17.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ +@Data public class WxMpMenu implements Serializable { private static final long serialVersionUID = -5794350513426702252L; @@ -29,31 +34,16 @@ public static WxMpMenu fromJson(String json) { return WxGsonBuilder.create().fromJson(json, WxMpMenu.class); } - public WxMpConditionalMenu getMenu() { - return menu; - } - - public void setMenu(WxMpConditionalMenu menu) { - this.menu = menu; - } - - public List getConditionalMenu() { - return conditionalMenu; - } - - public void setConditionalMenu(List conditionalMenu) { - this.conditionalMenu = conditionalMenu; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public String toJson() { return WxGsonBuilder.create().toJson(this); } + @Data public static class WxMpConditionalMenu implements Serializable { private static final long serialVersionUID = -2279946921755382289L; @@ -66,32 +56,9 @@ public static class WxMpConditionalMenu implements Serializable { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public List getButtons() { - return buttons; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public void setButtons(List buttons) { - this.buttons = buttons; - } - - public WxMenuRule getRule() { - return rule; - } - - public void setRule(WxMenuRule rule) { - this.rule = rule; - } - - public String getMenuId() { - return menuId; - } - - public void setMenuId(String menuId) { - this.menuId = menuId; - } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java index c278bd4c1a..b9d8e941f1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/menu/WxMpSelfMenuInfo.java @@ -1,18 +1,23 @@ package me.chanjar.weixin.mp.bean.menu; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + /** *
  * Created by Binary Wang on 2016-11-25.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ +@Data public class WxMpSelfMenuInfo implements Serializable { private static final long serialVersionUID = -81203094124202901L; @@ -24,18 +29,13 @@ public class WxMpSelfMenuInfo implements Serializable { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public List getButtons() { - return this.buttons; - } - - public void setButtons(List buttons) { - this.buttons = buttons; - } + @Data + public static class WxMpSelfMenuButton implements Serializable { + private static final long serialVersionUID = -4426602953309048341L; - public static class WxMpSelfMenuButton { /** *
      * 菜单的类型,公众平台官网上能够设置的菜单类型有view(跳转网页)、text(返回文本,下同)、img、photo、video、voice。
@@ -89,101 +89,38 @@ public static class WxMpSelfMenuButton {
 
     @Override
     public String toString() {
-      return ToStringUtils.toSimpleString(this);
-    }
-
-    public SubButtons getSubButtons() {
-      return subButtons;
-    }
-
-    public void setSubButtons(SubButtons subButtons) {
-      this.subButtons = subButtons;
-    }
-
-    public String getType() {
-      return type;
-    }
-
-    public void setType(String type) {
-      this.type = type;
-    }
-
-    public String getName() {
-      return name;
+      return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
     }
 
-    public void setName(String name) {
-      this.name = name;
-    }
-
-    public String getKey() {
-      return key;
-    }
-
-    public void setKey(String key) {
-      this.key = key;
-    }
-
-    public String getUrl() {
-      return url;
-    }
-
-    public void setUrl(String url) {
-      this.url = url;
-    }
-
-    public String getValue() {
-      return value;
-    }
-
-    public void setValue(String value) {
-      this.value = value;
-    }
-
-    public NewsInfo getNewsInfo() {
-      return newsInfo;
-    }
-
-    public void setNewsInfo(NewsInfo newsInfo) {
-      this.newsInfo = newsInfo;
-    }
+    @Data
+    public static class SubButtons implements Serializable {
+      private static final long serialVersionUID = 1763350658575521079L;
 
-    public static class SubButtons {
       @SerializedName("list")
       private List subButtons = new ArrayList<>();
 
       @Override
       public String toString() {
-        return ToStringUtils.toSimpleString(this);
-      }
-
-      public List getSubButtons() {
-        return subButtons;
-      }
-
-      public void setSubButtons(List subButtons) {
-        this.subButtons = subButtons;
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
       }
     }
 
-    public static class NewsInfo {
+    @Data
+    public static class NewsInfo implements Serializable {
+      private static final long serialVersionUID = 3449813746347818457L;
+
       @SerializedName("list")
       private List news = new ArrayList<>();
 
       @Override
       public String toString() {
-        return ToStringUtils.toSimpleString(this);
+        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
       }
 
-      public List getNews() {
-        return news;
-      }
-
-      public void setNews(List news) {
-        this.news = news;
-      }
+      @Data
+      public static class NewsInButton  implements Serializable {
+        private static final long serialVersionUID = 8701455967664912972L;
 
-      public static class NewsInButton {
         /**
          * 图文消息的标题
          */
@@ -223,64 +160,9 @@ public static class NewsInButton {
 
         @Override
         public String toString() {
-          return ToStringUtils.toSimpleString(this);
-        }
-
-        public String getTitle() {
-          return title;
-        }
-
-        public void setTitle(String title) {
-          this.title = title;
-        }
-
-        public String getDigest() {
-          return digest;
-        }
-
-        public void setDigest(String digest) {
-          this.digest = digest;
-        }
-
-        public String getAuthor() {
-          return author;
+          return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
         }
 
-        public void setAuthor(String author) {
-          this.author = author;
-        }
-
-        public Integer getShowCover() {
-          return showCover;
-        }
-
-        public void setShowCover(Integer showCover) {
-          this.showCover = showCover;
-        }
-
-        public String getCoverUrl() {
-          return coverUrl;
-        }
-
-        public void setCoverUrl(String coverUrl) {
-          this.coverUrl = coverUrl;
-        }
-
-        public String getContentUrl() {
-          return contentUrl;
-        }
-
-        public void setContentUrl(String contentUrl) {
-          this.contentUrl = contentUrl;
-        }
-
-        public String getSourceUrl() {
-          return sourceUrl;
-        }
-
-        public void setSourceUrl(String sourceUrl) {
-          this.sourceUrl = sourceUrl;
-        }
       }
     }
   }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/HardWare.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/HardWare.java
index 1ef3ee6b7c..f29321d4fc 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/HardWare.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/HardWare.java
@@ -1,12 +1,15 @@
 package me.chanjar.weixin.mp.bean.message;
 
+import java.io.Serializable;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamConverter;
-import me.chanjar.weixin.common.util.ToStringUtils;
+import lombok.Data;
 import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import java.io.Serializable;
-
 /**
  * 
  *  Created by BinaryWang on 2017/5/4.
@@ -15,6 +18,7 @@
  * @author Binary Wang
  */
 @XStreamAlias("HardWare")
+@Data
 public class HardWare implements Serializable{
   private static final long serialVersionUID = -1295785297354896461L;
 
@@ -33,22 +37,6 @@ public class HardWare implements Serializable{
 
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
-  }
-
-  public String getMessageView() {
-    return messageView;
-  }
-
-  public void setMessageView(String messageView) {
-    this.messageView = messageView;
-  }
-
-  public String getMessageAction() {
-    return messageAction;
-  }
-
-  public void setMessageAction(String messageAction) {
-    this.messageAction = messageAction;
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/ScanCodeInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/ScanCodeInfo.java
index c5c32cb522..2af977ca80 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/ScanCodeInfo.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/ScanCodeInfo.java
@@ -1,12 +1,15 @@
 package me.chanjar.weixin.mp.bean.message;
 
+import java.io.Serializable;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamConverter;
-import me.chanjar.weixin.common.util.ToStringUtils;
+import lombok.Data;
 import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import java.io.Serializable;
-
 /**
  * 
  *  Created by BinaryWang on 2017/5/4.
@@ -15,41 +18,27 @@
  * @author Binary Wang
  */
 @XStreamAlias("ScanCodeInfo")
+@Data
 public class ScanCodeInfo implements Serializable {
   private static final long serialVersionUID = 4745181270645050122L;
 
+  /**
+   * 扫描类型,一般是qrcode.
+   */
   @XStreamAlias("ScanType")
   @XStreamConverter(value = XStreamCDataConverter.class)
   private String scanType;
+
+  /**
+   * 扫描结果,即二维码对应的字符串信息.
+   */
   @XStreamAlias("ScanResult")
   @XStreamConverter(value = XStreamCDataConverter.class)
   private String scanResult;
 
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
-  }
-
-  /**
-   * 扫描类型,一般是qrcode
-   */
-  public String getScanType() {
-    return this.scanType;
-  }
-
-  public void setScanType(String scanType) {
-    this.scanType = scanType;
-  }
-
-  /**
-   * 扫描结果,即二维码对应的字符串信息
-   */
-  public String getScanResult() {
-    return this.scanResult;
-  }
-
-  public void setScanResult(String scanResult) {
-    this.scanResult = scanResult;
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendLocationInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendLocationInfo.java
index 8ecb3c8bff..5d725557d5 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendLocationInfo.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendLocationInfo.java
@@ -1,12 +1,15 @@
 package me.chanjar.weixin.mp.bean.message;
 
+import java.io.Serializable;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamConverter;
-import me.chanjar.weixin.common.util.ToStringUtils;
+import lombok.Data;
 import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 
-import java.io.Serializable;
-
 /**
  * 
  *  Created by BinaryWang on 2017/5/4.
@@ -15,6 +18,7 @@
  * @author Binary Wang
  */
 @XStreamAlias("SendLocationInfo")
+@Data
 public class SendLocationInfo implements Serializable {
   private static final long serialVersionUID = 6633214140499161130L;
 
@@ -36,50 +40,10 @@ public class SendLocationInfo implements Serializable {
 
   @XStreamAlias("Poiname")
   @XStreamConverter(value = XStreamCDataConverter.class)
-  private String poiname;
+  private String poiName;
 
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
-  }
-
-  public String getLocationX() {
-    return this.locationX;
-  }
-
-  public void setLocationX(String locationX) {
-    this.locationX = locationX;
-  }
-
-  public String getLocationY() {
-    return this.locationY;
-  }
-
-  public void setLocationY(String locationY) {
-    this.locationY = locationY;
-  }
-
-  public String getScale() {
-    return this.scale;
-  }
-
-  public void setScale(String scale) {
-    this.scale = scale;
-  }
-
-  public String getLabel() {
-    return this.label;
-  }
-
-  public void setLabel(String label) {
-    this.label = label;
-  }
-
-  public String getPoiname() {
-    return this.poiname;
-  }
-
-  public void setPoiname(String poiname) {
-    this.poiname = poiname;
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendPicsInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendPicsInfo.java
index cf5c374edf..318e7cee3a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendPicsInfo.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/SendPicsInfo.java
@@ -1,14 +1,17 @@
 package me.chanjar.weixin.mp.bean.message;
 
-import com.thoughtworks.xstream.annotations.XStreamAlias;
-import com.thoughtworks.xstream.annotations.XStreamConverter;
-import me.chanjar.weixin.common.util.ToStringUtils;
-import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
-
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import lombok.Data;
+import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
+
 /**
  * 
  *  Created by BinaryWang on 2017/5/4.
@@ -17,6 +20,7 @@
  * @author Binary Wang
  */
 @XStreamAlias("SendPicsInfo")
+@Data
 public class SendPicsInfo implements Serializable {
   private static final long serialVersionUID = -4572837013294199227L;
 
@@ -28,22 +32,11 @@ public class SendPicsInfo implements Serializable {
 
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
-  }
-
-  public Long getCount() {
-    return this.count;
-  }
-
-  public void setCount(Long count) {
-    this.count = count;
-  }
-
-  public List getPicList() {
-    return this.picList;
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 
   @XStreamAlias("item")
+  @Data
   public static class Item implements Serializable {
     private static final long serialVersionUID = 7706235740094081194L;
 
@@ -53,15 +46,8 @@ public static class Item implements Serializable {
 
     @Override
     public String toString() {
-      return ToStringUtils.toSimpleString(this);
-    }
-
-    public String getPicMd5Sum() {
-      return this.picMd5Sum;
+      return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
     }
 
-    public void setPicMd5Sum(String picMd5Sum) {
-      this.picMd5Sum = picMd5Sum;
-    }
   }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
index 2ea17b9e07..ae476331a1 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessage.java
@@ -1,21 +1,26 @@
 package me.chanjar.weixin.mp.bean.message;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import com.thoughtworks.xstream.annotations.XStreamConverter;
-import me.chanjar.weixin.common.util.ToStringUtils;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.api.WxConsts;
 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.XStreamTransformer;
-import org.apache.commons.io.IOUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
 
 /**
  * 
- * 微信推送过来的消息,xml格式
+ * 微信推送过来的消息,xml格式.
  * 部分未注释的字段的解释请查阅相关微信开发文档:
  * 接收普通消息
  * 接收事件推送
@@ -23,6 +28,8 @@
  *
  * @author chanjarster
  */
+@Data
+@Slf4j
 @XStreamAlias("xml")
 public class WxMpXmlMessage implements Serializable {
   private static final long serialVersionUID = -3586245291677274914L;
@@ -126,28 +133,29 @@ public class WxMpXmlMessage implements Serializable {
   // 群发消息返回的结果
   ///////////////////////////////////////
   /**
-   * 群发的结果
+   * 群发的结果.
    */
   @XStreamAlias("Status")
   @XStreamConverter(value = XStreamCDataConverter.class)
   private String status;
   /**
-   * group_id下粉丝数;或者openid_list中的粉丝数
+   * group_id下粉丝数;或者openid_list中的粉丝数.
    */
   @XStreamAlias("TotalCount")
   private Integer totalCount;
   /**
-   * 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount
+   * 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数.
+   * 原则上,filterCount = sentCount + errorCount
    */
   @XStreamAlias("FilterCount")
   private Integer filterCount;
   /**
-   * 发送成功的粉丝数
+   * 发送成功的粉丝数.
    */
   @XStreamAlias("SentCount")
   private Integer sentCount;
   /**
-   * 发送失败的粉丝数
+   * 发送失败的粉丝数.
    */
   @XStreamAlias("ErrorCount")
   private Integer errorCount;
@@ -156,17 +164,17 @@ public class WxMpXmlMessage implements Serializable {
   // 客服会话管理相关事件推送
   ///////////////////////////////////////
   /**
-   * 创建或关闭客服会话时的客服帐号
+   * 创建或关闭客服会话时的客服帐号.
    */
   @XStreamAlias("KfAccount")
   private String kfAccount;
   /**
-   * 转接客服会话时的转入客服帐号
+   * 转接客服会话时的转入客服帐号.
    */
   @XStreamAlias("ToKfAccount")
   private String toKfAccount;
   /**
-   * 转接客服会话时的转出客服帐号
+   * 转接客服会话时的转出客服帐号.
    */
   @XStreamAlias("FromKfAccount")
   private String fromKfAccount;
@@ -174,6 +182,7 @@ public class WxMpXmlMessage implements Serializable {
   ///////////////////////////////////////
   // 卡券相关事件推送
   ///////////////////////////////////////
+
   @XStreamAlias("CardId")
   @XStreamConverter(value = XStreamCDataConverter.class)
   private String cardId;
@@ -182,8 +191,11 @@ public class WxMpXmlMessage implements Serializable {
   @XStreamConverter(value = XStreamCDataConverter.class)
   private String friendUserName;
 
+  /**
+   * 是否为转赠,1代表是,0代表否.
+   */
   @XStreamAlias("IsGiveByFriend")
-  private Integer isGiveByFriend; // 是否为转赠,1代表是,0代表否
+  private Integer isGiveByFriend;
 
   @XStreamAlias("UserCardCode")
   @XStreamConverter(value = XStreamCDataConverter.class)
@@ -197,14 +209,14 @@ public class WxMpXmlMessage implements Serializable {
   private Integer outerId;
 
   /**
-   * 用户删除会员卡后可重新找回,当用户本次操作为找回时,该值为1,否则为0
+   * 用户删除会员卡后可重新找回,当用户本次操作为找回时,该值为1,否则为0.
    */
   @XStreamAlias("IsRestoreMemberCard")
   private String isRestoreMemberCard;
 
   /**
    * 
-   * 领取场景值,用于领取渠道数据统计。可在生成二维码接口及添加Addcard接口中自定义该字段的字符串值。
+   * 领取场景值,用于领取渠道数据统计。可在生成二维码接口及添加Addcard接口中自定义该字段的字符串值.
    * 核销卡券时:开发者发起核销时传入的自定义参数,用于进行核销渠道统计
    * 另外:
    * 官网文档中,微信卡券>>卡券事件推送>>2.7 进入会员卡事件推送 user_view_card
@@ -215,43 +227,45 @@ public class WxMpXmlMessage implements Serializable {
   private String outerStr;
 
   /**
-   * 是否转赠退回,0代表不是,1代表是。
+   * 是否转赠退回,0代表不是,1代表是.
    */
   @XStreamAlias("IsReturnBack")
   private String isReturnBack;
 
   /**
-   * 是否是群转赠,0代表不是,1代表是。
+   * 是否是群转赠,0代表不是,1代表是.
    */
   @XStreamAlias("IsChatRoom")
   private String isChatRoom;
 
   /**
-   * 核销来源。支持开发者统计API核销(FROM_API)、公众平台核销(FROM_MP)、卡券商户助手核销(FROM_MOBILE_HELPER)(核销员微信号)
+   * 核销来源.
+   * 支持开发者统计API核销(FROM_API)、公众平台核销(FROM_MP)、卡券商户助手核销(FROM_MOBILE_HELPER)(核销员微信号)
    */
   @XStreamAlias("ConsumeSource")
   private String consumeSource;
 
   /**
-   * 门店名称,当前卡券核销的门店名称(只有通过自助核销和买单核销时才会出现该字段)
+   * 门店名称.
+   * 当前卡券核销的门店名称(只有通过自助核销和买单核销时才会出现该字段)
    */
   @XStreamAlias("LocationName")
   private String locationName;
 
   /**
-   * 核销该卡券核销员的openid(只有通过卡券商户助手核销时才会出现)
+   * 核销该卡券核销员的openid(只有通过卡券商户助手核销时才会出现).
    */
   @XStreamAlias("StaffOpenId")
   private String staffOpenId;
 
   /**
-   * 自助核销时,用户输入的验证码
+   * 自助核销时,用户输入的验证码.
    */
   @XStreamAlias("VerifyCode")
   private String verifyCode;
 
   /**
-   * 自助核销时,用户输入的备注金额
+   * 自助核销时,用户输入的备注金额.
    */
   @XStreamAlias("RemarkAmount")
   private String remarkAmount;
@@ -259,7 +273,7 @@ public class WxMpXmlMessage implements Serializable {
   /**
    * 
    * 官网文档中,微信卡券>>卡券事件推送>>2.10 库存报警事件card_sku_remind
-   * Detail:报警详细信息
+   * Detail:报警详细信息.
    * 
*/ @XStreamAlias("Detail") @@ -268,7 +282,7 @@ public class WxMpXmlMessage implements Serializable { /** *
    * 官网文档中,微信卡券>>卡券事件推送>>2.9 会员卡内容更新事件 update_member_card
-   * ModifyBonus:变动的积分值
+   * ModifyBonus:变动的积分值.
    * 
*/ @XStreamAlias("ModifyBonus") @@ -277,7 +291,7 @@ public class WxMpXmlMessage implements Serializable { /** *
    * 官网文档中,微信卡券>>卡券事件推送>>2.9 会员卡内容更新事件 update_member_card
-   * ModifyBalance:变动的余额值
+   * ModifyBalance:变动的余额值.
    * 
*/ @XStreamAlias("ModifyBalance") @@ -286,7 +300,7 @@ public class WxMpXmlMessage implements Serializable { /** *
    * 官网文档中,微信卡券>>卡券事件推送>>2.6 买单事件推送 User_pay_from_pay_cell
-   * TransId:微信支付交易订单号(只有使用买单功能核销的卡券才会出现)
+   * TransId:微信支付交易订单号(只有使用买单功能核销的卡券才会出现).
    * 
*/ @XStreamAlias("TransId") @@ -328,33 +342,105 @@ public class WxMpXmlMessage implements Serializable { @XStreamAlias("SendLocationInfo") private SendLocationInfo sendLocationInfo = new SendLocationInfo(); + /** + * 审核不通过原因 + */ + @XStreamAlias("RefuseReason") + private String refuseReason; + + /** + * 是否为朋友推荐,0代表否,1代表是 + */ + @XStreamAlias("IsRecommendByFriend") + private String isRecommendByFriend; + + /** + * 购买券点时,实际支付成功的时间 + */ + @XStreamAlias("PayFinishTime") + private String payFinishTime; + + /** + * 购买券点时,支付二维码的生成时间 + */ + @XStreamAlias("CreateOrderTime") + private String createOrderTime; + + /** + * 购买券点时,支付二维码的生成时间 + */ + @XStreamAlias("Desc") + private String desc; + + /** + * 剩余免费券点数量 + */ + @XStreamAlias("FreeCoinCount") + private String freeCoinCount; + + /** + * 剩余付费券点数量 + */ + @XStreamAlias("PayCoinCount") + private String payCoinCount; + + /** + * 本次变动的免费券点数量 + */ + @XStreamAlias("RefundFreeCoinCount") + private String refundFreeCoinCount; + + /** + * 本次变动的付费券点数量 + */ + @XStreamAlias("RefundPayCoinCount") + private String refundPayCoinCount; + + /** + *
+   *    所要拉取的订单类型 ORDER_TYPE_SYS_ADD 平台赠送券点 ORDER_TYPE_WXPAY 充值券点 ORDER_TYPE_REFUND 库存未使用回退券点
+   *    ORDER_TYPE_REDUCE 券点兑换库存 ORDER_TYPE_SYS_REDUCE 平台扣减
+   * 
+ */ + @XStreamAlias("OrderType") + private String orderType; + + /** + * 系统备注,说明此次变动的缘由,如开通账户奖励、门店奖励、核销奖励以及充值、扣减。 + */ + @XStreamAlias("Memo") + private String memo; + + /** + * 所开发票的详情 + */ + @XStreamAlias("ReceiptInfo") + private String receiptInfo; + + /////////////////////////////////////// // 门店审核事件推送 /////////////////////////////////////// /** - * UniqId - * 商户自己内部ID,即字段中的sid + * 商户自己内部ID,即字段中的sid. */ @XStreamAlias("UniqId") private String storeUniqId; /** - * PoiId - * 微信的门店ID,微信内门店唯一标示ID + * 微信的门店ID,微信内门店唯一标示ID. */ @XStreamAlias("PoiId") private String poiId; /** - * Result - * 审核结果,成功succ 或失败fail + * 审核结果,成功succ 或失败fail. */ @XStreamAlias("Result") private String result; /** - * msg - * 成功的通知信息,或审核失败的驳回理由 + * 成功的通知信息,或审核失败的驳回理由. */ @XStreamAlias("msg") private String msg; @@ -363,46 +449,74 @@ public class WxMpXmlMessage implements Serializable { // 微信认证事件推送 /////////////////////////////////////// /** - * ExpiredTime - * 资质认证成功/名称认证成功: 有效期 (整形),指的是时间戳,将于该时间戳认证过期 + * 资质认证成功/名称认证成功: 有效期 (整形),指的是时间戳,将于该时间戳认证过期. * 年审通知: 有效期 (整形),指的是时间戳,将于该时间戳认证过期,需尽快年审 * 认证过期失效通知: 有效期 (整形),指的是时间戳,表示已于该时间戳认证过期,需要重新发起微信认证 */ @XStreamAlias("ExpiredTime") private Long expiredTime; /** - * FailTime - * 失败发生时间 (整形),时间戳 + * 失败发生时间 (整形),时间戳. */ @XStreamAlias("FailTime") private Long failTime; /** - * FailReason - * 认证失败的原因 + * 认证失败的原因. */ @XStreamAlias("FailReason") private String failReason; + /////////////////////////////////////// + // 微信小店 6.1订单付款通知 + /////////////////////////////////////// + /** + * 订单ID. + */ + @XStreamAlias("OrderId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String orderId; + + /** + * 订单状态. + */ + @XStreamAlias("OrderStatus") + private String orderStatus; + + /** + * 商品ID. + */ + @XStreamAlias("ProductId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String productId; + + /** + * 商品SKU信息. + */ + @XStreamAlias("SkuInfo") + @XStreamConverter(value = XStreamCDataConverter.class) + private String skuInfo; /////////////////////////////////////// // 微信硬件平台相关事件推送 /////////////////////////////////////// /** - * 设备类型,目前为"公众账号原始ID" + * 设备类型. + * 目前为"公众账号原始ID" */ @XStreamAlias("DeviceType") @XStreamConverter(value = XStreamCDataConverter.class) private String deviceType; /** - * 设备ID,第三方提供 + * 设备ID. + * 第三方提供 */ @XStreamAlias("DeviceID") @XStreamConverter(value = XStreamCDataConverter.class) private String deviceId; /** - * 微信用户账号的OpenID + * 微信用户账号的OpenID. */ @XStreamAlias("OpenID") @XStreamConverter(value = XStreamCDataConverter.class) @@ -412,13 +526,17 @@ public class WxMpXmlMessage implements Serializable { private HardWare hardWare = new HardWare(); /** - * 请求类型:0:退订设备状态;1:心跳;(心跳的处理方式跟订阅一样)2:订阅设备状态 + * 请求类型. + * 0:退订设备状态; + * 1:心跳;(心跳的处理方式跟订阅一样) + * 2:订阅设备状态 */ @XStreamAlias("OpType") private Integer opType; /** - * 设备状态:0:未连接;1:已连接 + * 设备状态. + * 0:未连接;1:已连接 */ @XStreamAlias("DeviceStatus") private Integer deviceStatus; @@ -434,7 +552,7 @@ public static WxMpXmlMessage fromXml(InputStream is) { } /** - * 从加密字符串转换 + * 从加密字符串转换. * * @param encryptedXml 密文 * @param wxMpConfigStorage 配置存储器对象 @@ -442,213 +560,33 @@ public static WxMpXmlMessage fromXml(InputStream is) { * @param nonce 随机串 * @param msgSignature 签名串 */ - public static WxMpXmlMessage fromEncryptedXml(String encryptedXml, - WxMpConfigStorage wxMpConfigStorage, String timestamp, String nonce, - String msgSignature) { + public static WxMpXmlMessage fromEncryptedXml(String encryptedXml, WxMpConfigStorage wxMpConfigStorage, + String timestamp, String nonce, String msgSignature) { WxMpCryptUtil cryptUtil = new WxMpCryptUtil(wxMpConfigStorage); - String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, - encryptedXml); + String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml); + log.debug("解密后的原始xml消息内容:{}", plainText); return fromXml(plainText); } - public static WxMpXmlMessage fromEncryptedXml(InputStream is, - WxMpConfigStorage wxMpConfigStorage, String timestamp, String nonce, - String msgSignature) { + public static WxMpXmlMessage fromEncryptedXml(InputStream is, WxMpConfigStorage wxMpConfigStorage, String timestamp, + String nonce, String msgSignature) { try { - return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxMpConfigStorage, - timestamp, nonce, msgSignature); + return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), wxMpConfigStorage, timestamp, nonce, msgSignature); } catch (IOException e) { throw new RuntimeException(e); } } - public Integer getOpType() { - return opType; - } - - public void setOpType(Integer opType) { - this.opType = opType; - } - - public Integer getDeviceStatus() { - - return deviceStatus; - } - - public void setDeviceStatus(Integer deviceStatus) { - this.deviceStatus = deviceStatus; - } - - public HardWare getHardWare() { - return hardWare; - } - - public void setHardWare(HardWare hardWare) { - this.hardWare = hardWare; - } - - public String getDeviceType() { - return deviceType; - } - - public void setDeviceType(String deviceType) { - this.deviceType = deviceType; - } - - public String getDeviceId() { - return deviceId; - } - - public void setDeviceId(String deviceId) { - this.deviceId = deviceId; - } - - public String getOpenId() { - return openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public Long getExpiredTime() { - return this.expiredTime; - } - - public void setExpiredTime(Long expiredTime) { - this.expiredTime = expiredTime; - } - - public Long getFailTime() { - return this.failTime; - } - - public void setFailTime(Long failTime) { - this.failTime = failTime; - } - - public String getFailReason() { - return this.failReason; - } - - public void setFailReason(String failReason) { - this.failReason = failReason; - } - - public String getDetail() { - return detail; - } - - public void setDetail(String detail) { - this.detail = detail; - } - - public String getModifyBonus() { - return modifyBonus; - } - - public void setModifyBonus(String modifyBonus) { - this.modifyBonus = modifyBonus; - } - - public String getModifyBalance() { - return modifyBalance; - } - - public void setModifyBalance(String modifyBalance) { - this.modifyBalance = modifyBalance; - } - - public String getTransId() { - return transId; - } - - public void setTransId(String transId) { - this.transId = transId; - } - - public String getLocationId() { - return locationId; - } - - public void setLocationId(String locationId) { - this.locationId = locationId; - } - - public String getFee() { - return fee; - } - - public void setFee(String fee) { - this.fee = fee; - } - - public String getOriginalFee() { - return originalFee; - } - - public void setOriginalFee(String originalFee) { - this.originalFee = originalFee; - } - - public String getStoreUniqId() { - return this.storeUniqId; - } - - public void setStoreUniqId(String storeUniqId) { - this.storeUniqId = storeUniqId; - } - - public String getPoiId() { - return this.poiId; - } - - public void setPoiId(String poiId) { - this.poiId = poiId; - } - - public String getResult() { - return this.result; - } - - public void setResult(String result) { - this.result = result; - } - - public String getMsg() { - return this.msg; - } - - public void setMsg(String msg) { - this.msg = msg; - } - - public String getToUser() { - return this.toUser; - } - - public void setToUser(String toUser) { - this.toUser = toUser; - } - - public Long getCreateTime() { - return this.createTime; - } - - public void setCreateTime(Long createTime) { - this.createTime = createTime; - } - /** *
    * 当接受用户消息时,可能会获得以下值:
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LOCATION}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LINK}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_EVENT}
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#LOCATION}
+   * {@link WxConsts.XmlMsgType#LINK}
+   * {@link WxConsts.XmlMsgType#EVENT}
    * 
*/ public String getMsgType() { @@ -658,408 +596,21 @@ public String getMsgType() { /** *
    * 当发送消息的时候使用:
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_NEWS}
-   * {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_MUSIC}
+   * {@link WxConsts.XmlMsgType#TEXT}
+   * {@link WxConsts.XmlMsgType#IMAGE}
+   * {@link WxConsts.XmlMsgType#VOICE}
+   * {@link WxConsts.XmlMsgType#VIDEO}
+   * {@link WxConsts.XmlMsgType#NEWS}
+   * {@link WxConsts.XmlMsgType#MUSIC}
    * 
- * - * @param msgType */ public void setMsgType(String msgType) { this.msgType = msgType; } - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public Long getMsgId() { - return this.msgId; - } - - public void setMsgId(Long msgId) { - this.msgId = msgId; - } - - public String getPicUrl() { - return this.picUrl; - } - - public void setPicUrl(String picUrl) { - this.picUrl = picUrl; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public String getFormat() { - return this.format; - } - - public void setFormat(String format) { - this.format = format; - } - - public String getThumbMediaId() { - return this.thumbMediaId; - } - - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } - - public Double getLocationX() { - return this.locationX; - } - - public void setLocationX(Double locationX) { - this.locationX = locationX; - } - - public Double getLocationY() { - return this.locationY; - } - - public void setLocationY(Double locationY) { - this.locationY = locationY; - } - - public Double getScale() { - return this.scale; - } - - public void setScale(Double scale) { - this.scale = scale; - } - - public String getLabel() { - return this.label; - } - - public void setLabel(String label) { - this.label = label; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getEvent() { - return this.event; - } - - public void setEvent(String event) { - this.event = event; - } - - public String getEventKey() { - return this.eventKey; - } - - public void setEventKey(String eventKey) { - this.eventKey = eventKey; - } - - public String getTicket() { - return this.ticket; - } - - public void setTicket(String ticket) { - this.ticket = ticket; - } - - public Double getLatitude() { - return this.latitude; - } - - public void setLatitude(Double latitude) { - this.latitude = latitude; - } - - public Double getLongitude() { - return this.longitude; - } - - public void setLongitude(Double longitude) { - this.longitude = longitude; - } - - public Double getPrecision() { - return this.precision; - } - - public void setPrecision(Double precision) { - this.precision = precision; - } - - public String getRecognition() { - return this.recognition; - } - - public void setRecognition(String recognition) { - this.recognition = recognition; - } - - public String getFromUser() { - return this.fromUser; - } - - public void setFromUser(String fromUser) { - this.fromUser = fromUser; - } - - public String getStatus() { - return this.status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Integer getTotalCount() { - return this.totalCount; - } - - public void setTotalCount(Integer totalCount) { - this.totalCount = totalCount; - } - - public Integer getFilterCount() { - return this.filterCount; - } - - public void setFilterCount(Integer filterCount) { - this.filterCount = filterCount; - } - - public Integer getSentCount() { - return this.sentCount; - } - - public void setSentCount(Integer sentCount) { - this.sentCount = sentCount; - } - - public Integer getErrorCount() { - return this.errorCount; - } - - public void setErrorCount(Integer errorCount) { - this.errorCount = errorCount; - } - - public String getCardId() { - return this.cardId; - } - - public void setCardId(String cardId) { - this.cardId = cardId; - } - - public String getFriendUserName() { - return this.friendUserName; - } - - public void setFriendUserName(String friendUserName) { - this.friendUserName = friendUserName; - } - - public Integer getIsGiveByFriend() { - return this.isGiveByFriend; - } - - public void setIsGiveByFriend(Integer isGiveByFriend) { - this.isGiveByFriend = isGiveByFriend; - } - - public String getUserCardCode() { - return this.userCardCode; - } - - public void setUserCardCode(String userCardCode) { - this.userCardCode = userCardCode; - } - - public String getOldUserCardCode() { - return this.oldUserCardCode; - } - - public void setOldUserCardCode(String oldUserCardCode) { - this.oldUserCardCode = oldUserCardCode; - } - - public Integer getOuterId() { - return this.outerId; - } - - public void setOuterId(Integer outerId) { - this.outerId = outerId; - } - - public ScanCodeInfo getScanCodeInfo() { - return this.scanCodeInfo; - } - - public void setScanCodeInfo(ScanCodeInfo scanCodeInfo) { - this.scanCodeInfo = scanCodeInfo; - } - - public SendPicsInfo getSendPicsInfo() { - return this.sendPicsInfo; - } - - public void setSendPicsInfo(SendPicsInfo sendPicsInfo) { - this.sendPicsInfo = sendPicsInfo; - } - - public SendLocationInfo getSendLocationInfo() { - return this.sendLocationInfo; - } - - public void setSendLocationInfo( - SendLocationInfo sendLocationInfo) { - this.sendLocationInfo = sendLocationInfo; - } - - public Long getMenuId() { - return this.menuId; - } - - public void setMenuId(Long menuId) { - this.menuId = menuId; - } - - public String getKfAccount() { - return this.kfAccount; - } - - public void setKfAccount(String kfAccount) { - this.kfAccount = kfAccount; - } - - public String getToKfAccount() { - return this.toKfAccount; - } - - public void setToKfAccount(String toKfAccount) { - this.toKfAccount = toKfAccount; - } - - public String getFromKfAccount() { - return this.fromKfAccount; - } - - public void setFromKfAccount(String fromKfAccount) { - this.fromKfAccount = fromKfAccount; - } - - public String getIsRestoreMemberCard() { - return isRestoreMemberCard; - } - - public void setIsRestoreMemberCard(String isRestoreMemberCard) { - this.isRestoreMemberCard = isRestoreMemberCard; - } - - public String getOuterStr() { - return outerStr; - } - - public void setOuterStr(String outerStr) { - this.outerStr = outerStr; - } - - public String getIsReturnBack() { - return isReturnBack; - } - - public void setIsReturnBack(String isReturnBack) { - this.isReturnBack = isReturnBack; - } - - public String getIsChatRoom() { - return isChatRoom; - } - - public void setIsChatRoom(String isChatRoom) { - this.isChatRoom = isChatRoom; - } - - public String getConsumeSource() { - return this.consumeSource; - } - - public void setConsumeSource(String consumeSource) { - this.consumeSource = consumeSource; - } - - public String getLocationName() { - return this.locationName; - } - - public void setLocationName(String locationName) { - this.locationName = locationName; - } - - public String getStaffOpenId() { - return this.staffOpenId; - } - - public void setStaffOpenId(String staffOpenId) { - this.staffOpenId = staffOpenId; - } - - public String getVerifyCode() { - return this.verifyCode; - } - - public void setVerifyCode(String verifyCode) { - this.verifyCode = verifyCode; - } - - public String getRemarkAmount() { - return this.remarkAmount; - } - - public void setRemarkAmount(String remarkAmount) { - this.remarkAmount = remarkAmount; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java index c18508b527..dbb0ab90f9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessage.java @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = -2684778597067990723L; @@ -14,15 +18,7 @@ public class WxMpXmlOutImageMessage extends WxMpXmlOutMessage { private String mediaId; public WxMpXmlOutImageMessage() { - this.msgType = WxConsts.XML_MSG_IMAGE; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; + this.msgType = WxConsts.XmlMsgType.IMAGE; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java index c84cc665b9..b1940fc487 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMessage.java @@ -2,6 +2,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.builder.outxml.*; @@ -11,6 +12,7 @@ import java.io.Serializable; @XStreamAlias("xml") +@Data public abstract class WxMpXmlOutMessage implements Serializable { private static final long serialVersionUID = -381382011286216263L; @@ -78,38 +80,6 @@ public static TransferCustomerServiceBuilder TRANSFER_CUSTOMER_SERVICE() { return new TransferCustomerServiceBuilder(); } - public String getToUserName() { - return this.toUserName; - } - - public void setToUserName(String toUserName) { - this.toUserName = toUserName; - } - - public String getFromUserName() { - return this.fromUserName; - } - - public void setFromUserName(String fromUserName) { - this.fromUserName = fromUserName; - } - - public Long getCreateTime() { - return this.createTime; - } - - public void setCreateTime(Long createTime) { - this.createTime = createTime; - } - - public String getMsgType() { - return this.msgType; - } - - public void setMsgType(String msgType) { - this.msgType = msgType; - } - @SuppressWarnings("unchecked") public String toXml() { return XStreamTransformer.toXml((Class) this.getClass(), this); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessage.java index 2676e69077..1124f45857 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessage.java @@ -2,10 +2,16 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import java.io.Serializable; + @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxMpXmlOutMusicMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = -4159937804975448945L; @@ -13,51 +19,13 @@ public class WxMpXmlOutMusicMessage extends WxMpXmlOutMessage { protected final Music music = new Music(); public WxMpXmlOutMusicMessage() { - this.msgType = WxConsts.XML_MSG_MUSIC; - } - - public String getTitle() { - return this.music.getTitle(); - } - - public void setTitle(String title) { - this.music.setTitle(title); - } - - public String getDescription() { - return this.music.getDescription(); - } - - public void setDescription(String description) { - this.music.setDescription(description); - } - - public String getThumbMediaId() { - return this.music.getThumbMediaId(); - } - - public void setThumbMediaId(String thumbMediaId) { - this.music.setThumbMediaId(thumbMediaId); - } - - public String getMusicUrl() { - return this.music.getMusicUrl(); - } - - public void setMusicUrl(String musicUrl) { - this.music.setMusicUrl(musicUrl); - } - - public String getHqMusicUrl() { - return this.music.getHqMusicUrl(); - } - - public void setHqMusicUrl(String hqMusicUrl) { - this.music.setHqMusicUrl(hqMusicUrl); + this.msgType = WxConsts.XmlMsgType.MUSIC; } @XStreamAlias("Music") - public static class Music { + @Data + public static class Music implements Serializable { + private static final long serialVersionUID = -5492592401691895334L; @XStreamAlias("Title") @XStreamConverter(value = XStreamCDataConverter.class) @@ -78,47 +46,46 @@ public static class Music { @XStreamAlias("HQMusicUrl") @XStreamConverter(value = XStreamCDataConverter.class) private String hqMusicUrl; + } - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } + public String getTitle() { + return this.music.title; + } - public String getDescription() { - return this.description; - } + public void setTitle(String title) { + this.music.title = title; + } - public void setDescription(String description) { - this.description = description; - } + public String getDescription() { + return this.music.description; + } - public String getThumbMediaId() { - return this.thumbMediaId; - } + public void setDescription(String description) { + this.music.description = description; + } - public void setThumbMediaId(String thumbMediaId) { - this.thumbMediaId = thumbMediaId; - } + public String getThumbMediaId() { + return this.music.thumbMediaId; + } - public String getMusicUrl() { - return this.musicUrl; - } + public void setThumbMediaId(String thumbMediaId) { + this.music.thumbMediaId = thumbMediaId; + } - public void setMusicUrl(String musicUrl) { - this.musicUrl = musicUrl; - } + public String getMusicUrl() { + return this.music.musicUrl; + } - public String getHqMusicUrl() { - return this.hqMusicUrl; - } + public void setMusicUrl(String musicUrl) { + this.music.musicUrl = musicUrl; + } - public void setHqMusicUrl(String hqMusicUrl) { - this.hqMusicUrl = hqMusicUrl; - } + public String getHqMusicUrl() { + return this.music.hqMusicUrl; + } + public void setHqMusicUrl(String hqMusicUrl) { + this.music.hqMusicUrl = hqMusicUrl; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java index 797b042525..f7405600ef 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java @@ -2,6 +2,8 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; @@ -10,6 +12,8 @@ import java.util.List; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = -4604402850905714772L; @@ -19,11 +23,7 @@ public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage { protected int articleCount; public WxMpXmlOutNewsMessage() { - this.msgType = WxConsts.XML_MSG_NEWS; - } - - public int getArticleCount() { - return this.articleCount; + this.msgType = WxConsts.XmlMsgType.NEWS; } public void addArticle(Item item) { @@ -31,63 +31,26 @@ public void addArticle(Item item) { this.articleCount = this.articles.size(); } - public List getArticles() { - return this.articles; - } - - @XStreamAlias("item") + @Data public static class Item implements Serializable { - private static final long serialVersionUID = -4971456355028904754L; @XStreamAlias("Title") @XStreamConverter(value = XStreamCDataConverter.class) - private String Title; + private String title; @XStreamAlias("Description") @XStreamConverter(value = XStreamCDataConverter.class) - private String Description; + private String description; @XStreamAlias("PicUrl") @XStreamConverter(value = XStreamCDataConverter.class) - private String PicUrl; + private String picUrl; @XStreamAlias("Url") @XStreamConverter(value = XStreamCDataConverter.class) - private String Url; - - public String getTitle() { - return this.Title; - } - - public void setTitle(String title) { - this.Title = title; - } - - public String getDescription() { - return this.Description; - } - - public void setDescription(String description) { - this.Description = description; - } - - public String getPicUrl() { - return this.PicUrl; - } - - public void setPicUrl(String picUrl) { - this.PicUrl = picUrl; - } - - public String getUrl() { - return this.Url; - } - - public void setUrl(String url) { - this.Url = url; - } + private String url; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java index 7c98c625e7..cbaa05abc3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessage.java @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxMpXmlOutTextMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = -3972786455288763361L; @@ -14,16 +18,7 @@ public class WxMpXmlOutTextMessage extends WxMpXmlOutMessage { private String content; public WxMpXmlOutTextMessage() { - this.msgType = WxConsts.XML_MSG_TEXT; + this.msgType = WxConsts.XmlMsgType.TEXT; } - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java index 3a3cfc4b4c..5b0857830e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTransferKefuMessage.java @@ -2,12 +2,16 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; import java.io.Serializable; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxMpXmlOutTransferKefuMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = 1850903037285841322L; @@ -15,18 +19,11 @@ public class WxMpXmlOutTransferKefuMessage extends WxMpXmlOutMessage { protected TransInfo transInfo; public WxMpXmlOutTransferKefuMessage() { - this.msgType = WxConsts.CUSTOM_MSG_TRANSFER_CUSTOMER_SERVICE; - } - - public TransInfo getTransInfo() { - return this.transInfo; - } - - public void setTransInfo(TransInfo transInfo) { - this.transInfo = transInfo; + this.msgType = WxConsts.KefuMsgType.TRANSFER_CUSTOMER_SERVICE; } @XStreamAlias("TransInfo") + @Data public static class TransInfo implements Serializable { private static final long serialVersionUID = -6317885617135706056L; @@ -34,12 +31,5 @@ public static class TransInfo implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) private String kfAccount; - public String getKfAccount() { - return this.kfAccount; - } - - public void setKfAccount(String kfAccount) { - this.kfAccount = kfAccount; - } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessage.java index 346cd5b160..7f43a56809 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessage.java @@ -2,12 +2,16 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; import java.io.Serializable; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxMpXmlOutVideoMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = 1745902309380113978L; @@ -15,35 +19,11 @@ public class WxMpXmlOutVideoMessage extends WxMpXmlOutMessage { protected final Video video = new Video(); public WxMpXmlOutVideoMessage() { - this.msgType = WxConsts.XML_MSG_VIDEO; + this.msgType = WxConsts.XmlMsgType.VIDEO; } - public String getMediaId() { - return this.video.getMediaId(); - } - - public void setMediaId(String mediaId) { - this.video.setMediaId(mediaId); - } - - public String getTitle() { - return this.video.getTitle(); - } - - public void setTitle(String title) { - this.video.setTitle(title); - } - - public String getDescription() { - return this.video.getDescription(); - } - - public void setDescription(String description) { - this.video.setDescription(description); - } - - @XStreamAlias("Video") + @Data public static class Video implements Serializable { private static final long serialVersionUID = -6445448977569651183L; @@ -59,30 +39,29 @@ public static class Video implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) private String description; - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } + } - public String getTitle() { - return this.title; - } + public String getMediaId() { + return this.video.mediaId; + } - public void setTitle(String title) { - this.title = title; - } + public void setMediaId(String mediaId) { + this.video.mediaId = mediaId; + } - public String getDescription() { - return this.description; - } + public String getTitle() { + return this.video.title; + } - public void setDescription(String description) { - this.description = description; - } + public void setTitle(String title) { + this.video.title = title; + } + public String getDescription() { + return this.video.description; } + public void setDescription(String description) { + this.video.description = description; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java index a810e5a0f1..bd91b861ee 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessage.java @@ -2,10 +2,14 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter; @XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = 240367390249860551L; @@ -14,15 +18,7 @@ public class WxMpXmlOutVoiceMessage extends WxMpXmlOutMessage { private String mediaId; public WxMpXmlOutVoiceMessage() { - this.msgType = WxConsts.XML_MSG_VOICE; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; + this.msgType = WxConsts.XmlMsgType.VOICE; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java index 5684557bea..7cbf9b7f10 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java @@ -1,16 +1,20 @@ package me.chanjar.weixin.mp.bean.result; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.bean.WxMpCard; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.bean.WxMpCard; + /** * 卡券查询Code,核销Code接口返回结果 * * @author YuJian * @version 15/11/11 */ +@Data public class WxMpCardResult implements Serializable { private static final long serialVersionUID = -7950878428289035637L; @@ -26,57 +30,9 @@ public class WxMpCardResult implements Serializable { private Boolean canConsume; - public String getErrorCode() { - return this.errorCode; - } - - public void setErrorCode(String errorCode) { - this.errorCode = errorCode; - } - - public String getErrorMsg() { - return this.errorMsg; - } - - public void setErrorMsg(String errorMsg) { - this.errorMsg = errorMsg; - } - - public String getOpenId() { - return this.openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public WxMpCard getCard() { - return this.card; - } - - public void setCard(WxMpCard card) { - this.card = card; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getUserCardStatus() { - return this.userCardStatus; - } - - public void setUserCardStatus(String userCardStatus) { - this.userCardStatus = userCardStatus; - } - - public Boolean getCanConsume() { - return this.canConsume; - } - - public void setCanConsume(Boolean canConsume) { - this.canConsume = canConsume; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfo.java index 563dc6aca8..d68fcacfe8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfo.java @@ -1,29 +1,34 @@ package me.chanjar.weixin.mp.bean.result; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.common.util.json.WxBooleanTypeAdapter; import me.chanjar.weixin.common.util.json.WxDateTypeAdapter; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; -import java.util.Date; -import java.util.List; - /** *
- * 公众号的自动回复规则
+ * 公众号的自动回复规则.
  * Created by Binary Wang on 2017-7-8.
- * @author Binary Wang
  * 
+ * + * @author Binary Wang */ +@Data public class WxMpCurrentAutoReplyInfo implements Serializable { private static final long serialVersionUID = 8294705001262751638L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public static WxMpCurrentAutoReplyInfo fromJson(String json) { @@ -47,52 +52,13 @@ public static WxMpCurrentAutoReplyInfo fromJson(String json) { @SerializedName("keyword_autoreply_info") private KeywordAutoReplyInfo keywordAutoReplyInfo; - public Boolean getAddFriendReplyOpen() { - return this.isAddFriendReplyOpen; - } - - public void setAddFriendReplyOpen(Boolean addFriendReplyOpen) { - isAddFriendReplyOpen = addFriendReplyOpen; - } - - public Boolean getAutoReplyOpen() { - return this.isAutoReplyOpen; - } - - public void setAutoReplyOpen(Boolean autoReplyOpen) { - isAutoReplyOpen = autoReplyOpen; - } - - public AutoReplyInfo getAddFriendAutoReplyInfo() { - return this.addFriendAutoReplyInfo; - } - - public void setAddFriendAutoReplyInfo(AutoReplyInfo addFriendAutoReplyInfo) { - this.addFriendAutoReplyInfo = addFriendAutoReplyInfo; - } - - public AutoReplyInfo getMessageDefaultAutoReplyInfo() { - return this.messageDefaultAutoReplyInfo; - } - - public void setMessageDefaultAutoReplyInfo(AutoReplyInfo messageDefaultAutoReplyInfo) { - this.messageDefaultAutoReplyInfo = messageDefaultAutoReplyInfo; - } - - public KeywordAutoReplyInfo getKeywordAutoReplyInfo() { - return this.keywordAutoReplyInfo; - } - - public void setKeywordAutoReplyInfo(KeywordAutoReplyInfo keywordAutoReplyInfo) { - this.keywordAutoReplyInfo = keywordAutoReplyInfo; - } - + @Data public static class AutoReplyRule implements Serializable { private static final long serialVersionUID = -6415971838145909046L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } @SerializedName("rule_name") @@ -111,53 +77,15 @@ public String toString() { @SerializedName("reply_list_info") private List replyListInfo; - public String getRuleName() { - return this.ruleName; - } - - public void setRuleName(String ruleName) { - this.ruleName = ruleName; - } - - public Date getCreateTime() { - return this.createTime; - } - - public void setCreateTime(Date createTime) { - this.createTime = createTime; - } - - public String getReplyMode() { - return this.replyMode; - } - - public void setReplyMode(String replyMode) { - this.replyMode = replyMode; - } - - public List getKeywordListInfo() { - return this.keywordListInfo; - } - - public void setKeywordListInfo(List keywordListInfo) { - this.keywordListInfo = keywordListInfo; - } - - public List getReplyListInfo() { - return this.replyListInfo; - } - - public void setReplyListInfo(List replyListInfo) { - this.replyListInfo = replyListInfo; - } } + @Data public static class ReplyInfo implements Serializable { private static final long serialVersionUID = -3429575601599101690L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } private String type; @@ -166,56 +94,28 @@ public String toString() { @SerializedName("news_info") private NewsInfo newsInfo; - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public NewsInfo getNewsInfo() { - return this.newsInfo; - } - - public void setNewsInfo(NewsInfo newsInfo) { - this.newsInfo = newsInfo; - } } + @Data public static class NewsInfo implements Serializable { private static final long serialVersionUID = 2958827725972593328L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } private List list; - public List getList() { - return this.list; - } - - public void setList(List list) { - this.list = list; - } } + @Data public static class NewsItem implements Serializable { private static final long serialVersionUID = -680356309029767176L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } @SerializedName("cover_url") @@ -231,69 +131,15 @@ public String toString() { private String sourceUrl; private String title; - public String getCoverUrl() { - return this.coverUrl; - } - - public void setCoverUrl(String coverUrl) { - this.coverUrl = coverUrl; - } - - public String getAuthor() { - return this.author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getContentUrl() { - return this.contentUrl; - } - - public void setContentUrl(String contentUrl) { - this.contentUrl = contentUrl; - } - - public String getDigest() { - return this.digest; - } - - public void setDigest(String digest) { - this.digest = digest; - } - - public Boolean getShowCover() { - return this.showCover; - } - - public void setShowCover(Boolean showCover) { - this.showCover = showCover; - } - - public String getSourceUrl() { - return this.sourceUrl; - } - - public void setSourceUrl(String sourceUrl) { - this.sourceUrl = sourceUrl; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } } + @Data public static class KeywordInfo implements Serializable { private static final long serialVersionUID = 7720246983986706379L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } private String type; @@ -301,76 +147,31 @@ public String toString() { private String matchMode; private String content; - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getMatchMode() { - return this.matchMode; - } - - public void setMatchMode(String matchMode) { - this.matchMode = matchMode; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } } + @Data public static class KeywordAutoReplyInfo implements Serializable { private static final long serialVersionUID = -8789197949404753083L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } private List list; - - public List getList() { - return this.list; - } - - public void setList(List list) { - this.list = list; - } } + @Data public static class AutoReplyInfo implements Serializable { private static final long serialVersionUID = 4993719555937843712L; @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } private String type; private String content; - - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassSendResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassSendResult.java index 56cfd13d97..392cc046c8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassSendResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassSendResult.java @@ -1,10 +1,13 @@ package me.chanjar.weixin.mp.bean.result; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** *
  * 群发消息一发送就返回的结果
@@ -16,6 +19,7 @@
  *
  * @author chanjarster
  */
+@Data
 public class WxMpMassSendResult implements Serializable {
   private static final long serialVersionUID = -4816336807575562818L;
 
@@ -28,41 +32,9 @@ public static WxMpMassSendResult fromJson(String json) {
     return WxMpGsonBuilder.create().fromJson(json, WxMpMassSendResult.class);
   }
 
-  public String getErrorCode() {
-    return this.errorCode;
-  }
-
-  public void setErrorCode(String errorCode) {
-    this.errorCode = errorCode;
-  }
-
-  public String getErrorMsg() {
-    return this.errorMsg;
-  }
-
-  public void setErrorMsg(String errorMsg) {
-    this.errorMsg = errorMsg;
-  }
-
-  public String getMsgId() {
-    return this.msgId;
-  }
-
-  public void setMsgId(String msgId) {
-    this.msgId = msgId;
-  }
-
-  public String getMsgDataId() {
-    return this.msgDataId;
-  }
-
-  public void setMsgDataId(String msgDataId) {
-    this.msgDataId = msgDataId;
-  }
-
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassUploadResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassUploadResult.java
index f8ca889652..984108917c 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassUploadResult.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpMassUploadResult.java
@@ -1,18 +1,22 @@
 package me.chanjar.weixin.mp.bean.result;
 
-import me.chanjar.weixin.common.util.ToStringUtils;
-import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
-
 import java.io.Serializable;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
 /**
  * 
- * 上传群发用的素材的结果
+ * 上传群发用的素材的结果.
  * 视频和图文消息需要在群发前上传素材
  * 
* * @author chanjarster */ +@Data public class WxMpMassUploadResult implements Serializable { private static final long serialVersionUID = 6568157943644994029L; @@ -24,33 +28,9 @@ public static WxMpMassUploadResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxMpMassUploadResult.class); } - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getMediaId() { - return this.mediaId; - } - - public void setMediaId(String mediaId) { - this.mediaId = mediaId; - } - - public long getCreatedAt() { - return this.createdAt; - } - - public void setCreatedAt(long createdAt) { - this.createdAt = createdAt; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java index 3f49397975..33fa172dc6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java @@ -1,10 +1,17 @@ package me.chanjar.weixin.mp.bean.result; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 + */ +@Data public class WxMpOAuth2AccessToken implements Serializable { private static final long serialVersionUID = -1345910558078620805L; @@ -18,62 +25,18 @@ public class WxMpOAuth2AccessToken implements Serializable { private String scope; + /** + * https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN. + * 本接口在scope参数为snsapi_base时不再提供unionID字段。 + */ private String unionId; public static WxMpOAuth2AccessToken fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxMpOAuth2AccessToken.class); } - public String getRefreshToken() { - return this.refreshToken; - } - - public void setRefreshToken(String refreshToken) { - this.refreshToken = refreshToken; - } - - public String getOpenId() { - return this.openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public String getScope() { - return this.scope; - } - - public void setScope(String scope) { - this.scope = scope; - } - - public String getAccessToken() { - return this.accessToken; - } - - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - public int getExpiresIn() { - return this.expiresIn; - } - - public void setExpiresIn(int expiresIn) { - this.expiresIn = expiresIn; - } - - public String getUnionId() { - return this.unionId; - } - - public void setUnionId(String unionId) { - this.unionId = unionId; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java index 7ba6151c3e..ee78096b33 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpQrCodeTicket.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean.result; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -9,44 +10,21 @@ * * @author chanjarster */ +@Data public class WxMpQrCodeTicket implements Serializable { private static final long serialVersionUID = 5777119669111011584L; protected String ticket; - protected int expire_seconds = -1; + /** + * 如果为-1,说明是永久 + */ + protected int expireSeconds = -1; protected String url; public static WxMpQrCodeTicket fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpQrCodeTicket.class); } - public String getTicket() { - return this.ticket; - } - - public void setTicket(String ticket) { - this.ticket = ticket; - } - - /** - * 如果返回-1说明是永久 - */ - public int getExpire_seconds() { - return this.expire_seconds; - } - - public void setExpire_seconds(int expire_seconds) { - this.expire_seconds = expire_seconds; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - @Override public String toString() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java index 723ea7adc9..5c2962b82a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean.result; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -11,6 +12,7 @@ * * @author Daniel Qian */ +@Data public class WxMpSemanticQueryResult implements Serializable { private static final long serialVersionUID = 4811088544804441365L; @@ -25,52 +27,4 @@ public static WxMpSemanticQueryResult fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxMpSemanticQueryResult.class); } - public String getQuery() { - return this.query; - } - - public void setQuery(String query) { - this.query = query; - } - - public String getType() { - return this.type; - } - - public void setType(String type) { - this.type = type; - } - - public String getSemantic() { - return this.semantic; - } - - public void setSemantic(String semantic) { - this.semantic = semantic; - } - - public String getResult() { - return this.result; - } - - public void setResult(String result) { - this.result = result; - } - - public String getAnswer() { - return this.answer; - } - - public void setAnswer(String answer) { - this.answer = answer; - } - - public String getText() { - return this.text; - } - - public void setText(String text) { - this.text = text; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java index e9e2bae6c1..818c4c5f8a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java @@ -1,39 +1,80 @@ package me.chanjar.weixin.mp.bean.result; +import java.io.Serializable; +import java.lang.reflect.Type; +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; -import java.lang.reflect.Type; -import java.util.List; - /** - * 微信用户信息 + * 微信用户信息. * * @author chanjarster */ +@Data public class WxMpUser implements Serializable { private static final long serialVersionUID = 5788154322646488738L; private Boolean subscribe; private String openId; private String nickname; - private String sex; + /** + * 性别描述信息:男、女、未知等. + */ + private String sexDesc; + /** + * 性别表示:1,2等数字. + */ + private Integer sex; private String language; private String city; private String province; private String country; private String headImgUrl; private Long subscribeTime; + /** + * https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN + *
+   * 只有在将公众号绑定到微信开放平台帐号后,才会出现该字段。
+   * 另外,在用户未关注公众号时,将不返回用户unionID信息。
+   * 已关注的用户,开发者可使用“获取用户基本信息接口”获取unionID;
+   * 未关注用户,开发者可使用“微信授权登录接口”并将scope参数设置为snsapi_userinfo,获取用户unionID
+   * 
+ */ private String unionId; - private Integer sexId; private String remark; private Integer groupId; private Long[] tagIds; + /** + * 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom). + */ + private String[] privileges; + + /** + * subscribe_scene 返回用户关注的渠道来源. + * ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENEPROFILE LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_OTHERS 其他 + */ + private String subscribeScene; + + /** + * qr_scene 二维码扫码场景(开发者自定义). + */ + private String qrScene; + + /** + * qr_scene_str 二维码扫码场景描述(开发者自定义). + */ + private String qrSceneStr; + + public static WxMpUser fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUser.class); } @@ -46,133 +87,9 @@ public static List fromJsonList(String json) { return gson.fromJson(jsonObject.get("user_info_list"), collectionType); } - public Boolean getSubscribe() { - return this.subscribe; - } - - public void setSubscribe(Boolean subscribe) { - this.subscribe = subscribe; - } - - public String getOpenId() { - return this.openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public String getNickname() { - return this.nickname; - } - - public void setNickname(String nickname) { - this.nickname = nickname; - } - - public String getSex() { - return this.sex; - } - - public void setSex(String sex) { - this.sex = sex; - } - - public String getLanguage() { - return this.language; - } - - public void setLanguage(String language) { - this.language = language; - } - - public String getCity() { - return this.city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getProvince() { - return this.province; - } - - public void setProvince(String province) { - this.province = province; - } - - public String getCountry() { - return this.country; - } - - public void setCountry(String country) { - this.country = country; - } - - public String getHeadImgUrl() { - return this.headImgUrl; - } - - public void setHeadImgUrl(String headImgUrl) { - this.headImgUrl = headImgUrl; - } - - public Long getSubscribeTime() { - return this.subscribeTime; - } - - public void setSubscribeTime(Long subscribeTime) { - this.subscribeTime = subscribeTime; - } - - /** - * 只有在将公众号绑定到微信开放平台帐号后,才会出现该字段。 - */ - public String getUnionId() { - return this.unionId; - } - - public void setUnionId(String unionId) { - this.unionId = unionId; - } - - public Integer getSexId() { - - return this.sexId; - } - - public void setSexId(Integer sexId) { - this.sexId = sexId; - } - - public String getRemark() { - return this.remark; - } - - public void setRemark(String remark) { - this.remark = remark; - } - - public Integer getGroupId() { - return this.groupId; - } - - public void setGroupId(Integer groupId) { - this.groupId = groupId; - } - - public Long[] getTagIds() { - return this.tagIds; - } - - public void setTagIds(Long[] tagIds) { - this.tagIds = tagIds; - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserBlacklistGetResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserBlacklistGetResult.java index 5fe0a9448b..83e1e24424 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserBlacklistGetResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserBlacklistGetResult.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean.result; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -9,6 +10,7 @@ /** * @author miller */ +@Data public class WxMpUserBlacklistGetResult implements Serializable { private static final long serialVersionUID = -8780216463588687626L; @@ -21,38 +23,6 @@ public static WxMpUserBlacklistGetResult fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUserBlacklistGetResult.class); } - public int getTotal() { - return this.total; - } - - public void setTotal(int total) { - this.total = total; - } - - public int getCount() { - return this.count; - } - - public void setCount(int count) { - this.count = count; - } - - public List getOpenidList() { - return this.openidList; - } - - public void setOpenidList(List openidList) { - this.openidList = openidList; - } - - public String getNextOpenid() { - return this.nextOpenid; - } - - public void setNextOpenid(String nextOpenid) { - this.nextOpenid = nextOpenid; - } - @Override public String toString() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java index 6e367aeca1..5f816456e1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUserList.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.mp.bean.result; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -11,6 +12,7 @@ * * @author chanjarster */ +@Data public class WxMpUserList implements Serializable { private static final long serialVersionUID = 1389073042674901032L; @@ -23,38 +25,6 @@ public static WxMpUserList fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUserList.class); } - public long getTotal() { - return this.total; - } - - public void setTotal(long total) { - this.total = total; - } - - public int getCount() { - return this.count; - } - - public void setCount(int count) { - this.count = count; - } - - public List getOpenids() { - return this.openids; - } - - public void setOpenids(List openids) { - this.openids = openids; - } - - public String getNextOpenid() { - return this.nextOpenid; - } - - public void setNextOpenid(String nextOpenid) { - this.nextOpenid = nextOpenid; - } - @Override public String toString() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java new file mode 100644 index 0000000000..e93bf75cf9 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpDeviceIdentifier.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpDeviceIdentifier implements Serializable { + private Integer device_id; + private String uuid; + private Integer page_id; + private Integer major; + private Integer minor; + public JsonObject toJsonObject(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("device_id", device_id); + jsonObject.addProperty("uuid", uuid); + jsonObject.addProperty("major", major); + jsonObject.addProperty("minor", minor); + return jsonObject; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java new file mode 100644 index 0000000000..71da0b1c65 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundDeviceBindPageQuery.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.Data; + +import java.util.Collection; + +@Data +public class WxMpShakeAroundDeviceBindPageQuery { + private WxMpDeviceIdentifier deviceIdentifier; + private Collection pageIds; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + JsonArray jsonArray = new JsonArray(); + for(Integer pageid: pageIds){ + jsonArray.add(pageid); + } + jsonObject.add("page_ids", jsonArray); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java new file mode 100644 index 0000000000..b04ced93bd --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddQuery.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; +@Data +public class WxMpShakeAroundPageAddQuery implements Serializable { + private String title; + private String description; + private String pageUrl; + private String comment; + private String iconUrl; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("title", title); + jsonObject.addProperty("description", description); + jsonObject.addProperty("page_url", pageUrl); + jsonObject.addProperty("comment", comment); + jsonObject.addProperty("icon_url", iconUrl); + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java new file mode 100644 index 0000000000..632fe4f351 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundPageAddResult.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundPageAddResult implements Serializable { + private Integer errorCode; + private String errorMsg; + private Integer pageId; + public static WxMpShakeAroundPageAddResult fromJson(String json) { + JsonObject jsonObject = WxMpGsonBuilder.INSTANCE.create().fromJson(json, JsonObject.class); + WxMpShakeAroundPageAddResult result = new WxMpShakeAroundPageAddResult(); + result.setErrorCode(GsonHelper.getInteger(jsonObject, "errcode")); + result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); + jsonObject = jsonObject.getAsJsonObject("data"); + if(jsonObject != null){ + result.setPageId(GsonHelper.getInteger(jsonObject, "page_id")); + } + return result; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java new file mode 100644 index 0000000000..390fe50964 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchQuery.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.mp.bean.shake; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMpShakeAroundRelationSearchQuery implements Serializable { + private int type; + private Integer pageId; + private Integer begin; + private Integer count; + private WxMpDeviceIdentifier deviceIdentifier; + public String toJsonString(){ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("type", type); + switch (type){ + case 1: + jsonObject.add("device_identifier", deviceIdentifier.toJsonObject()); + break; + case 2: + jsonObject.addProperty("page_id", pageId); + jsonObject.addProperty("begin", begin); + jsonObject.addProperty("count", count); + break; + default: + throw new IllegalArgumentException("type error"); + } + return jsonObject.toString(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java new file mode 100644 index 0000000000..2b7269e572 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/shake/WxMpShakeAroundRelationSearchResult.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.mp.bean.shake; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +public class WxMpShakeAroundRelationSearchResult implements Serializable { + private Integer errcode; + private String errmsg; + private WxMpShakeAcoundRelationSearch data; + public static WxMpShakeAroundRelationSearchResult fromJson(String json) { + return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpShakeAroundRelationSearchResult.class); + } + @Data + public static class WxMpShakeAcoundRelationSearch implements Serializable{ + private List relations; + private Integer total_count; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java index 155942a79b..03f814af69 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreBaseInfo.java @@ -1,24 +1,30 @@ package me.chanjar.weixin.mp.bean.store; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; import me.chanjar.weixin.common.annotation.Required; -import me.chanjar.weixin.common.util.ToStringUtils; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; -import java.math.BigDecimal; -import java.util.List; - /** *
  *  门店基础信息
  *  Created by Binary Wang on 2016-09-23.
  * 
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data +@Builder public class WxMpStoreBaseInfo implements Serializable { private static final long serialVersionUID = 829577606838118218L; @@ -96,7 +102,8 @@ public class WxMpStoreBaseInfo implements Serializable { */ @Required @SerializedName("offset_type") - private Integer offsetType = 1; + @Builder.Default + private final Integer offsetType = 1; /** * longitude * 门店所在地理位置的经度 @@ -170,192 +177,21 @@ public static WxMpStoreBaseInfo fromJson(String json) { return WxMpGsonBuilder.create().fromJson(json, WxMpStoreBaseInfo.class); } - public static WxMpStoreBaseInfoBuilder builder() { - return new WxMpStoreBaseInfoBuilder(); - } - @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public String toJson() { - JsonElement base_info = WxMpGsonBuilder.create().toJsonTree(this); + JsonElement baseInfo = WxMpGsonBuilder.create().toJsonTree(this); JsonObject jsonObject = new JsonObject(); - jsonObject.add("base_info", base_info); + jsonObject.add("base_info", baseInfo); JsonObject business = new JsonObject(); business.add("business", jsonObject); return business.toString(); } - public String getSid() { - return this.sid; - } - - public void setSid(String sid) { - this.sid = sid; - } - - public String getBusinessName() { - return this.businessName; - } - - public void setBusinessName(String businessName) { - this.businessName = businessName; - } - - public String getBranchName() { - return this.branchName; - } - - public void setBranchName(String branchName) { - this.branchName = branchName; - } - - public String getProvince() { - return this.province; - } - - public void setProvince(String province) { - this.province = province; - } - - public String getCity() { - return this.city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getDistrict() { - return this.district; - } - - public void setDistrict(String district) { - this.district = district; - } - - public String getAddress() { - return this.address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getTelephone() { - return this.telephone; - } - - public void setTelephone(String telephone) { - this.telephone = telephone; - } - - public String[] getCategories() { - return this.categories; - } - - public void setCategories(String[] categories) { - this.categories = categories; - } - - public Integer getOffsetType() { - return this.offsetType; - } - - public void setOffsetType(Integer offsetType) { - this.offsetType = offsetType; - } - - public BigDecimal getLongitude() { - return this.longitude; - } - - public void setLongitude(BigDecimal longitude) { - this.longitude = longitude; - } - - public BigDecimal getLatitude() { - return this.latitude; - } - - public void setLatitude(BigDecimal latitude) { - this.latitude = latitude; - } - - public List getPhotos() { - return this.photos; - } - - public void setPhotos(List photos) { - this.photos = photos; - } - - public String getRecommend() { - return this.recommend; - } - - public void setRecommend(String recommend) { - this.recommend = recommend; - } - - public String getSpecial() { - return this.special; - } - - public void setSpecial(String special) { - this.special = special; - } - - public String getIntroduction() { - return this.introduction; - } - - public void setIntroduction(String introduction) { - this.introduction = introduction; - } - - public String getOpenTime() { - return this.openTime; - } - - public void setOpenTime(String openTime) { - this.openTime = openTime; - } - - public Integer getAvgPrice() { - return this.avgPrice; - } - - public void setAvgPrice(Integer avgPrice) { - this.avgPrice = avgPrice; - } - - public Integer getAvailableState() { - return this.availableState; - } - - public void setAvailableState(Integer availableState) { - this.availableState = availableState; - } - - public Integer getUpdateStatus() { - return this.updateStatus; - } - - public void setUpdateStatus(Integer updateStatus) { - this.updateStatus = updateStatus; - } - - public String getPoiId() { - return this.poiId; - } - - public void setPoiId(String poiId) { - this.poiId = poiId; - } - + @Data public static class WxMpStorePhoto implements Serializable { private static final long serialVersionUID = -2942447907614186861L; /** @@ -364,193 +200,6 @@ public static class WxMpStorePhoto implements Serializable { @SerializedName("photo_url") private String photoUrl; - public String getPhotoUrl() { - return photoUrl; - } - - public void setPhotoUrl(String photoUrl) { - this.photoUrl = photoUrl; - } - } - - public static class WxMpStoreBaseInfoBuilder { - private String sid; - private String businessName; - private String branchName; - private String province; - private String city; - private String district; - private String address; - private String telephone; - private String[] categories; - private Integer offsetType; - private BigDecimal longitude; - private BigDecimal latitude; - private List photos; - private String recommend; - private String special; - private String introduction; - private String openTime; - private Integer avgPrice; - private Integer availableState; - private Integer updateStatus; - private String poiId; - - public WxMpStoreBaseInfoBuilder sid(String sid) { - this.sid = sid; - return this; - } - - public WxMpStoreBaseInfoBuilder businessName(String businessName) { - this.businessName = businessName; - return this; - } - - public WxMpStoreBaseInfoBuilder branchName(String branchName) { - this.branchName = branchName; - return this; - } - - public WxMpStoreBaseInfoBuilder province(String province) { - this.province = province; - return this; - } - - public WxMpStoreBaseInfoBuilder city(String city) { - this.city = city; - return this; - } - - public WxMpStoreBaseInfoBuilder district(String district) { - this.district = district; - return this; - } - - public WxMpStoreBaseInfoBuilder address(String address) { - this.address = address; - return this; - } - - public WxMpStoreBaseInfoBuilder telephone(String telephone) { - this.telephone = telephone; - return this; - } - - public WxMpStoreBaseInfoBuilder categories(String[] categories) { - this.categories = categories; - return this; - } - - public WxMpStoreBaseInfoBuilder offsetType(Integer offsetType) { - this.offsetType = offsetType; - return this; - } - - public WxMpStoreBaseInfoBuilder longitude(BigDecimal longitude) { - this.longitude = longitude; - return this; - } - - public WxMpStoreBaseInfoBuilder latitude(BigDecimal latitude) { - this.latitude = latitude; - return this; - } - - public WxMpStoreBaseInfoBuilder photos(List photos) { - this.photos = photos; - return this; - } - - public WxMpStoreBaseInfoBuilder recommend(String recommend) { - this.recommend = recommend; - return this; - } - - public WxMpStoreBaseInfoBuilder special(String special) { - this.special = special; - return this; - } - - public WxMpStoreBaseInfoBuilder introduction(String introduction) { - this.introduction = introduction; - return this; - } - - public WxMpStoreBaseInfoBuilder openTime(String openTime) { - this.openTime = openTime; - return this; - } - - public WxMpStoreBaseInfoBuilder avgPrice(Integer avgPrice) { - this.avgPrice = avgPrice; - return this; - } - - public WxMpStoreBaseInfoBuilder availableState(Integer availableState) { - this.availableState = availableState; - return this; - } - - public WxMpStoreBaseInfoBuilder updateStatus(Integer updateStatus) { - this.updateStatus = updateStatus; - return this; - } - - public WxMpStoreBaseInfoBuilder poiId(String poiId) { - this.poiId = poiId; - return this; - } - - public WxMpStoreBaseInfoBuilder from(WxMpStoreBaseInfo origin) { - this.sid(origin.sid); - this.businessName(origin.businessName); - this.branchName(origin.branchName); - this.province(origin.province); - this.city(origin.city); - this.district(origin.district); - this.address(origin.address); - this.telephone(origin.telephone); - this.categories(origin.categories); - this.offsetType(origin.offsetType); - this.longitude(origin.longitude); - this.latitude(origin.latitude); - this.photos(origin.photos); - this.recommend(origin.recommend); - this.special(origin.special); - this.introduction(origin.introduction); - this.openTime(origin.openTime); - this.avgPrice(origin.avgPrice); - this.availableState(origin.availableState); - this.updateStatus(origin.updateStatus); - this.poiId(origin.poiId); - return this; - } - - public WxMpStoreBaseInfo build() { - WxMpStoreBaseInfo m = new WxMpStoreBaseInfo(); - m.sid = this.sid; - m.businessName = this.businessName; - m.branchName = this.branchName; - m.province = this.province; - m.city = this.city; - m.district = this.district; - m.address = this.address; - m.telephone = this.telephone; - m.categories = this.categories; - m.offsetType = this.offsetType; - m.longitude = this.longitude; - m.latitude = this.latitude; - m.photos = this.photos; - m.recommend = this.recommend; - m.special = this.special; - m.introduction = this.introduction; - m.openTime = this.openTime; - m.avgPrice = this.avgPrice; - m.availableState = this.availableState; - m.updateStatus = this.updateStatus; - m.poiId = this.poiId; - return m; - } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java index fcbb9aa5ea..3002e190cb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreInfo.java @@ -1,10 +1,17 @@ package me.chanjar.weixin.mp.bean.store; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +/** + * @author BinaryWang + */ +@Data public class WxMpStoreInfo implements Serializable{ private static final long serialVersionUID = 7300598931768355461L; @@ -13,15 +20,6 @@ public class WxMpStoreInfo implements Serializable{ @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - - public WxMpStoreBaseInfo getBaseInfo() { - return this.baseInfo; - } - - public void setBaseInfo(WxMpStoreBaseInfo baseInfo) { - this.baseInfo = baseInfo; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java index 6ebb58901f..079b5c1cad 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/store/WxMpStoreListResult.java @@ -1,40 +1,44 @@ package me.chanjar.weixin.mp.bean.store; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** *
  * 门店列表结果类
  * Created by Binary Wang on 2016-09-27.
  * 
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data public class WxMpStoreListResult implements Serializable { private static final long serialVersionUID = 5388907559949538663L; /** - * 错误码,0为正常 + * 错误码,0为正常. */ @SerializedName("errcode") private Integer errCode; /** - * 错误信息 + * 错误信息. */ @SerializedName("errmsg") private String errMsg; /** - * 门店信息列表 + * 门店信息列表. */ @SerializedName("business_list") private List businessList; /** - * 门店信息总数 + * 门店信息总数. */ @SerializedName("total_count") private Integer totalCount; @@ -45,39 +49,7 @@ public static WxMpStoreListResult fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public Integer getTotalCount() { - return this.totalCount; - } - - public void setTotalCount(Integer totalCount) { - this.totalCount = totalCount; - } - - public Integer getErrCode() { - return this.errCode; - } - - public void setErrCode(Integer errCode) { - this.errCode = errCode; - } - - public String getErrMsg() { - return this.errMsg; - } - - public void setErrMsg(String errMsg) { - this.errMsg = errMsg; - } - - public List getBusinessList() { - return this.businessList; - } - - public void setBusinessList(List businessList) { - this.businessList = businessList; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/subscribe/WxMpSubscribeMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/subscribe/WxMpSubscribeMessage.java new file mode 100644 index 0000000000..b6f1eef5a3 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/subscribe/WxMpSubscribeMessage.java @@ -0,0 +1,87 @@ +package me.chanjar.weixin.mp.bean.subscribe; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * @author Mklaus + * @date 2018-01-22 下午12:18 + */ +@Data +@NoArgsConstructor +@Builder +@AllArgsConstructor +public class WxMpSubscribeMessage { + + /** + * 接收者openid. + */ + private String toUser; + + /** + * 模板ID. + */ + private String templateId; + + /** + * 模板跳转链接. + *
+   * url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。
+   * 开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。
+   * 
+ */ + private String url; + + /** + * 跳小程序所需数据,不需跳小程序可不用传该数据. + * + * @see #url + */ + private MiniProgram miniProgram; + + /** + * 订阅场景值 + */ + private String scene; + + /** + * 消息标题 (15字以内) + */ + private String title; + + /** + * 消息内容文本 (200字以内) + */ + private String contentValue; + + /** + * 消息内容文本颜色 + */ + private String contentColor; + + + public String toJson() { + return WxMpGsonBuilder.INSTANCE.create().toJson(this); + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class MiniProgram implements Serializable { + private static final long serialVersionUID = -7945254706501974849L; + + private String appid; + private String pagePath; + + /** + * 是否使用path,否则使用pagepath. + * 加入此字段是基于微信官方接口变化多端的考虑 + */ + private boolean usePath = false; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java index a1bd50660e..d6606cf1f1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxTagListUser.java @@ -1,35 +1,39 @@ package me.chanjar.weixin.mp.bean.tag; -import com.google.gson.annotations.SerializedName; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** *
  * 获取标签下粉丝列表的结果对象
  * Created by Binary Wang on 2016-09-19.
  * 
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data public class WxTagListUser implements Serializable { private static final long serialVersionUID = -4551768374200676112L; /** - * "count":2,这次获取的粉丝数量 + * "count":2,这次获取的粉丝数量. */ @SerializedName("count") private Integer count; /** - * "data" 粉丝列表 + * "data" 粉丝列表. */ @SerializedName("data") private WxTagListUserData data; /** - * "next_openid" 拉取列表最后一个用户的openid + * "next_openid" 拉取列表最后一个用户的openid. */ @SerializedName("next_openid") private String nextOpenid; @@ -44,53 +48,22 @@ public String toJson() { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public Integer getCount() { - return this.count; - } - - public void setCount(Integer count) { - this.count = count; - } - - public WxTagListUserData getData() { - return this.data; - } - - public void setData(WxTagListUserData data) { - this.data = data; - } - - public String getNextOpenid() { - return this.nextOpenid; - } - - public void setNextOpenid(String nextOpenid) { - this.nextOpenid = nextOpenid; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } + @Data public static class WxTagListUserData implements Serializable { private static final long serialVersionUID = -8584537400336245701L; /** - * openid 列表 + * openid 列表. */ @SerializedName("openid") private List openidList; @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public List getOpenidList() { - return this.openidList; - } - - public void setOpenidList(List openidList) { - this.openidList = openidList; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java index a06a1ce40a..77251df24d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/tag/WxUserTag.java @@ -1,36 +1,40 @@ package me.chanjar.weixin.mp.bean.tag; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; -import java.util.List; - /** *
  *  用户标签对象
  *  Created by Binary Wang on 2016/9/2.
  * 
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data public class WxUserTag implements Serializable { private static final long serialVersionUID = -7722428695667031252L; /** - * id 标签id,由微信分配 + * 标签id,由微信分配. */ private Long id; /** - * name 标签名,UTF8编码 + * 标签名,UTF8编码. */ private String name; /** - * count 此标签下粉丝数 + * 此标签下粉丝数. */ private Integer count; @@ -47,36 +51,12 @@ public static List listFromJson(String json) { }.getType()); } - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getCount() { - return this.count; - } - - public void setCount(Integer count) { - this.count = count; - } - - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } - public String toJson() { return WxMpGsonBuilder.create().toJson(this); } @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java index 079210775a..5ccd89fd8e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplate.java @@ -1,58 +1,62 @@ package me.chanjar.weixin.mp.bean.template; +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + import com.google.gson.JsonParser; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; -import java.util.List; - /** *
  * 模板列表信息
  * Created by Binary Wang on 2016-10-17.
  * 
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data public class WxMpTemplate implements Serializable { private static final JsonParser JSON_PARSER = new JsonParser(); private static final long serialVersionUID = -7366474522571199372L; /** - * template_id + * template_id. * 模板ID */ @SerializedName("template_id") private String templateId; /** - * title + * title. * 模板标题 */ @SerializedName("title") private String title; /** - * primary_industry + * primary_industry. * 模板所属行业的一级行业 */ @SerializedName("primary_industry") private String primaryIndustry; /** - * deputy_industry + * deputy_industry. * 模板所属行业的二级行业 */ @SerializedName("deputy_industry") private String deputyIndustry; /** - * content + * content. * 模板内容 */ @SerializedName("content") private String content; /** - * example + * example. * 模板示例 */ @SerializedName("example") @@ -66,55 +70,7 @@ public static List fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getTemplateId() { - return this.templateId; - } - - public void setTemplateId(String templateId) { - this.templateId = templateId; - } - - public String getTitle() { - return this.title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getPrimaryIndustry() { - return this.primaryIndustry; - } - - public void setPrimaryIndustry(String primaryIndustry) { - this.primaryIndustry = primaryIndustry; - } - - public String getDeputyIndustry() { - return this.deputyIndustry; - } - - public void setDeputyIndustry(String deputyIndustry) { - this.deputyIndustry = deputyIndustry; - } - - public String getContent() { - return this.content; - } - - public void setContent(String content) { - this.content = content; - } - - public String getExample() { - return this.example; - } - - public void setExample(String example) { - this.example = example; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateData.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateData.java index f9d81e4028..ada9952040 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateData.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateData.java @@ -1,10 +1,13 @@ package me.chanjar.weixin.mp.bean.template; +import lombok.Data; + import java.io.Serializable; /** * @author Daniel Qian */ +@Data public class WxMpTemplateData implements Serializable { private static final long serialVersionUID = 6301835292940277870L; @@ -26,28 +29,4 @@ public WxMpTemplateData(String name, String value, String color) { this.color = color; } - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getValue() { - return this.value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getColor() { - return this.color; - } - - public void setColor(String color) { - this.color = color; - } - } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java index b142c3f70f..40bfd18a47 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustry.java @@ -1,14 +1,18 @@ package me.chanjar.weixin.mp.bean.template; -import me.chanjar.weixin.common.util.ToStringUtils; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** * @author miller */ +@Data public class WxMpTemplateIndustry implements Serializable { private static final long serialVersionUID = -7700398224795914722L; @@ -29,33 +33,17 @@ public static WxMpTemplateIndustry fromJson(String json) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } public String toJson() { return WxMpGsonBuilder.create().toJson(this); } - public Industry getPrimaryIndustry() { - return this.primaryIndustry; - } - - public void setPrimaryIndustry(Industry primaryIndustry) { - this.primaryIndustry = primaryIndustry; - } - - public Industry getSecondIndustry() { - return this.secondIndustry; - } - - public void setSecondIndustry(Industry secondIndustry) { - this.secondIndustry = secondIndustry; - } - /** - * @author miller - * 官方文档中,创建和获取的数据结构不一样。所以采用冗余字段的方式,实现相应的接口 + * 官方文档中,创建和获取的数据结构不一样。所以采用冗余字段的方式,实现相应的接口. */ + @Data public static class Industry implements Serializable { private static final long serialVersionUID = -1707184885588012142L; private String id; @@ -77,31 +65,8 @@ public Industry(String id, String firstClass, String secondClass) { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } - public String getId() { - return this.id; - } - - public void setId(String id) { - this.id = id; - } - - public String getFirstClass() { - return this.firstClass; - } - - public void setFirstClass(String firstClass) { - this.firstClass = firstClass; - } - - public String getSecondClass() { - return this.secondClass; - } - - public void setSecondClass(String secondClass) { - this.secondClass = secondClass; - } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java index 95d619a486..cb70893a9c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java @@ -1,182 +1,88 @@ package me.chanjar.weixin.mp.bean.template; -import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; - import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + /** + * 模板消息. * 参考 http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN 发送模板消息接口部分 + * + * @author Binary Wang */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder public class WxMpTemplateMessage implements Serializable { private static final long serialVersionUID = 5063374783759519418L; /** - * 接收者openid + * 接收者openid. */ private String toUser; /** - * 模板ID + * 模板ID. */ private String templateId; /** + * 模板跳转链接. *
-   * 跳小程序所需数据,不需跳小程序可不用传该数据
    * url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。
    * 开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。
    * 
*/ private String url; + /** - * 模板跳转链接 + * 跳小程序所需数据,不需跳小程序可不用传该数据. * * @see #url */ private MiniProgram miniProgram; /** - * 模板数据 + * 模板数据. */ private List data = new ArrayList<>(); - public WxMpTemplateMessage() { - } - - public static WxMpTemplateMessageBuilder builder() { - return new WxMpTemplateMessageBuilder(); - } - - public String getToUser() { - return this.toUser; - } - - public void setToUser(String toUser) { - this.toUser = toUser; - } - - public String getTemplateId() { - return this.templateId; - } - - public void setTemplateId(String templateId) { - this.templateId = templateId; - } - - public String getUrl() { - return this.url; - } - - public void setUrl(String url) { - this.url = url; - } - - public List getData() { - return this.data; - } - - public void setData(List data) { - this.data = data; - } - - public void addWxMpTemplateData(WxMpTemplateData datum) { + public WxMpTemplateMessage addData(WxMpTemplateData datum) { + if (this.data == null) { + this.data = new ArrayList<>(); + } this.data.add(datum); - } - - public MiniProgram getMiniProgram() { - return this.miniProgram; - } - - public void setMiniProgram(MiniProgram miniProgram) { - this.miniProgram = miniProgram; + return this; } public String toJson() { return WxMpGsonBuilder.INSTANCE.create().toJson(this); } + @Data + @NoArgsConstructor + @AllArgsConstructor public static class MiniProgram implements Serializable { private static final long serialVersionUID = -7945254706501974849L; private String appid; private String pagePath; - public MiniProgram() { - } - - public MiniProgram(String appid, String pagePath) { - this.appid = appid; - this.pagePath = pagePath; - } - - public String getAppid() { - return this.appid; - } - - public void setAppid(String appid) { - this.appid = appid; - } - - public String getPagePath() { - return this.pagePath; - } - - public void setPagePath(String pagePath) { - this.pagePath = pagePath; - } - } - - public static class WxMpTemplateMessageBuilder { - private String toUser; - private String templateId; - private String url; - private List data = new ArrayList<>(); - private MiniProgram miniProgram; - - public WxMpTemplateMessageBuilder toUser(String toUser) { - this.toUser = toUser; - return this; - } - - public WxMpTemplateMessageBuilder templateId(String templateId) { - this.templateId = templateId; - return this; - } - - public WxMpTemplateMessageBuilder url(String url) { - this.url = url; - return this; - } - - public WxMpTemplateMessageBuilder data(List data) { - this.data = data; - return this; - } - - public WxMpTemplateMessageBuilder from(WxMpTemplateMessage origin) { - this.toUser(origin.toUser); - this.templateId(origin.templateId); - this.url(origin.url); - this.data(origin.data); - return this; - } - - public WxMpTemplateMessageBuilder miniProgram(MiniProgram miniProgram) { - this.miniProgram = miniProgram; - return this; - } - - public WxMpTemplateMessage build() { - WxMpTemplateMessage m = new WxMpTemplateMessage(); - m.toUser = this.toUser; - m.templateId = this.templateId; - m.url = this.url; - m.data = this.data; - m.miniProgram = this.miniProgram; - return m; - } + /** + * 是否使用path,否则使用pagepath. + * 加入此字段是基于微信官方接口变化多端的考虑 + */ + private boolean usePath = true; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/wifi/WxMpWifiShopListResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/wifi/WxMpWifiShopListResult.java new file mode 100644 index 0000000000..69947aefcd --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/wifi/WxMpWifiShopListResult.java @@ -0,0 +1,90 @@ +package me.chanjar.weixin.mp.bean.wifi; + +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.List; + +/** + *
+ *  Created by BinaryWang on 2018/6/10.
+ * 
+ * + * @author Binary Wang + */ +@Data +public class WxMpWifiShopListResult { + public static WxMpWifiShopListResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson( + new JsonParser().parse(json).getAsJsonObject().get("data"), + WxMpWifiShopListResult.class); + } + + /** + * 总数 + */ + @SerializedName("totalcount") + private int totalCount; + + /** + * 分页下标 + */ + @SerializedName("pageindex") + private int pageIndex; + + /** + * 分页页数 + */ + @SerializedName("pagecount") + private int pageCount; + + private List records; + + @Data + public static class Record { + + /** + * 门店ID(适用于微信连Wi-Fi业务) + */ + @SerializedName("shop_id") + private Integer shopId; + + /** + * 门店名称 + */ + @SerializedName("shop_name") + private String shopName; + + /** + * 无线网络设备的ssid,未添加设备为空,多个ssid时显示第一个 + */ + @SerializedName("ssid") + private String ssid; + + /** + * 无线网络设备的ssid列表,返回数组格式 + */ + @SerializedName("ssid_list") + private List ssidList; + + /** + * 门店内设备的设备类型,0-未添加设备,1-专业型设备,4-密码型设备,5-portal自助型设备,31-portal改造型设备 + */ + @SerializedName("protocol_type") + private Integer protocolType; + + /** + * 商户自己的id,与门店poi_id对应关系,建议在添加门店时候建立关联关系,具体请参考“微信门店接口” + */ + @SerializedName("sid") + private String sid; + + /** + * 门店ID(适用于微信卡券、微信门店业务),具体定义参考微信门店,与shop_id一一对应 + */ + @SerializedName("poi_id") + private String poiId; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/ImageBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/ImageBuilder.java index 24d8aabab9..438b0a98a1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/ImageBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/ImageBuilder.java @@ -15,7 +15,7 @@ public final class ImageBuilder extends BaseBuilder { private String mediaId; public ImageBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_IMAGE; + this.msgType = WxConsts.KefuMsgType.IMAGE; } public ImageBuilder mediaId(String media_id) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MiniProgramPageBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MiniProgramPageBuilder.java new file mode 100644 index 0000000000..0aedbae9c6 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MiniProgramPageBuilder.java @@ -0,0 +1,61 @@ +package me.chanjar.weixin.mp.builder.kefu; + +import me.chanjar.weixin.common.api.WxConsts.KefuMsgType; +import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; + +/** + * 小程序卡片 builder + *
+ * 用法:
+ * WxMpKefuMessage m = WxMpKefuMessage.MINIPROGRAMPAGE().title("xxxx").thumbMediaId("xxxxx").appId("xxxx").pagePath("****").toUser(...).build();
+ * 
+ * + * @author boris.bao + */ +public final class MiniProgramPageBuilder extends BaseBuilder { + + private String title; + private String appId; + private String pagePath; + private String thumbMediaId; + + public MiniProgramPageBuilder() { + this.msgType = KefuMsgType.MINIPROGRAMPAGE; + } + + + public MiniProgramPageBuilder title(String title) { + this.title = title; + return this; + } + + public MiniProgramPageBuilder appId(String appId) { + this.appId = appId; + return this; + } + + + public MiniProgramPageBuilder pagePath(String pagePath) { + this.pagePath = pagePath; + return this; + } + + + public MiniProgramPageBuilder thumbMediaId(String thumbMediaId) { + this.thumbMediaId = thumbMediaId; + return this; + } + + + @Override + public WxMpKefuMessage build() { + WxMpKefuMessage m = super.build(); + m.setTitle(this.title); + m.setMiniProgramAppId(this.appId); + m.setMiniProgramPagePath(this.pagePath); + m.setThumbMediaId(this.thumbMediaId); + return m; + } + + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MpNewsBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MpNewsBuilder.java index b8fac10258..0d520132f4 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MpNewsBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MpNewsBuilder.java @@ -16,7 +16,7 @@ public final class MpNewsBuilder extends BaseBuilder { private String mediaId; public MpNewsBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_MPNEWS; + this.msgType = WxConsts.KefuMsgType.MPNEWS; } public MpNewsBuilder mediaId(String mediaId) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MusicBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MusicBuilder.java index 8d23bacd4e..0cd40db438 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MusicBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/MusicBuilder.java @@ -24,7 +24,7 @@ public final class MusicBuilder extends BaseBuilder { private String hqMusicUrl; public MusicBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_MUSIC; + this.msgType = WxConsts.KefuMsgType.MUSIC; } public MusicBuilder musicUrl(String musicurl) { @@ -47,8 +47,8 @@ public MusicBuilder description(String description) { return this; } - public MusicBuilder thumbMediaId(String thumb_media_id) { - this.thumbMediaId = thumb_media_id; + public MusicBuilder thumbMediaId(String thumbMediaId) { + this.thumbMediaId = thumbMediaId; return this; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/NewsBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/NewsBuilder.java index 11e866e84a..3c00303557 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/NewsBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/NewsBuilder.java @@ -20,7 +20,7 @@ public final class NewsBuilder extends BaseBuilder { private List articles = new ArrayList<>(); public NewsBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_NEWS; + this.msgType = WxConsts.KefuMsgType.NEWS; } public NewsBuilder addArticle(WxMpKefuMessage.WxArticle... articles) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/TextBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/TextBuilder.java index 6d9100e94a..b8f58bdd34 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/TextBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/TextBuilder.java @@ -15,7 +15,7 @@ public final class TextBuilder extends BaseBuilder { private String content; public TextBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_TEXT; + this.msgType = WxConsts.KefuMsgType.TEXT; } public TextBuilder content(String content) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VideoBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VideoBuilder.java index d7d3772bda..e9276637d3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VideoBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VideoBuilder.java @@ -24,7 +24,7 @@ public final class VideoBuilder extends BaseBuilder { private String thumbMediaId; public VideoBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_VIDEO; + this.msgType = WxConsts.KefuMsgType.VIDEO; } public VideoBuilder mediaId(String mediaId) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VoiceBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VoiceBuilder.java index 9fa92f21c8..a5211548cb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VoiceBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/VoiceBuilder.java @@ -15,7 +15,7 @@ public final class VoiceBuilder extends BaseBuilder { private String mediaId; public VoiceBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_VOICE; + this.msgType = WxConsts.KefuMsgType.VOICE; } public VoiceBuilder mediaId(String media_id) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/WxCardBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/WxCardBuilder.java index c9eacf0c13..64cb067206 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/WxCardBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/kefu/WxCardBuilder.java @@ -15,7 +15,7 @@ public final class WxCardBuilder extends BaseBuilder { private String cardId; public WxCardBuilder() { - this.msgType = WxConsts.CUSTOM_MSG_WXCARD; + this.msgType = WxConsts.KefuMsgType.WXCARD; } public WxCardBuilder cardId(String cardId) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java index 5b199cc52e..741bffae66 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/BaseBuilder.java @@ -25,7 +25,7 @@ public BuilderType fromUser(String fromusername) { public void setCommon(WxMpXmlOutMessage m) { m.setToUserName(this.toUserName); m.setFromUserName(this.fromUserName); - m.setCreateTime(System.currentTimeMillis() / 1000l); + m.setCreateTime(System.currentTimeMillis() / 1000L); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/TransferCustomerServiceBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/TransferCustomerServiceBuilder.java index bc018e8fd3..8821608dae 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/TransferCustomerServiceBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/TransferCustomerServiceBuilder.java @@ -1,17 +1,19 @@ package me.chanjar.weixin.mp.builder.outxml; -import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTransferKefuMessage; import org.apache.commons.lang3.StringUtils; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTransferKefuMessage; + /** * 客服消息builder *
- * 用法: WxMpKefuMessage m = WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE().content(...).toUser(...).build();
+ * 用法: WxMpXmlOutTransferKefuMessage m = WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE().kfAccount("").toUser("").build();
  * 
* * @author chanjarster */ -public final class TransferCustomerServiceBuilder extends BaseBuilder { +public final class TransferCustomerServiceBuilder + extends BaseBuilder { private String kfAccount; public TransferCustomerServiceBuilder kfAccount(String kf) { @@ -28,6 +30,7 @@ public WxMpXmlOutTransferKefuMessage build() { transInfo.setKfAccount(this.kfAccount); m.setTransInfo(transInfo); } + return m; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/VideoBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/VideoBuilder.java index e9f7c85b42..9a965f5b78 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/VideoBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/builder/outxml/VideoBuilder.java @@ -32,9 +32,9 @@ public VideoBuilder mediaId(String mediaId) { public WxMpXmlOutVideoMessage build() { WxMpXmlOutVideoMessage m = new WxMpXmlOutVideoMessage(); setCommon(m); - m.setTitle(this.title); - m.setDescription(this.description); - m.setMediaId(this.mediaId); + m.getVideo().setTitle(this.title); + m.getVideo().setDescription(this.description); + m.getVideo().setMediaId(this.mediaId); return m; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java index 503367cfd7..df1790e3da 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java @@ -4,8 +4,9 @@ *
  * 微信公众号事件的相关常量
  * Created by Binary Wang on 2017-5-10.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ public class WxMpEventConstants { /** diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpQrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpQrCodeRequestExecutor.java deleted file mode 100644 index 6feb137925..0000000000 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpQrCodeRequestExecutor.java +++ /dev/null @@ -1,53 +0,0 @@ -package me.chanjar.weixin.mp.util.http.okhttp; - -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.RequestHttp; -import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; - -import okhttp3.*; -import okio.BufferedSink; -import okio.Okio; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.UUID; - -/** - * Created by ecoolper on 2017/5/5. - */ -public class OkhttpQrCodeRequestExecutor extends QrCodeRequestExecutor { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - public OkhttpQrCodeRequestExecutor(RequestHttp requestHttp) { - super(requestHttp); - } - - @Override - public File execute(String uri, WxMpQrCodeTicket data) throws WxErrorException, IOException { - logger.debug("OkhttpQrCodeRequestExecutor is running"); - //得到httpClient - OkHttpClient client = requestHttp.getRequestHttpClient(); - Request request = new Request.Builder().url(uri).get().build(); - Response response = client.newCall(request).execute(); - String contentTypeHeader = response.header("Content-Type"); - if ("text/plain".equals(contentTypeHeader)) { - String responseContent = response.body().string(); - throw new WxErrorException(WxError.fromJson(responseContent)); - } - File temp = File.createTempFile(UUID.randomUUID().toString(), ".png"); - try (BufferedSink sink = Okio.buffer(Okio.sink(temp))) { - sink.writeAll(response.body().source()); - } - temp.deleteOnExit(); - - return temp; - } -} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java index 124845ed6b..524e153140 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java @@ -10,6 +10,7 @@ import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; import me.chanjar.weixin.mp.bean.material.*; import me.chanjar.weixin.mp.bean.result.*; +import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; @@ -30,6 +31,7 @@ public class WxMpGsonBuilder { INSTANCE.registerTypeAdapter(WxMpMassUploadResult.class, new WxMpMassUploadResultAdapter()); INSTANCE.registerTypeAdapter(WxMpQrCodeTicket.class, new WxQrCodeTicketAdapter()); INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMpSubscribeMessage.class, new WxMpSubscribeMessageGsonAdapter()); INSTANCE.registerTypeAdapter(WxMpSemanticQueryResult.class, new WxMpSemanticQueryResultAdapter()); INSTANCE.registerTypeAdapter(WxMpOAuth2AccessToken.class, new WxMpOAuth2AccessTokenAdapter()); INSTANCE.registerTypeAdapter(WxDataCubeUserSummary.class, new WxMpUserSummaryGsonAdapter()); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java index 56297ce2bd..63389866f3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpKefuMessageGsonAdapter.java @@ -1,15 +1,8 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.api.WxConsts.KefuMsgType; import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; import org.apache.commons.lang3.StringUtils; @@ -23,25 +16,25 @@ public JsonElement serialize(WxMpKefuMessage message, Type typeOfSrc, JsonSerial messageJson.addProperty("touser", message.getToUser()); messageJson.addProperty("msgtype", message.getMsgType()); - if (WxConsts.CUSTOM_MSG_TEXT.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) { JsonObject text = new JsonObject(); text.addProperty("content", message.getContent()); messageJson.add("text", text); } - if (WxConsts.CUSTOM_MSG_IMAGE.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.IMAGE.equals(message.getMsgType())) { JsonObject image = new JsonObject(); image.addProperty("media_id", message.getMediaId()); messageJson.add("image", image); } - if (WxConsts.CUSTOM_MSG_VOICE.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.VOICE.equals(message.getMsgType())) { JsonObject voice = new JsonObject(); voice.addProperty("media_id", message.getMediaId()); messageJson.add("voice", voice); } - if (WxConsts.CUSTOM_MSG_VIDEO.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.VIDEO.equals(message.getMsgType())) { JsonObject video = new JsonObject(); video.addProperty("media_id", message.getMediaId()); video.addProperty("thumb_media_id", message.getThumbMediaId()); @@ -50,7 +43,7 @@ public JsonElement serialize(WxMpKefuMessage message, Type typeOfSrc, JsonSerial messageJson.add("video", video); } - if (WxConsts.CUSTOM_MSG_MUSIC.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.MUSIC.equals(message.getMsgType())) { JsonObject music = new JsonObject(); music.addProperty("title", message.getTitle()); music.addProperty("description", message.getDescription()); @@ -60,7 +53,7 @@ public JsonElement serialize(WxMpKefuMessage message, Type typeOfSrc, JsonSerial messageJson.add("music", music); } - if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.NEWS.equals(message.getMsgType())) { JsonObject newsJsonObject = new JsonObject(); JsonArray articleJsonArray = new JsonArray(); for (WxMpKefuMessage.WxArticle article : message.getArticles()) { @@ -75,18 +68,27 @@ public JsonElement serialize(WxMpKefuMessage message, Type typeOfSrc, JsonSerial messageJson.add("news", newsJsonObject); } - if (WxConsts.CUSTOM_MSG_MPNEWS.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.MPNEWS.equals(message.getMsgType())) { JsonObject json = new JsonObject(); json.addProperty("media_id", message.getMpNewsMediaId()); messageJson.add("mpnews", json); } - if (WxConsts.CUSTOM_MSG_WXCARD.equals(message.getMsgType())) { + if (WxConsts.KefuMsgType.WXCARD.equals(message.getMsgType())) { JsonObject wxcard = new JsonObject(); wxcard.addProperty("card_id", message.getCardId()); messageJson.add("wxcard", wxcard); } + if (KefuMsgType.MINIPROGRAMPAGE.equals(message.getMsgType())) { + JsonObject miniProgramPage = new JsonObject(); + miniProgramPage.addProperty("title", message.getTitle()); + miniProgramPage.addProperty("appid", message.getMiniProgramAppId()); + miniProgramPage.addProperty("pagepath", message.getMiniProgramPagePath()); + miniProgramPage.addProperty("thumb_media_id", message.getThumbMediaId()); + messageJson.add("miniprogrampage", miniProgramPage); + } + if (StringUtils.isNotBlank(message.getKfAccount())) { JsonObject newsJsonObject = new JsonObject(); newsJsonObject.addProperty("kf_account", message.getKfAccount()); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsArticleGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsArticleGsonAdapter.java index e4d8840344..70343de94d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsArticleGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsArticleGsonAdapter.java @@ -1,19 +1,15 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; import me.chanjar.weixin.common.util.json.GsonHelper; import me.chanjar.weixin.mp.bean.WxMpMassNews; +import org.apache.commons.lang3.BooleanUtils; import java.lang.reflect.Type; +/** + * @author codepiano + */ public class WxMpMassNewsArticleGsonAdapter implements JsonSerializer, JsonDeserializer { @Override @@ -67,7 +63,7 @@ public WxMpMassNews.WxMpMassNewsArticle deserialize(JsonElement jsonElement, Typ } JsonElement showCoverPic = articleInfo.get("show_cover_pic"); if (showCoverPic != null && !showCoverPic.isJsonNull()) { - article.setShowCoverPic(GsonHelper.getAsBoolean(showCoverPic)); + article.setShowCoverPic(BooleanUtils.toBoolean(showCoverPic.getAsInt())); } return article; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsGsonAdapter.java index fecf494d85..b780300e4e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassNewsGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassOpenIdsMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassOpenIdsMessageGsonAdapter.java index 64dfbb1234..562222fc67 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassOpenIdsMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassOpenIdsMessageGsonAdapter.java @@ -1,19 +1,15 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; +import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Type; +/** + * @author someone + */ public class WxMpMassOpenIdsMessageGsonAdapter implements JsonSerializer { @Override @@ -26,33 +22,38 @@ public JsonElement serialize(WxMpMassOpenIdsMessage message, Type typeOfSrc, Jso } messageJson.add("touser", toUsers); - if (WxConsts.MASS_MSG_NEWS.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.MPNEWS.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_NEWS, sub); + messageJson.add(WxConsts.MassMsgType.MPNEWS, sub); } - if (WxConsts.MASS_MSG_TEXT.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.TEXT.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("content", message.getContent()); - messageJson.add(WxConsts.MASS_MSG_TEXT, sub); + messageJson.add(WxConsts.MassMsgType.TEXT, sub); } - if (WxConsts.MASS_MSG_VOICE.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.VOICE.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_VOICE, sub); + messageJson.add(WxConsts.MassMsgType.VOICE, sub); } - if (WxConsts.MASS_MSG_IMAGE.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.IMAGE.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_IMAGE, sub); + messageJson.add(WxConsts.MassMsgType.IMAGE, sub); } - if (WxConsts.MASS_MSG_VIDEO.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.MPVIDEO.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_VIDEO, sub); + messageJson.add(WxConsts.MassMsgType.MPVIDEO, sub); } messageJson.addProperty("msgtype", message.getMsgType()); messageJson.addProperty("send_ignore_reprint", message.isSendIgnoreReprint() ? 0 : 1); + + if(StringUtils.isNotEmpty(message.getClientMsgId())){ + messageJson.addProperty("clientmsgid", message.getClientMsgId()); + } + return messageJson; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java index fd210fb33a..bd8ede336d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassPreviewMessageGsonAdapter.java @@ -18,30 +18,30 @@ public JsonElement serialize(WxMpMassPreviewMessage wxMpMassPreviewMessage, Type JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("towxname", wxMpMassPreviewMessage.getToWxUserName()); jsonObject.addProperty("touser", wxMpMassPreviewMessage.getToWxUserOpenid()); - if (WxConsts.MASS_MSG_NEWS.equals(wxMpMassPreviewMessage.getMsgType())) { + if (WxConsts.MassMsgType.MPNEWS.equals(wxMpMassPreviewMessage.getMsgType())) { JsonObject news = new JsonObject(); news.addProperty("media_id", wxMpMassPreviewMessage.getMediaId()); - jsonObject.add(WxConsts.MASS_MSG_NEWS, news); + jsonObject.add(WxConsts.MassMsgType.MPNEWS, news); } - if (WxConsts.MASS_MSG_TEXT.equals(wxMpMassPreviewMessage.getMsgType())) { + if (WxConsts.MassMsgType.TEXT.equals(wxMpMassPreviewMessage.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("content", wxMpMassPreviewMessage.getContent()); - jsonObject.add(WxConsts.MASS_MSG_TEXT, sub); + jsonObject.add(WxConsts.MassMsgType.TEXT, sub); } - if (WxConsts.MASS_MSG_VOICE.equals(wxMpMassPreviewMessage.getMsgType())) { + if (WxConsts.MassMsgType.VOICE.equals(wxMpMassPreviewMessage.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", wxMpMassPreviewMessage.getMediaId()); - jsonObject.add(WxConsts.MASS_MSG_VOICE, sub); + jsonObject.add(WxConsts.MassMsgType.VOICE, sub); } - if (WxConsts.MASS_MSG_IMAGE.equals(wxMpMassPreviewMessage.getMsgType())) { + if (WxConsts.MassMsgType.IMAGE.equals(wxMpMassPreviewMessage.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", wxMpMassPreviewMessage.getMediaId()); - jsonObject.add(WxConsts.MASS_MSG_IMAGE, sub); + jsonObject.add(WxConsts.MassMsgType.IMAGE, sub); } - if (WxConsts.MASS_MSG_VIDEO.equals(wxMpMassPreviewMessage.getMsgType())) { + if (WxConsts.MassMsgType.MPVIDEO.equals(wxMpMassPreviewMessage.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", wxMpMassPreviewMessage.getMediaId()); - jsonObject.add(WxConsts.MASS_MSG_VIDEO, sub); + jsonObject.add(WxConsts.MassMsgType.MPVIDEO, sub); } jsonObject.addProperty("msgtype", wxMpMassPreviewMessage.getMsgType()); return jsonObject; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassSendResultAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassSendResultAdapter.java index 5a652f0aab..aebbca5ec8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassSendResultAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassSendResultAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassTagMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassTagMessageGsonAdapter.java index 5b133b0ed1..3d8f58ffa9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassTagMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassTagMessageGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.JsonElement; @@ -14,9 +6,13 @@ import com.google.gson.JsonSerializer; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.bean.WxMpMassTagMessage; +import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Type; +/** + * @author someone + */ public class WxMpMassTagMessageGsonAdapter implements JsonSerializer { @Override @@ -32,33 +28,38 @@ public JsonElement serialize(WxMpMassTagMessage message, Type typeOfSrc, JsonSer } messageJson.add("filter", filter); - if (WxConsts.MASS_MSG_NEWS.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.MPNEWS.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_NEWS, sub); + messageJson.add(WxConsts.MassMsgType.MPNEWS, sub); } - if (WxConsts.MASS_MSG_TEXT.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.TEXT.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("content", message.getContent()); - messageJson.add(WxConsts.MASS_MSG_TEXT, sub); + messageJson.add(WxConsts.MassMsgType.TEXT, sub); } - if (WxConsts.MASS_MSG_VOICE.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.VOICE.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_VOICE, sub); + messageJson.add(WxConsts.MassMsgType.VOICE, sub); } - if (WxConsts.MASS_MSG_IMAGE.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.IMAGE.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_IMAGE, sub); + messageJson.add(WxConsts.MassMsgType.IMAGE, sub); } - if (WxConsts.MASS_MSG_VIDEO.equals(message.getMsgType())) { + if (WxConsts.MassMsgType.MPVIDEO.equals(message.getMsgType())) { JsonObject sub = new JsonObject(); sub.addProperty("media_id", message.getMediaId()); - messageJson.add(WxConsts.MASS_MSG_VIDEO, sub); + messageJson.add(WxConsts.MassMsgType.MPVIDEO, sub); } messageJson.addProperty("msgtype", message.getMsgType()); messageJson.addProperty("send_ignore_reprint", message.isSendIgnoreReprint() ? 0 : 1); + + if (StringUtils.isNotEmpty(message.getClientMsgId())) { + messageJson.addProperty("clientmsgid", message.getClientMsgId()); + } + return messageJson; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassUploadResultAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassUploadResultAdapter.java index e20175d767..b526e8ce6e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassUploadResultAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassUploadResultAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassVideoAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassVideoAdapter.java index e7bd8c3997..f6570f4881 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassVideoAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMassVideoAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.JsonElement; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialArticleUpdateGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialArticleUpdateGsonAdapter.java index 2705462e8a..bdbbde561d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialArticleUpdateGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialArticleUpdateGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.JsonElement; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialCountResultAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialCountResultAdapter.java index 3f96addfc7..ce002a28cc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialCountResultAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialCountResultAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonAdapter.java index 1460813e82..b19fa422e2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonItemAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonItemAdapter.java index 7b4bee2e00..d17bb50c39 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonItemAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialFileBatchGetGsonItemAdapter.java @@ -1,38 +1,30 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; import me.chanjar.weixin.common.util.json.GsonHelper; -import me.chanjar.weixin.mp.bean.material.WxMpMaterialFileBatchGetResult; +import me.chanjar.weixin.mp.bean.material.WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem; import java.lang.reflect.Type; import java.util.Date; -public class WxMpMaterialFileBatchGetGsonItemAdapter implements JsonDeserializer { +public class WxMpMaterialFileBatchGetGsonItemAdapter implements JsonDeserializer { @Override - public WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { - WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem wxMaterialFileBatchGetNewsItem = new WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem(); + public WxMaterialFileBatchGetNewsItem deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxMaterialFileBatchGetNewsItem newsItem = new WxMaterialFileBatchGetNewsItem(); JsonObject json = jsonElement.getAsJsonObject(); if (json.get("media_id") != null && !json.get("media_id").isJsonNull()) { - wxMaterialFileBatchGetNewsItem.setMediaId(GsonHelper.getAsString(json.get("media_id"))); + newsItem.setMediaId(GsonHelper.getAsString(json.get("media_id"))); } if (json.get("update_time") != null && !json.get("update_time").isJsonNull()) { - wxMaterialFileBatchGetNewsItem.setUpdateTime(new Date(1000 * GsonHelper.getAsLong(json.get("update_time")))); + newsItem.setUpdateTime(new Date(1000 * GsonHelper.getAsLong(json.get("update_time")))); } if (json.get("name") != null && !json.get("name").isJsonNull()) { - wxMaterialFileBatchGetNewsItem.setName(GsonHelper.getAsString(json.get("name"))); + newsItem.setName(GsonHelper.getAsString(json.get("name"))); } if (json.get("url") != null && !json.get("url").isJsonNull()) { - wxMaterialFileBatchGetNewsItem.setUrl(GsonHelper.getAsString(json.get("url"))); + newsItem.setUrl(GsonHelper.getAsString(json.get("url"))); } - return wxMaterialFileBatchGetNewsItem; + return newsItem; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsArticleGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsArticleGsonAdapter.java index 5a17a7bdb8..faad5ec528 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsArticleGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsArticleGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; @@ -15,6 +7,9 @@ import java.lang.reflect.Type; +/** + * @author codepiano + */ public class WxMpMaterialNewsArticleGsonAdapter implements JsonSerializer, JsonDeserializer { @Override @@ -86,7 +81,7 @@ public WxMpMaterialNews.WxMpMaterialNewsArticle deserialize(JsonElement jsonElem } JsonElement showCoverPic = articleInfo.get("show_cover_pic"); if (showCoverPic != null && !showCoverPic.isJsonNull()) { - article.setShowCoverPic(GsonHelper.getAsBoolean(showCoverPic)); + article.setShowCoverPic(BooleanUtils.toBoolean(showCoverPic.getAsInt())); } JsonElement url = articleInfo.get("url"); if (url != null && !url.isJsonNull()) { @@ -95,12 +90,12 @@ public WxMpMaterialNews.WxMpMaterialNewsArticle deserialize(JsonElement jsonElem JsonElement needOpenComment = articleInfo.get("need_open_comment"); if (needOpenComment != null && !needOpenComment.isJsonNull()) { - article.setNeedOpenComment(GsonHelper.getAsBoolean(needOpenComment)); + article.setNeedOpenComment(BooleanUtils.toBoolean(needOpenComment.getAsInt())); } JsonElement onlyFansCanComment = articleInfo.get("only_fans_can_comment"); if (onlyFansCanComment != null && !onlyFansCanComment.isJsonNull()) { - article.setOnlyFansCanComment(GsonHelper.getAsBoolean(onlyFansCanComment)); + article.setOnlyFansCanComment(BooleanUtils.toBoolean(onlyFansCanComment.getAsInt())); } return article; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonAdapter.java index 2a88a8f236..203b1ad8ce 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonItemAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonItemAdapter.java index e56ecf4239..2c455e76da 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonItemAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsBatchGetGsonItemAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsGsonAdapter.java index 084e355cbc..6d307c47bb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialNewsGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialUploadResultAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialUploadResultAdapter.java index 0ccefd8336..db279ce1d3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialUploadResultAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMaterialUploadResultAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUpdateResultGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUpdateResultGsonAdapter.java index dc068db1e8..0d45946311 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUpdateResultGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUpdateResultGsonAdapter.java @@ -29,7 +29,7 @@ public WxMpMemberCardUpdateResult deserialize(JsonElement jsonElement, Type type result.setOpenId(GsonHelper.getString(jsonObject, "openid")); result.setErrorCode(GsonHelper.getString(jsonObject, "errcode")); result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); - result.setResultBalance(GsonHelper.getInteger(jsonObject, "result_balance")); + result.setResultBalance(GsonHelper.getDouble(jsonObject, "result_balance")); result.setResultBonus(GsonHelper.getInteger(jsonObject, "result_bonus")); return result; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java index 5a97ee7496..3b14e0dc10 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java @@ -28,6 +28,7 @@ public WxMpMemberCardUserInfoResult deserialize(JsonElement jsonElement, Type ty result.setNickname(GsonHelper.getString(jsonObject, "nickname")); result.setMembershipNumber(GsonHelper.getString(jsonObject, "membership_number")); result.setBonus(GsonHelper.getInteger(jsonObject, "bonus")); + result.setBalance(GsonHelper.getDouble(jsonObject, "balance")); result.setSex(GsonHelper.getString(jsonObject, "sex")); result.setUserCardStatus(GsonHelper.getString(jsonObject, "user_card_status")); result.setHasActive(GsonHelper.getBoolean(jsonObject, "has_active")); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java index 247182d2c4..f5b2a87d79 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSubscribeMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSubscribeMessageGsonAdapter.java new file mode 100644 index 0000000000..6f32195a7c --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSubscribeMessageGsonAdapter.java @@ -0,0 +1,59 @@ +package me.chanjar.weixin.mp.util.json; + +import java.lang.reflect.Type; + +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.subscribe.WxMpSubscribeMessage; + +/** + * @author Mklaus + * @date 2018-01-22 下午12:31 + */ +public class WxMpSubscribeMessageGsonAdapter implements JsonSerializer { + + @Override + public JsonElement serialize(WxMpSubscribeMessage message, Type type, JsonSerializationContext jsonSerializationContext) { + JsonObject messageJson = new JsonObject(); + messageJson.addProperty("touser", message.getToUser()); + messageJson.addProperty("template_id", message.getTemplateId()); + + if (message.getUrl() != null) { + messageJson.addProperty("url", message.getUrl()); + } + + final WxMpSubscribeMessage.MiniProgram miniProgram = message.getMiniProgram(); + if (miniProgram != null) { + JsonObject miniProgramJson = new JsonObject(); + miniProgramJson.addProperty("appid", miniProgram.getAppid()); + if (miniProgram.isUsePath()) { + miniProgramJson.addProperty("path", miniProgram.getPagePath()); + } else { + miniProgramJson.addProperty("pagepath", miniProgram.getPagePath()); + } + messageJson.add("miniprogram", miniProgramJson); + } + + messageJson.addProperty("scene", message.getScene()); + messageJson.addProperty("title", message.getTitle()); + + JsonObject data = new JsonObject(); + messageJson.add("data", data); + + JsonObject content = new JsonObject(); + data.add("content", content); + + if (message.getContentValue() != null) { + content.addProperty("value", message.getContentValue()); + } + + if (message.getContentColor() != null) { + content.addProperty("color", message.getContentColor()); + } + + return messageJson; + + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java index 9668a768a7..73f8c4e3ab 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java @@ -1,13 +1,7 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; +import java.lang.reflect.Type; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; @@ -15,8 +9,9 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; -import java.lang.reflect.Type; - +/** + * @author chanjarster + */ public class WxMpTemplateMessageGsonAdapter implements JsonSerializer { @Override @@ -28,10 +23,15 @@ public JsonElement serialize(WxMpTemplateMessage message, Type typeOfSrc, JsonSe messageJson.addProperty("url", message.getUrl()); } - if (message.getMiniProgram() != null) { + final WxMpTemplateMessage.MiniProgram miniProgram = message.getMiniProgram(); + if (miniProgram != null) { JsonObject miniProgramJson = new JsonObject(); - miniProgramJson.addProperty("appid", message.getMiniProgram().getAppid()); - miniProgramJson.addProperty("pagepath", message.getMiniProgram().getPagePath()); + miniProgramJson.addProperty("appid", miniProgram.getAppid()); + if (miniProgram.isUsePath()) { + miniProgramJson.addProperty("path", miniProgram.getPagePath()); + } else { + miniProgramJson.addProperty("pagepath", miniProgram.getPagePath()); + } messageJson.add("miniprogram", miniProgramJson); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserCumulateGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserCumulateGsonAdapter.java index 7897096e34..517d09880c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserCumulateGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserCumulateGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java index e47d405fdf..910ae8c89f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserGsonAdapter.java @@ -1,51 +1,58 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; -import com.google.gson.*; +import java.lang.reflect.Type; + +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 me.chanjar.weixin.common.util.json.GsonHelper; import me.chanjar.weixin.mp.bean.result.WxMpUser; -import java.lang.reflect.Type; - public class WxMpUserGsonAdapter implements JsonDeserializer { @Override public WxMpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject o = json.getAsJsonObject(); - WxMpUser wxMpUser = new WxMpUser(); + WxMpUser user = new WxMpUser(); Integer subscribe = GsonHelper.getInteger(o, "subscribe"); if (subscribe != null) { - wxMpUser.setSubscribe(!new Integer(0).equals(subscribe)); + user.setSubscribe(!new Integer(0).equals(subscribe)); } - wxMpUser.setCity(GsonHelper.getString(o, "city")); - wxMpUser.setCountry(GsonHelper.getString(o, "country")); - wxMpUser.setHeadImgUrl(GsonHelper.getString(o, "headimgurl")); - wxMpUser.setLanguage(GsonHelper.getString(o, "language")); - wxMpUser.setNickname(GsonHelper.getString(o, "nickname")); - wxMpUser.setOpenId(GsonHelper.getString(o, "openid")); - wxMpUser.setProvince(GsonHelper.getString(o, "province")); - wxMpUser.setSubscribeTime(GsonHelper.getLong(o, "subscribe_time")); - wxMpUser.setUnionId(GsonHelper.getString(o, "unionid")); - Integer sexId = GsonHelper.getInteger(o, "sex"); - wxMpUser.setRemark(GsonHelper.getString(o, "remark")); - wxMpUser.setGroupId(GsonHelper.getInteger(o, "groupid")); - wxMpUser.setTagIds(GsonHelper.getLongArray(o, "tagid_list")); - wxMpUser.setSexId(sexId); - if (new Integer(1).equals(sexId)) { - wxMpUser.setSex("男"); - } else if (new Integer(2).equals(sexId)) { - wxMpUser.setSex("女"); - } else { - wxMpUser.setSex("未知"); + user.setCity(GsonHelper.getString(o, "city")); + user.setCountry(GsonHelper.getString(o, "country")); + user.setHeadImgUrl(GsonHelper.getString(o, "headimgurl")); + user.setLanguage(GsonHelper.getString(o, "language")); + user.setNickname(GsonHelper.getString(o, "nickname")); + user.setOpenId(GsonHelper.getString(o, "openid")); + user.setProvince(GsonHelper.getString(o, "province")); + user.setSubscribeTime(GsonHelper.getLong(o, "subscribe_time")); + user.setUnionId(GsonHelper.getString(o, "unionid")); + user.setRemark(GsonHelper.getString(o, "remark")); + user.setGroupId(GsonHelper.getInteger(o, "groupid")); + user.setTagIds(GsonHelper.getLongArray(o, "tagid_list")); + user.setPrivileges(GsonHelper.getStringArray(o, "privilege")); + user.setSubscribeScene(GsonHelper.getString(o, "subscribe_scene")); + user.setQrScene(GsonHelper.getString(o, "qr_scene")); + user.setQrSceneStr(GsonHelper.getString(o, "qr_scene_str")); + + Integer sex = GsonHelper.getInteger(o, "sex"); + if (sex != null) { + user.setSex(sex); + switch (sex) { + case 1: + user.setSexDesc("男"); + break; + case 2: + user.setSexDesc("女"); + break; + default: + user.setSexDesc("未知"); + } + } - return wxMpUser; + return user; } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserSummaryGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserSummaryGsonAdapter.java index b101e01ff4..b5a2a782ac 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserSummaryGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpUserSummaryGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxQrCodeTicketAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxQrCodeTicketAdapter.java index bd1bbd90ff..c052826bcf 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxQrCodeTicketAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxQrCodeTicketAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; @@ -28,7 +20,7 @@ public WxMpQrCodeTicket deserialize(JsonElement json, Type typeOfT, JsonDeserial ticket.setTicket(GsonHelper.getAsString(ticketJsonObject.get("ticket"))); } if (ticketJsonObject.get("expire_seconds") != null && !ticketJsonObject.get("expire_seconds").isJsonNull()) { - ticket.setExpire_seconds(GsonHelper.getAsPrimitiveInt(ticketJsonObject.get("expire_seconds"))); + ticket.setExpireSeconds(GsonHelper.getAsPrimitiveInt(ticketJsonObject.get("expire_seconds"))); } if (ticketJsonObject.get("url") != null && !ticketJsonObject.get("url").isJsonNull()) { ticket.setUrl(GsonHelper.getAsString(ticketJsonObject.get("url"))); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java index e150a63fc5..619017e88d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxUserListGsonAdapter.java @@ -1,11 +1,3 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ package me.chanjar.weixin.mp.util.json; import com.google.gson.*; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialDeleteRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteApacheHttpRequestExecutor.java similarity index 76% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialDeleteRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteApacheHttpRequestExecutor.java index be0991d3a2..b64093252d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialDeleteRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteApacheHttpRequestExecutor.java @@ -1,11 +1,11 @@ -package me.chanjar.weixin.mp.util.http.apache; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.util.http.MaterialDeleteRequestExecutor; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; @@ -20,8 +20,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class ApacheMaterialDeleteRequestExecutor extends MaterialDeleteRequestExecutor { - public ApacheMaterialDeleteRequestExecutor(RequestHttp requestHttp) { +public class MaterialDeleteApacheHttpRequestExecutor extends MaterialDeleteRequestExecutor { + public MaterialDeleteApacheHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -38,7 +38,7 @@ public Boolean execute(String uri, String materialId) throws WxErrorException, I httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params))); try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialDeleteRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteJoddHttpRequestExecutor.java similarity index 67% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialDeleteRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteJoddHttpRequestExecutor.java index 0344e1cddc..f1ffdd6bf5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialDeleteRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteJoddHttpRequestExecutor.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.util.http.jodd; +package me.chanjar.weixin.mp.util.requestexecuter.material; import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; @@ -6,18 +6,18 @@ import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.util.http.MaterialDeleteRequestExecutor; import java.io.IOException; /** * Created by ecoolper on 2017/5/5. */ -public class JoddMaterialDeleteRequestExecutor extends MaterialDeleteRequestExecutor { - public JoddMaterialDeleteRequestExecutor(RequestHttp requestHttp) { +public class MaterialDeleteJoddHttpRequestExecutor extends MaterialDeleteRequestExecutor { + public MaterialDeleteJoddHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -33,7 +33,7 @@ public Boolean execute(String uri, String materialId) throws WxErrorException, I HttpResponse response = request.send(); response.charset(StringPool.UTF_8); String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialDeleteRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteOkhttpRequestExecutor.java similarity index 68% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialDeleteRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteOkhttpRequestExecutor.java index 40ac27465e..1635793e95 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialDeleteRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteOkhttpRequestExecutor.java @@ -1,10 +1,10 @@ -package me.chanjar.weixin.mp.util.http.okhttp; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.mp.util.http.MaterialDeleteRequestExecutor; import okhttp3.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,17 +14,17 @@ /** * Created by ecoolper on 2017/5/5. */ -public class OkhttpMaterialDeleteRequestExecutor extends MaterialDeleteRequestExecutor { +public class MaterialDeleteOkhttpRequestExecutor extends MaterialDeleteRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public OkhttpMaterialDeleteRequestExecutor(RequestHttp requestHttp) { + public MaterialDeleteOkhttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @Override public Boolean execute(String uri, String materialId) throws WxErrorException, IOException { - logger.debug("OkhttpMaterialDeleteRequestExecutor is running"); + logger.debug("MaterialDeleteOkhttpRequestExecutor is running"); //得到httpClient OkHttpClient client = requestHttp.getRequestHttpClient(); @@ -32,7 +32,7 @@ public Boolean execute(String uri, String materialId) throws WxErrorException, I Request request = new Request.Builder().url(uri).post(requestBody).build(); Response response = client.newCall(request).execute(); String responseContent = response.body().string(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteRequestExecutor.java similarity index 56% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteRequestExecutor.java index 51b7a67764..a185b54d75 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteRequestExecutor.java @@ -1,10 +1,7 @@ -package me.chanjar.weixin.mp.util.http; +package me.chanjar.weixin.mp.util.requestexecuter.material; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialDeleteRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialDeleteRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialDeleteRequestExecutor; public abstract class MaterialDeleteRequestExecutor implements RequestExecutor { protected RequestHttp requestHttp; @@ -16,11 +13,11 @@ public MaterialDeleteRequestExecutor(RequestHttp requestHttp) { public static RequestExecutor create(RequestHttp requestHttp) { switch (requestHttp.getRequestType()) { case APACHE_HTTP: - return new ApacheMaterialDeleteRequestExecutor(requestHttp); + return new MaterialDeleteApacheHttpRequestExecutor(requestHttp); case JODD_HTTP: - return new JoddMaterialDeleteRequestExecutor(requestHttp); + return new MaterialDeleteJoddHttpRequestExecutor(requestHttp); case OK_HTTP: - return new OkhttpMaterialDeleteRequestExecutor(requestHttp); + return new MaterialDeleteOkhttpRequestExecutor(requestHttp); default: return null; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialNewsInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoApacheHttpRequestExecutor.java similarity index 71% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialNewsInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoApacheHttpRequestExecutor.java index 5298160f35..aa717c0acc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialNewsInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoApacheHttpRequestExecutor.java @@ -1,12 +1,13 @@ -package me.chanjar.weixin.mp.util.http.apache; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import com.google.common.collect.ImmutableMap; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews; -import me.chanjar.weixin.mp.util.http.MaterialNewsInfoRequestExecutor; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; @@ -18,16 +19,18 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; /** - * Created by ecoolper on 2017/5/5. + * httpclient 实现的素材请求执行器. + * + * @author ecoolper + * @date 2017/5/5 */ -public class ApacheMaterialNewsInfoRequestExecutor extends MaterialNewsInfoRequestExecutor { +public class MaterialNewsInfoApacheHttpRequestExecutor + extends MaterialNewsInfoRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public ApacheMaterialNewsInfoRequestExecutor(RequestHttp requestHttp) { + public MaterialNewsInfoApacheHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -39,13 +42,11 @@ public WxMpMaterialNews execute(String uri, String materialId) throws WxErrorExc httpPost.setConfig(config); } - Map params = new HashMap<>(); - params.put("media_id", materialId); - httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params))); + httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(ImmutableMap.of("media_id", materialId)))); try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); this.logger.debug("响应原始数据:{}", responseContent); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialNewsInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoJoddHttpRequestExecutor.java similarity index 61% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialNewsInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoJoddHttpRequestExecutor.java index 181a640787..d91e2afc15 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialNewsInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoJoddHttpRequestExecutor.java @@ -1,16 +1,18 @@ -package me.chanjar.weixin.mp.util.http.jodd; +package me.chanjar.weixin.mp.util.requestexecuter.material; +import com.google.common.collect.ImmutableMap; import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; import jodd.http.HttpResponse; import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews; -import me.chanjar.weixin.mp.util.http.MaterialNewsInfoRequestExecutor; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,27 +22,27 @@ /** * Created by ecoolper on 2017/5/5. */ -public class JoddMaterialNewsInfoRequestExecutor extends MaterialNewsInfoRequestExecutor { +public class MaterialNewsInfoJoddHttpRequestExecutor extends MaterialNewsInfoRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public JoddMaterialNewsInfoRequestExecutor(RequestHttp requestHttp) { + public MaterialNewsInfoJoddHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @Override public WxMpMaterialNews execute(String uri, String materialId) throws WxErrorException, IOException { - HttpRequest request = HttpRequest.post(uri); if (requestHttp.getRequestHttpProxy() != null) { requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); } - request.withConnectionProvider(requestHttp.getRequestHttpClient()); - request.query("media_id", materialId); + HttpRequest request = HttpRequest.post(uri) + .withConnectionProvider(requestHttp.getRequestHttpClient()) + .body(WxGsonBuilder.create().toJson(ImmutableMap.of("media_id", materialId))); HttpResponse response = request.send(); response.charset(StringPool.UTF_8); String responseContent = response.bodyText(); this.logger.debug("响应原始数据:{}", responseContent); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialNewsInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoOkhttpRequestExecutor.java similarity index 64% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialNewsInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoOkhttpRequestExecutor.java index 3f46ab7880..5883a05842 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialNewsInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoOkhttpRequestExecutor.java @@ -1,11 +1,13 @@ -package me.chanjar.weixin.mp.util.http.okhttp; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import com.google.common.collect.ImmutableMap; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews; -import me.chanjar.weixin.mp.util.http.MaterialNewsInfoRequestExecutor; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import okhttp3.*; import org.slf4j.Logger; @@ -16,9 +18,9 @@ /** * Created by ecoolper on 2017/5/5. */ -public class OkhttpMaterialNewsInfoRequestExecutor extends MaterialNewsInfoRequestExecutor { +public class MaterialNewsInfoOkhttpRequestExecutor extends MaterialNewsInfoRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public OkhttpMaterialNewsInfoRequestExecutor(RequestHttp requestHttp) { + public MaterialNewsInfoOkhttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -28,14 +30,15 @@ public WxMpMaterialNews execute(String uri, String materialId) throws WxErrorExc //得到httpClient OkHttpClient client = requestHttp.getRequestHttpClient(); - RequestBody requestBody = new FormBody.Builder().add("media_id", materialId).build(); + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), + WxGsonBuilder.create().toJson(ImmutableMap.of("media_id", materialId))); Request request = new Request.Builder().url(uri).post(requestBody).build(); Response response = client.newCall(request).execute(); String responseContent = response.body().string(); this.logger.debug("响应原始数据:{}", responseContent); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialNewsInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoRequestExecutor.java similarity index 60% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialNewsInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoRequestExecutor.java index 24c00fe75a..62ef709aca 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialNewsInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoRequestExecutor.java @@ -1,11 +1,8 @@ -package me.chanjar.weixin.mp.util.http; +package me.chanjar.weixin.mp.util.requestexecuter.material; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews; -import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialNewsInfoRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialNewsInfoRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialNewsInfoRequestExecutor; public abstract class MaterialNewsInfoRequestExecutor implements RequestExecutor { protected RequestHttp requestHttp; @@ -17,11 +14,11 @@ public MaterialNewsInfoRequestExecutor(RequestHttp requestHttp) { public static RequestExecutor create(RequestHttp requestHttp) { switch (requestHttp.getRequestType()) { case APACHE_HTTP: - return new ApacheMaterialNewsInfoRequestExecutor(requestHttp); + return new MaterialNewsInfoApacheHttpRequestExecutor(requestHttp); case JODD_HTTP: - return new JoddMaterialNewsInfoRequestExecutor(requestHttp); + return new MaterialNewsInfoJoddHttpRequestExecutor(requestHttp); case OK_HTTP: - return new OkhttpMaterialNewsInfoRequestExecutor(requestHttp); + return new MaterialNewsInfoOkhttpRequestExecutor(requestHttp); default: //TODO 需要优化抛出异常 return null; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadApacheHttpRequestExecutor.java similarity index 80% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadApacheHttpRequestExecutor.java index 445ff2736e..d2e1029f9c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadApacheHttpRequestExecutor.java @@ -1,13 +1,13 @@ -package me.chanjar.weixin.mp.util.http.apache; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.bean.material.WxMpMaterial; import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; import org.apache.http.Consts; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; @@ -27,8 +27,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class ApacheMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - public ApacheMaterialUploadRequestExecutor(RequestHttp requestHttp) { +public class MaterialUploadApacheHttpRequestExecutor extends MaterialUploadRequestExecutor { + public MaterialUploadApacheHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -41,7 +41,7 @@ public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throw } if (material == null) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("非法请求,material参数为空").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); } File file = material.getFile(); @@ -64,7 +64,7 @@ public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throw try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadJoddHttpRequestExecutor.java similarity index 73% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadJoddHttpRequestExecutor.java index ce30323695..a09788a8de 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadJoddHttpRequestExecutor.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.util.http.jodd; +package me.chanjar.weixin.mp.util.requestexecuter.material; import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; @@ -6,13 +6,13 @@ import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.bean.material.WxMpMaterial; import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; import java.io.File; import java.io.FileNotFoundException; @@ -22,8 +22,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class JoddMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { - public JoddMaterialUploadRequestExecutor(RequestHttp requestHttp) { +public class MaterialUploadJoddHttpRequestExecutor extends MaterialUploadRequestExecutor { + public MaterialUploadJoddHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -36,7 +36,7 @@ public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throw request.withConnectionProvider(requestHttp.getRequestHttpClient()); if (material == null) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("非法请求,material参数为空").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); } File file = material.getFile(); @@ -52,7 +52,7 @@ public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throw HttpResponse response = request.send(); response.charset(StringPool.UTF_8); String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadOkhttpRequestExecutor.java similarity index 76% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadOkhttpRequestExecutor.java index ef4bcbb299..879df49675 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadOkhttpRequestExecutor.java @@ -1,13 +1,13 @@ -package me.chanjar.weixin.mp.util.http.okhttp; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.bean.material.WxMpMaterial; import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; import okhttp3.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,18 +20,18 @@ /** * Created by ecoolper on 2017/5/5. */ -public class OkhttpMaterialUploadRequestExecutor extends MaterialUploadRequestExecutor { +public class MaterialUploadOkhttpRequestExecutor extends MaterialUploadRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public OkhttpMaterialUploadRequestExecutor(RequestHttp requestHttp) { + public MaterialUploadOkhttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @Override public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throws WxErrorException, IOException { - logger.debug("OkhttpMaterialUploadRequestExecutor is running"); + logger.debug("MaterialUploadOkhttpRequestExecutor is running"); if (material == null) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("非法请求,material参数为空").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("非法请求,material参数为空").build()); } File file = material.getFile(); if (file == null || !file.exists()) { @@ -55,7 +55,7 @@ public WxMpMaterialUploadResult execute(String uri, WxMpMaterial material) throw Request request = new Request.Builder().url(uri).post(bodyBuilder.build()).build(); Response response = client.newCall(request).execute(); String responseContent = response.body().string(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadRequestExecutor.java similarity index 62% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadRequestExecutor.java index c850d28cf9..c279be3213 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadRequestExecutor.java @@ -1,13 +1,13 @@ -package me.chanjar.weixin.mp.util.http; +package me.chanjar.weixin.mp.util.requestexecuter.material; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.material.WxMpMaterial; import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult; -import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialUploadRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialUploadRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialUploadRequestExecutor; +/** + * @author codepiano + */ public abstract class MaterialUploadRequestExecutor implements RequestExecutor { protected RequestHttp requestHttp; @@ -18,11 +18,11 @@ public MaterialUploadRequestExecutor(RequestHttp requestHttp) { public static RequestExecutor create(RequestHttp requestHttp) { switch (requestHttp.getRequestType()) { case APACHE_HTTP: - return new ApacheMaterialUploadRequestExecutor(requestHttp); + return new MaterialUploadApacheHttpRequestExecutor(requestHttp); case JODD_HTTP: - return new JoddMaterialUploadRequestExecutor(requestHttp); + return new MaterialUploadJoddHttpRequestExecutor(requestHttp); case OK_HTTP: - return new OkhttpMaterialUploadRequestExecutor(requestHttp); + return new MaterialUploadOkhttpRequestExecutor(requestHttp); default: return null; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialVideoInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoApacheHttpRequestExecutor.java similarity index 77% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialVideoInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoApacheHttpRequestExecutor.java index 7b81ea863f..65af9cf71c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialVideoInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoApacheHttpRequestExecutor.java @@ -1,12 +1,12 @@ -package me.chanjar.weixin.mp.util.http.apache; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult; -import me.chanjar.weixin.mp.util.http.MaterialVideoInfoRequestExecutor; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; @@ -21,8 +21,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class ApacheMaterialVideoInfoRequestExecutor extends MaterialVideoInfoRequestExecutor { - public ApacheMaterialVideoInfoRequestExecutor(RequestHttp requestHttp) { +public class MaterialVideoInfoApacheHttpRequestExecutor extends MaterialVideoInfoRequestExecutor { + public MaterialVideoInfoApacheHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -39,7 +39,7 @@ public WxMpMaterialVideoInfoResult execute(String uri, String materialId) throws httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params))); try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialVideoInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoJoddHttpRequestExecutor.java similarity index 69% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialVideoInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoJoddHttpRequestExecutor.java index ab4ce6682c..852bea5da4 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialVideoInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoJoddHttpRequestExecutor.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.util.http.jodd; +package me.chanjar.weixin.mp.util.requestexecuter.material; import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; @@ -6,19 +6,19 @@ import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult; -import me.chanjar.weixin.mp.util.http.MaterialVideoInfoRequestExecutor; import java.io.IOException; /** * Created by ecoolper on 2017/5/5. */ -public class JoddMaterialVideoInfoRequestExecutor extends MaterialVideoInfoRequestExecutor { - public JoddMaterialVideoInfoRequestExecutor(RequestHttp requestHttp) { +public class MaterialVideoInfoJoddHttpRequestExecutor extends MaterialVideoInfoRequestExecutor { + public MaterialVideoInfoJoddHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -34,7 +34,7 @@ public WxMpMaterialVideoInfoResult execute(String uri, String materialId) throws HttpResponse response = request.send(); response.charset(StringPool.UTF_8); String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialVideoInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoOkhttpRequestExecutor.java similarity index 71% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialVideoInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoOkhttpRequestExecutor.java index 79dd12be53..118c9673af 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialVideoInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoOkhttpRequestExecutor.java @@ -1,11 +1,11 @@ -package me.chanjar.weixin.mp.util.http.okhttp; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult; -import me.chanjar.weixin.mp.util.http.MaterialVideoInfoRequestExecutor; import okhttp3.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,16 +15,16 @@ /** * Created by ecoolper on 2017/5/5. */ -public class OkhttpMaterialVideoInfoRequestExecutor extends MaterialVideoInfoRequestExecutor { +public class MaterialVideoInfoOkhttpRequestExecutor extends MaterialVideoInfoRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public OkhttpMaterialVideoInfoRequestExecutor(RequestHttp requestHttp) { + public MaterialVideoInfoOkhttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @Override public WxMpMaterialVideoInfoResult execute(String uri, String materialId) throws WxErrorException, IOException { - logger.debug("OkhttpMaterialVideoInfoRequestExecutor is running"); + logger.debug("MaterialVideoInfoOkhttpRequestExecutor is running"); //得到httpClient OkHttpClient client = requestHttp.getRequestHttpClient(); @@ -32,7 +32,7 @@ public WxMpMaterialVideoInfoResult execute(String uri, String materialId) throws Request request = new Request.Builder().url(uri).post(requestBody).build(); Response response = client.newCall(request).execute(); String responseContent = response.body().string(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } else { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVideoInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoRequestExecutor.java similarity index 61% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVideoInfoRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoRequestExecutor.java index 73948052ff..b09fd75ae2 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVideoInfoRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoRequestExecutor.java @@ -1,13 +1,10 @@ -package me.chanjar.weixin.mp.util.http; +package me.chanjar.weixin.mp.util.requestexecuter.material; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult; - import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialVideoInfoRequestExecutor; - import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialVideoInfoRequestExecutor; - import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialVideoInfoRequestExecutor; public abstract class MaterialVideoInfoRequestExecutor implements RequestExecutor { @@ -20,11 +17,11 @@ public MaterialVideoInfoRequestExecutor(RequestHttp requestHttp) { public static RequestExecutor create(RequestHttp requestHttp) { switch (requestHttp.getRequestType()) { case APACHE_HTTP: - return new ApacheMaterialVideoInfoRequestExecutor(requestHttp); + return new MaterialVideoInfoApacheHttpRequestExecutor(requestHttp); case JODD_HTTP: - return new JoddMaterialVideoInfoRequestExecutor(requestHttp); + return new MaterialVideoInfoJoddHttpRequestExecutor(requestHttp); case OK_HTTP: - return new OkhttpMaterialVideoInfoRequestExecutor(requestHttp); + return new MaterialVideoInfoOkhttpRequestExecutor(requestHttp); default: return null; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadApacheHttpRequestExecutor.java similarity index 81% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialVoiceAndImageDownloadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadApacheHttpRequestExecutor.java index b1011a5282..cb295d0670 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadApacheHttpRequestExecutor.java @@ -1,11 +1,10 @@ -package me.chanjar.weixin.mp.util.http.apache; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler; import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.util.http.MaterialVoiceAndImageDownloadRequestExecutor; import org.apache.commons.io.IOUtils; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; @@ -25,8 +24,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class ApacheMaterialVoiceAndImageDownloadRequestExecutor extends MaterialVoiceAndImageDownloadRequestExecutor { - public ApacheMaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { +public class MaterialVoiceAndImageDownloadApacheHttpRequestExecutor extends MaterialVoiceAndImageDownloadRequestExecutor { + public MaterialVoiceAndImageDownloadApacheHttpRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { super(requestHttp, tmpDirFile); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadJoddHttpRequestExecutor.java similarity index 78% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialVoiceAndImageDownloadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadJoddHttpRequestExecutor.java index ca43a1455d..391befbbe3 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadJoddHttpRequestExecutor.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.util.http.jodd; +package me.chanjar.weixin.mp.util.requestexecuter.material; import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; @@ -6,11 +6,10 @@ import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.util.http.MaterialVoiceAndImageDownloadRequestExecutor; import org.apache.commons.io.IOUtils; import java.io.ByteArrayInputStream; @@ -22,8 +21,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class JoddMaterialVoiceAndImageDownloadRequestExecutor extends MaterialVoiceAndImageDownloadRequestExecutor { - public JoddMaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { +public class MaterialVoiceAndImageDownloadJoddHttpRequestExecutor extends MaterialVoiceAndImageDownloadRequestExecutor { + public MaterialVoiceAndImageDownloadJoddHttpRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { super(requestHttp, tmpDirFile); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadOkhttpRequestExecutor.java similarity index 73% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialVoiceAndImageDownloadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadOkhttpRequestExecutor.java index 8c48139183..8952d173f0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadOkhttpRequestExecutor.java @@ -1,15 +1,13 @@ -package me.chanjar.weixin.mp.util.http.okhttp; +package me.chanjar.weixin.mp.util.requestexecuter.material; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; -import me.chanjar.weixin.common.util.json.WxGsonBuilder; -import me.chanjar.weixin.mp.util.http.MaterialVoiceAndImageDownloadRequestExecutor; import okhttp3.*; import okio.BufferedSink; import okio.Okio; -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,16 +16,16 @@ /** * Created by ecoolper on 2017/5/5. */ -public class OkhttpMaterialVoiceAndImageDownloadRequestExecutor extends MaterialVoiceAndImageDownloadRequestExecutor { +public class MaterialVoiceAndImageDownloadOkhttpRequestExecutor extends MaterialVoiceAndImageDownloadRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public OkhttpMaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { + public MaterialVoiceAndImageDownloadOkhttpRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { super(requestHttp, tmpDirFile); } @Override public InputStream execute(String uri, String materialId) throws WxErrorException, IOException { - logger.debug("OkhttpMaterialVoiceAndImageDownloadRequestExecutor is running"); + logger.debug("MaterialVoiceAndImageDownloadOkhttpRequestExecutor is running"); OkHttpClient client = requestHttp.getRequestHttpClient(); RequestBody requestBody = new FormBody.Builder().add("media_id", materialId).build(); Request request = new Request.Builder().url(uri).get().post(requestBody).build(); @@ -35,7 +33,7 @@ public InputStream execute(String uri, String materialId) throws WxErrorExceptio String contentTypeHeader = response.header("Content-Type"); if ("text/plain".equals(contentTypeHeader)) { String responseContent = response.body().string(); - throw new WxErrorException(WxError.fromJson(responseContent)); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); } try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); BufferedSink sink = Okio.buffer(Okio.sink(outputStream))) { sink.writeAll(response.body().source()); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadRequestExecutor.java similarity index 54% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadRequestExecutor.java index 09cb70d0f5..c11c41cce0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVoiceAndImageDownloadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadRequestExecutor.java @@ -1,15 +1,13 @@ -package me.chanjar.weixin.mp.util.http; +package me.chanjar.weixin.mp.util.requestexecuter.material; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.mp.util.http.apache.ApacheMaterialVoiceAndImageDownloadRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddMaterialVoiceAndImageDownloadRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMaterialVoiceAndImageDownloadRequestExecutor; import java.io.File; import java.io.InputStream; -public abstract class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExecutor { +public abstract class MaterialVoiceAndImageDownloadRequestExecutor + implements RequestExecutor { protected RequestHttp requestHttp; protected File tmpDirFile; @@ -21,11 +19,11 @@ public MaterialVoiceAndImageDownloadRequestExecutor(RequestHttp requestHttp, Fil public static RequestExecutor create(RequestHttp requestHttp, File tmpDirFile) { switch (requestHttp.getRequestType()) { case APACHE_HTTP: - return new ApacheMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + return new MaterialVoiceAndImageDownloadApacheHttpRequestExecutor(requestHttp, tmpDirFile); case JODD_HTTP: - return new JoddMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + return new MaterialVoiceAndImageDownloadJoddHttpRequestExecutor(requestHttp, tmpDirFile); case OK_HTTP: - return new OkhttpMaterialVoiceAndImageDownloadRequestExecutor(requestHttp, tmpDirFile); + return new MaterialVoiceAndImageDownloadOkhttpRequestExecutor(requestHttp, tmpDirFile); default: return null; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadApacheHttpRequestExecutor.java similarity index 73% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadApacheHttpRequestExecutor.java index 63e278e43c..dc6d979222 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheMediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadApacheHttpRequestExecutor.java @@ -1,11 +1,11 @@ -package me.chanjar.weixin.mp.util.http.apache; +package me.chanjar.weixin.mp.util.requestexecuter.media; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; @@ -21,16 +21,18 @@ /** * Created by ecoolper on 2017/5/5. + * + * @author ecoolper */ -public class ApacheMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { - public ApacheMediaImgUploadRequestExecutor(RequestHttp requestHttp) { +public class MediaImgUploadApacheHttpRequestExecutor extends MediaImgUploadRequestExecutor { + public MediaImgUploadApacheHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @Override public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { if (data == null) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("文件对象为空").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); } HttpPost httpPost = new HttpPost(uri); @@ -49,12 +51,14 @@ public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorExcep try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } return WxMediaImgUploadResult.fromJson(responseContent); + } finally { + httpPost.releaseConnection(); } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadHttpRequestExecutor.java similarity index 69% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadHttpRequestExecutor.java index d0fdbfb856..c7ff37ba88 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddMediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadHttpRequestExecutor.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.util.http.jodd; +package me.chanjar.weixin.mp.util.requestexecuter.media; import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; @@ -6,27 +6,29 @@ import jodd.http.ProxyInfo; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; import java.io.File; import java.io.IOException; /** * Created by ecoolper on 2017/5/5. + * + * @author ecoolper */ -public class JoddMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { - public JoddMediaImgUploadRequestExecutor(RequestHttp requestHttp) { +public class MediaImgUploadHttpRequestExecutor extends MediaImgUploadRequestExecutor { + public MediaImgUploadHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @Override public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorException, IOException { if (data == null) { - throw new WxErrorException(WxError.newBuilder().setErrorMsg("文件对象为空").build()); + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); } HttpRequest request = HttpRequest.post(uri); @@ -39,7 +41,7 @@ public WxMediaImgUploadResult execute(String uri, File data) throws WxErrorExcep HttpResponse response = request.send(); response.charset(StringPool.UTF_8); String responseContent = response.bodyText(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadOkhttpRequestExecutor.java similarity index 73% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMediaImgUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadOkhttpRequestExecutor.java index f8e5859287..c787126e30 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/okhttp/OkhttpMediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadOkhttpRequestExecutor.java @@ -1,11 +1,11 @@ -package me.chanjar.weixin.mp.util.http.okhttp; +package me.chanjar.weixin.mp.util.requestexecuter.media; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; import okhttp3.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,17 +15,19 @@ /** * Created by ecoolper on 2017/5/5. + * + * @author ecoolper */ -public class OkhttpMediaImgUploadRequestExecutor extends MediaImgUploadRequestExecutor { +public class MediaImgUploadOkhttpRequestExecutor extends MediaImgUploadRequestExecutor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); - public OkhttpMediaImgUploadRequestExecutor(RequestHttp requestHttp) { + public MediaImgUploadOkhttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @Override public WxMediaImgUploadResult execute(String uri, File file) throws WxErrorException, IOException { - logger.debug("OkhttpMediaImgUploadRequestExecutor is running"); + logger.debug("MediaImgUploadOkhttpRequestExecutor is running"); //得到httpClient OkHttpClient client = requestHttp.getRequestHttpClient(); @@ -39,7 +41,7 @@ public WxMediaImgUploadResult execute(String uri, File file) throws WxErrorExcep Request request = new Request.Builder().url(uri).post(body).build(); Response response = client.newCall(request).execute(); String responseContent = response.body().string(); - WxError error = WxError.fromJson(responseContent); + WxError error = WxError.fromJson(responseContent, WxType.MP); if (error.getErrorCode() != 0) { throw new WxErrorException(error); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadRequestExecutor.java similarity index 61% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MediaImgUploadRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadRequestExecutor.java index e187561fc8..c937fbe51a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MediaImgUploadRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadRequestExecutor.java @@ -1,11 +1,8 @@ -package me.chanjar.weixin.mp.util.http; +package me.chanjar.weixin.mp.util.requestexecuter.media; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult; -import me.chanjar.weixin.mp.util.http.apache.ApacheMediaImgUploadRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddMediaImgUploadRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpMediaImgUploadRequestExecutor; import java.io.File; @@ -22,11 +19,11 @@ public MediaImgUploadRequestExecutor(RequestHttp requestHttp) { public static RequestExecutor create(RequestHttp requestHttp) { switch (requestHttp.getRequestType()) { case APACHE_HTTP: - return new ApacheMediaImgUploadRequestExecutor(requestHttp); + return new MediaImgUploadApacheHttpRequestExecutor(requestHttp); case JODD_HTTP: - return new JoddMediaImgUploadRequestExecutor(requestHttp); + return new MediaImgUploadHttpRequestExecutor(requestHttp); case OK_HTTP: - return new OkhttpMediaImgUploadRequestExecutor(requestHttp); + return new MediaImgUploadOkhttpRequestExecutor(requestHttp); default: return null; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheQrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeApacheHttpRequestExecutor.java similarity index 80% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheQrCodeRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeApacheHttpRequestExecutor.java index d7bfe637c5..6280be7a0b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/apache/ApacheQrCodeRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeApacheHttpRequestExecutor.java @@ -1,13 +1,13 @@ -package me.chanjar.weixin.mp.util.http.apache; +package me.chanjar.weixin.mp.util.requestexecuter.qrcode; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler; import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; @@ -25,8 +25,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class ApacheQrCodeRequestExecutor extends QrCodeRequestExecutor { - public ApacheQrCodeRequestExecutor(RequestHttp requestHttp) { +public class QrCodeApacheHttpRequestExecutor extends QrCodeRequestExecutor { + public QrCodeApacheHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -52,9 +52,10 @@ public File execute(String uri, WxMpQrCodeTicket ticket) throws WxErrorException Header[] contentTypeHeader = response.getHeaders("Content-Type"); if (contentTypeHeader != null && contentTypeHeader.length > 0) { // 出错 - if (ContentType.TEXT_PLAIN.getMimeType().equals(contentTypeHeader[0].getValue())) { + if (ContentType.TEXT_PLAIN.getMimeType() + .equals(ContentType.parse(contentTypeHeader[0].getValue()).getMimeType())) { String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); - throw new WxErrorException(WxError.fromJson(responseContent)); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); } } return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddQrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeJoddHttpRequestExecutor.java similarity index 81% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddQrCodeRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeJoddHttpRequestExecutor.java index 8b15dccf00..1798065f3e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/jodd/JoddQrCodeRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeJoddHttpRequestExecutor.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.util.http.jodd; +package me.chanjar.weixin.mp.util.requestexecuter.qrcode; import jodd.http.HttpConnectionProvider; import jodd.http.HttpRequest; @@ -7,12 +7,12 @@ import jodd.util.MimeTypes; import jodd.util.StringPool; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; import java.io.ByteArrayInputStream; import java.io.File; @@ -24,8 +24,8 @@ /** * Created by ecoolper on 2017/5/5. */ -public class JoddQrCodeRequestExecutor extends QrCodeRequestExecutor { - public JoddQrCodeRequestExecutor(RequestHttp requestHttp) { +public class QrCodeJoddHttpRequestExecutor extends QrCodeRequestExecutor { + public QrCodeJoddHttpRequestExecutor(RequestHttp requestHttp) { super(requestHttp); } @@ -51,7 +51,7 @@ public File execute(String uri, WxMpQrCodeTicket ticket) throws WxErrorException String contentTypeHeader = response.header("Content-Type"); if (MimeTypes.MIME_TEXT_PLAIN.equals(contentTypeHeader)) { String responseContent = response.bodyText(); - throw new WxErrorException(WxError.fromJson(responseContent)); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); } try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) { return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeOkhttpRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeOkhttpRequestExecutor.java new file mode 100644 index 0000000000..825af37725 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeOkhttpRequestExecutor.java @@ -0,0 +1,61 @@ +package me.chanjar.weixin.mp.util.requestexecuter.qrcode; + +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * + * @author ecoolper + * @date 2017/5/5 + */ +public class QrCodeOkhttpRequestExecutor extends QrCodeRequestExecutor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public QrCodeOkhttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public File execute(String uri, WxMpQrCodeTicket ticket) throws WxErrorException, IOException { + logger.debug("QrCodeOkhttpRequestExecutor is running"); + + if (ticket != null) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") + ? "ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8") + : "&ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8"); + } + + OkHttpClient client = requestHttp.getRequestHttpClient(); + Request request = new Request.Builder().url(uri).get().build(); + Response response = client.newCall(request).execute(); + String contentTypeHeader = response.header("Content-Type"); + if ("text/plain".equals(contentTypeHeader)) { + String responseContent = response.body().string(); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); + } + + try (InputStream inputStream = response.body().byteStream()) { + return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); + } + + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeRequestExecutor.java similarity index 57% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeRequestExecutor.java index 87c1920cd8..7c666cd0d5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeRequestExecutor.java @@ -1,11 +1,10 @@ -package me.chanjar.weixin.mp.util.http; +package me.chanjar.weixin.mp.util.requestexecuter.qrcode; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; -import me.chanjar.weixin.mp.util.http.apache.ApacheQrCodeRequestExecutor; -import me.chanjar.weixin.mp.util.http.jodd.JoddQrCodeRequestExecutor; -import me.chanjar.weixin.mp.util.http.okhttp.OkhttpQrCodeRequestExecutor; import java.io.File; @@ -21,17 +20,16 @@ public QrCodeRequestExecutor(RequestHttp requestHttp) { this.requestHttp = requestHttp; } - public static RequestExecutor create(RequestHttp requestHttp) { + public static RequestExecutor create(RequestHttp requestHttp) throws WxErrorException { switch (requestHttp.getRequestType()) { case APACHE_HTTP: - return new ApacheQrCodeRequestExecutor(requestHttp); + return new QrCodeApacheHttpRequestExecutor(requestHttp); case JODD_HTTP: - return new JoddQrCodeRequestExecutor(requestHttp); + return new QrCodeJoddHttpRequestExecutor(requestHttp); case OK_HTTP: - return new OkhttpQrCodeRequestExecutor(requestHttp); + return new QrCodeOkhttpRequestExecutor(requestHttp); default: - //TODO 需要优化,最好抛出异常 - return null; + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build()); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/voice/VoiceUploadApacheHttpRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/voice/VoiceUploadApacheHttpRequestExecutor.java new file mode 100644 index 0000000000..c23b3a3219 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/voice/VoiceUploadApacheHttpRequestExecutor.java @@ -0,0 +1,65 @@ +package me.chanjar.weixin.mp.util.requestexecuter.voice; + +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.IOException; + +/** + *
+ *  Created by BinaryWang on 2018/6/9.
+ * 
+ * + * @author Binary Wang + */ +public class VoiceUploadApacheHttpRequestExecutor extends VoiceUploadRequestExecutor { + public VoiceUploadApacheHttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public Boolean execute(String uri, File data) throws WxErrorException, IOException { + if (data == null) { + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件对象为空").build()); + } + + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + + HttpEntity entity = MultipartEntityBuilder + .create() + .addBinaryBody("media", data) + .setMode(HttpMultipartMode.RFC6532) + .build(); + httpPost.setEntity(entity); + httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent, WxType.MP); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + + return true; + } finally { + httpPost.releaseConnection(); + } + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/voice/VoiceUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/voice/VoiceUploadRequestExecutor.java new file mode 100644 index 0000000000..34c7ae2108 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/voice/VoiceUploadRequestExecutor.java @@ -0,0 +1,33 @@ +package me.chanjar.weixin.mp.util.requestexecuter.voice; + +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; + +import java.io.File; + +/** + *
+ *  Created by BinaryWang on 2018/6/9.
+ * 
+ * + * @author Binary Wang + */ +public abstract class VoiceUploadRequestExecutor implements RequestExecutor { + protected RequestHttp requestHttp; + + public VoiceUploadRequestExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + public static RequestExecutor create(RequestHttp requestHttp) { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new VoiceUploadApacheHttpRequestExecutor(requestHttp); + case JODD_HTTP: + case OK_HTTP: + default: + return null; + } + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java index 6835fa47a9..ace711a236 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/xml/XStreamTransformer.java @@ -1,11 +1,22 @@ package me.chanjar.weixin.mp.util.xml; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.thoughtworks.xstream.XStream; import me.chanjar.weixin.common.util.xml.XStreamInitializer; -import me.chanjar.weixin.mp.bean.message.*; - -import java.io.InputStream; -import java.util.*; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutImageMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMusicMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTransferKefuMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutVideoMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutVoiceMessage; public class XStreamTransformer { private static final Map, XStream> CLASS_2_XSTREAM_INSTANCE = new HashMap<>(); @@ -22,7 +33,7 @@ public class XStreamTransformer { } /** - * xml -> pojo + * xml -> pojo. */ @SuppressWarnings("unchecked") public static T fromXml(Class clazz, String xml) { @@ -37,29 +48,30 @@ public static T fromXml(Class clazz, InputStream is) { } /** - * pojo -> xml + * pojo -> xml. */ public static String toXml(Class clazz, T object) { return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); } /** - * 注册扩展消息的解析器 + * 注册扩展消息的解析器. * * @param clz 类型 * @param xStream xml解析器 */ - private static void register(Class clz, XStream xStream) { + public static void register(Class clz, XStream xStream) { CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); } /** - * 会自动注册该类及其子类 + * 会自动注册该类及其子类. * * @param clz 要注册的类 */ private static void registerClass(Class clz) { XStream xstream = XStreamInitializer.getInstance(); + xstream.processAnnotations(clz); xstream.processAnnotations(getInnerClasses(clz)); if (clz.equals(WxMpXmlMessage.class)) { diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java index 7fb10716f0..ffcd232cf4 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBaseAPITest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.test.ApiTestModule; import org.apache.commons.lang3.StringUtils; import org.testng.*; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java index fc0f70b776..507ab31b6b 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpBusyRetryTest.java @@ -1,9 +1,9 @@ package me.chanjar.weixin.mp.api; -import me.chanjar.weixin.common.bean.result.WxError; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.mp.api.impl.WxMpServiceApacheHttpClientImpl; +import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; import org.testng.annotations.*; import java.util.concurrent.ExecutionException; @@ -16,16 +16,14 @@ public class WxMpBusyRetryTest { @DataProvider(name = "getService") public Object[][] getService() { - WxMpService service = new WxMpServiceApacheHttpClientImpl() { + WxMpService service = new WxMpServiceHttpClientImpl() { @Override public synchronized T executeInternal( RequestExecutor executor, String uri, E data) throws WxErrorException { this.log.info("Executed"); - WxError error = new WxError(); - error.setErrorCode(-1); - throw new WxErrorException(error); + throw new WxErrorException(WxError.builder().errorCode(-1).build()); } }; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpJsAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpJsAPITest.java index e6be87302d..0b14d9564b 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpJsAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpJsAPITest.java @@ -1,7 +1,6 @@ package me.chanjar.weixin.mp.api; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.mp.api.test.ApiTestModule; import org.testng.*; @@ -23,7 +22,7 @@ public class WxMpJsAPITest { public void test() { - long timestamp = 1419835025l; + long timestamp = 1419835025L; String url = "http://omstest.vmall.com:23568/thirdparty/wechat/vcode/gotoshare?quantity=1&batchName=MATE7"; String noncestr = "82693e11-b9bc-448e-892f-f5289f46cd0f"; String jsapiTicket = "bxLdikRXVbTPdHSM05e5u4RbEYQn7pNQMPrfzl8lJNb1foLDa3HIwI3BRMkQmSO_5F64VFa75uURcq6Uz7QHgA"; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java index 35d13ee1e9..b9424eb023 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMessageRouterTest.java @@ -8,6 +8,8 @@ import org.testng.*; import org.testng.annotations.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.Map; /** @@ -23,21 +25,21 @@ public void prepare(boolean async, StringBuffer sb, WxMpMessageRouter router) { router .rule() .async(async) - .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1") + .msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1").content("CONTENT_1") .handler(new WxEchoMpMessageHandler(sb, "COMBINE_4")) .end() .rule() .async(async) - .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1") + .msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1") .handler(new WxEchoMpMessageHandler(sb, "COMBINE_3")) .end() .rule() .async(async) - .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK) + .msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK) .handler(new WxEchoMpMessageHandler(sb, "COMBINE_2")) .end() - .rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoMpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end() - .rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoMpMessageHandler(sb, WxConsts.EVT_CLICK)).end() + .rule().async(async).msgType(WxConsts.XmlMsgType.TEXT).handler(new WxEchoMpMessageHandler(sb, WxConsts.XmlMsgType.TEXT)).end() + .rule().async(async).event(WxConsts.EventType.CLICK).handler(new WxEchoMpMessageHandler(sb, WxConsts.EventType.CLICK)).end() .rule().async(async).eventKey("KEY_1").handler(new WxEchoMpMessageHandler(sb, "KEY_1")).end() .rule().async(async).eventKeyRegex("KEY_1*").handler(new WxEchoMpMessageHandler(sb, "KEY_123")).end() .rule().async(async).content("CONTENT_1").handler(new WxEchoMpMessageHandler(sb, "CONTENT_1")).end() @@ -66,10 +68,24 @@ public void testAsync(WxMpXmlMessage message, String expected) throws Interrupte WxMpMessageRouter router = new WxMpMessageRouter(null); prepare(true, sb, router); router.route(message); - Thread.sleep(500l); + Thread.sleep(500); + router.shutDownExecutorService(); Assert.assertEquals(sb.toString(), expected); } + @Test(dataProvider = "messages-1") + public void testExternalExcutorService(WxMpXmlMessage message, String expected) throws InterruptedException { + StringBuffer sb = new StringBuffer(); + ExecutorService executorService = Executors.newFixedThreadPool(100); + WxMpMessageRouter router = new WxMpMessageRouter(null, executorService); + prepare(true, sb, router); + router.route(message); + Thread.sleep(500); + executorService.shutdown(); + Assert.assertEquals(sb.toString(), expected); + } + + public void testConcurrency() throws InterruptedException { final WxMpMessageRouter router = new WxMpMessageRouter(null); router.rule().handler(new WxMpMessageHandler() { @@ -86,7 +102,7 @@ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map co public void run() { router.route(m); try { - Thread.sleep(1000l); + Thread.sleep(1000); } catch (InterruptedException e) { } } @@ -95,16 +111,16 @@ public void run() { new Thread(r).start(); } - Thread.sleep(1000l * 2); + Thread.sleep(2000); } @DataProvider(name = "messages-1") public Object[][] messages2() { WxMpXmlMessage message1 = new WxMpXmlMessage(); - message1.setMsgType(WxConsts.XML_MSG_TEXT); + message1.setMsgType(WxConsts.XmlMsgType.TEXT); WxMpXmlMessage message2 = new WxMpXmlMessage(); - message2.setEvent(WxConsts.EVT_CLICK); + message2.setEvent(WxConsts.EventType.CLICK); WxMpXmlMessage message3 = new WxMpXmlMessage(); message3.setEventKey("KEY_1"); @@ -122,23 +138,23 @@ public Object[][] messages2() { message7.setFormat("strangeformat"); WxMpXmlMessage c2 = new WxMpXmlMessage(); - c2.setMsgType(WxConsts.XML_MSG_TEXT); - c2.setEvent(WxConsts.EVT_CLICK); + c2.setMsgType(WxConsts.XmlMsgType.TEXT); + c2.setEvent(WxConsts.EventType.CLICK); WxMpXmlMessage c3 = new WxMpXmlMessage(); - c3.setMsgType(WxConsts.XML_MSG_TEXT); - c3.setEvent(WxConsts.EVT_CLICK); + c3.setMsgType(WxConsts.XmlMsgType.TEXT); + c3.setEvent(WxConsts.EventType.CLICK); c3.setEventKey("KEY_1"); WxMpXmlMessage c4 = new WxMpXmlMessage(); - c4.setMsgType(WxConsts.XML_MSG_TEXT); - c4.setEvent(WxConsts.EVT_CLICK); + c4.setMsgType(WxConsts.XmlMsgType.TEXT); + c4.setEvent(WxConsts.EventType.CLICK); c4.setEventKey("KEY_1"); c4.setContent("CONTENT_1"); return new Object[][]{ - new Object[]{message1, WxConsts.XML_MSG_TEXT + ","}, - new Object[]{message2, WxConsts.EVT_CLICK + ","}, + new Object[]{message1, WxConsts.XmlMsgType.TEXT + ","}, + new Object[]{message2, WxConsts.EventType.CLICK + ","}, new Object[]{message3, "KEY_1,"}, new Object[]{message4, "CONTENT_1,"}, new Object[]{message5, "ALL,"}, @@ -180,7 +196,7 @@ public void testSessionClean1(StandardSessionManager ism) throws InterruptedExce msg.setFromUser("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -200,7 +216,7 @@ public void testSessionClean2(StandardSessionManager ism) throws InterruptedExce msg.setFromUser("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } { @@ -214,7 +230,7 @@ public void testSessionClean2(StandardSessionManager ism) throws InterruptedExce msg.setFromUser("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -234,7 +250,7 @@ public void testSessionClean3(StandardSessionManager ism) throws InterruptedExce msg.setFromUser("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -253,7 +269,7 @@ public void testSessionClean4(StandardSessionManager ism) throws InterruptedExce msg.setFromUser("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } @@ -267,7 +283,7 @@ public void testSessionClean4(StandardSessionManager ism) throws InterruptedExce msg.setFromUser("abc"); router.route(msg); - Thread.sleep(2000l); + Thread.sleep(2000); Assert.assertEquals(ism.getActiveSessions(), 0); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java index 8c61a56059..d8ed016b37 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpMiscAPITest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.test.ApiTestModule; import org.testng.*; import org.testng.annotations.*; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpShortUrlAPITest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpShortUrlAPITest.java index 3e8a45c361..ec6e75d7c5 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpShortUrlAPITest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/WxMpShortUrlAPITest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.test.ApiTestModule; import org.testng.*; import org.testng.annotations.*; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImplTest.java new file mode 100644 index 0000000000..f10f988866 --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImplTest.java @@ -0,0 +1,47 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.AiLangType; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.test.ApiTestModule; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.io.File; + +/** + *
+ *  Created by BinaryWang on 2018/6/10.
+ * 
+ * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMpAiOpenServiceImplTest { + @Inject + protected WxMpService wxService; + + @Test + public void testUploadVoice() throws WxErrorException { + String voiceId = System.currentTimeMillis() + "a"; + AiLangType lang = AiLangType.zh_CN; + this.wxService.getAiOpenService().uploadVoice(voiceId, lang, new File("d:\\t.mp3")); + } + + @Test + public void testRecogniseVoice() throws WxErrorException { + String voiceId = System.currentTimeMillis() + "a"; + AiLangType lang = AiLangType.zh_CN; + final String result = this.wxService.getAiOpenService().recogniseVoice(voiceId, lang, new File("d:\\t.mp3")); + System.out.println(result); + } + + @Test + public void testTranslate() throws WxErrorException { + final String responseContent = this.wxService.getAiOpenService() + .translate(AiLangType.zh_CN, AiLangType.en_US, "微信文档很坑爹"); + System.out.println(responseContent); + } +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java index 3036013a7e..06945d9a08 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java @@ -91,4 +91,13 @@ public void testGetCardDetail() throws Exception { System.out.println(result); } + @Test + public void testUnavailableCardCode() throws Exception { + String cardId = "p2iQk1luzj50RHue6yeTPQpAx_Z4"; + String code = "134905347310"; + String reason = "换成新卡了"; + String result = this.wxService.getCardService().unavailableCardCode(cardId, code, reason); + assertNotNull(result); + System.out.println(result); + } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImplTest.java index 0f465d4a47..e5e0e22586 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDataCubeServiceImplTest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.bean.datacube.*; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImplTest.java index d48161e354..2039a5f32b 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImplTest.java @@ -2,7 +2,7 @@ import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.bean.device.WxDeviceQrCodeResult; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImplTest.java index 2bf5de1dc4..712e887423 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImplTest.java @@ -1,20 +1,28 @@ package me.chanjar.weixin.mp.api.impl; +import java.io.File; +import java.util.Date; + +import org.joda.time.DateTime; +import org.testng.annotations.*; + import com.google.inject.Inject; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.api.test.TestConfigStorage; import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; -import me.chanjar.weixin.mp.bean.kefu.result.*; -import org.joda.time.DateTime; -import org.testng.*; -import org.testng.annotations.*; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfInfo; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList; +import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList; -import java.io.File; -import java.util.Date; +import static org.assertj.core.api.Assertions.assertThat; /** * 测试客服相关接口 @@ -29,53 +37,50 @@ public class WxMpKefuServiceImplTest { protected WxMpService wxService; public void testSendKefuMpNewsMessage() throws WxErrorException { - TestConfigStorage configStorage = (TestConfigStorage) this.wxService - .getWxMpConfigStorage(); + TestConfigStorage configStorage = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); WxMpKefuMessage message = new WxMpKefuMessage(); - message.setMsgType(WxConsts.CUSTOM_MSG_MPNEWS); + message.setMsgType(WxConsts.KefuMsgType.MPNEWS); message.setToUser(configStorage.getOpenid()); message.setMpNewsMediaId("52R6dL2FxDpM9N1rCY3sYBqHwq-L7K_lz1sPI71idMg"); - this.wxService.getKefuService().sendKefuMessage(message); + boolean result = this.wxService.getKefuService().sendKefuMessage(message); + assertThat(result).isTrue(); } public void testSendKefuMessage() throws WxErrorException { - TestConfigStorage configStorage = (TestConfigStorage) this.wxService - .getWxMpConfigStorage(); + TestConfigStorage configStorage = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); WxMpKefuMessage message = new WxMpKefuMessage(); - message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); + message.setMsgType(WxConsts.KefuMsgType.TEXT); message.setToUser(configStorage.getOpenid()); - message.setContent( - "欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); + message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); - this.wxService.getKefuService().sendKefuMessage(message); + boolean result = this.wxService.getKefuService().sendKefuMessage(message); + assertThat(result).isTrue(); } public void testSendKefuMessageWithKfAccount() throws WxErrorException { - TestConfigStorage configStorage = (TestConfigStorage) this.wxService - .getWxMpConfigStorage(); + TestConfigStorage configStorage = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); WxMpKefuMessage message = new WxMpKefuMessage(); - message.setMsgType(WxConsts.CUSTOM_MSG_TEXT); + message.setMsgType(WxConsts.KefuMsgType.TEXT); message.setToUser(configStorage.getOpenid()); message.setKfAccount(configStorage.getKfAccount()); - message.setContent( - "欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); + message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); - this.wxService.getKefuService().sendKefuMessage(message); + boolean result = this.wxService.getKefuService().sendKefuMessage(message); + assertThat(result).isTrue(); } public void testKfList() throws WxErrorException { WxMpKfList kfList = this.wxService.getKefuService().kfList(); - Assert.assertNotNull(kfList); + assertThat(kfList).isNotNull(); for (WxMpKfInfo k : kfList.getKfList()) { System.err.println(k); } } public void testKfOnlineList() throws WxErrorException { - WxMpKfOnlineList kfOnlineList = this.wxService.getKefuService() - .kfOnlineList(); - Assert.assertNotNull(kfOnlineList); + WxMpKfOnlineList kfOnlineList = this.wxService.getKefuService().kfOnlineList(); + assertThat(kfOnlineList).isNotNull(); for (WxMpKfInfo k : kfOnlineList.getKfOnlineList()) { System.err.println(k); } @@ -83,8 +88,7 @@ public void testKfOnlineList() throws WxErrorException { @DataProvider public Object[][] getKfAccount() { - TestConfigStorage configStorage = (TestConfigStorage) this.wxService - .getWxMpConfigStorage(); + TestConfigStorage configStorage = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); return new Object[][]{{configStorage.getKfAccount()}}; } @@ -92,7 +96,7 @@ public Object[][] getKfAccount() { public void testKfAccountAdd(String kfAccount) throws WxErrorException { WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() .kfAccount(kfAccount).nickName("我晕").build(); - Assert.assertTrue(this.wxService.getKefuService().kfAccountAdd(request)); + assertThat(this.wxService.getKefuService().kfAccountAdd(request)).isTrue(); } @Test(dependsOnMethods = { @@ -100,7 +104,7 @@ public void testKfAccountAdd(String kfAccount) throws WxErrorException { public void testKfAccountUpdate(String kfAccount) throws WxErrorException { WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() .kfAccount(kfAccount).nickName("我晕").build(); - Assert.assertTrue(this.wxService.getKefuService().kfAccountUpdate(request)); + assertThat(this.wxService.getKefuService().kfAccountUpdate(request)).isTrue(); } @Test(dependsOnMethods = { @@ -108,71 +112,58 @@ public void testKfAccountUpdate(String kfAccount) throws WxErrorException { public void testKfAccountInviteWorker(String kfAccount) throws WxErrorException { WxMpKfAccountRequest request = WxMpKfAccountRequest.builder() .kfAccount(kfAccount).inviteWx(" ").build(); - Assert.assertTrue(this.wxService.getKefuService().kfAccountInviteWorker(request)); + assertThat(this.wxService.getKefuService().kfAccountInviteWorker(request)).isTrue(); } - @Test(dependsOnMethods = { - "testKfAccountUpdate"}, dataProvider = "getKfAccount") - public void testKfAccountUploadHeadImg(String kfAccount) - throws WxErrorException { + @Test(dependsOnMethods = {"testKfAccountUpdate", "testKfAccountAdd"}, dataProvider = "getKfAccount") + public void testKfAccountUploadHeadImg(String kfAccount) throws WxErrorException { File imgFile = new File("src\\test\\resources\\mm.jpeg"); - boolean result = this.wxService.getKefuService() - .kfAccountUploadHeadImg(kfAccount, imgFile); - Assert.assertTrue(result); + boolean result = this.wxService.getKefuService().kfAccountUploadHeadImg(kfAccount, imgFile); + assertThat(result).isTrue(); } @Test(dataProvider = "getKfAccount") public void testKfAccountDel(String kfAccount) throws WxErrorException { boolean result = this.wxService.getKefuService().kfAccountDel(kfAccount); - Assert.assertTrue(result); + assertThat(result).isTrue(); } @DataProvider public Object[][] getKfAccountAndOpenid() { - TestConfigStorage configStorage = (TestConfigStorage) this.wxService - .getWxMpConfigStorage(); - return new Object[][]{ - {configStorage.getKfAccount(), configStorage.getOpenid()}}; + TestConfigStorage configStorage = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); + return new Object[][]{{configStorage.getKfAccount(), configStorage.getOpenid()}}; } @Test(dataProvider = "getKfAccountAndOpenid") - public void testKfSessionCreate(String kfAccount, String openid) - throws WxErrorException { - boolean result = this.wxService.getKefuService().kfSessionCreate(openid, - kfAccount); - Assert.assertTrue(result); + public void testKfSessionCreate(String kfAccount, String openid) throws WxErrorException { + boolean result = this.wxService.getKefuService().kfSessionCreate(openid, kfAccount); + assertThat(result).isTrue(); } @Test(dataProvider = "getKfAccountAndOpenid") - public void testKfSessionClose(String kfAccount, String openid) - throws WxErrorException { - boolean result = this.wxService.getKefuService().kfSessionClose(openid, - kfAccount); - Assert.assertTrue(result); + public void testKfSessionClose(String kfAccount, String openid) throws WxErrorException { + boolean result = this.wxService.getKefuService().kfSessionClose(openid, kfAccount); + assertThat(result).isTrue(); } @Test(dataProvider = "getKfAccountAndOpenid") - public void testKfSessionGet(@SuppressWarnings("unused") String kfAccount, - String openid) throws WxErrorException { - WxMpKfSessionGetResult result = this.wxService.getKefuService() - .kfSessionGet(openid); - Assert.assertNotNull(result); + public void testKfSessionGet(@SuppressWarnings("unused") String kfAccount, String openid) throws WxErrorException { + WxMpKfSessionGetResult result = this.wxService.getKefuService().kfSessionGet(openid); + assertThat(result).isNotNull(); System.err.println(result); } @Test(dataProvider = "getKfAccount") public void testKfSessionList(String kfAccount) throws WxErrorException { - WxMpKfSessionList result = this.wxService.getKefuService() - .kfSessionList(kfAccount); - Assert.assertNotNull(result); + WxMpKfSessionList result = this.wxService.getKefuService().kfSessionList(kfAccount); + assertThat(result).isNotNull(); System.err.println(result); } @Test public void testKfSessionGetWaitCase() throws WxErrorException { - WxMpKfSessionWaitCaseList result = this.wxService.getKefuService() - .kfSessionGetWaitCase(); - Assert.assertNotNull(result); + WxMpKfSessionWaitCaseList result = this.wxService.getKefuService().kfSessionGetWaitCase(); + assertThat(result).isNotNull(); System.err.println(result); } @@ -181,7 +172,7 @@ public void testKfMsgList() throws WxErrorException { Date startTime = DateTime.now().minusDays(1).toDate(); Date endTime = DateTime.now().minusDays(0).toDate(); WxMpKfMsgList result = this.wxService.getKefuService().kfMsgList(startTime, endTime, 1L, 50); - Assert.assertNotNull(result); + assertThat(result).isNotNull(); System.err.println(result); } @@ -190,7 +181,14 @@ public void testKfMsgListAll() throws WxErrorException { Date startTime = DateTime.now().minusDays(1).toDate(); Date endTime = DateTime.now().minusDays(0).toDate(); WxMpKfMsgList result = this.wxService.getKefuService().kfMsgList(startTime, endTime); - Assert.assertNotNull(result); + assertThat(result).isNotNull(); System.err.println(result); } + + @Test + public void testSendKfTypingState() throws WxErrorException { + TestConfigStorage configStorage = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); + boolean result = this.wxService.getKefuService().sendKfTypingState(configStorage.getOpenid(), "Typing"); + assertThat(result).isTrue(); + } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImplTest.java index 3b6c048981..f2d7683021 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMassMessageServiceImplTest.java @@ -3,7 +3,7 @@ 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.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.api.test.TestConfigStorage; @@ -38,7 +38,7 @@ public void testTextMassOpenIdsMessageSend() throws WxErrorException { TestConfigStorage configProvider = (TestConfigStorage) this.wxService .getWxMpConfigStorage(); WxMpMassOpenIdsMessage massMessage = new WxMpMassOpenIdsMessage(); - massMessage.setMsgType(WxConsts.MASS_MSG_TEXT); + massMessage.setMsgType(WxConsts.MassMsgType.TEXT); massMessage.setContent("测试群发消息\n欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); massMessage.getToUsers().add(configProvider.getOpenid()); @@ -67,7 +67,7 @@ public void testMediaMassOpenIdsMessageSend(String massMsgType, String mediaId) @Test public void testTextMassGroupMessageSend() throws WxErrorException { WxMpMassTagMessage massMessage = new WxMpMassTagMessage(); - massMessage.setMsgType(WxConsts.MASS_MSG_TEXT); + massMessage.setMsgType(WxConsts.MassMsgType.TEXT); massMessage.setContent("测试群发消息\n欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World"); massMessage .setTagId(this.wxService.getUserTagService().tagGet().get(0).getId()); @@ -103,7 +103,7 @@ public Object[][] massMessages() throws WxErrorException, IOException { .getSystemResourceAsStream("mm.mp4")) { // 上传视频到媒体库 WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, inputStream); + .mediaUpload(WxConsts.MediaFileType.VIDEO, TestConstants.FILE_MP4, inputStream); assertNotNull(uploadMediaRes); assertNotNull(uploadMediaRes.getMediaId()); @@ -115,7 +115,7 @@ public Object[][] massMessages() throws WxErrorException, IOException { WxMpMassUploadResult uploadResult = this.wxService.getMassMessageService().massVideoUpload(video); assertNotNull(uploadResult); assertNotNull(uploadResult.getMediaId()); - messages[0] = new Object[]{WxConsts.MASS_MSG_VIDEO, uploadResult.getMediaId()}; + messages[0] = new Object[]{WxConsts.MassMsgType.MPVIDEO, uploadResult.getMediaId()}; } /* @@ -124,10 +124,10 @@ public Object[][] massMessages() throws WxErrorException, IOException { try (InputStream inputStream = ClassLoader .getSystemResourceAsStream("mm.jpeg")) { WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, inputStream); + .mediaUpload(WxConsts.MediaFileType.IMAGE, TestConstants.FILE_JPG, inputStream); assertNotNull(uploadMediaRes); assertNotNull(uploadMediaRes.getMediaId()); - messages[1] = new Object[]{WxConsts.MASS_MSG_IMAGE, uploadMediaRes.getMediaId()}; + messages[1] = new Object[]{WxConsts.MassMsgType.IMAGE, uploadMediaRes.getMediaId()}; } /* @@ -136,10 +136,10 @@ public Object[][] massMessages() throws WxErrorException, IOException { try (InputStream inputStream = ClassLoader .getSystemResourceAsStream("mm.mp3")) { WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, inputStream); + .mediaUpload(WxConsts.MediaFileType.VOICE, TestConstants.FILE_MP3, inputStream); assertNotNull(uploadMediaRes); assertNotNull(uploadMediaRes.getMediaId()); - messages[2] = new Object[]{WxConsts.MASS_MSG_VOICE, uploadMediaRes.getMediaId()}; + messages[2] = new Object[]{WxConsts.MassMsgType.VOICE, uploadMediaRes.getMediaId()}; } /* @@ -149,7 +149,7 @@ public Object[][] massMessages() throws WxErrorException, IOException { .getSystemResourceAsStream("mm.jpeg")) { // 上传照片到媒体库 WxMediaUploadResult uploadMediaRes = this.wxService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, inputStream); + .mediaUpload(WxConsts.MediaFileType.IMAGE, TestConstants.FILE_JPG, inputStream); assertNotNull(uploadMediaRes); assertNotNull(uploadMediaRes.getMediaId()); @@ -175,7 +175,7 @@ public Object[][] massMessages() throws WxErrorException, IOException { .massNewsUpload(news); assertNotNull(massUploadResult); assertNotNull(uploadMediaRes.getMediaId()); - messages[3] = new Object[]{WxConsts.MASS_MSG_NEWS, massUploadResult.getMediaId()}; + messages[3] = new Object[]{WxConsts.MassMsgType.MPNEWS, massUploadResult.getMediaId()}; } return messages; @@ -183,7 +183,7 @@ public Object[][] massMessages() throws WxErrorException, IOException { @Test public void testMassDelete() throws Exception { - this.wxService.getMassMessageService().delete(1,2); + this.wxService.getMassMessageService().delete(1L,2); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java index 309c4e0e47..afca1a2acf 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImplTest.java @@ -3,7 +3,7 @@ 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.common.error.WxErrorException; import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; @@ -48,10 +48,10 @@ public class WxMpMaterialServiceImplTest { @DataProvider public Object[][] mediaFiles() { return new Object[][]{ - new Object[]{WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, - new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, "mm.mp3"}, - new Object[]{WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, - new Object[]{WxConsts.MEDIA_THUMB, TestConstants.FILE_JPG, "mm.jpeg"} + new Object[]{WxConsts.MediaFileType.IMAGE, TestConstants.FILE_JPG, "mm.jpeg"}, + new Object[]{WxConsts.MediaFileType.VOICE, TestConstants.FILE_MP3, "mm.mp3"}, + new Object[]{WxConsts.MediaFileType.VIDEO, TestConstants.FILE_MP4, "mm.mp4"}, + new Object[]{WxConsts.MediaFileType.THUMB, TestConstants.FILE_JPG, "mm.jpeg"} }; } @@ -69,7 +69,7 @@ public void testUploadMaterial(String mediaType, String fileType, String fileNam WxMpMaterial wxMaterial = new WxMpMaterial(); wxMaterial.setFile(tempFile); wxMaterial.setName(fileName); - if (WxConsts.MEDIA_VIDEO.equals(mediaType)) { + if (WxConsts.MediaFileType.VIDEO.equals(mediaType)) { wxMaterial.setVideoTitle("title"); wxMaterial.setVideoIntroduction("test video description"); } @@ -78,12 +78,12 @@ public void testUploadMaterial(String mediaType, String fileType, String fileNam .materialFileUpload(mediaType, wxMaterial); assertNotNull(res.getMediaId()); - if (WxConsts.MEDIA_IMAGE.equals(mediaType) - || WxConsts.MEDIA_THUMB.equals(mediaType)) { + if (WxConsts.MediaFileType.IMAGE.equals(mediaType) + || WxConsts.MediaFileType.THUMB.equals(mediaType)) { assertNotNull(res.getUrl()); } - if (WxConsts.MEDIA_THUMB.equals(mediaType)) { + if (WxConsts.MediaFileType.THUMB.equals(mediaType)) { this.thumbMediaId = res.getMediaId(); } @@ -231,11 +231,11 @@ public void testMaterialNewsList() throws WxErrorException { assertNotNull(wxMpMaterialNewsBatchGetResult); } - @Test(dependsOnMethods = {"testMaterialNewsList"}) + @Test//(dependsOnMethods = {"testMaterialNewsList"}) public void testMaterialFileList() throws WxErrorException { - WxMpMaterialFileBatchGetResult wxMpMaterialVoiceBatchGetResult = this.wxService.getMaterialService().materialFileBatchGet(WxConsts.MATERIAL_VOICE, 0, 20); - WxMpMaterialFileBatchGetResult wxMpMaterialVideoBatchGetResult = this.wxService.getMaterialService().materialFileBatchGet(WxConsts.MATERIAL_VIDEO, 0, 20); - WxMpMaterialFileBatchGetResult wxMpMaterialImageBatchGetResult = this.wxService.getMaterialService().materialFileBatchGet(WxConsts.MATERIAL_IMAGE, 0, 20); + WxMpMaterialFileBatchGetResult wxMpMaterialVoiceBatchGetResult = this.wxService.getMaterialService().materialFileBatchGet(WxConsts.MaterialType.VOICE, 0, 20); + WxMpMaterialFileBatchGetResult wxMpMaterialVideoBatchGetResult = this.wxService.getMaterialService().materialFileBatchGet(WxConsts.MaterialType.VIDEO, 0, 20); + WxMpMaterialFileBatchGetResult wxMpMaterialImageBatchGetResult = this.wxService.getMaterialService().materialFileBatchGet(WxConsts.MaterialType.IMAGE, 0, 20); assertNotNull(wxMpMaterialVoiceBatchGetResult); assertNotNull(wxMpMaterialVideoBatchGetResult); assertNotNull(wxMpMaterialImageBatchGetResult); @@ -277,7 +277,7 @@ public void testUploadMedia(String mediaType, String fileType, String fileName) assertNotNull(res.getCreatedAt()); assertTrue(res.getMediaId() != null || res.getThumbMediaId() != null); - if (res.getMediaId() != null && !mediaType.equals(WxConsts.MEDIA_VIDEO)) { + if (res.getMediaId() != null && !mediaType.equals(WxConsts.MediaFileType.VIDEO)) { //video 不支持下载,所以不加入 this.mediaIdsToDownload.add(res.getMediaId()); } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java index 67eb5817cc..67d7ce6f87 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java @@ -1,12 +1,12 @@ package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; +import me.chanjar.weixin.mp.api.WxMpCardService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; +import me.chanjar.weixin.mp.bean.card.*; +import me.chanjar.weixin.mp.bean.card.enums.CardSceneType; +import me.chanjar.weixin.mp.bean.membercard.*; import org.testng.annotations.Guice; import org.testng.annotations.Test; @@ -22,15 +22,60 @@ public class WxMpMemberCardServiceImplTest { @Inject protected WxMpService wxService; - private String cardId = "abc"; - private String code = "123"; - private String openId = "xyz"; + private String cardId = "p2iQk1g2d03JXhVRDY5fZRVr236A"; + private String code = "435223630779"; + private String openId = "o2iQk1u5X-XIJkatmAK1Q8VVuS90"; + + @Test + public void createMemberCard()throws Exception{ +// String json = "{\"card\":{\"card_type\":\"MEMBER_CARD\",\"member_card\":{\"advanced_info\":{\"business_service\":\"BIZ_SERVICE_FREE_PARK,BIZ_SERVICE_WITH_PET,BIZ_SERVICE_FREE_WIFI\",\"text_image_list\":[{\"image_url\":\"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGkENppDhyqhR8bz5BiaJkPT7e6bPVcfBx5cAOLro2N3U989n8WJltkjQ/0\",\"text\":\"8月8日随机免单\"}]},\"auto_activate\":false,\"background_pic_url\":\"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0\",\"base_info\":{\"bind_openid\":false,\"brand_name\":\"商户名称\",\"can_give_friend\":false,\"can_share\":false,\"center_sub_title\":\"点击进入\",\"center_title\":\"商城首页\",\"center_url\":\"http://www.baidu.com\",\"code_type\":\"CODE_TYPE_QRCODE\",\"color\":\"Color090\",\"date_info\":{\"type\":\"DATE_TYPE_PERMANENT\"},\"description\":\"使用须知\",\"need_push_on_view\":false,\"notice\":\"测试会员卡\",\"service_phone\":\"4008803016\",\"title\":\"终生铂金卡\",\"use_all_locations\":true,\"use_custom_code\":false},\"prerogative\":\"享有特权说明\",\"supply_balance\":true,\"supply_bonus\":true,\"wx_activate\":false}}}"; +// WxMpMemberCardCreateMessage createMessage = WxMpMemberCardCreateMessage.fromJson(json); + + //基本卡券创建 + WxMpMemberCardCreateMessage createMessage = new WxMpMemberCardCreateMessage(); + MemberCardCreateRequest cardCreateRequest = new MemberCardCreateRequest(); + MemberCard memberCard = new MemberCard(); + memberCard.setPrerogative("特权说明"); + //激活方式 + memberCard.setAutoActivate(true);//自动激活 +// memberCard.setActivateUrl("http://www.qq.com"); +// memberCard.setWxActivate(false);//微信激活 + memberCard.setSupplyBonus(true); + memberCard.setSupplyBalance(false); + memberCard.setBackgroundPicUrl("http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0"); + memberCard.setDiscount(0); + + BaseInfo baseInfo = new BaseInfo(); + baseInfo.setLogoUrl("http://wx.qlogo.cn/mmopen/A6hCic476picOEWOJ7NsL7uWhRuh1LibrMC6byhCO6TV1lelyK9iaXbn8nAgFREibPJQTWDeKpicePt88ZHRc8wuicEM0qOllsMXic6O/0"); + baseInfo.setCodeType("CODE_TYPE_QRCODE"); + baseInfo.setBrandName("信舟科技"); + baseInfo.setTitle("铂金用户贵宾卡"); + baseInfo.setColor("Color010"); + baseInfo.setNotice("卡券使用提醒"); + baseInfo.setDescription("卡券使用说明"); + baseInfo.setServicePhone("4008803016"); + //商品信息 + Sku sku = new Sku(); + baseInfo.setSku(sku); + //使用日期 + DateInfo dateInfo = new DateInfo(); + baseInfo.setDateInfo(dateInfo); + + memberCard.setBaseInfo(baseInfo); + + cardCreateRequest.setMemberCard(memberCard); + createMessage.setCardCreateRequest(cardCreateRequest); + + WxMpCardCreateResult response = this.wxService.getMemberCardService().createMemberCard(createMessage); + assertNotNull(response); + System.out.println(response); + } @Test public void testActivateMemberCard() throws Exception { WxMpMemberCardActivatedMessage activatedMessage = new WxMpMemberCardActivatedMessage(); activatedMessage.setMembershipNumber(openId); - activatedMessage.setCode(code); +// activatedMessage.setCode(code); activatedMessage.setCardId(cardId); activatedMessage.setInitBonus(2000); activatedMessage.setInitBonusRecord("测试激活送积分"); @@ -58,4 +103,41 @@ public void testUpdateUserMemberCard() throws Exception { System.out.println(result); } + /** + * 测试添加测试openid白名单 + * @throws Exception + */ + @Test + public void testAddTestWhiteList()throws Exception { + WxMpCardService cardService = this.wxService.getCardService(); + String response = cardService.addTestWhiteList(openId); + System.out.println(response); + } + + /** + * 测试创建会员卡投放二维码 + * @throws Exception + */ + @Test + public void testCreateQrcodeMemberCard()throws Exception{ + WxMpCardService cardService = this.wxService.getCardService(); + WxMpCardQrcodeCreateResult response = cardService.createQrcodeCard(cardId,"test"); + System.out.println(response); + } + + /** + * 测试创建货架接口 + * @throws Exception + */ + @Test + public void testCreateLandingPage()throws Exception{ + WxMpCardService cardService = this.wxService.getCardService(); + WxMpCardLandingPageCreateRequest request = new WxMpCardLandingPageCreateRequest(); + request.setBanner("http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0"); + request.setTitle("会员卡1"); + request.setScene(CardSceneType.SCENE_H5.name()); + request.addCard(cardId,"http://mmbiz.qpic.cn/mmbiz_jpg/upuF1LhUF8LjCLCFcQicgEiazFeonwDllGl6ibk4v5iaJDAbs7dGJU7iclOJ6nh7Hnz6ZsfDL8tGEeQVJyuhKsMFxUQ/0"); + WxMpCardLandingPageCreateResult response = cardService.createLandingPage(request); + System.out.println(response); + } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java index 8846809001..c25c946df4 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java @@ -4,14 +4,15 @@ import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.bean.menu.WxMenu; import me.chanjar.weixin.common.bean.menu.WxMenuButton; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; import me.chanjar.weixin.mp.bean.menu.WxMpMenu; -import org.testng.*; import org.testng.annotations.*; +import static org.testng.Assert.*; + /** * 测试菜单 * @@ -87,6 +88,14 @@ public void testCreateConditionalMenu() throws WxErrorException { System.out.println(this.menuId); } + @Test(dependsOnMethods = {"testCreateConditionalMenu"}) + public void testMenuGet_AfterCreateConditionalMenu() throws WxErrorException { + WxMpMenu wxMenu = this.wxService.getMenuService().menuGet(); + assertNotNull(wxMenu); + System.out.println(wxMenu.toJson()); + assertNotNull(wxMenu.getConditionalMenu().get(0).getRule().getTagId()); + } + @Test(dependsOnMethods = {"testCreateConditionalMenu"}) public void testDeleteConditionalMenu() throws WxErrorException { this.wxService.getMenuService().menuDelete(menuId); @@ -134,7 +143,7 @@ public void testCreateMenu_by_json() throws WxErrorException { @Test(dependsOnMethods = {"testMenuCreate"}) public void testMenuGet() throws WxErrorException { WxMpMenu wxMenu = this.wxService.getMenuService().menuGet(); - Assert.assertNotNull(wxMenu); + assertNotNull(wxMenu); System.out.println(wxMenu.toJson()); } @@ -147,12 +156,12 @@ public void testMenuDelete() throws WxErrorException { public Object[][] getMenu() { WxMenu menu = new WxMenu(); WxMenuButton button1 = new WxMenuButton(); - button1.setType(WxConsts.BUTTON_CLICK); + button1.setType(WxConsts.MenuButtonType.CLICK); button1.setName("今日歌曲"); button1.setKey("V1001_TODAY_MUSIC"); // WxMenuButton button2 = new WxMenuButton(); -// button2.setType(WxConsts.BUTTON_MINIPROGRAM); +// button2.setType(WxConsts.MenuButtonType.MINIPROGRAM); // button2.setName("小程序"); // button2.setAppId("wx286b93c14bbf93aa"); // button2.setPagePath("pages/lunar/index.html"); @@ -166,17 +175,17 @@ public Object[][] getMenu() { menu.getButtons().add(button3); WxMenuButton button31 = new WxMenuButton(); - button31.setType(WxConsts.BUTTON_VIEW); + button31.setType(WxConsts.MenuButtonType.VIEW); button31.setName("搜索"); button31.setUrl("http://www.soso.com/"); WxMenuButton button32 = new WxMenuButton(); - button32.setType(WxConsts.BUTTON_VIEW); + button32.setType(WxConsts.MenuButtonType.VIEW); button32.setName("视频"); button32.setUrl("http://v.qq.com/"); WxMenuButton button33 = new WxMenuButton(); - button33.setType(WxConsts.BUTTON_CLICK); + button33.setType(WxConsts.MenuButtonType.CLICK); button33.setName("赞一下我们"); button33.setKey("V1001_GOOD"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImplTest.java index 216eec77f0..833671e4b0 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpQrcodeServiceImplTest.java @@ -1,15 +1,17 @@ package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.RandomStringUtils; import org.testng.*; import org.testng.annotations.*; import java.io.File; +import java.io.IOException; /** * 测试用户相关的接口 @@ -37,7 +39,7 @@ public void testQrCodeCreateTmpTicket(int sceneId) throws WxErrorException { WxMpQrCodeTicket ticket = this.wxService.getQrcodeService().qrCodeCreateTmpTicket(sceneId, null); Assert.assertNotNull(ticket.getUrl()); Assert.assertNotNull(ticket.getTicket()); - Assert.assertTrue(ticket.getExpire_seconds() != -1); + Assert.assertTrue(ticket.getExpireSeconds() != -1); System.out.println(ticket); } @@ -47,7 +49,7 @@ public void testQrCodeCreateTmpTicketWithSceneStr(String sceneStr) throws WxErro WxMpQrCodeTicket ticket = this.wxService.getQrcodeService().qrCodeCreateTmpTicket(sceneStr, null); Assert.assertNotNull(ticket.getUrl()); Assert.assertNotNull(ticket.getTicket()); - Assert.assertTrue(ticket.getExpire_seconds() != -1); + Assert.assertTrue(ticket.getExpireSeconds() != -1); System.out.println(ticket); } @@ -56,7 +58,7 @@ public void testQrCodeCreateLastTicket(int sceneId) throws WxErrorException { WxMpQrCodeTicket ticket = this.wxService.getQrcodeService().qrCodeCreateLastTicket(sceneId); Assert.assertNotNull(ticket.getUrl()); Assert.assertNotNull(ticket.getTicket()); - Assert.assertTrue(ticket.getExpire_seconds() == -1); + Assert.assertTrue(ticket.getExpireSeconds() == -1); System.out.println(ticket); } @@ -65,6 +67,12 @@ public void testQrCodePicture() throws WxErrorException { File file = this.wxService.getQrcodeService().qrCodePicture(ticket); Assert.assertNotNull(file); System.out.println(file.getAbsolutePath()); + + try { + FileUtils.copyFile(file,new File("d:\\t.jpg")); + } catch (IOException e) { + e.printStackTrace(); + } } public void testQrCodePictureUrl() throws WxErrorException { diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java index c3f9f69d7b..e9999f577d 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java @@ -2,7 +2,7 @@ import com.google.inject.Inject; import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.api.test.TestConfigStorage; @@ -15,7 +15,6 @@ @Test @Guice(modules = ApiTestModule.class) public class WxMpServiceImplTest { - @Inject private WxMpService wxService; @@ -28,137 +27,17 @@ public void testGetCurrentAutoReplyInfo() throws WxErrorException { } @Test - public void testCheckSignature() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testGetAccessToken() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testGetAccessTokenBoolean() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testGetJsapiTicket() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testGetJsapiTicketBoolean() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testCreateJsapiSignature() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testCustomMessageSend() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testMassNewsUpload() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testMassVideoUpload() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testMassGroupMessageSend() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testMassOpenIdsMessageSend() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testMassMessagePreview() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testShortUrl() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testSetIndustry() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testGetIndustry() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testSemanticQuery() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testOauth2buildAuthorizationUrl() { - Assert.fail("Not yet implemented"); + public void testClearQuota() throws WxErrorException { + this.wxService.clearQuota(wxService.getWxMpConfigStorage().getAppId()); } @Test public void testBuildQrConnectUrl() { String qrconnectRedirectUrl = ((TestConfigStorage) this.wxService.getWxMpConfigStorage()).getQrconnectRedirectUrl(); String qrConnectUrl = this.wxService.buildQrConnectUrl(qrconnectRedirectUrl, - WxConsts.QRCONNECT_SCOPE_SNSAPI_LOGIN, null); + WxConsts.QrConnectScope.SNSAPI_LOGIN, null); Assert.assertNotNull(qrConnectUrl); System.out.println(qrConnectUrl); } - @Test - public void testOauth2getAccessToken() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testOauth2refreshAccessToken() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testOauth2getUserInfo() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testOauth2validateAccessToken() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testGetCallbackIP() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testGet() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testPost() { - Assert.fail("Not yet implemented"); - } - - @Test - public void testExecute() { - Assert.fail("Not yet implemented"); - } - } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java index ed5845088b..564259c664 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.bean.store.WxMpStoreBaseInfo; @@ -12,11 +12,12 @@ import java.math.BigDecimal; import java.util.List; -import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.*; /** - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016-09-23. + * Created by Binary Wang on 2016-09-23. + * + * @author Binary Wang */ @Test @Guice(modules = ApiTestModule.class) @@ -25,25 +26,36 @@ public class WxMpStoreServiceImplTest { private WxMpService wxMpService; /** - * Test method for {@link WxMpStoreServiceImpl#add(me.chanjar.weixin.mp.bean.store.WxMpStoreBaseInfo)}. - * - * @throws WxErrorException + * Test method for {@link WxMpStoreServiceImpl#add(WxMpStoreBaseInfo)}. */ public void testAdd() throws WxErrorException { - this.wxMpService.getStoreService().add(WxMpStoreBaseInfo.builder().build()); this.wxMpService.getStoreService() - .add(WxMpStoreBaseInfo.builder().businessName("haha").branchName("abc") - .province("aaa").district("aaa").telephone("122").address("abc").categories(new String[]{"美食,江浙菜"}) + .add(WxMpStoreBaseInfo.builder() + .businessName("haha") + .branchName("abc") + .province("aaa") + .district("aaa") + .telephone("122") + .address("abc") + .categories(new String[]{"美食,江浙菜"}) .longitude(new BigDecimal("115.32375")) - .latitude(new BigDecimal("25.097486")).city("aaa").offsetType(1) + .latitude(new BigDecimal("25.097486")) + .city("aaa") .build()); + // 以下运行会抛异常 + this.wxMpService.getStoreService().add(WxMpStoreBaseInfo.builder().build()); } public void testUpdate() throws WxErrorException { this.wxMpService.getStoreService() - .update(WxMpStoreBaseInfo.builder().poiId("291503654").telephone("020-12345678") - .sid("aaa").avgPrice(35).openTime("8:00-20:00").special("免费wifi,外卖服务") - .introduction("麦当劳是全球大型跨国连锁餐厅,1940 年创立于美国,在世界上大约拥有3 万间分店。主要售卖汉堡包,以及薯条、炸鸡、汽水、冰品、沙拉、水果等快餐食品").offsetType(1) + .update(WxMpStoreBaseInfo.builder() + .poiId("291503654") + .telephone("020-12345678") + .sid("aaa") + .avgPrice(35) + .openTime("8:00-20:00") + .special("免费wifi,外卖服务") + .introduction("麦当劳是全球大型跨国连锁餐厅,1940 年创立于美国,在世界上大约拥有3 万间分店。主要售卖汉堡包,以及薯条、炸鸡、汽水、冰品、沙拉、水果等快餐食品") .build()); } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImplTest.java new file mode 100644 index 0000000000..77a661ee58 --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpSubscribeMsgServiceImplTest.java @@ -0,0 +1,48 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.test.ApiTestModule; +import me.chanjar.weixin.mp.api.test.TestConfigStorage; +import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage; +import org.testng.Assert; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +/** + * @author Mklaus + * @date 2018-01-22 下午2:02 + */ +@Guice(modules = ApiTestModule.class) +public class WxMpSubscribeMsgServiceImplTest { + + @Inject + protected WxMpService wxService; + + @Test + public void testSendSubscribeMessage() throws WxErrorException { + TestConfigStorage configStorage = (TestConfigStorage) this.wxService + .getWxMpConfigStorage(); + + WxMpSubscribeMessage message = WxMpSubscribeMessage.builder() + .title("weixin test") + .toUser(configStorage.getOpenid()) + .scene("1000") + .contentColor("#FF0000") + .contentValue("Send subscribe message test") + .build(); + + try { + boolean send = this.wxService.getSubscribeMsgService().sendSubscribeMessage(message); + Assert.assertTrue(send); + } catch (WxErrorException e) { + // 当用户没有授权,获取之前的授权已使用。微信会返回错误代码 {"errcode":43101,"errmsg":"user refuse to accept the msg hint: [xxxxxxxxxxx]"} + if (e.getError().getErrorCode() != 43101) { + throw e; + } + } + + } + +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java index 2c348702ca..94d759fc75 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.api.test.TestConfigStorage; @@ -10,8 +10,9 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; import org.apache.commons.lang3.RandomStringUtils; -import org.testng.*; -import org.testng.annotations.*; +import org.testng.Assert; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; import java.text.SimpleDateFormat; import java.util.Date; @@ -20,8 +21,9 @@ /** *
  * Created by Binary Wang on 2016-10-14.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ @Guice(modules = ApiTestModule.class) public class WxMpTemplateMsgServiceImplTest { @@ -36,12 +38,12 @@ public void testSendTemplateMsg() throws WxErrorException { .getWxMpConfigStorage(); WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() .toUser(configStorage.getOpenid()) - .templateId(configStorage.getTemplateId()).build(); - templateMessage.addWxMpTemplateData( - new WxMpTemplateData("first", dateFormat.format(new Date()), "#FF00FF")); - templateMessage.addWxMpTemplateData( - new WxMpTemplateData("remark", RandomStringUtils.randomAlphanumeric(100), "#FF00FF")); - templateMessage.setUrl(" "); + .templateId(configStorage.getTemplateId()) + .url(" ") + .build(); + + templateMessage.addData(new WxMpTemplateData("first", dateFormat.format(new Date()), "#FF00FF")) + .addData(new WxMpTemplateData("remark", RandomStringUtils.randomAlphanumeric(100), "#FF00FF")); String msgId = this.wxService.getTemplateMsgService().sendTemplateMsg(templateMessage); Assert.assertNotNull(msgId); System.out.println(msgId); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java index 27f117916e..0a4cd21a17 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserServiceImplTest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.mp.api.impl; import com.google.inject.Inject; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.api.test.TestConfigStorage; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImplTest.java index cc8676d477..1a96ba510a 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImplTest.java @@ -12,8 +12,9 @@ import java.util.List; /** - * @author binarywang(Binary Wang) - * Created by Binary Wang on 2016/9/2. + * Created by Binary Wang on 2016/9/2. + * + * @author Binary Wang */ @Test @Guice(modules = ApiTestModule.class) diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImplTest.java new file mode 100644 index 0000000000..e129474e39 --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpWifiServiceImplTest.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.test.ApiTestModule; +import me.chanjar.weixin.mp.bean.wifi.WxMpWifiShopListResult; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +/** + *
+ *  Created by BinaryWang on 2018/6/10.
+ * 
+ * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMpWifiServiceImplTest { + @Inject + private WxMpService wxService; + + @Test + public void testListShop() throws WxErrorException { + final WxMpWifiShopListResult result = this.wxService.getWifiService().listShop(1, 2); + System.out.println(result); + } +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java index 2a9421a499..98173f7d35 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java @@ -1,32 +1,41 @@ package me.chanjar.weixin.mp.api.test; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.locks.ReentrantLock; + +import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.inject.Binder; import com.google.inject.Module; import com.thoughtworks.xstream.XStream; import me.chanjar.weixin.common.util.xml.XStreamInitializer; import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.impl.WxMpServiceApacheHttpClientImpl; import me.chanjar.weixin.mp.api.impl.WxMpServiceOkHttpImpl; -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.locks.ReentrantLock; - public class ApiTestModule implements Module { + private final Logger log = LoggerFactory.getLogger(this.getClass()); + private static final String TEST_CONFIG_XML = "test-config.xml"; @Override public void configure(Binder binder) { - try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) { - TestConfigStorage config = this.fromXml(TestConfigStorage.class, is1); + try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(TEST_CONFIG_XML)) { + if (inputStream == null) { + throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成"); + } + + TestConfigStorage config = this.fromXml(TestConfigStorage.class, inputStream); config.setAccessTokenLock(new ReentrantLock()); - WxMpService wxService = new WxMpServiceOkHttpImpl(); + WxMpService wxService = new WxMpServiceHttpClientImpl(); wxService.setWxMpConfigStorage(config); binder.bind(WxMpService.class).toInstance(wxService); binder.bind(WxMpConfigStorage.class).toInstance(config); } catch (IOException e) { - e.printStackTrace(); + this.log.error(e.getMessage(), e); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java index 6400f81dee..ed6c5cb168 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/TestConfigStorage.java @@ -52,10 +52,12 @@ public void setQrconnectRedirectUrl(String qrconnectRedirectUrl) { this.qrconnectRedirectUrl = qrconnectRedirectUrl; } + @Override public String getTemplateId() { return this.templateId; } + @Override public void setTemplateId(String templateId) { this.templateId = templateId; } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java index c25c502495..4f983dde13 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessageTest.java @@ -2,8 +2,8 @@ import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage.WxArticle; -import org.testng.*; -import org.testng.annotations.*; +import org.testng.Assert; +import org.testng.annotations.Test; @Test public class WxMpKefuMessageTest { @@ -11,68 +11,78 @@ public class WxMpKefuMessageTest { public void testTextReply() { WxMpKefuMessage reply = new WxMpKefuMessage(); reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_TEXT); + reply.setMsgType(WxConsts.KefuMsgType.TEXT); reply.setContent("sfsfdsdf"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); + Assert + .assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); } public void testTextBuild() { WxMpKefuMessage reply = WxMpKefuMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); + Assert + .assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); } public void testImageReply() { WxMpKefuMessage reply = new WxMpKefuMessage(); reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_IMAGE); + reply.setMsgType(WxConsts.KefuMsgType.IMAGE); reply.setMediaId("MEDIA_ID"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testImageBuild() { WxMpKefuMessage reply = WxMpKefuMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testVoiceReply() { WxMpKefuMessage reply = new WxMpKefuMessage(); reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_VOICE); + reply.setMsgType(WxConsts.KefuMsgType.VOICE); reply.setMediaId("MEDIA_ID"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testVoiceBuild() { WxMpKefuMessage reply = WxMpKefuMessage.VOICE().toUser("OPENID").mediaId("MEDIA_ID").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); } public void testVideoReply() { WxMpKefuMessage reply = new WxMpKefuMessage(); reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_VIDEO); + reply.setMsgType(WxConsts.KefuMsgType.VIDEO); reply.setMediaId("MEDIA_ID"); reply.setThumbMediaId("MEDIA_ID"); reply.setTitle("TITLE"); reply.setDescription("DESCRIPTION"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); } public void testVideoBuild() { - WxMpKefuMessage reply = WxMpKefuMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); + WxMpKefuMessage reply = WxMpKefuMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID") + .thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); } public void testMusicReply() { WxMpKefuMessage reply = new WxMpKefuMessage(); reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_MUSIC); + reply.setMsgType(WxConsts.KefuMsgType.MUSIC); reply.setThumbMediaId("MEDIA_ID"); reply.setDescription("DESCRIPTION"); reply.setTitle("TITLE"); reply.setMusicUrl("MUSIC_URL"); reply.setHqMusicUrl("HQ_MUSIC_URL"); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"music\",\"music\":{\"title\":\"TITLE\",\"description\":\"DESCRIPTION\",\"thumb_media_id\":\"MEDIA_ID\",\"musicurl\":\"MUSIC_URL\",\"hqmusicurl\":\"HQ_MUSIC_URL\"}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"music\",\"music\":{\"title\":\"TITLE\",\"description\":\"DESCRIPTION\",\"thumb_media_id\":\"MEDIA_ID\",\"musicurl\":\"MUSIC_URL\",\"hqmusicurl\":\"HQ_MUSIC_URL\"}}"); } public void testMusicBuild() { @@ -84,13 +94,14 @@ public void testMusicBuild() { .musicUrl("MUSIC_URL") .hqMusicUrl("HQ_MUSIC_URL") .build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"music\",\"music\":{\"title\":\"TITLE\",\"description\":\"DESCRIPTION\",\"thumb_media_id\":\"MEDIA_ID\",\"musicurl\":\"MUSIC_URL\",\"hqmusicurl\":\"HQ_MUSIC_URL\"}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"music\",\"music\":{\"title\":\"TITLE\",\"description\":\"DESCRIPTION\",\"thumb_media_id\":\"MEDIA_ID\",\"musicurl\":\"MUSIC_URL\",\"hqmusicurl\":\"HQ_MUSIC_URL\"}}"); } public void testNewsReply() { WxMpKefuMessage reply = new WxMpKefuMessage(); reply.setToUser("OPENID"); - reply.setMsgType(WxConsts.CUSTOM_MSG_NEWS); + reply.setMsgType(WxConsts.KefuMsgType.NEWS); WxArticle article1 = new WxArticle(); article1.setUrl("URL"); @@ -106,8 +117,8 @@ public void testNewsReply() { article2.setTitle("Happy Day"); reply.getArticles().add(article2); - - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); } public void testNewsBuild() { @@ -125,7 +136,22 @@ public void testNewsBuild() { WxMpKefuMessage reply = WxMpKefuMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); - Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); + } + + public void testMiniProgramPageBuild() { + + WxMpKefuMessage reply = WxMpKefuMessage.MINIPROGRAMPAGE() + .toUser("OPENID") + .title("title") + .appId("appid") + .pagePath("pagepath") + .thumbMediaId("thumb_media_id") + .build(); + + Assert.assertEquals(reply.toJson(), + "{\"touser\":\"OPENID\",\"msgtype\":\"miniprogrampage\",\"miniprogrampage\":{\"title\":\"title\",\"appid\":\"appid\",\"pagepath\":\"pagepath\",\"thumb_media_id\":\"thumb_media_id\"}}"); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessageTest.java index 9c2bbf56ac..2224329b26 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlMessageTest.java @@ -58,7 +58,7 @@ public void testFromXml() { assertEquals(wxMessage.getToUser(), "toUser"); assertEquals(wxMessage.getFromUser(), "fromUser"); assertEquals(wxMessage.getCreateTime(), new Long(1348831860L)); - assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); assertEquals(wxMessage.getContent(), "this is a test"); assertEquals(wxMessage.getMsgId(), new Long(1234567890123456L)); assertEquals(wxMessage.getPicUrl(), "this is a url"); @@ -86,7 +86,7 @@ public void testFromXml() { assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); - assertEquals(wxMessage.getSendLocationInfo().getPoiname(), "wo de poi"); + assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); } public void testFromXml2() { @@ -139,7 +139,7 @@ public void testFromXml2() { assertEquals(wxMessage.getToUser(), "toUser"); assertEquals(wxMessage.getFromUser(), "fromUser"); assertEquals(wxMessage.getCreateTime(), new Long(1348831860L)); - assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT); assertEquals(wxMessage.getContent(), "this is a test"); assertEquals(wxMessage.getMsgId(), new Long(1234567890123456L)); assertEquals(wxMessage.getPicUrl(), "this is a url"); @@ -167,7 +167,7 @@ public void testFromXml2() { assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113"); assertEquals(wxMessage.getSendLocationInfo().getScale(), "15"); assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号"); - assertEquals(wxMessage.getSendLocationInfo().getPoiname(), "wo de poi"); + assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi"); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessageTest.java index ab732c315c..8aaa3b2879 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutImageMessageTest.java @@ -9,7 +9,7 @@ public class WxMpXmlOutImageMessageTest { public void test() { WxMpXmlOutImageMessage m = new WxMpXmlOutImageMessage(); m.setMediaId("ddfefesfsdfef"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("from"); m.setToUserName("to"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessageTest.java index f75e6321e6..592a6a50ed 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutMusicMessageTest.java @@ -13,7 +13,7 @@ public void test() { m.setHqMusicUrl("hQMusicUrl"); m.setMusicUrl("musicUrl"); m.setThumbMediaId("thumbMediaId"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("fromUser"); m.setToUserName("toUser"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessageTest.java index f8f72c9e5e..26eb06a2b8 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessageTest.java @@ -8,7 +8,7 @@ public class WxMpXmlOutNewsMessageTest { public void test() { WxMpXmlOutNewsMessage m = new WxMpXmlOutNewsMessage(); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("fromUser"); m.setToUserName("toUser"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessageTest.java index c005c26107..605f4b2563 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutTextMessageTest.java @@ -9,7 +9,7 @@ public class WxMpXmlOutTextMessageTest { public void test() { WxMpXmlOutTextMessage m = new WxMpXmlOutTextMessage(); m.setContent("content"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("from"); m.setToUserName("to"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessageTest.java index 2ba9f549de..a00cdc3282 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVideoMessageTest.java @@ -11,7 +11,7 @@ public void test() { m.setMediaId("media_id"); m.setTitle("title"); m.setDescription("ddfff"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("fromUser"); m.setToUserName("toUser"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessageTest.java index d3f1346fec..d426cbe31c 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutVoiceMessageTest.java @@ -9,7 +9,7 @@ public class WxMpXmlOutVoiceMessageTest { public void test() { WxMpXmlOutVoiceMessage m = new WxMpXmlOutVoiceMessage(); m.setMediaId("ddfefesfsdfef"); - m.setCreateTime(1122l); + m.setCreateTime(1122L); m.setFromUserName("from"); m.setToUserName("to"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfoTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfoTest.java index da2cddff40..dbed60bac9 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfoTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpCurrentAutoReplyInfoTest.java @@ -145,8 +145,8 @@ public void testFromJson() throws Exception { WxMpCurrentAutoReplyInfo autoReplyInfo = WxMpCurrentAutoReplyInfo.fromJson(json); assertNotNull(autoReplyInfo); - assertTrue(autoReplyInfo.getAddFriendReplyOpen()); - assertTrue(autoReplyInfo.getAutoReplyOpen()); + assertTrue(autoReplyInfo.getIsAddFriendReplyOpen()); + assertTrue(autoReplyInfo.getIsAutoReplyOpen()); assertNotNull(autoReplyInfo.getAddFriendAutoReplyInfo()); assertNotNull(autoReplyInfo.getMessageDefaultAutoReplyInfo()); assertTrue(autoReplyInfo.getKeywordAutoReplyInfo().getList().size() > 0); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/subscribe/WxMpSubscribeMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/subscribe/WxMpSubscribeMessageTest.java new file mode 100644 index 0000000000..61d3d6fa6f --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/subscribe/WxMpSubscribeMessageTest.java @@ -0,0 +1,46 @@ +package me.chanjar.weixin.mp.bean.subscribe; + +import org.testng.annotations.*; + +import static org.testng.AssertJUnit.*; + +/** + * @author Mklaus + * @date 2018-01-22 下午1:41 + */ +public class WxMpSubscribeMessageTest { + @Test + public void testToJson() { + String actual = "{" + + "\"touser\":\"OPENID\"," + + "\"template_id\":\"TEMPLATE_ID\"," + + "\"url\":\"URL\"," + + "\"miniprogram\":{" + + "\"appid\":\"xiaochengxuappid12345\"," + + "\"pagepath\":\"index?foo=bar\"" + + "}," + + "\"scene\":\"SCENE\"," + + "\"title\":\"TITLE\"," + + "\"data\":{" + + "\"content\":{" + + "\"value\":\"VALUE\"," + + "\"color\":\"COLOR\"" + + "}" + + "}" + + "}"; + + WxMpSubscribeMessage message = WxMpSubscribeMessage.builder() + .toUser("OPENID") + .templateId("TEMPLATE_ID") + .url("URL") + .miniProgram(new WxMpSubscribeMessage.MiniProgram("xiaochengxuappid12345", "index?foo=bar",false)) + .scene("SCENE") + .title("TITLE") + .contentValue("VALUE") + .contentColor("COLOR") + .build(); + + assertEquals(message.toJson(), actual); + + } +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessageTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessageTest.java index ac415ff454..5a3f67fb1d 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessageTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessageTest.java @@ -1,28 +1,29 @@ package me.chanjar.weixin.mp.bean.template; -import org.testng.annotations.*; +import org.testng.annotations.Test; -import static org.testng.AssertJUnit.*; +import static org.testng.AssertJUnit.assertEquals; /** *
  * Created by Binary Wang on 2017-3-30.
- * @author binarywang(Binary Wang)
  * 
+ * + * @author Binary Wang */ public class WxMpTemplateMessageTest { @Test - public void testToJson() throws Exception { + public void testToJson() { WxMpTemplateMessage tm = WxMpTemplateMessage.builder() .toUser("OPENID") .templateId("ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY") - .miniProgram(new WxMpTemplateMessage.MiniProgram("xiaochengxuappid12345", "index?foo=bar")) + .miniProgram(new WxMpTemplateMessage.MiniProgram("xiaochengxuappid12345", "index?foo=bar",true)) .url("http://weixin.qq.com/download") .build(); - tm.addWxMpTemplateData( + tm.addData( new WxMpTemplateData("first", "haahah", "#FF00FF")); - tm.addWxMpTemplateData( + tm.addData( new WxMpTemplateData("remark", "heihei", "#FF00FF")); assertEquals(tm.toJson(), "{\"touser\":\"OPENID\",\"template_id\":\"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY\",\"url\":\"http://weixin.qq.com/download\",\"miniprogram\":{\"appid\":\"xiaochengxuappid12345\",\"pagepath\":\"index?foo=bar\"},\"data\":{\"first\":{\"value\":\"haahah\",\"color\":\"#FF00FF\"},\"remark\":{\"value\":\"heihei\",\"color\":\"#FF00FF\"}}}"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoGuessNumberHandler.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoGuessNumberHandler.java index 1743b1f955..0e04972350 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoGuessNumberHandler.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoGuessNumberHandler.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.demo; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSession; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.mp.api.WxMpMessageHandler; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java index 2390071b6c..22b58ccf16 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoImageHandler.java @@ -2,7 +2,7 @@ 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.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpService; @@ -19,7 +19,7 @@ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map co WxMpService wxMpService, WxSessionManager sessionManager) { try { WxMediaUploadResult wxMediaUploadResult = wxMpService.getMaterialService() - .mediaUpload(WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg")); + .mediaUpload(WxConsts.MediaFileType.IMAGE, TestConstants.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg")); WxMpXmlOutImageMessage m = WxMpXmlOutMessage .IMAGE() diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoOAuth2Handler.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoOAuth2Handler.java index 6460f851d0..91020c4ece 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoOAuth2Handler.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/DemoOAuth2Handler.java @@ -19,7 +19,7 @@ public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, WxSessionManager sessionManager) { String href = "测试oauth2"; + WxConsts.OAuth2Scope.SNSAPI_USERINFO, null) + "\">测试oauth2"; return WxMpXmlOutMessage.TEXT().content(href) .fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()) .build(); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java index e42a192b1f..257e533205 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoInMemoryConfigStorage.java @@ -6,6 +6,7 @@ import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; import java.io.InputStream; +import java.util.concurrent.locks.ReentrantLock; /** * @author Daniel Qian @@ -16,13 +17,17 @@ class WxMpDemoInMemoryConfigStorage extends WxMpInMemoryConfigStorage { public static WxMpDemoInMemoryConfigStorage fromXml(InputStream is) { XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(WxMpDemoInMemoryConfigStorage.class); - return (WxMpDemoInMemoryConfigStorage) xstream.fromXML(is); + WxMpDemoInMemoryConfigStorage wxMpDemoInMemoryConfigStorage = (WxMpDemoInMemoryConfigStorage) xstream.fromXML(is); + wxMpDemoInMemoryConfigStorage.accessTokenLock = new ReentrantLock(); + wxMpDemoInMemoryConfigStorage.cardApiTicketLock = new ReentrantLock(); + wxMpDemoInMemoryConfigStorage.jsapiTicketLock = new ReentrantLock(); + return wxMpDemoInMemoryConfigStorage; } @Override public String toString() { return "SimpleWxConfigProvider [appId=" + this.appId + ", secret=" + this.secret + ", accessToken=" + this.accessToken - + ", expiresTime=" + this.expiresTime + ", token=" + this.token + ", aesKey=" + this.aesKey + "]"; + + ", expiresTime=" + this.expiresTime + ", token=" + this.token + ", aesKey=" + this.aesKey + ", templateId=" + this.templateId + "]"; } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java index 3e16042d7f..d2f4fde881 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java @@ -5,7 +5,7 @@ import me.chanjar.weixin.mp.api.WxMpMessageHandler; import me.chanjar.weixin.mp.api.WxMpMessageRouter; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.impl.WxMpServiceApacheHttpClientImpl; +import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHolder; @@ -47,7 +47,7 @@ private static void initWeixin() { .fromXml(is1); wxMpConfigStorage = config; - wxMpService = new WxMpServiceApacheHttpClientImpl(); + wxMpService = new WxMpServiceHttpClientImpl(); wxMpService.setWxMpConfigStorage(config); WxMpMessageHandler logHandler = new DemoLogHandler(); @@ -58,7 +58,7 @@ private static void initWeixin() { wxMpMessageRouter = new WxMpMessageRouter(wxMpService); wxMpMessageRouter.rule().handler(logHandler).next().rule() - .msgType(WxConsts.XML_MSG_TEXT).matcher(guessNumberHandler) + .msgType(WxConsts.XmlMsgType.TEXT).matcher(guessNumberHandler) .handler(guessNumberHandler).end().rule().async(false).content("哈哈") .handler(textHandler).end().rule().async(false).content("图片") .handler(imageHandler).end().rule().async(false).content("oauth") diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java index e739a93689..4712fb322f 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.mp.demo; -import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.bean.result.WxMpUser; diff --git a/weixin-java-open/README.md b/weixin-java-open/README.md new file mode 100644 index 0000000000..1f935a9713 --- /dev/null +++ b/weixin-java-open/README.md @@ -0,0 +1,88 @@ +消息机制未实现,下面为通知回调中设置的代码部分 + +以下代码可通过腾讯全网发布测试用例 +``` +@RestController +@RequestMapping("notify") +public class NotifyController extends WechatThridBaseController { + @Autowired + protected WxOpenServiceDemo wxOpenService; + @RequestMapping("receive_ticket") + public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, @RequestParam("signature") String signature, + @RequestParam(name = "encrypt_type", required = false) String encType, + @RequestParam(name = "msg_signature", required = false) String msgSignature) { + this.logger.info( + "\n接收微信请求:[signature=[{}], encType=[{}], msgSignature=[{}]," + + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", + signature, encType, msgSignature, timestamp, nonce, requestBody); + + if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { + throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); + } + + // aes加密的消息 + WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); + this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); + String out = null; + try { + out = wxOpenService.getWxOpenComponentService().route(inMessage); + } catch (WxErrorException e) { + throw new ResponseException(ErrorCodeEnum.ERROR, e); + } + + this.logger.debug("\n组装回复信息:{}", out); + + return out; + } + @RequestMapping("{appId}/callback") + public Object callback(@RequestBody(required = false)String requestBody, + @PathVariable ("appId") String appId, + @RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestParam("openid") String openid, + @RequestParam("encrypt_type") String encType, + @RequestParam("msg_signature") String msgSignature) { + this.logger.info( + "\n接收微信请求:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}]," + + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", + appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody); + logger.info("query:"+getHttpServletRequest().getQueryString()+"\nbody:"+requestBody); + if (!StringUtils.equalsIgnoreCase("aes", encType) || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { + throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); + } + + String out = ""; + // aes加密的消息 + WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody, wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); + this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); + // 全网发布测试用例 + if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) { + try { + if (StringUtils.equals(inMessage.getMsgType(), "text")) { + if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) { + out = new WxOpenCryptUtil(wxOpenService.getWxOpenConfigStorage()).encrypt( + WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback") + .fromUser(inMessage.getToUser()) + .toUser(inMessage.getFromUser()) + .build() + .toXml() + ); + } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) { + String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api"; + WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build(); + wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); + } + } else if (StringUtils.equals(inMessage.getMsgType(), "event")) { + WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build(); + wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); + } + } catch (WxErrorException e) { + logger.error("callback", e); + } + } + return out; + } +} +``` diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml new file mode 100644 index 0000000000..1c055eb090 --- /dev/null +++ b/weixin-java-open/pom.xml @@ -0,0 +1,106 @@ + + + + 4.0.0 + + com.github.binarywang + weixin-java-parent + 3.2.0 + + weixin-java-open + Weixin Java Tools - Open + 微信开放平台Java SDK + + + 007 + 007gzs@gmail.com + https://github.com/007gzs + + + + + com.github.binarywang + weixin-java-common + ${project.version} + + + com.github.binarywang + weixin-java-mp + ${project.version} + + + com.github.binarywang + weixin-java-miniapp + ${project.version} + + + + org.jodd + jodd-http + provided + + + com.squareup.okhttp3 + okhttp + provided + + + + org.testng + testng + test + + + com.google.inject + guice + test + + + org.eclipse.jetty + jetty-server + test + + + org.eclipse.jetty + jetty-servlet + test + + + joda-time + joda-time + test + + + redis.clients + jedis + + + ch.qos.logback + logback-classic + test + + + org.projectlombok + lombok + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + src/test/resources/testng.xml + + + + + + + + diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java new file mode 100644 index 0000000000..7c1b8465e8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -0,0 +1,147 @@ +package me.chanjar.weixin.open.api; + +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +import java.util.List; + +/** + * @author 007 + */ +public interface WxOpenComponentService { + String API_COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; + String API_CREATE_PREAUTHCODE_URL = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode"; + String API_QUERY_AUTH_URL = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth"; + String API_AUTHORIZER_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token"; + String API_GET_AUTHORIZER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info"; + String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option"; + String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option"; + + String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; + String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; + + /** + * 用code换取oauth2的access token + */ + String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s"; + /** + * 刷新oauth2的access token + */ + String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s&component_appid=%s"; + + String MINIAPP_JSCODE_2_SESSION = "https://api.weixin.qq.com/sns/component/jscode2session?appid=%s&js_code=%s&grant_type=authorization_code&component_appid=%s"; + + WxMpService getWxMpServiceByAppid(String appid); + + /** + * 获取指定appid的开放平台小程序服务(继承一般小程序服务能力) + * + * @param appid + * @return + */ + WxOpenMaService getWxMaServiceByAppid(String appid); + + WxOpenConfigStorage getWxOpenConfigStorage(); + + boolean checkSignature(String timestamp, String nonce, String signature); + + String getComponentAccessToken(boolean forceRefresh) throws WxErrorException; + + /** + * 获取用户授权页URL(来路URL和成功跳转URL 的域名都需要为三方平台设置的 登录授权的发起页域名) + */ + String getPreAuthUrl(String redirectURI) throws WxErrorException; + + /** + * authType 要授权的帐号类型:1则商户点击链接后,手机端仅展示公众号、2表示仅展示小程序,3表示公众号和小程序都展示。如果为未指定,则默认小程序和公众号都展示。第三方平台开发者可以使用本字段来控制授权的帐号类型。 + * bizAppid 指定授权唯一的小程序或公众号 + * 注:auth_type、biz_appid两个字段互斥。 + */ + String getPreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException; + + String route(WxOpenXmlMessage wxMessage) throws WxErrorException; + + /** + * 使用授权码换取公众号或小程序的接口调用凭据和授权信息 + */ + WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException; + + /** + * 获取授权方的帐号基本信息 + */ + WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException; + + /** + * 获取授权方的选项设置信息 + */ + WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException; + + /** + * 设置授权方的选项信息 + */ + void setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException; + + String getAuthorizerAccessToken(String appid, boolean forceRefresh) throws WxErrorException; + + WxMpOAuth2AccessToken oauth2getAccessToken(String appid, String code) throws WxErrorException; + + boolean checkSignature(String appId, String timestamp, String nonce, String signature); + + WxMpOAuth2AccessToken oauth2refreshAccessToken(String appid, String refreshToken) throws WxErrorException; + + String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state); + + WxMaJscode2SessionResult miniappJscode2Session(String appId, String jsCode) throws WxErrorException; + + /** + * 代小程序实现业务 + *

+ * 小程序代码模版库管理:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1506504150_nMMh6&token=&lang=zh_CN + * access_token 为 component_access_token + */ + String GET_TEMPLATE_DRAFT_LIST_URL = "https://api.weixin.qq.com/wxa/gettemplatedraftlist"; + String GET_TEMPLATE_LIST_URL = "https://api.weixin.qq.com/wxa/gettemplatelist"; + String ADD_TO_TEMPLATE_URL = "https://api.weixin.qq.com/wxa/addtotemplate"; + String DELETE_TEMPLATE_URL = "https://api.weixin.qq.com/wxa/deletetemplate"; + + /** + * 获取草稿箱内的所有临时代码草稿 + * + * @return 草稿箱代码模板列表(draftId) + * @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档 + */ + List getTemplateDraftList() throws WxErrorException; + + /** + * 获取代码模版库中的所有小程序代码模版 + * + * @return 小程序代码模版列表(templateId) + * @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档 + */ + List getTemplateList() throws WxErrorException; + + /** + * 将草稿箱的草稿选为小程序代码模版 + * + * @param draftId 草稿ID,本字段可通过“获取草稿箱内的所有临时代码草稿”接口获得 + * @throws WxErrorException 操作失败时抛出,具体错误码请看此接口的注释文档 + * @see #getTemplateDraftList + */ + void addToTemplate(long draftId) throws WxErrorException; + + /** + * 删除指定小程序代码模版 + * + * @param templateId 要删除的模版ID + * @throws WxErrorException 操作失败时抛出,具体错误码请看此接口的注释文档 + * @see #getTemplateList + */ + void deleteTemplate(long templateId) throws WxErrorException; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java new file mode 100644 index 0000000000..de9044ee1b --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java @@ -0,0 +1,131 @@ +package me.chanjar.weixin.open.api; + +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; + +/** + * @author 007 + */ +public interface WxOpenConfigStorage { + + String getComponentAppId(); + + void setComponentAppId(String componentAppId); + + String getComponentAppSecret(); + + void setComponentAppSecret(String componentAppSecret); + + String getComponentToken(); + + void setComponentToken(String componentToken); + + String getComponentAesKey(); + + void setComponentAesKey(String componentAesKey); + + String getComponentVerifyTicket(); + + void setComponentVerifyTicket(String componentVerifyTicket); + + String getComponentAccessToken(); + + boolean isComponentAccessTokenExpired(); + + void expireComponentAccessToken(); + + void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken); + + String getHttpProxyHost(); + + int getHttpProxyPort(); + + String getHttpProxyUsername(); + + String getHttpProxyPassword(); + + ApacheHttpClientBuilder getApacheHttpClientBuilder(); + + WxMpConfigStorage getWxMpConfigStorage(String appId); + + WxMaConfig getWxMaConfig(String appId); + + /** + * 应该是线程安全的 + * + * @param componentAccessToken 新的accessToken值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds); + + /** + * 是否自动刷新token + */ + boolean autoRefreshToken(); + + String getAuthorizerRefreshToken(String appId); + + void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken); + + String getAuthorizerAccessToken(String appId); + + boolean isAuthorizerAccessTokenExpired(String appId); + + /** + * 强制将access token过期掉 + */ + void expireAuthorizerAccessToken(String appId); + + /** + * 应该是线程安全的 + * + * @param authorizerAccessToken 要更新的WxAccessToken对象 + */ + void updateAuthorizerAccessToken(String appId, WxOpenAuthorizerAccessToken authorizerAccessToken); + + /** + * 应该是线程安全的 + * + * @param authorizerAccessToken 新的accessToken值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds); + + String getJsapiTicket(String appId); + + boolean isJsapiTicketExpired(String appId); + + /** + * 强制将jsapi ticket过期掉 + */ + void expireJsapiTicket(String appId); + + /** + * 应该是线程安全的 + * + * @param jsapiTicket 新的jsapi ticket值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds); + + String getCardApiTicket(String appId); + + + boolean isCardApiTicketExpired(String appId); + + /** + * 强制将卡券api ticket过期掉 + */ + void expireCardApiTicket(String appId); + + /** + * 应该是线程安全的 + * + * @param cardApiTicket 新的cardApi ticket值 + * @param expiresInSeconds 过期时间,以秒为单位 + */ + void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds); +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java new file mode 100644 index 0000000000..2cb82ff7d1 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java @@ -0,0 +1,335 @@ +package me.chanjar.weixin.open.api; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo; +import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage; +import me.chanjar.weixin.open.bean.result.*; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + *

+ *     微信开放平台代小程序实现服务能力
+ *     https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489144594_DhNoV&token=&lang=zh_CN
+ * 
+ * + * @author yqx + * @date 2018/9/12 + */ +public interface WxOpenMaService extends WxMaService { + + /** + * 设置小程序服务器域名 + * + *
+   *     授权给第三方的小程序,其服务器域名只可以为第三方的服务器,当小程序通过第三方发布代码上线后,小程序原先自己配置的服务器域名将被删除,
+   *     只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加第三方自身的域名。
+   *     提示:需要先将域名登记到第三方平台的小程序服务器域名中,才可以调用接口进行配置
+   * 
+ */ + String API_MODIFY_DOMAIN = "https://api.weixin.qq.com/wxa/modify_domain"; + + /** + * 设置小程序业务域名(仅供第三方代小程序调用) + *
+   *     授权给第三方的小程序,其业务域名只可以为第三方的服务器,当小程序通过第三方发布代码上线后,小程序原先自己配置的业务域名将被删除,
+   *     只保留第三方平台的域名,所以第三方平台在代替小程序发布代码之前,需要调用接口为小程序添加业务域名。
+   * 提示:
+   * 1、需要先将域名登记到第三方平台的小程序业务域名中,才可以调用接口进行配置。
+   * 2、为授权的小程序配置域名时支持配置子域名,例如第三方登记的业务域名如为qq.com,则可以直接将qq.com及其子域名(如xxx.qq.com)也配置到授权的小程序中。
+   * 
+ */ + String API_SET_WEBVIEW_DOMAIN = "https://api.weixin.qq.com/wxa/setwebviewdomain"; + + /** + * 获取帐号基本信息 + *
+   * GET请求
+   * 注意:需要使用1.3环节获取到的新创建小程序appid及authorization_code换取authorizer_refresh_token进而得到authorizer_access_token。
+   * 
+ */ + String API_GET_ACCOUNT_BASICINFO = "https://api.weixin.qq.com/cgi-bin/account/getaccountbasicinfo"; + + /** + * 绑定微信用户为小程序体验者 + */ + String API_BIND_TESTER = "https://api.weixin.qq.com/wxa/bind_tester"; + + + /** + * 解除绑定微信用户为小程序体验者 + */ + String API_UNBIND_TESTER = "https://api.weixin.qq.com/wxa/unbind_tester"; + + + /** + * 获取体验者列表 + */ + String API_GET_TESTERLIST = "https://api.weixin.qq.com/wxa/memberauth"; + + /** + * 以下接口为三方平台代小程序实现的代码管理功能 + *

+ * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140610_Uavc4&token=fe774228c66725425675810097f9e48d0737a4bf&lang=zh_CN + *

+ */ + + /** + * 1. 为授权的小程序帐号上传小程序代码 + */ + String API_CODE_COMMIT = "https://api.weixin.qq.com/wxa/commit"; + + /** + * 2. 获取体验小程序的体验二维码 + */ + String API_TEST_QRCODE = "https://api.weixin.qq.com/wxa/get_qrcode"; + + /** + * 3. 获取授权小程序帐号的可选类目 + */ + String API_GET_CATEGORY = "https://api.weixin.qq.com/wxa/get_category"; + + /** + * 4. 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) + */ + String API_GET_PAGE = "https://api.weixin.qq.com/wxa/get_page"; + + /** + * 5. 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) + */ + String API_SUBMIT_AUDIT = "https://api.weixin.qq.com/wxa/submit_audit"; + + /** + * 7. 查询某个指定版本的审核状态(仅供第三方代小程序调用) + */ + String API_GET_AUDIT_STATUS = "https://api.weixin.qq.com/wxa/get_auditstatus"; + + /** + * 8. 查询最新一次提交的审核状态(仅供第三方代小程序调用) + */ + String API_GET_LATEST_AUDIT_STATUS = "https://api.weixin.qq.com/wxa/get_latest_auditstatus"; + + /** + * 9. 发布已通过审核的小程序(仅供第三方代小程序调用) + */ + String API_RELEASE = "https://api.weixin.qq.com/wxa/release"; + + /** + * 10. 修改小程序线上代码的可见状态(仅供第三方代小程序调用) + */ + String API_CHANGE_VISITSTATUS = "https://api.weixin.qq.com/wxa/change_visitstatus"; + + /** + * 11.小程序版本回退(仅供第三方代小程序调用) + */ + String API_REVERT_CODE_RELEASE = "https://api.weixin.qq.com/wxa/revertcoderelease"; + + /** + * 12.查询当前设置的最低基础库版本及各版本用户占比 (仅供第三方代小程序调用) + */ + String API_GET_WEAPP_SUPPORT_VERSION = "https://api.weixin.qq.com/cgi-bin/wxopen/getweappsupportversion"; + + /** + * 13.设置最低基础库版本(仅供第三方代小程序调用) + */ + String API_SET_WEAPP_SUPPORT_VERSION = "https://api.weixin.qq.com/cgi-bin/wxopen/setweappsupportversion"; + + /** + * 14.设置小程序“扫普通链接二维码打开小程序”能力 + *

+ * TODO 暂时不实现 + *

+ */ + + /** + * 15.小程序审核撤回 + *

+ * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。 + *

+ */ + String API_UNDO_CODE_AUDIT = "https://api.weixin.qq.com/wxa/undocodeaudit"; + + /** + * 16.1 小程序分阶段发布-分阶段发布接口 + */ + String API_GRAY_RELEASE = "https://api.weixin.qq.com/wxa/grayrelease"; + + /** + * 16.2 小程序分阶段发布-取消分阶段发布 + */ + String API_REVERT_GRAY_RELEASE = "https://api.weixin.qq.com/wxa/revertgrayrelease"; + + /** + * 16.3 小程序分阶段发布-查询当前分阶段发布详情 + */ + String API_GET_GRAY_RELEASE_PLAN = "https://api.weixin.qq.com/wxa/getgrayreleaseplan"; + + + /** + * 获得小程序的域名配置信息 + * + * @return + */ + WxOpenMaDomainResult getDomain() throws WxErrorException; + + /** + * 修改域名 + * + * @param action delete删除, set覆盖, get获取 + * @param requestdomainList + * @param wsrequestdomainList + * @param uploaddomainList + * @param downloaddomainList + * @return + * @throws WxErrorException + */ + WxOpenMaDomainResult modifyDomain(String action, List requestdomainList, List wsrequestdomainList, List uploaddomainList, List downloaddomainList) throws WxErrorException; + + /** + * 获取小程序的业务域名 + * + * @return 直接返回字符串 + */ + String getWebViewDomain() throws WxErrorException; + + /** + * 设置小程序的业务域名 + * + * @param action add添加, delete删除, set覆盖 + * @param domainList + * @return 直接返回字符串 + */ + String setWebViewDomain(String action, List domainList) throws WxErrorException; + + /** + * 获取小程序的信息 + * + * @return + * @throws WxErrorException + */ + String getAccountBasicInfo() throws WxErrorException; + + /** + * 绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + String bindTester(String wechatid) throws WxErrorException; + + /** + * 解除绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + String unbindTester(String wechatid) throws WxErrorException; + + /** + * 获得体验者列表 + * + * @return + * @throws WxErrorException + */ + WxOpenMaTesterListResult getTesterList() throws WxErrorException; + + /** + * 1、为授权的小程序帐号上传小程序代码 + * + * @param templateId 代码模板ID + * @param userVersion 用户定义版本 + * @param userDesc 用户定义版本描述 + * @param extInfo 第三方自定义的配置 + * @return + * @throws WxErrorException + */ + String codeCommit(Long templateId, String userVersion, String userDesc, WxMaOpenCommitExtInfo extInfo) throws WxErrorException; + + /** + * 获取体验小程序的体验二维码 + * + * @param pagePath + * @param params + * @return + */ + File getTestQrcode(String pagePath, Map params) throws WxErrorException; + + /** + * 获取授权小程序帐号的可选类目 + *

+ * 注意:该接口可获取已设置的二级类目及用于代码审核的可选三级类目。 + *

+ * + * @return WxOpenMaCategoryListResult + * @throws WxErrorException + */ + WxOpenMaCategoryListResult getCategoryList() throws WxErrorException; + + /** + * 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) + * + * @return + * @throws WxErrorException + */ + WxOpenMaPageListResult getPageList() throws WxErrorException; + + /** + * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) + * + * @param submitAuditMessage + * @return + * @throws WxErrorException + */ + WxOpenMaSubmitAuditResult submitAudit(WxOpenMaSubmitAuditMessage submitAuditMessage) throws WxErrorException; + + /** + * 查询某个指定版本的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + String getAuditStatus(Long auditid) throws WxErrorException; + + /** + * 查询最新一次提交的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + String getLatestAuditStatus(Long auditid) throws WxErrorException; + + /** + * 发布已通过审核的小程序(仅供第三方代小程序调用) + * + * @return + * @throws WxErrorException + */ + String releaesAudited() throws WxErrorException; + + /** + * 11. 小程序版本回退(仅供第三方代小程序调用) + * + * @return + * @throws WxErrorException + */ + String revertCodeReleaes() throws WxErrorException; + + /** + * 15. 小程序审核撤回 + *

+ * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。 + *

+ * + * @return + * @throws WxErrorException + */ + String undoCodeAudit() throws WxErrorException; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenService.java new file mode 100644 index 0000000000..a157581b36 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenService.java @@ -0,0 +1,25 @@ +package me.chanjar.weixin.open.api; + +import me.chanjar.weixin.common.error.WxErrorException; + +/** + * @author 007 + */ +public interface WxOpenService { + WxOpenComponentService getWxOpenComponentService(); + + WxOpenConfigStorage getWxOpenConfigStorage(); + + void setWxOpenConfigStorage(WxOpenConfigStorage wxOpenConfigStorage); + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 + */ + String get(String url, String queryParam) throws WxErrorException; + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 + */ + String post(String url, String postData) throws WxErrorException; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java new file mode 100644 index 0000000000..2fd53dc5c2 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java @@ -0,0 +1,365 @@ +package me.chanjar.weixin.open.api.impl; + +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.URIUtil; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.api.WxOpenMaService; +import me.chanjar.weixin.open.api.WxOpenService; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; +import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +/** + * @author 007 + */ +public class WxOpenComponentServiceImpl implements WxOpenComponentService { + private static final JsonParser JSON_PARSER = new JsonParser(); + private static final Map WX_OPEN_MA_SERVICE_MAP = new Hashtable<>(); + private static final Map WX_OPEN_MP_SERVICE_MAP = new Hashtable<>(); + + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxOpenService wxOpenService; + + public WxOpenComponentServiceImpl(WxOpenService wxOpenService) { + this.wxOpenService = wxOpenService; + } + + @Override + public WxMpService getWxMpServiceByAppid(String appId) { + WxMpService wxMpService = WX_OPEN_MP_SERVICE_MAP.get(appId); + if (wxMpService == null) { + synchronized (WX_OPEN_MP_SERVICE_MAP) { + wxMpService = WX_OPEN_MP_SERVICE_MAP.get(appId); + if (wxMpService == null) { + wxMpService = new WxOpenMpServiceImpl(this, appId, getWxOpenConfigStorage().getWxMpConfigStorage(appId)); + + WX_OPEN_MP_SERVICE_MAP.put(appId, wxMpService); + } + } + } + return wxMpService; + } + + @Override + public WxOpenMaService getWxMaServiceByAppid(String appId) { + WxOpenMaService wxOpenMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); + if (wxOpenMaService == null) { + synchronized (WX_OPEN_MA_SERVICE_MAP) { + wxOpenMaService = WX_OPEN_MA_SERVICE_MAP.get(appId); + if (wxOpenMaService == null) { + wxOpenMaService = new WxOpenMaServiceImpl(this, appId, getWxOpenConfigStorage().getWxMaConfig(appId)); + WX_OPEN_MA_SERVICE_MAP.put(appId, wxOpenMaService); + } + } + } + return wxOpenMaService; + } + + public WxOpenService getWxOpenService() { + return wxOpenService; + } + + @Override + public WxOpenConfigStorage getWxOpenConfigStorage() { + return wxOpenService.getWxOpenConfigStorage(); + } + + @Override + public boolean checkSignature(String timestamp, String nonce, String signature) { + try { + return SHA1.gen(getWxOpenConfigStorage().getComponentToken(), timestamp, nonce) + .equals(signature); + } catch (Exception e) { + this.log.error("Checking signature failed, and the reason is :" + e.getMessage()); + return false; + } + } + + @Override + public String getComponentAccessToken(boolean forceRefresh) throws WxErrorException { + + if (this.getWxOpenConfigStorage().isComponentAccessTokenExpired() || forceRefresh) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("component_appsecret", getWxOpenConfigStorage().getComponentAppSecret()); + jsonObject.addProperty("component_verify_ticket", getWxOpenConfigStorage().getComponentVerifyTicket()); + + String responseContent = this.getWxOpenService().post(API_COMPONENT_TOKEN_URL, jsonObject.toString()); + WxOpenComponentAccessToken componentAccessToken = WxOpenComponentAccessToken.fromJson(responseContent); + getWxOpenConfigStorage().updateComponentAccessTokent(componentAccessToken); + } + return this.getWxOpenConfigStorage().getComponentAccessToken(); + } + + private String post(String uri, String postData) throws WxErrorException { + return post(uri, postData, "component_access_token"); + } + + private String post(String uri, String postData, String accessTokenKey) throws WxErrorException { + String componentAccessToken = getComponentAccessToken(false); + String uriWithComponentAccessToken = uri + (uri.contains("?") ? "&" : "?") + accessTokenKey + "=" + componentAccessToken; + try { + return getWxOpenService().post(uriWithComponentAccessToken, postData); + } catch (WxErrorException e) { + WxError error = e.getError(); + /* + * 发生以下情况时尝试刷新access_token + * 40001 获取access_token时AppSecret错误,或者access_token无效 + * 42001 access_token超时 + * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 + */ + if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { + // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token + this.getWxOpenConfigStorage().expireComponentAccessToken(); + if (this.getWxOpenConfigStorage().autoRefreshToken()) { + return this.post(uri, postData, accessTokenKey); + } + } + if (error.getErrorCode() != 0) { + throw new WxErrorException(error, e); + } + return null; + } + } + + private String get(String uri) throws WxErrorException { + return get(uri, "component_access_token"); + } + + private String get(String uri, String accessTokenKey) throws WxErrorException { + String componentAccessToken = getComponentAccessToken(false); + String uriWithComponentAccessToken = uri + (uri.contains("?") ? "&" : "?") + accessTokenKey + "=" + componentAccessToken; + try { + return getWxOpenService().get(uriWithComponentAccessToken, null); + } catch (WxErrorException e) { + WxError error = e.getError(); + /* + * 发生以下情况时尝试刷新access_token + * 40001 获取access_token时AppSecret错误,或者access_token无效 + * 42001 access_token超时 + * 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 + */ + if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { + // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token + this.getWxOpenConfigStorage().expireComponentAccessToken(); + if (this.getWxOpenConfigStorage().autoRefreshToken()) { + return this.get(uri, accessTokenKey); + } + } + if (error.getErrorCode() != 0) { + throw new WxErrorException(error, e); + } + return null; + } + } + + @Override + public String getPreAuthUrl(String redirectURI) throws WxErrorException { + return getPreAuthUrl(redirectURI, null, null); + } + + @Override + public String getPreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + String responseContent = post(API_CREATE_PREAUTHCODE_URL, jsonObject.toString()); + jsonObject = WxGsonBuilder.create().fromJson(responseContent, JsonObject.class); + + StringBuilder preAuthUrl = new StringBuilder(String.format(COMPONENT_LOGIN_PAGE_URL, + getWxOpenConfigStorage().getComponentAppId(), + jsonObject.get("pre_auth_code").getAsString(), + URIUtil.encodeURIComponent(redirectURI))); + if (StringUtils.isNotEmpty(authType)) { + preAuthUrl.append("&auth_type=").append(authType); + } + if (StringUtils.isNotEmpty(bizAppid)) { + preAuthUrl.append("&biz_appid=").append(bizAppid); + } + + return preAuthUrl.toString(); + } + + + @Override + public String route(final WxOpenXmlMessage wxMessage) throws WxErrorException { + if (wxMessage == null) { + throw new NullPointerException("message is empty"); + } + if (StringUtils.equalsIgnoreCase(wxMessage.getInfoType(), "component_verify_ticket")) { + getWxOpenConfigStorage().setComponentVerifyTicket(wxMessage.getComponentVerifyTicket()); + return "success"; + } + //新增、跟新授权 + if (StringUtils.equalsAnyIgnoreCase(wxMessage.getInfoType(), "authorized", "updateauthorized")) { + WxOpenQueryAuthResult queryAuth = wxOpenService.getWxOpenComponentService().getQueryAuth(wxMessage.getAuthorizationCode()); + if (queryAuth == null || queryAuth.getAuthorizationInfo() == null || queryAuth.getAuthorizationInfo().getAuthorizerAppid() == null) { + throw new NullPointerException("getQueryAuth"); + } + return "success"; + } + return ""; + } + + @Override + public WxOpenQueryAuthResult getQueryAuth(String authorizationCode) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorization_code", authorizationCode); + String responseContent = post(API_QUERY_AUTH_URL, jsonObject.toString()); + WxOpenQueryAuthResult queryAuth = WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenQueryAuthResult.class); + if (queryAuth == null || queryAuth.getAuthorizationInfo() == null) { + return queryAuth; + } + WxOpenAuthorizationInfo authorizationInfo = queryAuth.getAuthorizationInfo(); + if (authorizationInfo.getAuthorizerAccessToken() != null) { + getWxOpenConfigStorage().updateAuthorizerAccessToken(authorizationInfo.getAuthorizerAppid(), + authorizationInfo.getAuthorizerAccessToken(), authorizationInfo.getExpiresIn()); + } + if (authorizationInfo.getAuthorizerRefreshToken() != null) { + getWxOpenConfigStorage().setAuthorizerRefreshToken(authorizationInfo.getAuthorizerAppid(), authorizationInfo.getAuthorizerRefreshToken()); + } + return queryAuth; + } + + @Override + public WxOpenAuthorizerInfoResult getAuthorizerInfo(String authorizerAppid) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", authorizerAppid); + String responseContent = post(API_GET_AUTHORIZER_INFO_URL, jsonObject.toString()); + return WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenAuthorizerInfoResult.class); + } + + @Override + public WxOpenAuthorizerOptionResult getAuthorizerOption(String authorizerAppid, String optionName) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", authorizerAppid); + jsonObject.addProperty("option_name", optionName); + String responseContent = post(API_GET_AUTHORIZER_OPTION_URL, jsonObject.toString()); + return WxOpenGsonBuilder.create().fromJson(responseContent, WxOpenAuthorizerOptionResult.class); + } + + @Override + public void setAuthorizerOption(String authorizerAppid, String optionName, String optionValue) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", authorizerAppid); + jsonObject.addProperty("option_name", optionName); + jsonObject.addProperty("option_value", optionValue); + post(API_SET_AUTHORIZER_OPTION_URL, jsonObject.toString()); + } + + @Override + public String getAuthorizerAccessToken(String appId, boolean forceRefresh) throws WxErrorException { + + if (this.getWxOpenConfigStorage().isAuthorizerAccessTokenExpired(appId) || forceRefresh) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("component_appid", getWxOpenConfigStorage().getComponentAppId()); + jsonObject.addProperty("authorizer_appid", appId); + jsonObject.addProperty("authorizer_refresh_token", getWxOpenConfigStorage().getAuthorizerRefreshToken(appId)); + String responseContent = post(API_AUTHORIZER_TOKEN_URL, jsonObject.toString()); + + WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent); + getWxOpenConfigStorage().updateAuthorizerAccessToken(appId, wxOpenAuthorizerAccessToken); + } + return this.getWxOpenConfigStorage().getAuthorizerAccessToken(appId); + } + + @Override + public WxMpOAuth2AccessToken oauth2getAccessToken(String appId, String code) throws WxErrorException { + String url = String.format(OAUTH2_ACCESS_TOKEN_URL, appId, code, getWxOpenConfigStorage().getComponentAppId()); + String responseContent = get(url); + return WxMpOAuth2AccessToken.fromJson(responseContent); + } + + @Override + public boolean checkSignature(String appid, String timestamp, String nonce, String signature) { + return false; + } + + @Override + public WxMpOAuth2AccessToken oauth2refreshAccessToken(String appId, String refreshToken) throws WxErrorException { + String url = String.format(OAUTH2_REFRESH_TOKEN_URL, appId, refreshToken, getWxOpenConfigStorage().getComponentAppId()); + String responseContent = get(url); + return WxMpOAuth2AccessToken.fromJson(responseContent); + } + + @Override + public String oauth2buildAuthorizationUrl(String appId, String redirectURI, String scope, String state) { + return String.format(CONNECT_OAUTH2_AUTHORIZE_URL, + appId, URIUtil.encodeURIComponent(redirectURI), scope, StringUtils.trimToEmpty(state), getWxOpenConfigStorage().getComponentAppId()); + } + + @Override + public WxMaJscode2SessionResult miniappJscode2Session(String appId, String jsCode) throws WxErrorException { + String url = String.format(MINIAPP_JSCODE_2_SESSION, appId, jsCode, getWxOpenConfigStorage().getComponentAppId()); + String responseContent = get(url); + return WxMaJscode2SessionResult.fromJson(responseContent); + } + + @Override + public List getTemplateDraftList() throws WxErrorException { + String responseContent = get(GET_TEMPLATE_DRAFT_LIST_URL, "access_token"); + JsonObject response = JSON_PARSER.parse(StringUtils.defaultString(responseContent, "{}")).getAsJsonObject(); + boolean hasDraftList = response.has("draft_list"); + if (hasDraftList) { + return WxOpenGsonBuilder.create().fromJson(response.getAsJsonArray("draft_list"), + new TypeToken>() { + }.getType()); + } else { + return null; + } + } + + @Override + public List getTemplateList() throws WxErrorException { + String responseContent = get(GET_TEMPLATE_LIST_URL, "access_token"); + JsonObject response = JSON_PARSER.parse(StringUtils.defaultString(responseContent, "{}")).getAsJsonObject(); + boolean hasDraftList = response.has("template_list"); + if (hasDraftList) { + return WxOpenGsonBuilder.create().fromJson(response.getAsJsonArray("template_list"), + new TypeToken>() { + }.getType()); + } else { + return null; + } + } + + @Override + public void addToTemplate(long draftId) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("draft_id", draftId); + post(ADD_TO_TEMPLATE_URL, param.toString(), "access_token"); + } + + @Override + public void deleteTemplate(long templateId) throws WxErrorException { + JsonObject param = new JsonObject(); + param.addProperty("template_id", templateId); + post(DELETE_TEMPLATE_URL, param.toString(), "access_token"); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java new file mode 100644 index 0000000000..a340be8164 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java @@ -0,0 +1,472 @@ +package me.chanjar.weixin.open.api.impl; + + +import java.io.File; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; + +/** + * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 + * + * @author 007 + */ +public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { + private String componentAppId; + private String componentAppSecret; + private String componentToken; + private String componentAesKey; + private String componentVerifyTicket; + private String componentAccessToken; + private long componentExpiresTime; + + private String httpProxyHost; + private int httpProxyPort; + private String httpProxyUsername; + private String httpProxyPassword; + private ApacheHttpClientBuilder apacheHttpClientBuilder; + + private Map authorizerRefreshTokens = new Hashtable<>(); + private Map authorizerAccessTokens = new Hashtable<>(); + private Map jsapiTickets = new Hashtable<>(); + private Map cardApiTickets = new Hashtable<>(); + + @Override + public String getComponentAppId() { + return componentAppId; + } + + @Override + public void setComponentAppId(String componentAppId) { + this.componentAppId = componentAppId; + } + + @Override + public String getComponentAppSecret() { + return componentAppSecret; + } + + @Override + public void setComponentAppSecret(String componentAppSecret) { + this.componentAppSecret = componentAppSecret; + } + + @Override + public String getComponentToken() { + return componentToken; + } + + @Override + public void setComponentToken(String componentToken) { + this.componentToken = componentToken; + } + + @Override + public String getComponentAesKey() { + return componentAesKey; + } + + @Override + public void setComponentAesKey(String componentAesKey) { + this.componentAesKey = componentAesKey; + } + + @Override + public String getComponentVerifyTicket() { + return componentVerifyTicket; + } + + @Override + public void setComponentVerifyTicket(String componentVerifyTicket) { + this.componentVerifyTicket = componentVerifyTicket; + } + + @Override + public String getComponentAccessToken() { + return componentAccessToken; + } + + @Override + public boolean isComponentAccessTokenExpired() { + return System.currentTimeMillis() > componentExpiresTime; + } + + @Override + public void expireComponentAccessToken() { + this.componentExpiresTime = 0L; + } + + @Override + public void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken) { + updateComponentAccessTokent(componentAccessToken.getComponentAccessToken(), componentAccessToken.getExpiresIn()); + } + + @Override + public String getHttpProxyHost() { + return httpProxyHost; + } + + public void setHttpProxyHost(String httpProxyHost) { + this.httpProxyHost = httpProxyHost; + } + + @Override + public int getHttpProxyPort() { + return httpProxyPort; + } + + public void setHttpProxyPort(int httpProxyPort) { + this.httpProxyPort = httpProxyPort; + } + + @Override + public String getHttpProxyUsername() { + return httpProxyUsername; + } + + public void setHttpProxyUsername(String httpProxyUsername) { + this.httpProxyUsername = httpProxyUsername; + } + + @Override + public String getHttpProxyPassword() { + return httpProxyPassword; + } + + public void setHttpProxyPassword(String httpProxyPassword) { + this.httpProxyPassword = httpProxyPassword; + } + + @Override + public ApacheHttpClientBuilder getApacheHttpClientBuilder() { + return apacheHttpClientBuilder; + } + + public ApacheHttpClientBuilder setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { + return this.apacheHttpClientBuilder = apacheHttpClientBuilder; + } + + @Override + public WxMpConfigStorage getWxMpConfigStorage(String appId) { + return new WxOpenInnerConfigStorage(this, appId); + } + + @Override + public WxMaConfig getWxMaConfig(String appId) { + return new WxOpenInnerConfigStorage(this, appId); + } + + @Override + public void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds) { + this.componentAccessToken = componentAccessToken; + this.componentExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + } + + @Override + public boolean autoRefreshToken() { + return true; + } + + private String getTokenString(Map map, String key) { + Token token = map.get(key); + if (token == null || (token.expiresTime != null && System.currentTimeMillis() > token.expiresTime)) { + return null; + } + return token.token; + } + + private void expireToken(Map map, String key) { + Token token = map.get(key); + if (token != null) { + token.expiresTime = 0L; + } + } + + private void updateToken(Map map, String key, String tokenString, Integer expiresInSeconds) { + Token token = map.get(key); + if (token == null) { + token = new Token(); + map.put(key, token); + } + token.token = tokenString; + if (expiresInSeconds != null) { + token.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; + } + } + + @Override + public String getAuthorizerRefreshToken(String appId) { + return getTokenString(authorizerRefreshTokens, appId); + } + + @Override + public void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken) { + updateToken(authorizerRefreshTokens, appId, authorizerRefreshToken, null); + } + + @Override + public String getAuthorizerAccessToken(String appId) { + return getTokenString(authorizerAccessTokens, appId); + } + + + @Override + public boolean isAuthorizerAccessTokenExpired(String appId) { + return getTokenString(authorizerAccessTokens, appId) == null; + } + + @Override + public void expireAuthorizerAccessToken(String appId) { + expireToken(authorizerAccessTokens, appId); + } + + @Override + public void updateAuthorizerAccessToken(String appId, WxOpenAuthorizerAccessToken authorizerAccessToken) { + updateAuthorizerAccessToken(appId, authorizerAccessToken.getAuthorizerAccessToken(), authorizerAccessToken.getExpiresIn()); + } + + @Override + public void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds) { + updateToken(authorizerAccessTokens, appId, authorizerAccessToken, expiresInSeconds); + } + + @Override + public String getJsapiTicket(String appId) { + return getTokenString(jsapiTickets, appId); + } + + @Override + public boolean isJsapiTicketExpired(String appId) { + return getTokenString(jsapiTickets, appId) == null; + } + + @Override + public void expireJsapiTicket(String appId) { + expireToken(jsapiTickets, appId); + } + + @Override + public void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds) { + updateToken(jsapiTickets, appId, jsapiTicket, expiresInSeconds); + } + + @Override + public String getCardApiTicket(String appId) { + return getTokenString(cardApiTickets, appId); + } + + @Override + public boolean isCardApiTicketExpired(String appId) { + return getTokenString(cardApiTickets, appId) == null; + } + + @Override + public void expireCardApiTicket(String appId) { + expireToken(cardApiTickets, appId); + } + + @Override + public void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds) { + updateToken(cardApiTickets, appId, cardApiTicket, expiresInSeconds); + } + + private static class Token { + private String token; + private Long expiresTime; + } + + private static class WxOpenInnerConfigStorage implements WxMpConfigStorage, WxMaConfig { + private WxOpenConfigStorage wxOpenConfigStorage; + private String appId; + private Lock accessTokenLock = new ReentrantLock(); + private Lock jsapiTicketLock = new ReentrantLock(); + private Lock cardApiTicketLock = new ReentrantLock(); + + private WxOpenInnerConfigStorage(WxOpenConfigStorage wxOpenConfigStorage, String appId) { + this.wxOpenConfigStorage = wxOpenConfigStorage; + this.appId = appId; + } + + @Override + public String getAccessToken() { + return wxOpenConfigStorage.getAuthorizerAccessToken(appId); + } + + @Override + public Lock getAccessTokenLock() { + return this.accessTokenLock; + } + + @Override + public boolean isAccessTokenExpired() { + return wxOpenConfigStorage.isAuthorizerAccessTokenExpired(appId); + } + + @Override + public synchronized void updateAccessToken(WxAccessToken accessToken) { + updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); + } + + @Override + public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { + wxOpenConfigStorage.updateAuthorizerAccessToken(appId, accessToken, expiresInSeconds); + } + + @Override + public String getAppid() { + return this.appId; + } + + @Override + public void expireAccessToken() { + wxOpenConfigStorage.expireAuthorizerAccessToken(appId); + } + + @Override + public String getJsapiTicket() { + return wxOpenConfigStorage.getJsapiTicket(appId); + } + + @Override + public Lock getJsapiTicketLock() { + return this.jsapiTicketLock; + } + + @Override + public boolean isJsapiTicketExpired() { + return wxOpenConfigStorage.isJsapiTicketExpired(appId); + } + + @Override + public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { + wxOpenConfigStorage.updateJsapiTicket(appId, jsapiTicket, expiresInSeconds); + } + + @Override + public void expireJsapiTicket() { + wxOpenConfigStorage.expireJsapiTicket(appId); + } + + /** + * 卡券api_ticket + */ + @Override + public String getCardApiTicket() { + return wxOpenConfigStorage.getCardApiTicket(appId); + } + + @Override + public Lock getCardApiTicketLock() { + return this.cardApiTicketLock; + } + + @Override + public boolean isCardApiTicketExpired() { + return wxOpenConfigStorage.isCardApiTicketExpired(appId); + } + + @Override + public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { + wxOpenConfigStorage.updateCardApiTicket(appId, cardApiTicket, expiresInSeconds); + } + + @Override + public void expireCardApiTicket() { + wxOpenConfigStorage.expireCardApiTicket(appId); + } + + @Override + public String getAppId() { + return this.appId; + } + + @Override + public String getSecret() { + return null; + } + + @Override + public String getToken() { + return wxOpenConfigStorage.getComponentToken(); + } + + @Override + public String getTemplateId() { + return null; + } + + @Override + public long getExpiresTime() { + return 0; + } + + + @Override + public String getAesKey() { + return wxOpenConfigStorage.getComponentAesKey(); + } + + @Override + public String getMsgDataFormat() { + return null; + } + + @Override + public String getOauth2redirectUri() { + return null; + } + + @Override + public String getHttpProxyHost() { + return this.wxOpenConfigStorage.getHttpProxyHost(); + } + + @Override + public int getHttpProxyPort() { + return this.wxOpenConfigStorage.getHttpProxyPort(); + } + + @Override + public String getHttpProxyUsername() { + return this.wxOpenConfigStorage.getHttpProxyUsername(); + } + + @Override + public String getHttpProxyPassword() { + return this.wxOpenConfigStorage.getHttpProxyPassword(); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + @Override + public File getTmpDirFile() { + return null; + } + + @Override + public ApacheHttpClientBuilder getApacheHttpClientBuilder() { + return wxOpenConfigStorage.getApacheHttpClientBuilder(); + } + + + @Override + public boolean autoRefreshToken() { + return true; + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java new file mode 100644 index 0000000000..3745a15034 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java @@ -0,0 +1,201 @@ +package me.chanjar.weixin.open.api.impl; + +import org.apache.commons.lang3.StringUtils; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.util.Pool; + +/** + * @author 007 + */ +public class WxOpenInRedisConfigStorage extends WxOpenInMemoryConfigStorage { + private final static String COMPONENT_VERIFY_TICKET_KEY = "wechat_component_verify_ticket:"; + private final static String COMPONENT_ACCESS_TOKEN_KEY = "wechat_component_access_token:"; + + private final static String AUTHORIZER_REFRESH_TOKEN_KEY = "wechat_authorizer_refresh_token:"; + private final static String AUTHORIZER_ACCESS_TOKEN_KEY = "wechat_authorizer_access_token:"; + private final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket:"; + private final static String CARD_API_TICKET_KEY = "wechat_card_api_ticket:"; + + protected final Pool jedisPool; + /** + * redis 存储的 key 的前缀,可为空 + */ + private String keyPrefix; + private String componentVerifyTicketKey; + private String componentAccessTokenKey; + private String authorizerRefreshTokenKey; + private String authorizerAccessTokenKey; + private String jsapiTicketKey; + private String cardApiTicket; + + public WxOpenInRedisConfigStorage(Pool jedisPool) { + this.jedisPool = jedisPool; + } + + public WxOpenInRedisConfigStorage(Pool jedisPool, String keyPrefix) { + this.jedisPool = jedisPool; + this.keyPrefix = keyPrefix; + } + + public WxOpenInRedisConfigStorage(JedisPool jedisPool) { + this.jedisPool = jedisPool; + } + + @Override + public void setComponentAppId(String componentAppId) { + super.setComponentAppId(componentAppId); + String prefix = StringUtils.isBlank(keyPrefix) ? "" : + (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":")); + componentVerifyTicketKey = prefix + COMPONENT_VERIFY_TICKET_KEY.concat(componentAppId); + componentAccessTokenKey = prefix + COMPONENT_ACCESS_TOKEN_KEY.concat(componentAppId); + authorizerRefreshTokenKey = prefix + AUTHORIZER_REFRESH_TOKEN_KEY.concat(componentAppId); + authorizerAccessTokenKey = prefix + AUTHORIZER_ACCESS_TOKEN_KEY.concat(componentAppId); + this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(componentAppId); + this.cardApiTicket = CARD_API_TICKET_KEY.concat(componentAppId); + } + + @Override + public String getComponentVerifyTicket() { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.componentVerifyTicketKey); + } + } + + @Override + public void setComponentVerifyTicket(String componentVerifyTicket) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.set(this.componentVerifyTicketKey, componentVerifyTicket); + } + } + + @Override + public String getComponentAccessToken() { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.componentAccessTokenKey); + } + } + + @Override + public boolean isComponentAccessTokenExpired() { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(this.componentAccessTokenKey) < 2; + } + } + + @Override + public void expireComponentAccessToken(){ + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(this.componentAccessTokenKey, 0); + } + } + + @Override + public void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(this.componentAccessTokenKey, expiresInSeconds - 200, componentAccessToken); + } + } + + private String getKey(String prefix, String appId) { + return prefix.endsWith(":") ? prefix.concat(appId) : prefix.concat(":").concat(appId); + } + + @Override + public String getAuthorizerRefreshToken(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.getKey(this.authorizerRefreshTokenKey, appId)); + } + } + + @Override + public void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.set(this.getKey(this.authorizerRefreshTokenKey, appId), authorizerRefreshToken); + } + } + + @Override + public String getAuthorizerAccessToken(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.getKey(this.authorizerAccessTokenKey, appId)); + } + } + + @Override + public boolean isAuthorizerAccessTokenExpired(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(this.getKey(this.authorizerAccessTokenKey, appId)) < 2; + } + } + + @Override + public void expireAuthorizerAccessToken(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(this.getKey(this.authorizerAccessTokenKey, appId), 0); + } + } + + @Override + public void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(this.getKey(this.authorizerAccessTokenKey, appId), expiresInSeconds - 200, authorizerAccessToken); + } + } + + @Override + public String getJsapiTicket(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.getKey(this.jsapiTicketKey, appId)); + } + } + + @Override + public boolean isJsapiTicketExpired(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(this.getKey(this.jsapiTicketKey, appId)) < 2; + } + } + + @Override + public void expireJsapiTicket(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(this.getKey(this.jsapiTicketKey, appId), 0); + } + } + + @Override + public void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(this.getKey(this.jsapiTicketKey, appId), expiresInSeconds - 200, jsapiTicket); + } + } + + @Override + public String getCardApiTicket(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(this.getKey(this.cardApiTicket, appId)); + } + } + + @Override + public boolean isCardApiTicketExpired(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(this.getKey(this.cardApiTicket, appId)) < 2; + } + } + + @Override + public void expireCardApiTicket(String appId) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.expire(this.getKey(this.cardApiTicket, appId), 0); + } + } + + @Override + public void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.setex(this.getKey(this.cardApiTicket, appId), expiresInSeconds - 200, cardApiTicket); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java new file mode 100644 index 0000000000..2cdfcc45a8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java @@ -0,0 +1,346 @@ +package me.chanjar.weixin.open.api.impl; + +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenMaService; +import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage; +import me.chanjar.weixin.open.bean.result.*; +import me.chanjar.weixin.open.util.requestexecuter.ma.MaQrCodeRequestExecutor; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + * @author 007 + *
+ *     增加开放平台代小程序管理服务能力
+ *     说明:这里让这个服务公开便于调用者模拟本地测试服务
+ * 
+ * @author yqx + * @date 2018-09-12 + */ +public class WxOpenMaServiceImpl extends WxMaServiceImpl implements WxOpenMaService { + private WxOpenComponentService wxOpenComponentService; + private WxMaConfig wxMaConfig; + private String appId; + + public WxOpenMaServiceImpl(WxOpenComponentService wxOpenComponentService, String appId, WxMaConfig wxMaConfig) { + this.wxOpenComponentService = wxOpenComponentService; + this.appId = appId; + this.wxMaConfig = wxMaConfig; + initHttp(); + } + + @Override + public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException { + return wxOpenComponentService.miniappJscode2Session(appId, jsCode); + } + + @Override + public WxMaConfig getWxMaConfig() { + return wxMaConfig; + } + + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + return wxOpenComponentService.getAuthorizerAccessToken(appId, forceRefresh); + } + + /** + * 获得小程序的域名配置信息 + * + * @return + */ + @Override + public WxOpenMaDomainResult getDomain() throws WxErrorException { + return modifyDomain("get", null, null, null, null); + } + + /** + * 修改服务器域名 + * + * @param action delete删除, set覆盖, get获取 + * @param requestdomainList + * @param wsrequestdomainList + * @param uploaddomainList + * @param downloaddomainList + * @return + * @throws WxErrorException + */ + public WxOpenMaDomainResult modifyDomain(String action, List requestdomainList, List wsrequestdomainList, List uploaddomainList, List downloaddomainList) throws WxErrorException { + +// if (!"get".equals(action) && (requestdomainList == null || wsrequestdomainList == null || uploaddomainList == null || downloaddomainList == null)) { +// throw new WxErrorException(WxError.builder().errorCode(44004).errorMsg("域名参数不能为空").build()); +// } + JsonObject requestJson = new JsonObject(); + requestJson.addProperty("action", action); + if (!"get".equals(action)) { + requestJson.add("requestdomain", toJsonArray(requestdomainList)); + requestJson.add("wsrequestdomain", toJsonArray(wsrequestdomainList)); + requestJson.add("uploaddomain", toJsonArray(uploaddomainList)); + requestJson.add("downloaddomain", toJsonArray(downloaddomainList)); + } + String response = post(API_MODIFY_DOMAIN, GSON.toJson(requestJson)); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaDomainResult.class); + } + + /** + * 获取小程序的业务域名 + * + * @return + */ + @Override + public String getWebViewDomain() throws WxErrorException { + return setWebViewDomain("get", null); + } + + /** + * 设置小程序的业务域名 + * + * @param action add添加, delete删除, set覆盖 + * @param domainList + * @return + */ + @Override + public String setWebViewDomain(String action, List domainList) throws WxErrorException { + JsonObject requestJson = new JsonObject(); + requestJson.addProperty("action", action); + if (!"get".equals(action)) { + requestJson.add("webviewdomain", toJsonArray(domainList)); + } + String response = post(API_SET_WEBVIEW_DOMAIN, GSON.toJson(requestJson)); + //TODO 转化为对象返回 + return response; + } + + /** + * 获取小程序的信息,GET请求 + *
+   *     注意:这里不能直接用小程序的access_token
+   *     //TODO 待调整
+   * 
+ * + * @return + * @throws WxErrorException + */ + @Override + public String getAccountBasicInfo() throws WxErrorException { + String response = get(API_GET_ACCOUNT_BASICINFO, ""); + return response; + } + + /** + * 绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + @Override + public String bindTester(String wechatid) throws WxErrorException { + JsonObject paramJson = new JsonObject(); + paramJson.addProperty("wechatid", wechatid); + String response = post(API_BIND_TESTER, GSON.toJson(paramJson)); + return response; + } + + /** + * 解除绑定小程序体验者 + * + * @param wechatid 体验者微信号(不是openid) + * @return + * @throws WxErrorException + */ + @Override + public String unbindTester(String wechatid) throws WxErrorException { + JsonObject paramJson = new JsonObject(); + paramJson.addProperty("wechatid", wechatid); + String response = post(API_UNBIND_TESTER, GSON.toJson(paramJson)); + return response; + } + + /** + * 获得体验者列表 + * + * @return + * @throws WxErrorException + */ + @Override + public WxOpenMaTesterListResult getTesterList() throws WxErrorException { + JsonObject paramJson = new JsonObject(); + paramJson.addProperty("action", "get_experiencer"); + String response = post(API_GET_TESTERLIST, GSON.toJson(paramJson)); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaTesterListResult.class); + } + + /** + * 1、为授权的小程序帐号上传小程序代码 + * + * @param templateId 代码模板ID + * @param userVersion 用户定义版本 + * @param userDesc 用户定义版本描述 + * @param extInfo 第三方自定义的配置 + * @return + * @throws WxErrorException + */ + @Override + public String codeCommit(Long templateId, String userVersion, String userDesc, WxMaOpenCommitExtInfo extInfo) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("template_id", templateId); + params.addProperty("user_version", userVersion); + params.addProperty("user_desc", userDesc); + //注意:ext_json必须是字符串类型 + params.addProperty("ext_json", GSON.toJson(extInfo)); + String response = post(API_CODE_COMMIT, GSON.toJson(params)); + return response; + } + + /** + * 获取体验小程序的体验二维码 + * + * @param pagePath + * @param params + * @return + */ + @Override + public File getTestQrcode(String pagePath, Map params) throws WxErrorException { + WxMaQrcodeParam qrcodeParam = WxMaQrcodeParam.create(pagePath); + qrcodeParam.addPageParam(params); + return execute(MaQrCodeRequestExecutor.create(getRequestHttp()), API_TEST_QRCODE, qrcodeParam); + } + + /** + * 获取授权小程序帐号的可选类目 + *

+ * 注意:该接口可获取已设置的二级类目及用于代码审核的可选三级类目。 + *

+ * + * @return WxOpenMaCategoryListResult + * @throws WxErrorException + */ + @Override + public WxOpenMaCategoryListResult getCategoryList() throws WxErrorException { + String response = get(API_GET_CATEGORY, null); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaCategoryListResult.class); + } + + /** + * 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用) + * + * @return + * @throws WxErrorException + */ + @Override + public WxOpenMaPageListResult getPageList() throws WxErrorException { + String response = get(API_GET_PAGE, null); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaPageListResult.class); + } + + /** + * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) + * + * @param submitAuditMessage + * @return + * @throws WxErrorException + */ + public WxOpenMaSubmitAuditResult submitAudit(WxOpenMaSubmitAuditMessage submitAuditMessage) throws WxErrorException { + String response = post(API_SUBMIT_AUDIT, GSON.toJson(submitAuditMessage)); + return WxMaGsonBuilder.create().fromJson(response, WxOpenMaSubmitAuditResult.class); + } + + /** + * 7. 查询某个指定版本的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + @Override + public String getAuditStatus(Long auditid) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("auditid", auditid); + String response = post(API_GET_AUDIT_STATUS, GSON.toJson(params)); + return response; + } + + /** + * 8. 查询最新一次提交的审核状态(仅供第三方代小程序调用) + * + * @param auditid + * @return + * @throws WxErrorException + */ + @Override + public String getLatestAuditStatus(Long auditid) throws WxErrorException { + String response = get(API_GET_LATEST_AUDIT_STATUS, null); + return response; + } + + /** + * 9. 发布已通过审核的小程序(仅供第三方代小程序调用) + *

+ * 请填写空的数据包,POST的json数据包为空即可。 + *

+ * + * @return + * @throws WxErrorException + */ + @Override + public String releaesAudited() throws WxErrorException { + JsonObject params = new JsonObject(); + String response = post(API_RELEASE, GSON.toJson(params)); + return response; + } + + /** + * 11. 小程序版本回退(仅供第三方代小程序调用) + * + * @return + * @throws WxErrorException + */ + @Override + public String revertCodeReleaes() throws WxErrorException { + String response = get(API_REVERT_CODE_RELEASE, null); + return response; + } + + /** + * 15. 小程序审核撤回 + *

+ * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。 + *

+ * + * @return + * @throws WxErrorException + */ + @Override + public String undoCodeAudit() throws WxErrorException { + String response = get(API_UNDO_CODE_AUDIT, null); + return response; + } + + /** + * 将字符串对象转化为GsonArray对象 + * + * @param strList + * @return + */ + private JsonArray toJsonArray(List strList) { + JsonArray jsonArray = new JsonArray(); + if (strList != null && !strList.isEmpty()) { + for (String str : strList) { + jsonArray.add(str); + } + } + return jsonArray; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMessageRouter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMessageRouter.java new file mode 100644 index 0000000000..2e483fc0aa --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMessageRouter.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.mp.api.WxMpMessageRouter; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import me.chanjar.weixin.open.api.WxOpenService; + +import java.util.HashMap; +import java.util.Map; + +public class WxOpenMessageRouter extends WxMpMessageRouter { + private WxOpenService wxOpenService; + + public WxOpenMessageRouter(WxOpenService wxOpenService) { + super(null); + this.wxOpenService = wxOpenService; + } + + public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, String appId) { + return route(wxMessage, new HashMap(), appId); + } + + public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, final Map context, String appId) { + return route(wxMessage, context, wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId)); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java new file mode 100644 index 0000000000..a946fb7014 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMpServiceImpl.java @@ -0,0 +1,48 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.open.api.WxOpenComponentService; + +/** + * @author 007 + */ +/* package */ class WxOpenMpServiceImpl extends WxMpServiceImpl { + private WxOpenComponentService wxOpenComponentService; + private WxMpConfigStorage wxMpConfigStorage; + private String appId; + + public WxOpenMpServiceImpl(WxOpenComponentService wxOpenComponentService, String appId, WxMpConfigStorage wxMpConfigStorage) { + this.wxOpenComponentService = wxOpenComponentService; + this.appId = appId; + this.wxMpConfigStorage = wxMpConfigStorage; + initHttp(); + } + + @Override + public WxMpConfigStorage getWxMpConfigStorage() { + return wxMpConfigStorage; + } + + @Override + public String getAccessToken(boolean forceRefresh) throws WxErrorException { + return wxOpenComponentService.getAuthorizerAccessToken(appId, forceRefresh); + } + + @Override + public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException { + return wxOpenComponentService.oauth2getAccessToken(appId, code); + } + + @Override + public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException { + return wxOpenComponentService.oauth2refreshAccessToken(appId, refreshToken); + } + + @Override + public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) { + return wxOpenComponentService.oauth2buildAuthorizationUrl(appId, redirectURI, scope, state); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceAbstractImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceAbstractImpl.java new file mode 100644 index 0000000000..4949726402 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceAbstractImpl.java @@ -0,0 +1,61 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.api.WxOpenService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * @author 007 + */ +public abstract class WxOpenServiceAbstractImpl implements WxOpenService, RequestHttp { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + protected WxOpenComponentService wxOpenComponentService = new WxOpenComponentServiceImpl(this); + private WxOpenConfigStorage wxOpenConfigStorage; + + @Override + public WxOpenComponentService getWxOpenComponentService() { + return wxOpenComponentService; + } + + @Override + public WxOpenConfigStorage getWxOpenConfigStorage() { + return wxOpenConfigStorage; + } + + @Override + public void setWxOpenConfigStorage(WxOpenConfigStorage wxOpenConfigStorage) { + this.wxOpenConfigStorage = wxOpenConfigStorage; + this.initHttp(); + } + + /** + * 初始化 RequestHttp + */ + public abstract void initHttp(); + + protected synchronized T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { + try { + T result = executor.execute(uri, data); + this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uri, data, result); + return result; + } catch (WxErrorException e) { + WxError error = e.getError(); + if (error.getErrorCode() != 0) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uri, data, error); + throw new WxErrorException(error, e); + } + return null; + } catch (IOException e) { + this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uri, data, e.getMessage()); + throw new RuntimeException(e); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java new file mode 100644 index 0000000000..d9b7b49553 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceApacheHttpClientImpl.java @@ -0,0 +1,68 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; +import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import org.apache.http.HttpHost; +import org.apache.http.impl.client.CloseableHttpClient; + +/** + * apache-http方式实现 + * + * @author 007 + */ +public class WxOpenServiceApacheHttpClientImpl extends WxOpenServiceAbstractImpl { + private CloseableHttpClient httpClient; + private HttpHost httpProxy; + + @Override + public void initHttp() { + WxOpenConfigStorage configStorage = this.getWxOpenConfigStorage(); + ApacheHttpClientBuilder apacheHttpClientBuilder = configStorage.getApacheHttpClientBuilder(); + if (null == apacheHttpClientBuilder) { + apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); + } + + apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost()) + .httpProxyPort(configStorage.getHttpProxyPort()) + .httpProxyUsername(configStorage.getHttpProxyUsername()) + .httpProxyPassword(configStorage.getHttpProxyPassword()); + + if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) { + this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); + } + + this.httpClient = apacheHttpClientBuilder.build(); + + } + + @Override + public CloseableHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public HttpHost getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpType getRequestType() { + return HttpType.APACHE_HTTP; + } + + @Override + public String get(String url, String queryParam) throws WxErrorException { + return execute(SimpleGetRequestExecutor.create(this), url, queryParam); + } + + @Override + public String post(String url, String postData) throws WxErrorException { + return execute(SimplePostRequestExecutor.create(this), url, postData); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java new file mode 100644 index 0000000000..c807ccdf99 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenServiceImpl.java @@ -0,0 +1,8 @@ +package me.chanjar.weixin.open.api.impl; + +/** + * @author 007 + */ +public class WxOpenServiceImpl extends WxOpenServiceApacheHttpClientImpl { + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenAuthorizerAccessToken.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenAuthorizerAccessToken.java new file mode 100644 index 0000000000..9b86412bb3 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenAuthorizerAccessToken.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.open.bean; + +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; + +import java.io.Serializable; + +/** + * @author 007 + */ +public class WxOpenAuthorizerAccessToken implements Serializable { + private static final long serialVersionUID = -4069745419280727420L; + + private String authorizerAccessToken; + + private int expiresIn = -1; + + public static WxOpenAuthorizerAccessToken fromJson(String json) { + return WxOpenGsonBuilder.create().fromJson(json, WxOpenAuthorizerAccessToken.class); + } + + public String getAuthorizerAccessToken() { + return authorizerAccessToken; + } + + public void setAuthorizerAccessToken(String authorizerAccessToken) { + this.authorizerAccessToken = authorizerAccessToken; + } + + public int getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(int expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenComponentAccessToken.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenComponentAccessToken.java new file mode 100644 index 0000000000..8a97c24dfb --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenComponentAccessToken.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.open.bean; + +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; + +import java.io.Serializable; + +/** + * @author 007 + */ +public class WxOpenComponentAccessToken implements Serializable { + private static final long serialVersionUID = 2134550135400443725L; + + private String componentAccessToken; + + private int expiresIn = -1; + + public static WxOpenComponentAccessToken fromJson(String json) { + return WxOpenGsonBuilder.create().fromJson(json, WxOpenComponentAccessToken.class); + } + + public String getComponentAccessToken() { + return componentAccessToken; + } + + public void setComponentAccessToken(String componentAccessToken) { + this.componentAccessToken = componentAccessToken; + } + + public int getExpiresIn() { + return expiresIn; + } + + public void setExpiresIn(int expiresIn) { + this.expiresIn = expiresIn; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenMaCodeTemplate.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenMaCodeTemplate.java new file mode 100644 index 0000000000..be1bb9b138 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenMaCodeTemplate.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.open.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author Charming + * @since 2018-04-26 17:10 + */ +@Data +public class WxOpenMaCodeTemplate implements Serializable { + private static final long serialVersionUID = -3278116984473619010L; + /** + * 草稿id + */ + @SerializedName(value = "draftId", alternate = "draft_id") + private Long draftId; + /** + * 模版id + */ + @SerializedName(value = "templateId", alternate = "template_id") + private Long templateId; + /** + * 模版版本号,开发者自定义字段 + */ + @SerializedName(value = "userVersion", alternate = "user_version") + private String userVersion; + /** + * 模版描述 开发者自定义字段 + */ + @SerializedName(value = "userDesc", alternate = "user_desc") + private String userDesc; + /** + * 开发者上传草稿时间 / 被添加为模版的时间 + */ + @SerializedName(value = "createTime", alternate = "create_time") + private Long createTime; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizationInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizationInfo.java new file mode 100644 index 0000000000..23e8f1497e --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizationInfo.java @@ -0,0 +1,20 @@ +package me.chanjar.weixin.open.bean.auth; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizationInfo implements Serializable { + private static final long serialVersionUID = -8713680081354754208L; + + private String authorizerAppid; + private String authorizerAccessToken; + private int expiresIn; + private String authorizerRefreshToken; + private List funcInfo; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizerInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizerInfo.java new file mode 100644 index 0000000000..a80dab0307 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenAuthorizerInfo.java @@ -0,0 +1,66 @@ +package me.chanjar.weixin.open.bean.auth; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizerInfo implements Serializable { + private static final long serialVersionUID = -5327886953416394738L; + + private String nickName; + private String headImg; + private Integer serviceTypeInfo; + private Integer verifyTypeInfo; + private String userName; + private String principalName; + private Map businessInfo; + private String alias; + private String qrcodeUrl; + /** + * 账号介绍 + */ + private String signature; + + /** + * 可根据这个字段判断是否为小程序类型授权 + */ + private MiniProgramInfo miniProgramInfo; + + @Data + public class MiniProgramInfo { + @SerializedName("visit_status") + private Integer visitStatus; + /** + * 小程序已设置的各个服务器域名. + */ + private Network network; + private List categories; + + @Data + public class Category { + private String first; + private String second; + } + + @Data + public class Network { + @SerializedName("RequestDomain") + private List requestDomain; + @SerializedName("WsRequestDomain") + private List wsRequestDomain; + @SerializedName("UploadDomain") + private List uploadDomain; + @SerializedName("DownloadDomain") + private List downloadDomain; + @SerializedName("BizDomain") + private List bizDomain; + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenMiniProgramInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenMiniProgramInfo.java new file mode 100644 index 0000000000..44f56e6f2b --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/auth/WxOpenMiniProgramInfo.java @@ -0,0 +1,14 @@ +package me.chanjar.weixin.open.bean.auth; + +import lombok.Data; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.List; +import java.util.Map; + +@Data +public class WxOpenMiniProgramInfo { + private Map> network; + private List> categories; + private Integer visitStatus; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java new file mode 100644 index 0000000000..c38867bae7 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java @@ -0,0 +1,96 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 微信小程序三方平台代上传代码提交额外信息对象 + *

+ * 如果代码中已经有配置,则配置的合并规则为:除了pages和tabBar.list直接覆盖原配置,其他都为插入或同级覆盖。 + *

+ * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenCommitExtInfo implements Serializable { + + WxMaOpenCommitExtInfo() { + + } + + /** + * 授权小程序Appid,可填入商户小程序AppID,以区分不同商户 + */ + private String extAppid; + + @SerializedName("ext") + private Map extMap; + + @SerializedName("extPages") + private Map extPages; + + /** + * 页面路径列表(和app.json结构一致) + */ + @SerializedName("pages") + private List pageList; + + @SerializedName("window") + private WxMaOpenWindow window; + + @SerializedName("networkTimeout") + private WxMaOpenNetworkTimeout networkTimeout; + + @SerializedName("tabBar") + private WxMaOpenTabBar tabBar; + + /** + * 添加扩展项 + * + * @param key + * @param value + */ + public void addExt(String key, String value) { + if (extMap == null) + extMap = new HashMap<>(); + if (StringUtils.isNoneBlank(key, value)) + extMap.put(key, value); + } + + /** + * 添加扩展页面 + * + * @param pagePath + * @param page + */ + public void addExtPage(String pagePath, WxMaOpenPage page) { + if (extPages == null) + extPages = new HashMap<>(); + if (StringUtils.isNotBlank(pagePath) && page != null) + extPages.put(pagePath, page); + } + + /** + * 添加页面 + * + * @param pagePath + */ + public void addPage(String pagePath) { + if (pageList == null) + pageList = new ArrayList<>(); + if (StringUtils.isNotBlank(pagePath)) + pageList.add(pagePath); + } + + public static WxMaOpenCommitExtInfo INSTANCE() { + return new WxMaOpenCommitExtInfo(); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenNetworkTimeout.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenNetworkTimeout.java new file mode 100644 index 0000000000..9717f42af8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenNetworkTimeout.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenNetworkTimeout implements Serializable { + + private Integer request; + + private Integer connectSocket; + + private Integer uploadFile; + + private Integer downloadFile; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenPage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenPage.java new file mode 100644 index 0000000000..ca63fc3d8f --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenPage.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenPage implements Serializable { + private String navigationBarBackgroundColor; + private String navigationBarTextStyle; + private String navigationBarTitleText; + private String backgroundColor; + private String backgroundTextStyle; + private Boolean enablePullDownRefresh; + private Integer onReachBottomDistance; + private Boolean disableScroll; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTab.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTab.java new file mode 100644 index 0000000000..68d7cacbfd --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTab.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; +import lombok.NonNull; + +import java.io.Serializable; + +/** + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenTab implements Serializable { + @NonNull + private String pagePath; + + @NonNull + private String text; + private String iconPath; + private String selectedIconPath; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTabBar.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTabBar.java new file mode 100644 index 0000000000..6245c0331d --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenTabBar.java @@ -0,0 +1,49 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * tabBar对象 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +@NoArgsConstructor +public class WxMaOpenTabBar implements Serializable { + @NonNull + private String color; + + @NonNull + private String selectedColor; + + @NonNull + private String backgroundColor; + + private String borderStyle; + + @NonNull + @SerializedName("list") + private List tabList; + + private String position; + + /** + * 添加tab + * + * @param text + * @param pagePath + */ + public void addTab(String text, String pagePath) { + if (tabList == null) + tabList = new ArrayList<>(); + tabList.add(new WxMaOpenTab(pagePath, text)); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenWindow.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenWindow.java new file mode 100644 index 0000000000..4848f8c7b1 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenWindow.java @@ -0,0 +1,34 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * window对象 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaOpenWindow implements Serializable { + private String navigationBarBackgroundColor; + + private String navigationBarTextStyle; + + private String navigationBarTitleText; + + private String navigationStyle; + + private String backgroundColor; + + private String backgroundTextStyle; + + private String backgroundColorTop; + + private String backgroundColorBottom; + + private Boolean enablePullDownRefresh; + + private Integer onReachBottomDistance; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaQrcodeParam.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaQrcodeParam.java new file mode 100644 index 0000000000..2dafa037d6 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaQrcodeParam.java @@ -0,0 +1,86 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * 微信小程序体验二维码参数 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxMaQrcodeParam { + + WxMaQrcodeParam() { + + } + + /** + * 页面路径 + */ + private String pagePath; + + /** + * 页面参数 + */ + private Map pageParams; + + /** + * 添加页面参数 + * + * @param key + * @param value + */ + public WxMaQrcodeParam addPageParam(String key, String value) { + if (StringUtils.isNoneBlank(key, value)) { + if (pageParams == null) + pageParams = new HashMap<>(); + pageParams.put(key, value); + } + return this; + } + + /** + * 添加页面参数 + * + * @param params + * @return + */ + public WxMaQrcodeParam addPageParam(Map params) { + if (params != null) { + if (pageParams == null) + pageParams = new HashMap<>(); + pageParams.putAll(params); + } + return this; + } + + /** + * 组装完整的页面请求路径(带参数) + * + * @return + */ + public String getRequestPath() { + if (StringUtils.isNotBlank(getPagePath()) && getPageParams() != null && !getPageParams().isEmpty()) { + Set keys = getPageParams().keySet(); + StringBuilder sb = new StringBuilder(); + for (String key : keys) { + sb.append("&").append(key).append("=").append(getPageParams().get(key)); + } + return pagePath + "?" + sb.substring(1); + } else { + return pagePath; + } + } + + public static WxMaQrcodeParam create(String pagePath) { + WxMaQrcodeParam instance = new WxMaQrcodeParam(); + instance.setPagePath(pagePath); + return instance; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaCategory.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaCategory.java new file mode 100644 index 0000000000..88ca63ae5e --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaCategory.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 微信小程序分类目录 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxOpenMaCategory implements Serializable { + + @SerializedName("first_class") + private String firstClass; + + @SerializedName("second_class") + private String secondClass; + + @SerializedName("third_class") + private String thirdClass; + + @SerializedName("first_id") + private Integer firstId; + + @SerializedName("second_id") + private Integer secondId; + + @SerializedName("third_id") + private Integer thirdId; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaMember.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaMember.java new file mode 100644 index 0000000000..dc939373ab --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaMember.java @@ -0,0 +1,19 @@ +package me.chanjar.weixin.open.bean.ma; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 微信开放平台小程序成员对象 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaMember implements Serializable { + /** + * 人员对应的唯一字符串 + */ + private String userstr; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaSubmitAudit.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaSubmitAudit.java new file mode 100644 index 0000000000..9c9e712241 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaSubmitAudit.java @@ -0,0 +1,60 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 三方平台提交小程序代码审核 + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxOpenMaSubmitAudit implements Serializable { + + + /** + * 小程序的页面,可通过“获取小程序的第三方提交代码的页面配置”接口获得 + */ + @SerializedName("address") + private String pagePath; + + /** + * 小程序的标签,多个标签用空格分隔,标签不能多于10个,标签长度不超过20 + */ + @SerializedName("tag") + private String tag; + + /** + * 类目名称,可通过“获取授权小程序帐号的可选类目”接口获得 + */ + @SerializedName("first_class") + private String firstClass; + + @SerializedName("second_class") + private String secondClass; + + @SerializedName("third_class") + private String thirdClass; + + /** + * 类目的ID,可通过“获取授权小程序帐号的可选类目”接口获得 + */ + @SerializedName("first_id") + private Integer firstId; + + @SerializedName("second_id") + private Integer secondId; + + @SerializedName("third_id") + private Integer thirdId; + + /** + * 小程序页面的标题,标题长度不超过32 + */ + @SerializedName("title") + private String title; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java new file mode 100644 index 0000000000..a8d806b36e --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.bean.message; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.open.bean.ma.WxOpenMaSubmitAudit; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信小程序代码包提交审核(仅供第三方开发者代小程序调用) + * + * @author yqx + * @date 2018/9/13 + */ +@Data +public class WxOpenMaSubmitAuditMessage implements Serializable { + + @SerializedName("item_list") + private List itemList; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java new file mode 100644 index 0000000000..f38194529d --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java @@ -0,0 +1,108 @@ +package me.chanjar.weixin.open.bean.message; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +import org.apache.commons.io.IOUtils; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; +import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.util.WxOpenCryptUtil; +import me.chanjar.weixin.open.util.xml.XStreamTransformer; + +/** + * @author 007 + */ +@Data +@Slf4j +@XStreamAlias("xml") +public class WxOpenXmlMessage implements Serializable { + private static final long serialVersionUID = -5641769554709507771L; + + @XStreamAlias("AppId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String appId; + + @XStreamAlias("CreateTime") + private Long createTime; + + @XStreamAlias("InfoType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String infoType; + + @XStreamAlias("ComponentVerifyTicket") + @XStreamConverter(value = XStreamCDataConverter.class) + private String componentVerifyTicket; + + @XStreamAlias("AuthorizerAppid") + @XStreamConverter(value = XStreamCDataConverter.class) + private String authorizerAppid; + + @XStreamAlias("AuthorizationCode") + @XStreamConverter(value = XStreamCDataConverter.class) + private String authorizationCode; + + @XStreamAlias("AuthorizationCodeExpiredTime") + private Long authorizationCodeExpiredTime; + + @XStreamAlias("PreAuthCode") + @XStreamConverter(value = XStreamCDataConverter.class) + private String preAuthCode; + + public static String wxMpOutXmlMessageToEncryptedXml(WxMpXmlOutMessage message, WxOpenConfigStorage wxOpenConfigStorage) { + String plainXml = message.toXml(); + WxOpenCryptUtil pc = new WxOpenCryptUtil(wxOpenConfigStorage); + return pc.encrypt(plainXml); + } + + public static WxOpenXmlMessage fromXml(String xml) { + //修改微信变态的消息内容格式,方便解析 + xml = xml.replace("", ""); + return XStreamTransformer.fromXml(WxOpenXmlMessage.class, xml); + } + + public static WxOpenXmlMessage fromXml(InputStream is) { + return XStreamTransformer.fromXml(WxOpenXmlMessage.class, is); + } + + /** + * 从加密字符串转换 + * + * @param encryptedXml 密文 + * @param wxOpenConfigStorage 配置存储器对象 + * @param timestamp 时间戳 + * @param nonce 随机串 + * @param msgSignature 签名串 + */ + public static WxOpenXmlMessage fromEncryptedXml(String encryptedXml, WxOpenConfigStorage wxOpenConfigStorage, + String timestamp, String nonce, String msgSignature) { + WxOpenCryptUtil cryptUtil = new WxOpenCryptUtil(wxOpenConfigStorage); + String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml); + log.debug("解密后的原始xml消息内容:{}", plainText); + return fromXml(plainText); + } + + public static WxMpXmlMessage fromEncryptedMpXml(String encryptedXml, WxOpenConfigStorage wxOpenConfigStorage, + String timestamp, String nonce, String msgSignature) { + WxOpenCryptUtil cryptUtil = new WxOpenCryptUtil(wxOpenConfigStorage); + String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml); + return WxMpXmlMessage.fromXml(plainText); + } + + public static WxOpenXmlMessage fromEncryptedXml(InputStream is, WxOpenConfigStorage wxOpenConfigStorage, + String timestamp, String nonce, String msgSignature) { + try { + return fromEncryptedXml(IOUtils.toString(is, "UTF-8"), + wxOpenConfigStorage, timestamp, nonce, msgSignature); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerInfoResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerInfoResult.java new file mode 100644 index 0000000000..60dd065b56 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerInfoResult.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.open.bean.result; + +import lombok.Data; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizerInfoResult implements Serializable { + private static final long serialVersionUID = 3166298050833019785L; + + private WxOpenAuthorizationInfo authorizationInfo; + private WxOpenAuthorizerInfo authorizerInfo; + + public boolean isMiniProgram() { + return authorizerInfo != null && authorizerInfo.getMiniProgramInfo() != null; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerOptionResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerOptionResult.java new file mode 100644 index 0000000000..c0ccf008ad --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenAuthorizerOptionResult.java @@ -0,0 +1,17 @@ +package me.chanjar.weixin.open.bean.result; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxOpenAuthorizerOptionResult implements Serializable { + private static final long serialVersionUID = 4477837353654658179L; + + String authorizerAppid; + String optionName; + String optionValue; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaCategoryListResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaCategoryListResult.java new file mode 100644 index 0000000000..af113f16c0 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaCategoryListResult.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.open.bean.ma.WxOpenMaCategory; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序分类目录列表返回 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaCategoryListResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("category_list") + List categoryList; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaDomainResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaDomainResult.java new file mode 100644 index 0000000000..79775e4bae --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaDomainResult.java @@ -0,0 +1,33 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序域名设置返回对象 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaDomainResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("requestdomain") + List requestdomainList; + + @SerializedName("wsrequestdomain") + List wsrequestdomainList; + + @SerializedName("uploaddomain") + List uploaddomainList; + + @SerializedName("downloaddomain") + List downloaddomainList; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaPageListResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaPageListResult.java new file mode 100644 index 0000000000..b4c34fb262 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaPageListResult.java @@ -0,0 +1,30 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序第三方提交代码的页面配置列表 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaPageListResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("page_list") + List pageList; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaSubmitAuditResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaSubmitAuditResult.java new file mode 100644 index 0000000000..77f150c244 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaSubmitAuditResult.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 微信开放平台小程序发布代码审核结果 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaSubmitAuditResult implements Serializable { + + private String errcode; + private String errmsg; + + /** + * 审核编号 + */ + @SerializedName("auditid") + Long auditId; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaTesterListResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaTesterListResult.java new file mode 100644 index 0000000000..91c4af2a6d --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaTesterListResult.java @@ -0,0 +1,31 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.open.bean.ma.WxOpenMaMember; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.List; + +/** + * 微信开放平台小程序体验者列表返回 + * + * @author yqx + * @date 2018/9/12 + */ +@Data +public class WxOpenMaTesterListResult implements Serializable { + + private String errcode; + private String errmsg; + + @SerializedName("members") + List membersList; + + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenQueryAuthResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenQueryAuthResult.java new file mode 100644 index 0000000000..5da7b6e6cf --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenQueryAuthResult.java @@ -0,0 +1,16 @@ +package me.chanjar.weixin.open.bean.result; + +import lombok.Data; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxOpenQueryAuthResult implements Serializable { + private static final long serialVersionUID = 2394736235020206855L; + + private WxOpenAuthorizationInfo authorizationInfo; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/WxOpenCryptUtil.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/WxOpenCryptUtil.java new file mode 100644 index 0000000000..a27b6fe636 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/WxOpenCryptUtil.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.open.util; + +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import org.apache.commons.codec.binary.Base64; + +/** + * @author 007 + */ +public class WxOpenCryptUtil extends me.chanjar.weixin.common.util.crypto.WxCryptUtil { + /** + * 构造函数 + * + * @param wxOpenConfigStorage + */ + public WxOpenCryptUtil(WxOpenConfigStorage wxOpenConfigStorage) { + /* + * @param token 公众平台上,开发者设置的token + * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey + * @param appId 公众平台appid + */ + String encodingAesKey = wxOpenConfigStorage.getComponentAesKey(); + String token = wxOpenConfigStorage.getComponentToken(); + String appId = wxOpenConfigStorage.getComponentAppId(); + + this.token = token; + this.appidOrCorpid = appId; + this.aesKey = Base64.decodeBase64(encodingAesKey + "="); + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizationInfoGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizationInfoGsonAdapter.java new file mode 100644 index 0000000000..69df0647c8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizationInfoGsonAdapter.java @@ -0,0 +1,45 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +/** + * @author 007 + */ +public class WxOpenAuthorizationInfoGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizationInfo deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizationInfo authorizationInfo = new WxOpenAuthorizationInfo(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + authorizationInfo.setAuthorizerAppid(GsonHelper.getString(jsonObject, "authorizer_appid")); + authorizationInfo.setAuthorizerAccessToken(GsonHelper.getString(jsonObject, "authorizer_access_token")); + authorizationInfo.setExpiresIn(GsonHelper.getPrimitiveInteger(jsonObject, "expires_in")); + authorizationInfo.setAuthorizerRefreshToken(GsonHelper.getString(jsonObject, "authorizer_refresh_token")); + List funcInfo = new ArrayList<>(); + JsonArray jsonArray = GsonHelper.getAsJsonArray(jsonObject.get("func_info")); + if (jsonArray != null && !jsonArray.isJsonNull()) { + for (int i = 0; i < jsonArray.size(); i++) { + jsonObject = jsonArray.get(i).getAsJsonObject(); + if (jsonObject == null || jsonObject.isJsonNull()) { + continue; + } + jsonObject = jsonObject.getAsJsonObject("funcscope_category"); + if (jsonObject == null || jsonObject.isJsonNull()) { + continue; + } + Integer id = GsonHelper.getInteger(jsonObject, "id"); + if (id == null) { + continue; + } + funcInfo.add(id); + } + } + authorizationInfo.setFuncInfo(funcInfo); + return authorizationInfo; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerAccessTokenGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerAccessTokenGsonAdapter.java new file mode 100644 index 0000000000..82a04b9ba8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerAccessTokenGsonAdapter.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenAuthorizerAccessTokenGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerAccessToken deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerAccessToken authorizerAccessToken = new WxOpenAuthorizerAccessToken(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + authorizerAccessToken.setAuthorizerAccessToken(GsonHelper.getString(jsonObject, "authorizer_access_token")); + authorizerAccessToken.setExpiresIn(GsonHelper.getPrimitiveInteger(jsonObject, "expires_in")); + return authorizerAccessToken; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoGsonAdapter.java new file mode 100644 index 0000000000..2fb4e7957e --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoGsonAdapter.java @@ -0,0 +1,46 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; + +import java.lang.reflect.Type; +import java.util.Map; + +/** + * @author 007 + */ +public class WxOpenAuthorizerInfoGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerInfo deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerInfo authorizationInfo = new WxOpenAuthorizerInfo(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + authorizationInfo.setNickName(GsonHelper.getString(jsonObject, "nick_name")); + authorizationInfo.setHeadImg(GsonHelper.getString(jsonObject, "head_img")); + authorizationInfo.setUserName(GsonHelper.getString(jsonObject, "user_name")); + authorizationInfo.setPrincipalName(GsonHelper.getString(jsonObject, "principal_name")); + authorizationInfo.setAlias(GsonHelper.getString(jsonObject, "alias")); + authorizationInfo.setQrcodeUrl(GsonHelper.getString(jsonObject, "qrcode_url")); + authorizationInfo.setSignature(GsonHelper.getString(jsonObject, "signature")); + + if (jsonObject.has("service_type_info")) { + authorizationInfo.setServiceTypeInfo(GsonHelper.getInteger(jsonObject.getAsJsonObject("service_type_info"), "id")); + } + if (jsonObject.has("verify_type_info")) { + authorizationInfo.setVerifyTypeInfo(GsonHelper.getInteger(jsonObject.getAsJsonObject("verify_type_info"), "id")); + } + Map businessInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("business_info"), + new TypeToken>() { + }.getType()); + authorizationInfo.setBusinessInfo(businessInfo); + if (jsonObject.has("MiniProgramInfo")) { + WxOpenAuthorizerInfo.MiniProgramInfo miniProgramInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("MiniProgramInfo"), + new TypeToken() { + }.getType()); + authorizationInfo.setMiniProgramInfo(miniProgramInfo); + } + return authorizationInfo; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoResultGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoResultGsonAdapter.java new file mode 100644 index 0000000000..1cef0ff411 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerInfoResultGsonAdapter.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenAuthorizerInfoResultGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerInfoResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerInfoResult authorizerInfoResult = new WxOpenAuthorizerInfoResult(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + WxOpenAuthorizationInfo authorizationInfo = WxOpenGsonBuilder.INSTANCE.create().fromJson(jsonObject.get("authorization_info"), + new TypeToken() { + }.getType()); + + authorizerInfoResult.setAuthorizationInfo(authorizationInfo); + WxOpenAuthorizerInfo authorizerInfo = WxOpenGsonBuilder.INSTANCE.create().fromJson(jsonObject.get("authorizer_info"), + new TypeToken() { + }.getType()); + + authorizerInfoResult.setAuthorizerInfo(authorizerInfo); + return authorizerInfoResult; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerOptionResultGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerOptionResultGsonAdapter.java new file mode 100644 index 0000000000..8a2d379c31 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenAuthorizerOptionResultGsonAdapter.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenAuthorizerOptionResultGsonAdapter implements JsonDeserializer { + @Override + public WxOpenAuthorizerOptionResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenAuthorizerOptionResult authorizerOptionResult = new WxOpenAuthorizerOptionResult(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + authorizerOptionResult.setAuthorizerAppid(GsonHelper.getString(jsonObject, "authorizer_appid")); + authorizerOptionResult.setOptionName(GsonHelper.getString(jsonObject, "option_name")); + authorizerOptionResult.setOptionValue(GsonHelper.getString(jsonObject, "option_value")); + return authorizerOptionResult; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenComponentAccessTokenGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenComponentAccessTokenGsonAdapter.java new file mode 100644 index 0000000000..10ed85083c --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenComponentAccessTokenGsonAdapter.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenComponentAccessTokenGsonAdapter implements JsonDeserializer { + @Override + public WxOpenComponentAccessToken deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenComponentAccessToken componentAccessToken = new WxOpenComponentAccessToken(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + componentAccessToken.setComponentAccessToken(GsonHelper.getString(jsonObject, "component_access_token")); + componentAccessToken.setExpiresIn(GsonHelper.getPrimitiveInteger(jsonObject, "expires_in")); + return componentAccessToken; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java new file mode 100644 index 0000000000..2b390adef3 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; +import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +/** + * @author 007 + */ +public class WxOpenGsonBuilder { + + public static final GsonBuilder INSTANCE = new GsonBuilder(); + + static { + INSTANCE.disableHtmlEscaping(); + INSTANCE.registerTypeAdapter(WxOpenComponentAccessToken.class, new WxOpenComponentAccessTokenGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerAccessToken.class, new WxOpenAuthorizerAccessTokenGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizationInfo.class, new WxOpenAuthorizationInfoGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerInfo.class, new WxOpenAuthorizerInfoGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenQueryAuthResult.class, new WxOpenQueryAuthResultGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerInfoResult.class, new WxOpenAuthorizerInfoResultGsonAdapter()); + INSTANCE.registerTypeAdapter(WxOpenAuthorizerOptionResult.class, new WxOpenAuthorizerOptionResultGsonAdapter()); + + } + + public static Gson create() { + return INSTANCE.create(); + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenQueryAuthResultGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenQueryAuthResultGsonAdapter.java new file mode 100644 index 0000000000..8868d0fef7 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenQueryAuthResultGsonAdapter.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; +import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; + +import java.lang.reflect.Type; + +/** + * @author 007 + */ +public class WxOpenQueryAuthResultGsonAdapter implements JsonDeserializer { + @Override + public WxOpenQueryAuthResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxOpenQueryAuthResult queryAuthResult = new WxOpenQueryAuthResult(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + WxOpenAuthorizationInfo authorizationInfo = WxOpenGsonBuilder.INSTANCE.create().fromJson(jsonObject.get("authorization_info"), + new TypeToken() { + }.getType()); + + queryAuthResult.setAuthorizationInfo(authorizationInfo); + return queryAuthResult; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeApacheHttpRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeApacheHttpRequestExecutor.java new file mode 100644 index 0000000000..14bed802cc --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeApacheHttpRequestExecutor.java @@ -0,0 +1,68 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler; +import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.entity.ContentType; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * @author yqx + * @date 2018-09-13 + */ +public class MaQrCodeApacheHttpRequestExecutor extends MaQrCodeRequestExecutor { + public MaQrCodeApacheHttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public File execute(String uri, WxMaQrcodeParam qrcodeParam) throws WxErrorException, IOException { + if (qrcodeParam != null && StringUtils.isNotBlank(qrcodeParam.getPagePath())) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") + ? "path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8") + : "&path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8"); + } + + HttpGet httpGet = new HttpGet(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpGet.setConfig(config); + } + + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet); + InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) { + Header[] contentTypeHeader = response.getHeaders("Content-Type"); + if (contentTypeHeader != null && contentTypeHeader.length > 0) { + // 出错 + if (ContentType.TEXT_PLAIN.getMimeType() + .equals(ContentType.parse(contentTypeHeader[0].getValue()).getMimeType())) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp)); + } + } + return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); + } finally { + httpGet.releaseConnection(); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeJoddHttpRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeJoddHttpRequestExecutor.java new file mode 100644 index 0000000000..5c02711538 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeJoddHttpRequestExecutor.java @@ -0,0 +1,62 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import jodd.util.MimeTypes; +import jodd.util.StringPool; +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import org.apache.commons.lang3.StringUtils; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * @author yqx + * @date 2018-09-13 + */ +public class MaQrCodeJoddHttpRequestExecutor extends MaQrCodeRequestExecutor { + public MaQrCodeJoddHttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public File execute(String uri, WxMaQrcodeParam qrcodeParam) throws WxErrorException, IOException { + if (qrcodeParam != null && StringUtils.isNotBlank(qrcodeParam.getPagePath())) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") + ? "path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8") + : "&path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8"); + } + + + HttpRequest request = HttpRequest.get(uri); + if (requestHttp.getRequestHttpProxy() != null) { + requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); + } + request.withConnectionProvider(requestHttp.getRequestHttpClient()); + + HttpResponse response = request.send(); + response.charset(StringPool.UTF_8); + String contentTypeHeader = response.header("Content-Type"); + if (MimeTypes.MIME_TEXT_PLAIN.equals(contentTypeHeader)) { + String responseContent = response.bodyText(); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp)); + } + try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) { + return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeOkhttpRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeOkhttpRequestExecutor.java new file mode 100644 index 0000000000..dbcbac9bbe --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeOkhttpRequestExecutor.java @@ -0,0 +1,59 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import me.chanjar.weixin.common.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.UUID; + +/** + * @author yqx + * @date 2018-09-13 + */ +public class MaQrCodeOkhttpRequestExecutor extends MaQrCodeRequestExecutor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public MaQrCodeOkhttpRequestExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public File execute(String uri, WxMaQrcodeParam qrcodeParam) throws WxErrorException, IOException { + if (qrcodeParam != null && StringUtils.isNotBlank(qrcodeParam.getPagePath())) { + if (uri.indexOf('?') == -1) { + uri += '?'; + } + uri += uri.endsWith("?") + ? "path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8") + : "&path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8"); + } + + OkHttpClient client = requestHttp.getRequestHttpClient(); + Request request = new Request.Builder().url(uri).get().build(); + Response response = client.newCall(request).execute(); + String contentTypeHeader = response.header("Content-Type"); + if ("text/plain".equals(contentTypeHeader)) { + String responseContent = response.body().string(); + throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP)); + } + + try (InputStream inputStream = response.body().byteStream()) { + return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); + } + + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeRequestExecutor.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeRequestExecutor.java new file mode 100644 index 0000000000..55766d9952 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/requestexecuter/ma/MaQrCodeRequestExecutor.java @@ -0,0 +1,37 @@ +package me.chanjar.weixin.open.util.requestexecuter.ma; + +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.RequestExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam; + +import java.io.File; + +/** + * 获得小程序体验QrCode图片 请求执行器 + * + * @author yqx + * @date 2018-09-13 + */ +public abstract class MaQrCodeRequestExecutor implements RequestExecutor { + protected RequestHttp requestHttp; + + public MaQrCodeRequestExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + public static RequestExecutor create(RequestHttp requestHttp) throws WxErrorException { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new MaQrCodeApacheHttpRequestExecutor(requestHttp); + case JODD_HTTP: + return new MaQrCodeJoddHttpRequestExecutor(requestHttp); + case OK_HTTP: + return new MaQrCodeOkhttpRequestExecutor(requestHttp); + default: + throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("不支持的http框架").build()); + } + } + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/xml/XStreamTransformer.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/xml/XStreamTransformer.java new file mode 100644 index 0000000000..0065748ab9 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/xml/XStreamTransformer.java @@ -0,0 +1,93 @@ +package me.chanjar.weixin.open.util.xml; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.thoughtworks.xstream.XStream; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; +import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; + +/** + * @author 007 + */ +public class XStreamTransformer { + private static final Map, XStream> CLASS_2_XSTREAM_INSTANCE = new HashMap<>(); + + static { + registerClass(WxOpenXmlMessage.class); + } + + /** + * xml -> pojo. + */ + @SuppressWarnings("unchecked") + public static T fromXml(Class clazz, String xml) { + T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml); + return object; + } + + @SuppressWarnings("unchecked") + public static T fromXml(Class clazz, InputStream is) { + T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is); + return object; + } + + /** + * pojo -> xml. + */ + public static String toXml(Class clazz, T object) { + return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object); + } + + /** + * 注册扩展消息的解析器. + * + * @param clz 类型 + * @param xStream xml解析器 + */ + public static void register(Class clz, XStream xStream) { + CLASS_2_XSTREAM_INSTANCE.put(clz, xStream); + } + + /** + * 会自动注册该类及其子类. + * + * @param clz 要注册的类 + */ + private static void registerClass(Class clz) { + XStream xstream = XStreamInitializer.getInstance(); + + xstream.processAnnotations(clz); + xstream.processAnnotations(getInnerClasses(clz)); + if (clz.equals(WxOpenXmlMessage.class)) { + // 操蛋的微信,模板消息推送成功的消息是MsgID,其他消息推送过来是MsgId + xstream.aliasField("MsgID", WxOpenXmlMessage.class, "msgId"); + } + + register(clz, xstream); + } + + private static Class[] getInnerClasses(Class clz) { + Class[] innerClasses = clz.getClasses(); + if (innerClasses == null) { + return null; + } + + List> result = new ArrayList<>(); + result.addAll(Arrays.asList(innerClasses)); + for (Class inner : innerClasses) { + Class[] innerClz = getInnerClasses(inner); + if (innerClz == null) { + continue; + } + + result.addAll(Arrays.asList(innerClz)); + } + + return result.toArray(new Class[0]); + } +} diff --git a/weixin-java-osgi/pom.xml b/weixin-java-osgi/pom.xml index 91c84d24f3..693d530946 100644 --- a/weixin-java-osgi/pom.xml +++ b/weixin-java-osgi/pom.xml @@ -11,7 +11,7 @@ weixin-java-osgi bundle - WeiXin Java Tools - OSGI + Weixin Java Tools - OSGI 微信公众号Java SDK OSGI diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 05aa6c5f8f..b348a9b975 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,12 +5,12 @@ weixin-java-parent com.github.binarywang - 2.8.0 + 3.2.0 4.0.0 weixin-java-pay - WeiXin Java Tools - PAY + Weixin Java Tools - PAY 微信支付 Java SDK @@ -27,7 +27,23 @@ org.jodd jodd-http - provided + compile + + + + org.apache.commons + commons-lang3 + + + + commons-beanutils + commons-beanutils + 1.9.3 + + + org.bouncycastle + bcpkix-jdk15on + 1.59 @@ -40,11 +56,20 @@ testng test + + org.assertj + assertj-guava + test + com.google.inject guice test + + org.projectlombok + lombok + diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayApiData.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayApiData.java index ab1dec718c..f8277d15ba 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayApiData.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/WxPayApiData.java @@ -1,5 +1,8 @@ package com.github.binarywang.wxpay.bean; +import lombok.Data; +import lombok.NoArgsConstructor; + /** *
  * 微信支付接口请求数据封装对象
@@ -8,6 +11,8 @@
  *
  * @author Binary Wang
  */
+@Data
+@NoArgsConstructor
 public class WxPayApiData {
   /**
    * 接口请求地址
@@ -30,6 +35,8 @@ public class WxPayApiData {
   private String exceptionMsg;
 
   /**
+   * Instantiates a new Wx pay api data.
+   *
    * @param url          接口请求地址
    * @param requestData  请求数据
    * @param responseData 响应数据
@@ -42,38 +49,6 @@ public WxPayApiData(String url, String requestData, String responseData, String
     this.exceptionMsg = exceptionMsg;
   }
 
-  public String getUrl() {
-    return this.url;
-  }
-
-  public void setUrl(String url) {
-    this.url = url;
-  }
-
-  public String getRequestData() {
-    return this.requestData;
-  }
-
-  public void setRequestData(String requestData) {
-    this.requestData = requestData;
-  }
-
-  public String getResponseData() {
-    return this.responseData;
-  }
-
-  public void setResponseData(String responseData) {
-    this.responseData = responseData;
-  }
-
-  public String getExceptionMsg() {
-    return this.exceptionMsg;
-  }
-
-  public void setExceptionMsg(String exceptionMsg) {
-    this.exceptionMsg = exceptionMsg;
-  }
-
   @Override
   public String toString() {
     if (this.exceptionMsg != null) {
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java
index 3d83d0a6c6..61726e0405 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java
@@ -1,7 +1,8 @@
 package com.github.binarywang.wxpay.bean.coupon;
 
-import com.github.binarywang.wxpay.bean.request.WxPayBaseRequest;
+import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
 /**
@@ -12,8 +13,13 @@
  *
  * @author Binary Wang
  */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Builder(builderMethodName = "newBuilder")
+@NoArgsConstructor
+@AllArgsConstructor
 @XStreamAlias("xml")
-public class WxPayCouponInfoQueryRequest  extends WxPayBaseRequest {
+public class WxPayCouponInfoQueryRequest extends BaseWxPayRequest {
   /**
    * 
    * 字段名:代金券id
@@ -108,173 +114,10 @@ public class WxPayCouponInfoQueryRequest  extends WxPayBaseRequest {
   @XStreamAlias("type")
   private String type;
 
-  private WxPayCouponInfoQueryRequest(Builder builder) {
-    setAppid(builder.appid);
-    setMchId(builder.mchId);
-    setSubAppId(builder.subAppId);
-    setSubMchId(builder.subMchId);
-    setNonceStr(builder.nonceStr);
-    setSign(builder.sign);
-    setCouponId(builder.couponId);
-    setStockId(builder.stockId);
-    setOpenid(builder.openid);
-    setOpUserId(builder.opUserId);
-    setDeviceInfo(builder.deviceInfo);
-    setVersion(builder.version);
-    setType(builder.type);
-  }
-
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  public String getCouponId() {
-    return this.couponId;
-  }
-
-  public void setCouponId(String couponId) {
-    this.couponId = couponId;
-  }
-
-  public String getStockId() {
-    return this.stockId;
-  }
-
-  public void setStockId(String stockId) {
-    this.stockId = stockId;
-  }
-
-  public String getOpenid() {
-    return this.openid;
-  }
-
-  public void setOpenid(String openid) {
-    this.openid = openid;
-  }
-
-  public String getOpUserId() {
-    return this.opUserId;
-  }
-
-  public void setOpUserId(String opUserId) {
-    this.opUserId = opUserId;
-  }
-
-  public String getDeviceInfo() {
-    return this.deviceInfo;
-  }
-
-  public void setDeviceInfo(String deviceInfo) {
-    this.deviceInfo = deviceInfo;
-  }
-
-  public String getVersion() {
-    return this.version;
-  }
-
-  public void setVersion(String version) {
-    this.version = version;
-  }
-
-  public String getType() {
-    return this.type;
-  }
-
-  public void setType(String type) {
-    this.type = type;
-  }
 
   @Override
   protected void checkConstraints() {
     //do nothing
   }
 
-
-  public static final class Builder {
-    private String appid;
-    private String mchId;
-    private String subAppId;
-    private String subMchId;
-    private String nonceStr;
-    private String sign;
-    private String couponId;
-    private String stockId;
-    private String openid;
-    private String opUserId;
-    private String deviceInfo;
-    private String version;
-    private String type;
-
-    private Builder() {
-    }
-
-    public Builder appid(String appid) {
-      this.appid = appid;
-      return this;
-    }
-
-    public Builder mchId(String mchId) {
-      this.mchId = mchId;
-      return this;
-    }
-
-    public Builder subAppId(String subAppId) {
-      this.subAppId = subAppId;
-      return this;
-    }
-
-    public Builder subMchId(String subMchId) {
-      this.subMchId = subMchId;
-      return this;
-    }
-
-    public Builder nonceStr(String nonceStr) {
-      this.nonceStr = nonceStr;
-      return this;
-    }
-
-    public Builder sign(String sign) {
-      this.sign = sign;
-      return this;
-    }
-
-    public Builder couponId(String couponId) {
-      this.couponId = couponId;
-      return this;
-    }
-
-    public Builder stockId(String stockId) {
-      this.stockId = stockId;
-      return this;
-    }
-
-    public Builder openid(String openid) {
-      this.openid = openid;
-      return this;
-    }
-
-    public Builder opUserId(String opUserId) {
-      this.opUserId = opUserId;
-      return this;
-    }
-
-    public Builder deviceInfo(String deviceInfo) {
-      this.deviceInfo = deviceInfo;
-      return this;
-    }
-
-    public Builder version(String version) {
-      this.version = version;
-      return this;
-    }
-
-    public Builder type(String type) {
-      this.type = type;
-      return this;
-    }
-
-    public WxPayCouponInfoQueryRequest build() {
-      return new WxPayCouponInfoQueryRequest(this);
-    }
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
index bec1c9e10a..90bafc7819 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
@@ -1,7 +1,10 @@
 package com.github.binarywang.wxpay.bean.coupon;
 
-import com.github.binarywang.wxpay.bean.result.WxPayBaseResult;
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
 
 /**
  * 
@@ -11,11 +14,14 @@
  *
  * @author Binary Wang
  */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
 @XStreamAlias("xml")
-public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
+public class WxPayCouponInfoQueryResult extends BaseWxPayResult {
   /**
    * 
-   * 字段名:设备号
+   * 字段名:设备号.
    * 变量名:device_info
    * 是否必填:否
    * 示例值:123456sb
@@ -28,7 +34,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:批次ID
+   * 字段名:批次ID.
    * 变量名:coupon_stock_id
    * 是否必填:是
    * 示例值:1567
@@ -41,7 +47,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:代金券id
+   * 字段名:代金券id.
    * 变量名:coupon_id
    * 是否必填:是
    * 示例值:4242
@@ -54,7 +60,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:代金券面额
+   * 字段名:代金券面额.
    * 变量名:coupon_value
    * 是否必填:是
    * 示例值:4
@@ -67,7 +73,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:代金券使用门槛
+   * 字段名:代金券使用门槛.
    * 变量名:coupon_mininum
    * 是否必填:是
    * 示例值:10
@@ -80,7 +86,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:代金券名称
+   * 字段名:代金券名称.
    * 变量名:coupon_name
    * 是否必填:是
    * 示例值:测试代金券
@@ -93,20 +99,20 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:代金券状态
+   * 字段名:代金券状态.
    * 变量名:coupon_state
    * 是否必填:是
    * 示例值:SENDED
-   * 类型:int
+   * 类型:String
    * 说明:代金券状态:SENDED-可用,USED-已实扣,EXPIRED-已过期
    * 
*/ @XStreamAlias("coupon_state") - private Integer couponState; + private String couponState; /** *
-   * 字段名:代金券描述
+   * 字段名:代金券描述.
    * 变量名:coupon_desc
    * 是否必填:是
    * 示例值:微信支付-代金券
@@ -119,7 +125,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:实际优惠金额
+   * 字段名:实际优惠金额.
    * 变量名:coupon_use_value
    * 是否必填:是
    * 示例值:0
@@ -132,7 +138,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:优惠剩余可用额
+   * 字段名:优惠剩余可用额.
    * 变量名:coupon_remain_value
    * 是否必填:是
    * 示例值:4
@@ -145,7 +151,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:生效开始时间
+   * 字段名:生效开始时间.
    * 变量名:begin_time
    * 是否必填:是
    * 示例值:1943787483
@@ -158,7 +164,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:生效结束时间
+   * 字段名:生效结束时间.
    * 变量名:end_time
    * 是否必填:是
    * 示例值:1943787484
@@ -171,7 +177,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:发放时间
+   * 字段名:发放时间.
    * 变量名:send_time
    * 是否必填:是
    * 示例值:1943787420
@@ -184,7 +190,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:消耗方商户id
+   * 字段名:消耗方商户id.
    * 变量名:consumer_mch_id
    * 是否必填:否
    * 示例值:10000098
@@ -197,7 +203,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:发放来源
+   * 字段名:发放来源.
    * 变量名:send_source
    * 是否必填:是
    * 示例值:FULL_SEND
@@ -210,7 +216,7 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
 
   /**
    * 
-   * 字段名:是否允许部分使用
+   * 字段名:是否允许部分使用.
    * 变量名:is_partial_use
    * 是否必填:否
    * 示例值:1
@@ -221,131 +227,4 @@ public class WxPayCouponInfoQueryResult extends WxPayBaseResult {
   @XStreamAlias("is_partial_use")
   private String isPartialUse;
 
-  public String getDeviceInfo() {
-    return this.deviceInfo;
-  }
-
-  public void setDeviceInfo(String deviceInfo) {
-    this.deviceInfo = deviceInfo;
-  }
-
-  public String getCouponStockId() {
-    return this.couponStockId;
-  }
-
-  public void setCouponStockId(String couponStockId) {
-    this.couponStockId = couponStockId;
-  }
-
-  public String getCouponId() {
-    return this.couponId;
-  }
-
-  public void setCouponId(String couponId) {
-    this.couponId = couponId;
-  }
-
-  public Integer getCouponValue() {
-    return this.couponValue;
-  }
-
-  public void setCouponValue(Integer couponValue) {
-    this.couponValue = couponValue;
-  }
-
-  public Integer getCouponMininum() {
-    return this.couponMininum;
-  }
-
-  public void setCouponMininum(Integer couponMininum) {
-    this.couponMininum = couponMininum;
-  }
-
-  public String getCouponName() {
-    return this.couponName;
-  }
-
-  public void setCouponName(String couponName) {
-    this.couponName = couponName;
-  }
-
-  public Integer getCouponState() {
-    return this.couponState;
-  }
-
-  public void setCouponState(Integer couponState) {
-    this.couponState = couponState;
-  }
-
-  public String getCouponDesc() {
-    return this.couponDesc;
-  }
-
-  public void setCouponDesc(String couponDesc) {
-    this.couponDesc = couponDesc;
-  }
-
-  public Integer getCouponUseValue() {
-    return this.couponUseValue;
-  }
-
-  public void setCouponUseValue(Integer couponUseValue) {
-    this.couponUseValue = couponUseValue;
-  }
-
-  public Integer getCouponRemainValue() {
-    return this.couponRemainValue;
-  }
-
-  public void setCouponRemainValue(Integer couponRemainValue) {
-    this.couponRemainValue = couponRemainValue;
-  }
-
-  public String getBeginTime() {
-    return this.beginTime;
-  }
-
-  public void setBeginTime(String beginTime) {
-    this.beginTime = beginTime;
-  }
-
-  public String getEndTime() {
-    return this.endTime;
-  }
-
-  public void setEndTime(String endTime) {
-    this.endTime = endTime;
-  }
-
-  public String getSendTime() {
-    return this.sendTime;
-  }
-
-  public void setSendTime(String sendTime) {
-    this.sendTime = sendTime;
-  }
-
-  public String getConsumerMchId() {
-    return this.consumerMchId;
-  }
-
-  public void setConsumerMchId(String consumerMchId) {
-    this.consumerMchId = consumerMchId;
-  }
-
-  public String getSendSource() {
-    return this.sendSource;
-  }
-
-  public void setSendSource(String sendSource) {
-    this.sendSource = sendSource;
-  }
-
-  public String getIsPartialUse() {
-    return this.isPartialUse;
-  }
-
-  public void setIsPartialUse(String isPartialUse) {
-    this.isPartialUse = isPartialUse;
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
index 9a98fd64a2..5fa6da7de2 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
@@ -1,7 +1,8 @@
 package com.github.binarywang.wxpay.bean.coupon;
 
-import com.github.binarywang.wxpay.bean.request.WxPayBaseRequest;
+import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
 /**
@@ -12,8 +13,13 @@
  *
  * @author Binary Wang
  */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Builder(builderMethodName = "newBuilder")
+@NoArgsConstructor
+@AllArgsConstructor
 @XStreamAlias("xml")
-public class WxPayCouponSendRequest extends WxPayBaseRequest {
+public class WxPayCouponSendRequest extends BaseWxPayRequest {
   /**
    * 
    * 字段名:代金券批次id
@@ -122,190 +128,8 @@ public class WxPayCouponSendRequest extends WxPayBaseRequest {
   @XStreamAlias("type")
   private String type;
 
-  public WxPayCouponSendRequest() {
-  }
-
-  private WxPayCouponSendRequest(Builder builder) {
-    setAppid(builder.appid);
-    setMchId(builder.mchId);
-    setSubAppId(builder.subAppId);
-    setSubMchId(builder.subMchId);
-    setNonceStr(builder.nonceStr);
-    setSign(builder.sign);
-    setCouponStockId(builder.couponStockId);
-    setOpenidCount(builder.openidCount);
-    setPartnerTradeNo(builder.partnerTradeNo);
-    setOpenid(builder.openid);
-    setOpUserId(builder.opUserId);
-    setDeviceInfo(builder.deviceInfo);
-    setVersion(builder.version);
-    setType(builder.type);
-  }
-
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  public String getCouponStockId() {
-    return this.couponStockId;
-  }
-
-  public void setCouponStockId(String couponStockId) {
-    this.couponStockId = couponStockId;
-  }
-
-  public Integer getOpenidCount() {
-    return this.openidCount;
-  }
-
-  public void setOpenidCount(Integer openidCount) {
-    this.openidCount = openidCount;
-  }
-
-  public String getPartnerTradeNo() {
-    return this.partnerTradeNo;
-  }
-
-  public void setPartnerTradeNo(String partnerTradeNo) {
-    this.partnerTradeNo = partnerTradeNo;
-  }
-
-  public String getOpenid() {
-    return this.openid;
-  }
-
-  public void setOpenid(String openid) {
-    this.openid = openid;
-  }
-
-  public String getOpUserId() {
-    return this.opUserId;
-  }
-
-  public void setOpUserId(String opUserId) {
-    this.opUserId = opUserId;
-  }
-
-  public String getDeviceInfo() {
-    return this.deviceInfo;
-  }
-
-  public void setDeviceInfo(String deviceInfo) {
-    this.deviceInfo = deviceInfo;
-  }
-
-  public String getVersion() {
-    return this.version;
-  }
-
-  public void setVersion(String version) {
-    this.version = version;
-  }
-
-  public String getType() {
-    return this.type;
-  }
-
-  public void setType(String type) {
-    this.type = type;
-  }
-
   @Override
   protected void checkConstraints() {
     //do nothing
   }
-
-  public static final class Builder {
-    private String appid;
-    private String mchId;
-    private String subAppId;
-    private String subMchId;
-    private String nonceStr;
-    private String sign;
-    private String couponStockId;
-    private Integer openidCount;
-    private String partnerTradeNo;
-    private String openid;
-    private String opUserId;
-    private String deviceInfo;
-    private String version;
-    private String type;
-
-    private Builder() {
-    }
-
-    public Builder appid(String appid) {
-      this.appid = appid;
-      return this;
-    }
-
-    public Builder mchId(String mchId) {
-      this.mchId = mchId;
-      return this;
-    }
-
-    public Builder subAppId(String subAppId) {
-      this.subAppId = subAppId;
-      return this;
-    }
-
-    public Builder subMchId(String subMchId) {
-      this.subMchId = subMchId;
-      return this;
-    }
-
-    public Builder nonceStr(String nonceStr) {
-      this.nonceStr = nonceStr;
-      return this;
-    }
-
-    public Builder sign(String sign) {
-      this.sign = sign;
-      return this;
-    }
-
-    public Builder couponStockId(String couponStockId) {
-      this.couponStockId = couponStockId;
-      return this;
-    }
-
-    public Builder openidCount(Integer openidCount) {
-      this.openidCount = openidCount;
-      return this;
-    }
-
-    public Builder partnerTradeNo(String partnerTradeNo) {
-      this.partnerTradeNo = partnerTradeNo;
-      return this;
-    }
-
-    public Builder openid(String openid) {
-      this.openid = openid;
-      return this;
-    }
-
-    public Builder opUserId(String opUserId) {
-      this.opUserId = opUserId;
-      return this;
-    }
-
-    public Builder deviceInfo(String deviceInfo) {
-      this.deviceInfo = deviceInfo;
-      return this;
-    }
-
-    public Builder version(String version) {
-      this.version = version;
-      return this;
-    }
-
-    public Builder type(String type) {
-      this.type = type;
-      return this;
-    }
-
-    public WxPayCouponSendRequest build() {
-      return new WxPayCouponSendRequest(this);
-    }
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
index 1c562adae2..314845e46e 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
@@ -1,7 +1,10 @@
 package com.github.binarywang.wxpay.bean.coupon;
 
-import com.github.binarywang.wxpay.bean.result.WxPayBaseResult;
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
 
 /**
  * 
@@ -11,8 +14,11 @@
  *
  * @author Binary Wang
  */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
 @XStreamAlias("xml")
-public class WxPayCouponSendResult extends WxPayBaseResult {
+public class WxPayCouponSendResult extends BaseWxPayResult {
   /**
    * 
    * 字段名:设备号
@@ -130,75 +136,4 @@ public class WxPayCouponSendResult extends WxPayBaseResult {
   @XStreamAlias("ret_msg")
   private String retMsg;
 
-  public String getDeviceInfo() {
-    return this.deviceInfo;
-  }
-
-  public void setDeviceInfo(String deviceInfo) {
-    this.deviceInfo = deviceInfo;
-  }
-
-  public String getCouponStockId() {
-    return this.couponStockId;
-  }
-
-  public void setCouponStockId(String couponStockId) {
-    this.couponStockId = couponStockId;
-  }
-
-  public Integer getRespCount() {
-    return this.respCount;
-  }
-
-  public void setRespCount(Integer respCount) {
-    this.respCount = respCount;
-  }
-
-  public Integer getSuccessCount() {
-    return this.successCount;
-  }
-
-  public void setSuccessCount(Integer successCount) {
-    this.successCount = successCount;
-  }
-
-  public Integer getFailedCount() {
-    return this.failedCount;
-  }
-
-  public void setFailedCount(Integer failedCount) {
-    this.failedCount = failedCount;
-  }
-
-  public String getOpenid() {
-    return this.openid;
-  }
-
-  public void setOpenid(String openid) {
-    this.openid = openid;
-  }
-
-  public String getRetCode() {
-    return this.retCode;
-  }
-
-  public void setRetCode(String retCode) {
-    this.retCode = retCode;
-  }
-
-  public String getCouponId() {
-    return this.couponId;
-  }
-
-  public void setCouponId(String couponId) {
-    this.couponId = couponId;
-  }
-
-  public String getRetMsg() {
-    return this.retMsg;
-  }
-
-  public void setRetMsg(String retMsg) {
-    this.retMsg = retMsg;
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
index 24cec5523c..b8a78b40bf 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
@@ -1,7 +1,8 @@
 package com.github.binarywang.wxpay.bean.coupon;
 
-import com.github.binarywang.wxpay.bean.request.WxPayBaseRequest;
+import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
 /**
@@ -12,8 +13,13 @@
  *
  * @author Binary Wang
  */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Builder(builderMethodName = "newBuilder")
+@NoArgsConstructor
+@AllArgsConstructor
 @XStreamAlias("xml")
-public class WxPayCouponStockQueryRequest extends WxPayBaseRequest {
+public class WxPayCouponStockQueryRequest extends BaseWxPayRequest {
   /**
    * 
    * 字段名:代金券批次id
@@ -80,142 +86,9 @@ public class WxPayCouponStockQueryRequest extends WxPayBaseRequest {
   @XStreamAlias("type")
   private String type;
 
-  private WxPayCouponStockQueryRequest(Builder builder) {
-    setAppid(builder.appid);
-    setMchId(builder.mchId);
-    setSubAppId(builder.subAppId);
-    setSubMchId(builder.subMchId);
-    setNonceStr(builder.nonceStr);
-    setSign(builder.sign);
-    setCouponStockId(builder.couponStockId);
-    setOpUserId(builder.opUserId);
-    setDeviceInfo(builder.deviceInfo);
-    setVersion(builder.version);
-    setType(builder.type);
-  }
-
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  public String getCouponStockId() {
-    return this.couponStockId;
-  }
-
-  public void setCouponStockId(String couponStockId) {
-    this.couponStockId = couponStockId;
-  }
-
-  public String getOpUserId() {
-    return this.opUserId;
-  }
-
-  public void setOpUserId(String opUserId) {
-    this.opUserId = opUserId;
-  }
-
-  public String getDeviceInfo() {
-    return this.deviceInfo;
-  }
-
-  public void setDeviceInfo(String deviceInfo) {
-    this.deviceInfo = deviceInfo;
-  }
-
-  public String getVersion() {
-    return this.version;
-  }
-
-  public void setVersion(String version) {
-    this.version = version;
-  }
-
-  public String getType() {
-    return this.type;
-  }
-
-  public void setType(String type) {
-    this.type = type;
-  }
-
   @Override
   protected void checkConstraints() {
     //do nothing
   }
 
-  public static final class Builder {
-    private String appid;
-    private String mchId;
-    private String subAppId;
-    private String subMchId;
-    private String nonceStr;
-    private String sign;
-    private String couponStockId;
-    private String opUserId;
-    private String deviceInfo;
-    private String version;
-    private String type;
-
-    private Builder() {
-    }
-
-    public Builder appid(String appid) {
-      this.appid = appid;
-      return this;
-    }
-
-    public Builder mchId(String mchId) {
-      this.mchId = mchId;
-      return this;
-    }
-
-    public Builder subAppId(String subAppId) {
-      this.subAppId = subAppId;
-      return this;
-    }
-
-    public Builder subMchId(String subMchId) {
-      this.subMchId = subMchId;
-      return this;
-    }
-
-    public Builder nonceStr(String nonceStr) {
-      this.nonceStr = nonceStr;
-      return this;
-    }
-
-    public Builder sign(String sign) {
-      this.sign = sign;
-      return this;
-    }
-
-    public Builder couponStockId(String couponStockId) {
-      this.couponStockId = couponStockId;
-      return this;
-    }
-
-    public Builder opUserId(String opUserId) {
-      this.opUserId = opUserId;
-      return this;
-    }
-
-    public Builder deviceInfo(String deviceInfo) {
-      this.deviceInfo = deviceInfo;
-      return this;
-    }
-
-    public Builder version(String version) {
-      this.version = version;
-      return this;
-    }
-
-    public Builder type(String type) {
-      this.type = type;
-      return this;
-    }
-
-    public WxPayCouponStockQueryRequest build() {
-      return new WxPayCouponStockQueryRequest(this);
-    }
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
index 065c3f606d..c4bbc7053b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
@@ -1,7 +1,11 @@
 package com.github.binarywang.wxpay.bean.coupon;
 
-import com.github.binarywang.wxpay.bean.result.WxPayBaseResult;
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
 
 /**
  * 
@@ -11,8 +15,12 @@
  *
  * @author Binary Wang
  */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@AllArgsConstructor
 @XStreamAlias("xml")
-public class WxPayCouponStockQueryResult extends WxPayBaseResult {
+public class WxPayCouponStockQueryResult extends BaseWxPayResult {
   /**
    * 
    * 字段名:设备号
@@ -182,107 +190,4 @@ public class WxPayCouponStockQueryResult extends WxPayBaseResult {
   @XStreamAlias("coupon_budget")
   private Integer couponBudget;
 
-  public String getDeviceInfo() {
-    return this.deviceInfo;
-  }
-
-  public void setDeviceInfo(String deviceInfo) {
-    this.deviceInfo = deviceInfo;
-  }
-
-  public String getCouponStockId() {
-    return this.couponStockId;
-  }
-
-  public void setCouponStockId(String couponStockId) {
-    this.couponStockId = couponStockId;
-  }
-
-  public String getCouponName() {
-    return this.couponName;
-  }
-
-  public void setCouponName(String couponName) {
-    this.couponName = couponName;
-  }
-
-  public Integer getCouponValue() {
-    return this.couponValue;
-  }
-
-  public void setCouponValue(Integer couponValue) {
-    this.couponValue = couponValue;
-  }
-
-  public Integer getCouponMininumn() {
-    return this.couponMininumn;
-  }
-
-  public void setCouponMininumn(Integer couponMininumn) {
-    this.couponMininumn = couponMininumn;
-  }
-
-  public Integer getCouponStockStatus() {
-    return this.couponStockStatus;
-  }
-
-  public void setCouponStockStatus(Integer couponStockStatus) {
-    this.couponStockStatus = couponStockStatus;
-  }
-
-  public Integer getCouponTotal() {
-    return this.couponTotal;
-  }
-
-  public void setCouponTotal(Integer couponTotal) {
-    this.couponTotal = couponTotal;
-  }
-
-  public Integer getMaxQuota() {
-    return this.maxQuota;
-  }
-
-  public void setMaxQuota(Integer maxQuota) {
-    this.maxQuota = maxQuota;
-  }
-
-  public Integer getIsSendNum() {
-    return this.isSendNum;
-  }
-
-  public void setIsSendNum(Integer isSendNum) {
-    this.isSendNum = isSendNum;
-  }
-
-  public String getBeginTime() {
-    return this.beginTime;
-  }
-
-  public void setBeginTime(String beginTime) {
-    this.beginTime = beginTime;
-  }
-
-  public String getEndTime() {
-    return this.endTime;
-  }
-
-  public void setEndTime(String endTime) {
-    this.endTime = endTime;
-  }
-
-  public String getCreateTime() {
-    return this.createTime;
-  }
-
-  public void setCreateTime(String createTime) {
-    this.createTime = createTime;
-  }
-
-  public Integer getCouponBudget() {
-    return this.couponBudget;
-  }
-
-  public void setCouponBudget(Integer couponBudget) {
-    this.couponBudget = couponBudget;
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryRequest.java
new file mode 100644
index 0000000000..83d7419261
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryRequest.java
@@ -0,0 +1,27 @@
+package com.github.binarywang.wxpay.bean.entpay;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 
+ * 企业付款到银行卡的请求对象
+ * Created by Binary Wang on 2017/12/21.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@XStreamAlias("xml") +public class EntPayBankQueryRequest extends EntPayQueryRequest { + private static final long serialVersionUID = -479088843124447119L; + + @Override + protected boolean ignoreAppid() { + return true; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java new file mode 100644 index 0000000000..6020dbed77 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java @@ -0,0 +1,96 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + *
+ * 企业付款到银行卡查询返回结果.
+ * Created by Binary Wang on 2017/12/21.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@XStreamAlias("xml") +public class EntPayBankQueryResult extends BaseWxPayResult { + private static final long serialVersionUID = -8336631015989500746L; + + /** + * 商户企业付款单号 + */ + @XStreamAlias("partner_trade_no") + private String partnerTradeNo; + + /** + * 微信企业付款单号. + * 即为微信内部业务单号 + */ + @XStreamAlias("payment_no") + private String paymentNo; + + /** + * 银行卡号. + * 收款用户银行卡号(MD5加密) + */ + @XStreamAlias("bank_no_md5") + private String bankNoMd5; + + /** + * 用户真实姓名. + * 收款人真实姓名(MD5加密) + */ + @XStreamAlias("true_name_md5") + private String trueNameMd5; + + /** + * 付款金额. + */ + @XStreamAlias("amount") + private Integer amount; + + /** + * 代付单状态. + *
+   * PROCESSING(处理中,如有明确失败,则返回额外失败原因;否则没有错误原因)
+   * SUCCESS(付款成功)
+   * FAILED(付款失败)
+   * BANK_FAIL(银行退票,订单状态由付款成功流转至退票,退票时付款金额和手续费会自动退还)
+   * 
+ */ + @XStreamAlias("status") + private String status; + + /** + * 手续费金额 + */ + @XStreamAlias("cmms_amt") + private Integer cmmsAmount; + + /** + * 商户下单时间. + * 微信侧订单创建时间 + */ + @XStreamAlias("create_time") + private String createTime; + + /** + * 成功付款时间. + * 微信侧付款成功时间(但无法保证银行不会退票) + */ + @XStreamAlias("pay_succ_time") + private String paySuccessTime; + + /** + * 失败原因. + * 订单失败原因(如:余额不足) + */ + @XStreamAlias("reason") + private String failReason; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java new file mode 100644 index 0000000000..05ccebc23c --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java @@ -0,0 +1,128 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.annotation.Required; + +/** + *
+ *  企业付款到银行卡的请求对象类
+ *  Created by BinaryWang on 2017/12/20.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +@Builder +@XStreamAlias("xml") +public class EntPayBankRequest extends BaseWxPayRequest { + + /** + *
+   * 商户企业付款单号.
+   * 变量名:partner_trade_no
+   * 是否必填:是
+   * 示例值:1212121221227
+   * 类型:string(32)
+   * 描述:商户订单号,需保持唯一(只允许数字[0~9]或字母[A~Z]和[a~z],最短8位,最长32位)
+   * 
+ */ + @Required + @XStreamAlias("partner_trade_no") + private String partnerTradeNo; + + /** + *
+   * 收款方银行卡号.
+   * 传值时请传原始值
+   * 变量名:enc_bank_no
+   * 是否必填:是
+   * 示例值:8609cb22e1774a50a930e414cc71eca06121bcd266335cda230d24a7886a8d9f
+   * 类型:string(64)
+   * 描述:收款方银行卡号(采用标准RSA算法,公钥由微信侧提供),详见获取RSA加密公钥API
+   * 
+ */ + @Required + @XStreamAlias("enc_bank_no") + private String encBankNo; + + /** + *
+   * 收款方用户名.
+   * 传值时请传原始值
+   * 变量名:enc_true_name
+   * 是否必填:是
+   * 示例值:ca775af5f841bdf424b2e6eb86a6e21e
+   * 类型:string(64)
+   * 描述:收款方用户名(采用标准RSA算法,公钥由微信侧提供)详见获取RSA加密公钥API
+   * 
+ */ + @Required + @XStreamAlias("enc_true_name") + private String encTrueName; + + /** + *
+   * 收款方开户行.
+   * 变量名:bank_code
+   * 是否必填:是
+   * 示例值:1001
+   * 类型:string(64)
+   * 描述:银行卡所在开户行编号,详见银行编号列表
+   * 
+ */ + @Required + @XStreamAlias("bank_code") + private String bankCode; + + /** + *
+   * 付款金额.
+   * 变量名:amount
+   * 是否必填:是
+   * 示例值:100000
+   * 类型:int
+   * 描述:付款金额:RMB分(支付总额,不含手续费) 注:大于0的整数
+   * 
+ */ + @Required + @XStreamAlias("amount") + private Integer amount; + + /** + *
+   * 付款说明.
+   * 变量名:desc
+   * 是否必填:否
+   * 示例值:理财
+   * 类型:string
+   * 描述:企业付款到银行卡付款说明,即订单备注(UTF8编码,允许100个字符以内)
+   * 
+ */ + @Required + @XStreamAlias("desc") + private String description; + + @Override + protected void checkConstraints() throws WxPayException { + } + + @Override + protected String[] getIgnoredParamsForSign() { + return new String[]{"sign_type"}; + } + + @Override + protected boolean ignoreAppid() { + return true; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java new file mode 100644 index 0000000000..078e27e849 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java @@ -0,0 +1,51 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + *
+ * 企业付款到银行卡的响应结果.
+ * Created by Binary Wang on 2017/12/21.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@XStreamAlias("xml") +public class EntPayBankResult extends BaseWxPayResult { + private static final long serialVersionUID = 3449707749935227689L; + + /** + * 代付金额. + */ + @XStreamAlias("amount") + private Integer amount; + + /** + * 商户企业付款单号. + */ + @XStreamAlias("partner_trade_no") + private String partnerTradeNo; + + //############以下字段在return_code 和result_code都为SUCCESS的时候有返回############## + /** + * 微信企业付款单号. + * 代付成功后,返回的内部业务单号 + */ + @XStreamAlias("payment_no") + private String paymentNo; + + /** + * 手续费金额. + * RMB:分 + */ + @XStreamAlias("cmms_amt") + private Integer cmmsAmount; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java new file mode 100644 index 0000000000..987677a354 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java @@ -0,0 +1,60 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.annotation.Required; + +/** + *
+ * 企业付款请求对象.
+ * Created by Binary Wang on 2016/10/19.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +@XStreamAlias("xml") +public class EntPayQueryRequest extends BaseWxPayRequest { + private static final long serialVersionUID = 1972288742207813985L; + + /** + *
+   * 字段名:商户订单号.
+   * 变量名:partner_trade_no
+   * 是否必填:是
+   * 示例值:10000098201411111234567890
+   * 类型:String
+   * 描述商户订单号
+   * 
+ */ + @Required + @XStreamAlias("partner_trade_no") + private String partnerTradeNo; + + @Override + protected void checkConstraints() { + //do nothing + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + @Override + protected String[] getIgnoredParamsForSign() { + return new String[]{"sign_type"}; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java new file mode 100644 index 0000000000..e3cdba3b36 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java @@ -0,0 +1,78 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + *
+ * 企业付款查询返回结果.
+ * Created by Binary Wang on 2016/10/19.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@XStreamAlias("xml") +public class EntPayQueryResult extends BaseWxPayResult { + private static final long serialVersionUID = 3948485732447456947L; + + /** + * 商户订单号 + */ + @XStreamAlias("partner_trade_no") + private String partnerTradeNo; + + /** + * 付款单号 + */ + @XStreamAlias("detail_id") + private String detailId; + + /** + * 转账状态 + */ + @XStreamAlias("status") + private String status; + + /** + * 失败原因 + */ + @XStreamAlias("reason") + private String reason; + + /** + * 收款用户openid + */ + @XStreamAlias("openid") + private String openid; + + /** + * 收款用户姓名 + */ + @XStreamAlias("transfer_name") + private String transferName; + + /** + * 付款金额 + */ + @XStreamAlias("payment_amount") + private Integer paymentAmount; + + /** + * 转账时间 + */ + @XStreamAlias("transfer_time") + private String transferTime; + + /** + * 付款描述 + */ + @XStreamAlias("desc") + private String desc; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java new file mode 100644 index 0000000000..285b66ba49 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java @@ -0,0 +1,203 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.annotation.Required; + +/** + *
+ * 企业付款请求对象.
+ * Created by Binary Wang on 2016/10/02.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +@XStreamAlias("xml") +public class EntPayRequest extends BaseWxPayRequest { + /** + *
+   * 字段名:公众账号appid.
+   * 变量名:mch_appid
+   * 是否必填:是
+   * 示例值:wx8888888888888888
+   * 类型:String
+   * 描述:微信分配的公众账号ID(企业号corpid即为此appId)
+   * 
+ */ + @XStreamAlias("mch_appid") + private String mchAppid; + + /** + *
+   * 字段名:商户号.
+   * 变量名:mchid
+   * 是否必填:是
+   * 示例值:1900000109
+   * 类型:String(32)
+   * 描述:微信支付分配的商户号
+   * 
+ */ + @XStreamAlias("mchid") + private String mchId; + + /** + *
+   * 字段名:设备号.
+   * 变量名:device_info
+   * 是否必填:否
+   * 示例值:13467007045764
+   * 类型:String(32)
+   * 描述:微信支付分配的终端设备号
+   * 
+ */ + @XStreamAlias("device_info") + private String deviceInfo; + + /** + *
+   * 字段名:商户订单号.
+   * 变量名:partner_trade_no
+   * 是否必填:是
+   * 示例值:10000098201411111234567890
+   * 类型:String
+   * 描述:商户订单号
+   * 
+ */ + @Required + @XStreamAlias("partner_trade_no") + private String partnerTradeNo; + + /** + *
+   * 字段名:需保持唯一性 用户openid.
+   * 变量名:openid
+   * 是否必填:是
+   * 示例值:oxTWIuGaIt6gTKsQRLau2M0yL16E
+   * 类型:String
+   * 描述:商户appid下,某用户的openid
+   * 
+ */ + @Required + @XStreamAlias("openid") + private String openid; + + /** + *
+   * 字段名:校验用户姓名选项.
+   * 变量名:check_name
+   * 是否必填:是
+   * 示例值:OPTION_CHECK
+   * 类型:String
+   * 描述:NO_CHECK:不校验真实姓名 
+   * FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) 
+   * OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
+   * 
+ */ + @Required + @XStreamAlias("check_name") + private String checkName; + + /** + *
+   * 字段名:收款用户姓名.
+   * 变量名:re_user_name
+   * 是否必填:可选
+   * 示例值:马花花
+   * 类型:String
+   * 描述:收款用户真实姓名。
+   * 如果check_name设置为FORCE_CHECK或OPTION_CHECK,  则必填用户真实姓名
+   * 
+ */ + @XStreamAlias("re_user_name") + private String reUserName; + + /** + *
+   * 字段名:金额.
+   * 变量名:amount
+   * 是否必填:是
+   * 示例值:10099
+   * 类型:int
+   * 描述:企业付款金额, 单位为分
+   * 
+ */ + @Required + @XStreamAlias("amount") + private Integer amount; + + /** + *
+   * 字段名:企业付款描述信息.
+   * 变量名:desc
+   * 是否必填:是
+   * 示例值:理赔
+   * 类型:String
+   * 描述:企业付款操作说明信息。必填。
+   * 
+ */ + @Required + @XStreamAlias("desc") + private String description; + + /** + *
+   * 字段名:Ip地址.
+   * 变量名:spbill_create_ip
+   * 是否必填:是
+   * 示例值:192.168.0.1
+   * 类型:String(32)
+   * 描述:调用接口的机器Ip地址
+   * 
+ */ + @Required + @XStreamAlias("spbill_create_ip") + private String spbillCreateIp; + + @Override + protected void checkConstraints() { + + } + + @Override + public String getAppid() { + return this.mchAppid; + } + + @Override + public void setAppid(String appid) { + this.mchAppid = appid; + } + + @Override + public String getMchId() { + return this.mchId; + } + + @Override + public void setMchId(String mchId) { + this.mchId = mchId; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + @Override + protected String[] getIgnoredParamsForSign() { + return new String[]{"sign_type"}; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java new file mode 100644 index 0000000000..223c196395 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java @@ -0,0 +1,59 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +/** + *
+ * 企业付款返回结果
+ * Created by Binary Wang on 2016/10/02.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@XStreamAlias("xml") +public class EntPayResult extends BaseWxPayResult { + /** + * 商户号. + */ + @XStreamAlias("mchid") + private String mchId; + + /** + * 商户appid. + */ + @XStreamAlias("mch_appid") + private String mchAppid; + + /** + * 设备号. + */ + @XStreamAlias("device_info") + private String deviceInfo; + + //############以下字段在return_code 和result_code都为SUCCESS的时候有返回############## + /** + * 商户订单号. + */ + @XStreamAlias("partner_trade_no") + private String partnerTradeNo; + + /** + * 微信订单号. + */ + @XStreamAlias("payment_no") + private String paymentNo; + + /** + * 微信支付成功时间. + */ + @XStreamAlias("payment_time") + private String paymentTime; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java new file mode 100644 index 0000000000..f7f62afb7e --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java @@ -0,0 +1,31 @@ +package com.github.binarywang.wxpay.bean.entpay; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *
+ *  企业付款获取RSA加密公钥接口返回结果类
+ *  Created by BinaryWang on 2017/12/20.
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@XStreamAlias("xml") +public class GetPublicKeyResult extends BaseWxPayResult { + /** + * 商户号. + */ + @XStreamAlias("mch_id") + private String mchId; + + /** + * 密钥 + */ + @XStreamAlias("pub_key") + private String pubKey; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyResponse.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyResponse.java index e7a7ea9099..c71ed7de67 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyResponse.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayNotifyResponse.java @@ -4,12 +4,20 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; import com.thoughtworks.xstream.annotations.XStreamOmitField; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; import me.chanjar.weixin.common.util.xml.XStreamInitializer; /** * 微信支付订单和退款的异步通知共用的响应类 */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") public class WxPayNotifyResponse { @XStreamOmitField @@ -24,16 +32,12 @@ public class WxPayNotifyResponse { @XStreamAlias("return_msg") private String returnMsg; - public WxPayNotifyResponse() { - super(); - } - - public WxPayNotifyResponse(String returnCode, String returnMsg) { - super(); - this.returnCode = returnCode; - this.returnMsg = returnMsg; - } - + /** + * Fail string. + * + * @param msg the msg + * @return the string + */ public static String fail(String msg) { WxPayNotifyResponse response = new WxPayNotifyResponse(FAIL, msg); XStream xstream = XStreamInitializer.getInstance(); @@ -41,6 +45,12 @@ public static String fail(String msg) { return xstream.toXML(response); } + /** + * Success string. + * + * @param msg the msg + * @return the string + */ public static String success(String msg) { WxPayNotifyResponse response = new WxPayNotifyResponse(SUCCESS, msg); XStream xstream = XStreamInitializer.getInstance(); @@ -48,19 +58,4 @@ public static String success(String msg) { return xstream.toXML(response); } - public String getReturnCode() { - return returnCode; - } - - public void setReturnCode(String returnCode) { - this.returnCode = returnCode; - } - - public String getReturnMsg() { - return returnMsg; - } - - public void setReturnMsg(String returnMsg) { - this.returnMsg = returnMsg; - } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyCoupon.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyCoupon.java index cd948dfbac..cb1d6c242c 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyCoupon.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyCoupon.java @@ -1,15 +1,22 @@ package com.github.binarywang.wxpay.bean.notify; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; - import java.io.Serializable; import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import lombok.NoArgsConstructor; + /** - * 支付异步通知代金券详细 + * 支付异步通知代金券详细. + * + * @author aimilin */ +@Data +@NoArgsConstructor public class WxPayOrderNotifyCoupon implements Serializable { private static final long serialVersionUID = -4165343733538156097L; @@ -17,30 +24,12 @@ public class WxPayOrderNotifyCoupon implements Serializable { private String couponType; private Integer couponFee; - public String getCouponId() { - return couponId; - } - - public void setCouponId(String couponId) { - this.couponId = couponId; - } - - public String getCouponType() { - return couponType; - } - - public void setCouponType(String couponType) { - this.couponType = couponType; - } - - public Integer getCouponFee() { - return couponFee; - } - - public void setCouponFee(Integer couponFee) { - this.couponFee = couponFee; - } - + /** + * To map map. + * + * @param index the index + * @return the map + */ public Map toMap(int index) { Map map = new HashMap<>(); map.put("coupon_id_" + index, this.getCouponId()); @@ -51,6 +40,6 @@ public Map toMap(int index) { @Override public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java index 54657ac6ae..9fc9cebe07 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java @@ -1,30 +1,50 @@ package com.github.binarywang.wxpay.bean.notify; -import com.github.binarywang.wxpay.bean.result.WxPayBaseResult; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; import com.github.binarywang.wxpay.converter.WxPayOrderNotifyResultConverter; +import com.github.binarywang.wxpay.util.SignUtils; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; -import me.chanjar.weixin.common.util.BeanUtils; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import me.chanjar.weixin.common.util.xml.XStreamInitializer; -import java.io.Serializable; -import java.util.List; -import java.util.Map; - /** * 支付结果通用通知 ,文档见:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 * * @author aimilin6688 * @since 2.5.0 */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializable { +public class WxPayOrderNotifyResult extends BaseWxPayResult { private static final long serialVersionUID = 5389718115223345496L; /** *
-   * 字段名:设备号
+   * 字段名:营销详情.
+   * 变量名:promotion_detail
+   * 是否必填:否,单品优惠才有
+   * 类型:String(6000)
+   * 示例值:[{"promotion_detail":[{"promotion_id":"109519","name":"单品惠-6","scope":"SINGLE","type":"DISCOUNT","amount":5,"activity_id":"931386","wxpay_contribute":0,"merchant_contribute":0,"other_contribute":5,"goods_detail":[{"goods_id":"a_goods1","goods_remark":"商品备注","quantity":7,"price":1,"discount_amount":4},{"goods_id":"a_goods2","goods_remark":"商品备注","quantity":1,"price":2,"discount_amount":1}]}]}
+   * 描述:单品优惠专用参数,详见https://pay.weixin.qq.com/wiki/doc/api/danpin.php?chapter=9_203&index=4
+   * 
+ */ + @XStreamAlias("promotion_detail") + private String promotionDetail; + + /** + *
+   * 字段名:设备号.
    * 变量名:device_info
    * 是否必填:否
    * 类型:String(32)
@@ -37,7 +57,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:用户标识
+   * 字段名:用户标识.
    * 变量名:openid
    * 是否必填:是
    * 类型:String(128)
@@ -50,7 +70,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:是否关注公众账号
+   * 字段名:是否关注公众账号.
    * 变量名:is_subscribe
    * 是否必填:否
    * 类型:String(1)
@@ -63,7 +83,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:用户子标识
+   * 字段名:用户子标识.
    * 变量名:sub_openid
    * 是否必填:是
    * 类型:String(128)
@@ -76,7 +96,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:是否关注子公众账号
+   * 字段名:是否关注子公众账号.
    * 变量名:sub_is_subscribe
    * 是否必填:否
    * 类型:String(1)
@@ -90,7 +110,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:交易类型
+   * 字段名:交易类型.
    * 变量名:trade_type
    * 是否必填:是
    * 类型:String(16)
@@ -101,10 +121,9 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   @XStreamAlias("trade_type")
   private String tradeType;
 
-
   /**
    * 
-   * 字段名:付款银行
+   * 字段名:付款银行.
    * 变量名:bank_type
    * 是否必填:是
    * 类型:String(16)
@@ -117,7 +136,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:订单金额
+   * 字段名:订单金额.
    * 变量名:total_fee
    * 是否必填:是
    * 类型:Int
@@ -129,7 +148,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   private Integer totalFee;
   /**
    * 
-   * 字段名:应结订单金额
+   * 字段名:应结订单金额.
    * 变量名:settlement_total_fee
    * 是否必填:否
    * 类型:Int
@@ -141,7 +160,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   private Integer settlementTotalFee;
   /**
    * 
-   * 字段名:货币种类
+   * 字段名:货币种类.
    * 变量名:fee_type
    * 是否必填:否
    * 类型:String(8)
@@ -153,7 +172,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   private String feeType;
   /**
    * 
-   * 字段名:现金支付金额
+   * 字段名:现金支付金额.
    * 变量名:cash_fee
    * 是否必填:是
    * 类型:Int
@@ -165,7 +184,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   private Integer cashFee;
   /**
    * 
-   * 字段名:现金支付货币类型
+   * 字段名:现金支付货币类型.
    * 变量名:cash_fee_type
    * 是否必填:否
    * 类型:String(16)
@@ -177,7 +196,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   private String cashFeeType;
   /**
    * 
-   * 字段名:总代金券金额
+   * 字段名:总代金券金额.
    * 变量名:coupon_fee
    * 是否必填:否
    * 类型:Int
@@ -190,7 +209,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:代金券使用数量
+   * 字段名:代金券使用数量.
    * 变量名:coupon_count
    * 是否必填:否
    * 类型:Int
@@ -205,7 +224,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:微信支付订单号
+   * 字段名:微信支付订单号.
    * 变量名:transaction_id
    * 是否必填:是
    * 类型:String(32)
@@ -218,7 +237,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
 
   /**
    * 
-   * 字段名:商户订单号
+   * 字段名:商户订单号.
    * 变量名:out_trade_no
    * 是否必填:是
    * 类型:String(32)
@@ -230,7 +249,7 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   private String outTradeNo;
   /**
    * 
-   * 字段名:商家数据包
+   * 字段名:商家数据包.
    * 变量名:attach
    * 是否必填:否
    * 类型:String(128)
@@ -240,9 +259,10 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
    */
   @XStreamAlias("attach")
   private String attach;
+
   /**
    * 
-   * 字段名:支付完成时间
+   * 字段名:支付完成时间.
    * 变量名:time_end
    * 是否必填:是
    * 类型:String(14)
@@ -253,6 +273,24 @@ public class WxPayOrderNotifyResult extends WxPayBaseResult implements Serializa
   @XStreamAlias("time_end")
   private String timeEnd;
 
+  /**
+   * 
+   * 字段名:接口版本号.
+   * 变量名:version
+   * 类型:String(32)
+   * 示例值:1.0
+   * 更多信息,详见文档:https://pay.weixin.qq.com/wiki/doc/api/danpin.php?chapter=9_101&index=1
+   * 
+ */ + @XStreamAlias("version") + private String version; + + /** + * From xml wx pay order notify result. + * + * @param xmlString the xml string + * @return the wx pay order notify result + */ public static WxPayOrderNotifyResult fromXML(String xmlString) { XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(WxPayOrderNotifyResult.class); @@ -262,161 +300,9 @@ public static WxPayOrderNotifyResult fromXML(String xmlString) { return result; } - public Integer getCouponCount() { - return couponCount; - } - - public void setCouponCount(Integer couponCount) { - this.couponCount = couponCount; - } - - public List getCouponList() { - return couponList; - } - - public void setCouponList(List couponList) { - this.couponList = couponList; - } - - public String getDeviceInfo() { - return deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public String getOpenid() { - return openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getIsSubscribe() { - return isSubscribe; - } - - public void setIsSubscribe(String isSubscribe) { - this.isSubscribe = isSubscribe; - } - - public String getTradeType() { - return tradeType; - } - - public void setTradeType(String tradeType) { - this.tradeType = tradeType; - } - - public String getBankType() { - return bankType; - } - - public void setBankType(String bankType) { - this.bankType = bankType; - } - - public Integer getTotalFee() { - return totalFee; - } - - public void setTotalFee(Integer totalFee) { - this.totalFee = totalFee; - } - - public Integer getSettlementTotalFee() { - return settlementTotalFee; - } - - public void setSettlementTotalFee(Integer settlementTotalFee) { - this.settlementTotalFee = settlementTotalFee; - } - - public String getFeeType() { - return feeType; - } - - public void setFeeType(String feeType) { - this.feeType = feeType; - } - - public Integer getCashFee() { - return cashFee; - } - - public void setCashFee(Integer cashFee) { - this.cashFee = cashFee; - } - - public String getCashFeeType() { - return cashFeeType; - } - - public void setCashFeeType(String cashFeeType) { - this.cashFeeType = cashFeeType; - } - - public Integer getCouponFee() { - return couponFee; - } - - public void setCouponFee(Integer couponFee) { - this.couponFee = couponFee; - } - - public String getTransactionId() { - return transactionId; - } - - public void setTransactionId(String transactionId) { - this.transactionId = transactionId; - } - - public String getOutTradeNo() { - return outTradeNo; - } - - public void setOutTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - } - - public String getAttach() { - return attach; - } - - public void setAttach(String attach) { - this.attach = attach; - } - - public String getTimeEnd() { - return timeEnd; - } - - public void setTimeEnd(String timeEnd) { - this.timeEnd = timeEnd; - } - - public String getSubOpenid() { - return this.subOpenid; - } - - public void setSubOpenid(String subOpenid) { - this.subOpenid = subOpenid; - } - - public String getSubIsSubscribe() { - return this.subIsSubscribe; - } - - public void setSubIsSubscribe(String subIsSubscribe) { - this.subIsSubscribe = subIsSubscribe; - } - @Override public Map toMap() { - Map resultMap = BeanUtils.xmlBean2Map(this); + Map resultMap = SignUtils.xmlBean2Map(this); if (this.getCouponCount() != null && this.getCouponCount() > 0) { for (int i = 0; i < this.getCouponCount(); i++) { WxPayOrderNotifyCoupon coupon = couponList.get(i); @@ -428,6 +314,6 @@ public Map toMap() { @Override public String toString() { - return ToStringUtils.toSimpleString(this); + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java index 392c10144c..f738984a81 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java @@ -1,18 +1,23 @@ package com.github.binarywang.wxpay.bean.notify; -import com.github.binarywang.wxpay.bean.result.WxPayBaseResult; +import java.io.Serializable; +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; import com.github.binarywang.wxpay.exception.WxPayException; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; -import me.chanjar.weixin.common.util.ToStringUtils; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import me.chanjar.weixin.common.util.xml.XStreamInitializer; -import org.apache.commons.codec.binary.Base64; - -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; -import java.io.Serializable; -import java.math.BigInteger; -import java.security.MessageDigest; /** *
@@ -22,8 +27,12 @@
  *
  * @author Binary Wang
  */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@AllArgsConstructor
 @XStreamAlias("xml")
-public class WxPayRefundNotifyResult extends WxPayBaseResult implements Serializable {
+public class WxPayRefundNotifyResult extends BaseWxPayResult implements Serializable {
   private static final long serialVersionUID = 4651725860079259186L;
 
   /**
@@ -31,17 +40,17 @@ public class WxPayRefundNotifyResult extends WxPayBaseResult implements Serializ
    *
    * @param xmlString xml字符串
    * @param mchKey    商户密钥
+   * @return the wx pay refund notify result
+   * @throws WxPayException the wx pay exception
    */
   public static WxPayRefundNotifyResult fromXML(String xmlString, String mchKey) throws WxPayException {
-    WxPayRefundNotifyResult result = WxPayBaseResult.fromXML(xmlString, WxPayRefundNotifyResult.class);
+    WxPayRefundNotifyResult result = BaseWxPayResult.fromXML(xmlString, WxPayRefundNotifyResult.class);
     String reqInfoString = result.getReqInfoString();
     try {
-      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
-
-      final MessageDigest md5 = MessageDigest.getInstance("MD5");
-      md5.update(mchKey.getBytes());
-      final String keyMd5String = new BigInteger(1, md5.digest()).toString(16).toLowerCase();
+      final String keyMd5String = DigestUtils.md5Hex(mchKey).toLowerCase();
       SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(), "AES");
+
+      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
       cipher.init(Cipher.DECRYPT_MODE, key);
       result.setReqInfo(ReqInfo.fromXML(new String(cipher.doFinal(Base64.decodeBase64(reqInfoString)))));
     } catch (Exception e) {
@@ -66,18 +75,20 @@ public static WxPayRefundNotifyResult fromXML(String xmlString, String mchKey) t
   private ReqInfo reqInfo;
 
   /**
-   * 加密信息字段解密后的内容
+   * 加密信息字段解密后的内容.
    */
+  @Data
+  @NoArgsConstructor
   @XStreamAlias("root")
   public static class ReqInfo {
     @Override
     public String toString() {
-      return ToStringUtils.toSimpleString(this);
+      return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
     }
 
     /**
      * 
-     * 字段名:微信订单号
+     * 字段名:微信订单号.
      * 变量名:transaction_id
      * 是否必填:是
      * 类型:String(32)
@@ -90,7 +101,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:商户订单号
+     * 字段名:商户订单号.
      * 变量名:out_trade_no
      * 是否必填:是
      * 类型:String(32)
@@ -103,7 +114,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:微信退款单号
+     * 字段名:微信退款单号.
      * 变量名:refund_id
      * 是否必填:是
      * 类型:String(28)
@@ -116,7 +127,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:商户退款单号
+     * 字段名:商户退款单号.
      * 变量名:out_refund_no
      * 是否必填:是
      * 类型:String(64)
@@ -129,7 +140,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:订单金额
+     * 字段名:订单金额.
      * 变量名:total_fee
      * 是否必填:是
      * 类型:Int
@@ -142,7 +153,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:结订单金额
+     * 字段名:结订单金额.
      * 变量名:settlement_total_fee
      * 是否必填:否
      * 类型:Int
@@ -155,7 +166,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:申请退款金额
+     * 字段名:申请退款金额.
      * 变量名:refund_fee
      * 是否必填:是
      * 类型:Int
@@ -168,7 +179,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:退款金额
+     * 字段名:退款金额.
      * 变量名:settlement_refund_fee
      * 是否必填:是
      * 类型:Int
@@ -181,7 +192,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:退款状态
+     * 字段名:退款状态.
      * 变量名:refund_status
      * 是否必填:是
      * 类型:String(16)
@@ -194,7 +205,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:退款成功时间
+     * 字段名:退款成功时间.
      * 变量名:success_time
      * 是否必填:否
      * 类型: String(20)
@@ -206,7 +217,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:退款入账账户
+     * 字段名:退款入账账户.
      * 变量名:refund_recv_accout
      * 是否必填:是
      * 类型:String(64)
@@ -219,7 +230,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:退款资金来源
+     * 字段名:退款资金来源.
      * 变量名:refund_account
      * 是否必填:是
      * 类型:String(30)
@@ -232,7 +243,7 @@ public String toString() {
 
     /**
      * 
-     * 字段名:退款发起来源
+     * 字段名:退款发起来源.
      * 变量名:refund_request_source
      * 是否必填:是
      * 类型:String(30)
@@ -243,110 +254,12 @@ public String toString() {
     @XStreamAlias("refund_request_source")
     private String refundRequestSource;
 
-    public String getTransactionId() {
-      return transactionId;
-    }
-
-    public void setTransactionId(String transactionId) {
-      this.transactionId = transactionId;
-    }
-
-    public String getOutTradeNo() {
-      return outTradeNo;
-    }
-
-    public void setOutTradeNo(String outTradeNo) {
-      this.outTradeNo = outTradeNo;
-    }
-
-    public String getRefundId() {
-      return refundId;
-    }
-
-    public void setRefundId(String refundId) {
-      this.refundId = refundId;
-    }
-
-    public String getOutRefundNo() {
-      return outRefundNo;
-    }
-
-    public void setOutRefundNo(String outRefundNo) {
-      this.outRefundNo = outRefundNo;
-    }
-
-    public Integer getTotalFee() {
-      return totalFee;
-    }
-
-    public void setTotalFee(Integer totalFee) {
-      this.totalFee = totalFee;
-    }
-
-    public Integer getSettlementTotalFee() {
-      return settlementTotalFee;
-    }
-
-    public void setSettlementTotalFee(Integer settlementTotalFee) {
-      this.settlementTotalFee = settlementTotalFee;
-    }
-
-    public Integer getRefundFee() {
-      return refundFee;
-    }
-
-    public void setRefundFee(Integer refundFee) {
-      this.refundFee = refundFee;
-    }
-
-    public Integer getSettlementRefundFee() {
-      return settlementRefundFee;
-    }
-
-    public void setSettlementRefundFee(Integer settlementRefundFee) {
-      this.settlementRefundFee = settlementRefundFee;
-    }
-
-    public String getRefundStatus() {
-      return refundStatus;
-    }
-
-    public void setRefundStatus(String refundStatus) {
-      this.refundStatus = refundStatus;
-    }
-
-    public String getSuccessTime() {
-      return successTime;
-    }
-
-    public void setSuccessTime(String successTime) {
-      this.successTime = successTime;
-    }
-
-    public String getRefundRecvAccout() {
-      return refundRecvAccout;
-    }
-
-    public void setRefundRecvAccout(String refundRecvAccout) {
-      this.refundRecvAccout = refundRecvAccout;
-    }
-
-    public String getRefundAccount() {
-      return refundAccount;
-    }
-
-    public void setRefundAccount(String refundAccount) {
-      this.refundAccount = refundAccount;
-    }
-
-    public String getRefundRequestSource() {
-      return refundRequestSource;
-    }
-
-    public void setRefundRequestSource(String refundRequestSource) {
-      this.refundRequestSource = refundRequestSource;
-    }
-
+    /**
+     * From xml req info.
+     *
+     * @param xmlString the xml string
+     * @return the req info
+     */
     public static ReqInfo fromXML(String xmlString) {
       XStream xstream = XStreamInitializer.getInstance();
       xstream.processAnnotations(ReqInfo.class);
@@ -354,19 +267,4 @@ public static ReqInfo fromXML(String xmlString) {
     }
   }
 
-  public String getReqInfoString() {
-    return reqInfoString;
-  }
-
-  public void setReqInfoString(String reqInfoString) {
-    this.reqInfoString = reqInfoString;
-  }
-
-  public ReqInfo getReqInfo() {
-    return reqInfo;
-  }
-
-  public void setReqInfo(ReqInfo reqInfo) {
-    this.reqInfo = reqInfo;
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
new file mode 100644
index 0000000000..a87adabedd
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
@@ -0,0 +1,48 @@
+package com.github.binarywang.wxpay.bean.notify;
+
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 
+ * 扫码支付通知回调类.
+ * 具体定义,请查看文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4
+ * 
+ * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@XStreamAlias("xml") +public class WxScanPayNotifyResult extends BaseWxPayResult { + private static final long serialVersionUID = 3381324564266118986L; + + /** + * 用户标识. + */ + @XStreamAlias("openid") + private String openid; + + /** + *
+   * 是否关注公众账号.
+   * 仅在公众账号类型支付有效,取值范围:Y或N;Y-关注;N-未关注
+   * 
+ */ + @XStreamAlias("is_subscribe") + private String isSubscribe; + + /** + *
+   * 商品ID.
+   * 商户定义的商品id 或者订单号
+   * 
+ */ + @XStreamAlias("product_id") + private String productId; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayAppOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayAppOrderResult.java index 6688d602c9..9e405aa0f9 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayAppOrderResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayAppOrderResult.java @@ -1,5 +1,8 @@ package com.github.binarywang.wxpay.bean.order; +import lombok.Builder; +import lombok.Data; + /** *
  * APP支付调用统一下单接口后的组装所需参数的实现类
@@ -9,6 +12,8 @@
  *
  * @author Binary Wang
  */
+@Data
+@Builder
 public class WxPayAppOrderResult {
   private String sign;
   private String prepayId;
@@ -17,129 +22,4 @@ public class WxPayAppOrderResult {
   private String packageValue;
   private String timeStamp;
   private String nonceStr;
-
-  public WxPayAppOrderResult() {
-  }
-
-  private WxPayAppOrderResult(Builder builder) {
-    setSign(builder.sign);
-    setPrepayId(builder.prepayId);
-    setPartnerId(builder.partnerId);
-    setAppId(builder.appId);
-    setPackageValue(builder.packageValue);
-    setTimeStamp(builder.timeStamp);
-    setNonceStr(builder.nonceStr);
-  }
-
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  public String getSign() {
-    return this.sign;
-  }
-
-  public void setSign(String sign) {
-    this.sign = sign;
-  }
-
-  public String getPrepayId() {
-    return this.prepayId;
-  }
-
-  public void setPrepayId(String prepayId) {
-    this.prepayId = prepayId;
-  }
-
-  public String getPartnerId() {
-    return this.partnerId;
-  }
-
-  public void setPartnerId(String partnerId) {
-    this.partnerId = partnerId;
-  }
-
-  public String getAppId() {
-    return this.appId;
-  }
-
-  public void setAppId(String appId) {
-    this.appId = appId;
-  }
-
-  public String getPackageValue() {
-    return this.packageValue;
-  }
-
-  public void setPackageValue(String packageValue) {
-    this.packageValue = packageValue;
-  }
-
-  public String getTimeStamp() {
-    return this.timeStamp;
-  }
-
-  public void setTimeStamp(String timeStamp) {
-    this.timeStamp = timeStamp;
-  }
-
-  public String getNonceStr() {
-    return this.nonceStr;
-  }
-
-  public void setNonceStr(String nonceStr) {
-    this.nonceStr = nonceStr;
-  }
-
-  public static final class Builder {
-    private String sign;
-    private String prepayId;
-    private String partnerId;
-    private String appId;
-    private String packageValue;
-    private String timeStamp;
-    private String nonceStr;
-
-    private Builder() {
-    }
-
-    public Builder sign(String sign) {
-      this.sign = sign;
-      return this;
-    }
-
-    public Builder prepayId(String prepayId) {
-      this.prepayId = prepayId;
-      return this;
-    }
-
-    public Builder partnerId(String partnerId) {
-      this.partnerId = partnerId;
-      return this;
-    }
-
-    public Builder appId(String appId) {
-      this.appId = appId;
-      return this;
-    }
-
-    public Builder packageValue(String packageValue) {
-      this.packageValue = packageValue;
-      return this;
-    }
-
-    public Builder timeStamp(String timeStamp) {
-      this.timeStamp = timeStamp;
-      return this;
-    }
-
-    public Builder nonceStr(String nonceStr) {
-      this.nonceStr = nonceStr;
-      return this;
-    }
-
-    public WxPayAppOrderResult build() {
-      return new WxPayAppOrderResult(this);
-    }
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayMpOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayMpOrderResult.java
index d1ebdee051..12f8e43bc2 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayMpOrderResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayMpOrderResult.java
@@ -1,5 +1,9 @@
 package com.github.binarywang.wxpay.bean.order;
 
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Builder;
+import lombok.Data;
+
 /**
  * 
  * 微信公众号支付进行统一下单后组装所需参数的类
@@ -9,125 +13,17 @@
  *
  * @author Binary Wang
  */
+@Data
+@Builder
 public class WxPayMpOrderResult {
   private String appId;
   private String timeStamp;
   private String nonceStr;
   /**
-   * 由于package为java保留关键字,因此改为packageValue
+   * 由于package为java保留关键字,因此改为packageValue.
    */
+  @XStreamAlias("package")
   private String packageValue;
   private String signType;
   private String paySign;
-
-  private WxPayMpOrderResult(Builder builder) {
-    setAppId(builder.appId);
-    setTimeStamp(builder.timeStamp);
-    setNonceStr(builder.nonceStr);
-    setPackageValue(builder.packageValue);
-    setSignType(builder.signType);
-    setPaySign(builder.paySign);
-  }
-
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  public String getAppId() {
-    return this.appId;
-  }
-
-  public void setAppId(String appId) {
-    this.appId = appId;
-  }
-
-  public String getTimeStamp() {
-    return this.timeStamp;
-  }
-
-  public void setTimeStamp(String timeStamp) {
-    this.timeStamp = timeStamp;
-  }
-
-  public String getNonceStr() {
-    return this.nonceStr;
-  }
-
-  public void setNonceStr(String nonceStr) {
-    this.nonceStr = nonceStr;
-  }
-
-  public String getPackageValue() {
-    return this.packageValue;
-  }
-
-  public void setPackageValue(String packageValue) {
-    this.packageValue = packageValue;
-  }
-
-  public String getSignType() {
-    return this.signType;
-  }
-
-  public void setSignType(String signType) {
-    this.signType = signType;
-  }
-
-  public String getPaySign() {
-    return this.paySign;
-  }
-
-  public void setPaySign(String paySign) {
-    this.paySign = paySign;
-  }
-
-  public WxPayMpOrderResult() {
-  }
-
-
-  public static final class Builder {
-    private String appId;
-    private String timeStamp;
-    private String nonceStr;
-    private String packageValue;
-    private String signType;
-    private String paySign;
-
-    private Builder() {
-    }
-
-    public Builder appId(String appId) {
-      this.appId = appId;
-      return this;
-    }
-
-    public Builder timeStamp(String timeStamp) {
-      this.timeStamp = timeStamp;
-      return this;
-    }
-
-    public Builder nonceStr(String nonceStr) {
-      this.nonceStr = nonceStr;
-      return this;
-    }
-
-    public Builder packageValue(String packageValue) {
-      this.packageValue = packageValue;
-      return this;
-    }
-
-    public Builder signType(String signType) {
-      this.signType = signType;
-      return this;
-    }
-
-    public Builder paySign(String paySign) {
-      this.paySign = paySign;
-      return this;
-    }
-
-    public WxPayMpOrderResult build() {
-      return new WxPayMpOrderResult(this);
-    }
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayMwebOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayMwebOrderResult.java
new file mode 100644
index 0000000000..640d3cd3de
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayMwebOrderResult.java
@@ -0,0 +1,21 @@
+package com.github.binarywang.wxpay.bean.order;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 
+ * 微信H5支付统一下单后发起支付拼接所需参数实现类.
+ * Created by Binary Wang on 2018-4-21.
+ * 
+ * + * @author Binary Wang + */ +@Data +@AllArgsConstructor +public class WxPayMwebOrderResult { + @XStreamAlias("mwebUrl") + private String mwebUrl; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayNativeOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayNativeOrderResult.java index 3eb0e3748a..219c47a6f9 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayNativeOrderResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/order/WxPayNativeOrderResult.java @@ -1,5 +1,9 @@ package com.github.binarywang.wxpay.bean.order; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + /** *
  * 微信扫码支付统一下单后发起支付拼接所需参数实现类
@@ -8,41 +12,8 @@
  *
  * @author Binary Wang
  */
+@Data
+@AllArgsConstructor
 public class WxPayNativeOrderResult {
   private String codeUrl;
-
-  private WxPayNativeOrderResult(Builder builder) {
-    setCodeUrl(builder.codeUrl);
-  }
-
-  public static Builder newBuilder() {
-    return new Builder();
-  }
-
-  public String getCodeUrl() {
-    return this.codeUrl;
-  }
-
-  public void setCodeUrl(String codeUrl) {
-    this.codeUrl = codeUrl;
-  }
-
-  public WxPayNativeOrderResult() {
-  }
-
-  public static final class Builder {
-    private String codeUrl;
-
-    private Builder() {
-    }
-
-    public Builder codeUrl(String codeUrl) {
-      this.codeUrl = codeUrl;
-      return this;
-    }
-
-    public WxPayNativeOrderResult build() {
-      return new WxPayNativeOrderResult(this);
-    }
-  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
similarity index 62%
rename from weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java
rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
index 41a98d0ae4..3824e159b6 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayBaseRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
@@ -1,30 +1,39 @@
 package com.github.binarywang.wxpay.bean.request;
 
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.util.SignUtils;
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
-import me.chanjar.weixin.common.exception.WxErrorException;
+import lombok.Data;
+import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.util.BeanUtils;
-import me.chanjar.weixin.common.util.ToStringUtils;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
-import org.apache.commons.lang3.StringUtils;
 
-import java.math.BigDecimal;
+import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES;
 
 /**
  * 
- * Created by Binary Wang on 2016-10-24.
  *  微信支付请求对象共用的参数存放类
+ * Created by Binary Wang on 2016-10-24.
  * 
* - * @author binarywang(Binary Wang) + * @author Binary Wang */ -public abstract class WxPayBaseRequest { +@Data +public abstract class BaseWxPayRequest implements Serializable { + private static final long serialVersionUID = -4766915659779847060L; + /** *
-   * 字段名:公众账号ID
+   * 字段名:公众账号ID.
    * 变量名:appid
    * 是否必填:是
    * 类型:String(32)
@@ -36,7 +45,7 @@ public abstract class WxPayBaseRequest {
   protected String appid;
   /**
    * 
-   * 字段名:商户号
+   * 字段名:商户号.
    * 变量名:mch_id
    * 是否必填:是
    * 类型:String(32)
@@ -48,7 +57,7 @@ public abstract class WxPayBaseRequest {
   protected String mchId;
   /**
    * 
-   * 字段名:服务商模式下的子商户公众账号ID
+   * 字段名:服务商模式下的子商户公众账号ID.
    * 变量名:sub_appid
    * 是否必填:是
    * 类型:String(32)
@@ -60,7 +69,7 @@ public abstract class WxPayBaseRequest {
   protected String subAppId;
   /**
    * 
-   * 字段名:服务商模式下的子商户号
+   * 字段名:服务商模式下的子商户号.
    * 变量名:sub_mch_id
    * 是否必填:是
    * 类型:String(32)
@@ -72,7 +81,7 @@ public abstract class WxPayBaseRequest {
   protected String subMchId;
   /**
    * 
-   * 字段名:随机字符串
+   * 字段名:随机字符串.
    * 变量名:nonce_str
    * 是否必填:是
    * 类型:String(32)
@@ -84,7 +93,7 @@ public abstract class WxPayBaseRequest {
   protected String nonceStr;
   /**
    * 
-   * 字段名:签名
+   * 字段名:签名.
    * 变量名:sign
    * 是否必填:是
    * 类型:String(32)
@@ -97,7 +106,7 @@ public abstract class WxPayBaseRequest {
 
   /**
    * 
-   * 签名类型
+   * 签名类型.
    * sign_type
    * 否
    * String(32)
@@ -109,18 +118,19 @@ public abstract class WxPayBaseRequest {
   private String signType;
 
   /**
-   * 将单位为元转换为单位为分
+   * 将单位为元转换为单位为分.
    *
    * @param yuan 将要转换的元的数值字符串
+   * @return the integer
    */
-  public static Integer yuanToFee(String yuan) {
+  public static Integer yuanToFen(String yuan) {
     return new BigDecimal(yuan).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue();
   }
 
   /**
-   * 检查请求参数内容,包括必填参数以及特殊约束
+   * 检查请求参数内容,包括必填参数以及特殊约束.
    */
-  protected void checkFields() throws WxPayException {
+  private void checkFields() throws WxPayException {
     //check required fields
     try {
       BeanUtils.checkRequiredFields(this);
@@ -133,16 +143,14 @@ protected void checkFields() throws WxPayException {
   }
 
   /**
-   * 检查约束情况
+   * 检查约束情况.
+   *
+   * @throws WxPayException the wx pay exception
    */
   protected abstract void checkConstraints() throws WxPayException;
 
-  public String getAppid() {
-    return this.appid;
-  }
-
   /**
-   * 如果配置中已经设置,可以不设置值
+   * 如果配置中已经设置,可以不设置值.
    *
    * @param appid 微信公众号appid
    */
@@ -150,12 +158,8 @@ public void setAppid(String appid) {
     this.appid = appid;
   }
 
-  public String getMchId() {
-    return this.mchId;
-  }
-
   /**
-   * 如果配置中已经设置,可以不设置值
+   * 如果配置中已经设置,可以不设置值.
    *
    * @param mchId 微信商户号
    */
@@ -163,12 +167,8 @@ public void setMchId(String mchId) {
     this.mchId = mchId;
   }
 
-  public String getNonceStr() {
-    return this.nonceStr;
-  }
-
   /**
-   * 默认采用时间戳为随机字符串,可以不设置
+   * 默认采用时间戳为随机字符串,可以不设置.
    *
    * @param nonceStr 随机字符串
    */
@@ -176,64 +176,61 @@ public void setNonceStr(String nonceStr) {
     this.nonceStr = nonceStr;
   }
 
-  public String getSign() {
-    return this.sign;
-  }
-
-  public void setSign(String sign) {
-    this.sign = sign;
-  }
-
-  public String getSubAppId() {
-    return subAppId;
-  }
-
-  public void setSubAppId(String subAppId) {
-    this.subAppId = subAppId;
-  }
-
-  public String getSubMchId() {
-    return subMchId;
-  }
-
-  public void setSubMchId(String subMchId) {
-    this.subMchId = subMchId;
-  }
-
-  public String getSignType() {
-    return signType;
-  }
-
-  public void setSignType(String signType) {
-    this.signType = signType;
-  }
-
   @Override
   public String toString() {
-    return ToStringUtils.toSimpleString(this);
+    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
   }
 
+  /**
+   * To xml string.
+   *
+   * @return the string
+   */
   public String toXML() {
     XStream xstream = XStreamInitializer.getInstance();
+    //涉及到服务商模式的两个参数,在为空值时置为null,以免在请求时将空值传给微信服务器
+    this.setSubAppId(StringUtils.trimToNull(this.getSubAppId()));
+    this.setSubMchId(StringUtils.trimToNull(this.getSubMchId()));
     xstream.processAnnotations(this.getClass());
     return xstream.toXML(this);
   }
 
+  /**
+   * 签名时,是否忽略appid.
+   *
+   * @return the boolean
+   */
+  protected boolean ignoreAppid() {
+    return false;
+  }
+
+  /**
+   * 签名时,忽略的参数.
+   *
+   * @return the string [ ]
+   */
+  protected String[] getIgnoredParamsForSign() {
+    return new String[0];
+  }
+
   /**
    * 
-   * 检查参数,并设置签名
+   * 检查参数,并设置签名.
    * 1、检查参数(注意:子类实现需要检查参数的而外功能时,请在调用父类的方法前进行相应判断)
    * 2、补充系统参数,如果未传入则从配置里读取
    * 3、生成签名,并设置进去
    * 
* * @param config 支付配置对象,用于读取相应系统配置信息 + * @throws WxPayException the wx pay exception */ public void checkAndSign(WxPayConfig config) throws WxPayException { this.checkFields(); - if (StringUtils.isBlank(getAppid())) { - this.setAppid(config.getAppId()); + if (!ignoreAppid()) { + if (StringUtils.isBlank(getAppid())) { + this.setAppid(config.getAppId()); + } } if (StringUtils.isBlank(getMchId())) { @@ -248,11 +245,22 @@ public void checkAndSign(WxPayConfig config) throws WxPayException { this.setSubMchId(config.getSubMchId()); } + if (StringUtils.isBlank(getSignType())) { + if (config.getSignType() != null && !ALL_SIGN_TYPES.contains(config.getSignType())) { + throw new WxPayException("非法的signType配置:" + config.getSignType() + ",请检查配置!"); + } + this.setSignType(StringUtils.trimToNull(config.getSignType())); + } else { + if (!ALL_SIGN_TYPES.contains(this.getSignType())) { + throw new WxPayException("非法的sign_type参数:" + this.getSignType()); + } + } + if (StringUtils.isBlank(getNonceStr())) { this.setNonceStr(String.valueOf(System.currentTimeMillis())); } + //设置签名字段的值 - this.setSign(SignUtils.createSign(this, config.getMchKey(), this.signType)); + this.setSign(SignUtils.createSign(this, this.getSignType(), config.getMchKey(), this.getIgnoredParamsForSign())); } - } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java deleted file mode 100644 index f9135c34df..0000000000 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayQueryRequest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.github.binarywang.wxpay.bean.request; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import me.chanjar.weixin.common.annotation.Required; -import me.chanjar.weixin.common.util.ToStringUtils; - -/** - *
- * 企业付款请求对象
- * 注释中各行每个字段描述对应如下:
- * 
  • 字段名 - *
  • 变量名 - *
  • 是否必填 - *
  • 类型 - *
  • 示例值 - *
  • 描述 - *
  • - * Created by Binary Wang on 2016/10/19. - * - * @author binarywang (https://github.com/binarywang) - */ -@XStreamAlias("xml") -public class WxEntPayQueryRequest extends WxPayBaseRequest { - /** - *
    -   * 商户订单号
    -   * partner_trade_no
    -   * 是
    -   * 10000098201411111234567890
    -   * String
    -   * 商户订单号
    -   * 
    - */ - @Required - @XStreamAlias("partner_trade_no") - private String partnerTradeNo; - - public String getPartnerTradeNo() { - return this.partnerTradeNo; - } - - public void setPartnerTradeNo(String partnerTradeNo) { - this.partnerTradeNo = partnerTradeNo; - } - - @Override - protected void checkConstraints() { - //do nothing - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - -} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java deleted file mode 100644 index 7897ad02da..0000000000 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxEntPayRequest.java +++ /dev/null @@ -1,375 +0,0 @@ -package com.github.binarywang.wxpay.bean.request; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import me.chanjar.weixin.common.annotation.Required; -import me.chanjar.weixin.common.util.ToStringUtils; - -/** - *
    - * 企业付款请求对象
    - * 
    - * Created by Binary Wang on 2016/10/02. - * - * @author binarywang (https://github.com/binarywang) - */ -@XStreamAlias("xml") -public class WxEntPayRequest extends WxPayBaseRequest { - /** - *
    -   * 字段名:公众账号appid
    -   * 变量名:mch_appid
    -   * 是否必填:是
    -   * 示例值:wx8888888888888888
    -   * 类型:String
    -   * 描述:微信分配的公众账号ID(企业号corpid即为此appId)
    -   * 
    - */ - @XStreamAlias("mch_appid") - private String mchAppid; - - /** - *
    -   * 字段名:商户号
    -   * 变量名:mchid
    -   * 是否必填:是
    -   * 示例值:1900000109
    -   * 类型:String(32)
    -   * 描述:微信支付分配的商户号
    -   * 
    - */ - @XStreamAlias("mchid") - private String mchId; - - /** - *
    -   * 字段名:设备号
    -   * 变量名:device_info
    -   * 是否必填:否
    -   * 示例值:13467007045764
    -   * 类型:String(32)
    -   * 描述:微信支付分配的终端设备号
    -   * 
    - */ - @XStreamAlias("device_info") - private String deviceInfo; - - /** - *
    -   * 字段名:商户订单号
    -   * 变量名:partner_trade_no
    -   * 是否必填:是
    -   * 示例值:10000098201411111234567890
    -   * 类型:String
    -   * 描述:商户订单号
    -   * 
    - */ - @Required - @XStreamAlias("partner_trade_no") - private String partnerTradeNo; - - /** - *
    -   * 字段名:需保持唯一性 用户openid
    -   * 变量名:openid
    -   * 是否必填:是
    -   * 示例值:oxTWIuGaIt6gTKsQRLau2M0yL16E
    -   * 类型:String
    -   * 描述:商户appid下,某用户的openid
    -   * 
    - */ - @Required - @XStreamAlias("openid") - private String openid; - - /** - *
    -   * 字段名:校验用户姓名选项
    -   * 变量名:check_name
    -   * 是否必填:是
    -   * 示例值:OPTION_CHECK
    -   * 类型:String
    -   * 描述:NO_CHECK:不校验真实姓名 
    -   * FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) 
    -   * OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
    -   * 
    - */ - @Required - @XStreamAlias("check_name") - private String checkName; - - /** - *
    -   * 字段名:收款用户姓名
    -   * 变量名:re_user_name
    -   * 是否必填:可选
    -   * 示例值:马花花
    -   * 类型:String
    -   * 描述:收款用户真实姓名。
    -   * 如果check_name设置为FORCE_CHECK或OPTION_CHECK,  则必填用户真实姓名
    -   * 
    - */ - @XStreamAlias("re_user_name") - private String reUserName; - - /** - *
    -   * 字段名:金额
    -   * 变量名:amount
    -   * 是否必填:是
    -   * 示例值:10099
    -   * 类型:int
    -   * 描述:企业付款金额, 单位为分
    -   * 
    - */ - @Required - @XStreamAlias("amount") - private Integer amount; - - /** - *
    -   * 字段名:企业付款描述信息
    -   * 变量名:desc
    -   * 是否必填:是
    -   * 示例值:理赔
    -   * 类型:String
    -   * 描述:企业付款操作说明信息。必填。
    -   * 
    - */ - @Required - @XStreamAlias("desc") - private String description; - - /** - *
    -   * 字段名:Ip地址
    -   * 变量名:spbill_create_ip
    -   * 是否必填:是
    -   * 示例值:192.168.0.1
    -   * 类型:String(32)
    -   * 描述:调用接口的机器Ip地址
    -   * 
    - */ - @Required - @XStreamAlias("spbill_create_ip") - private String spbillCreateIp; - - public WxEntPayRequest() { - } - - private WxEntPayRequest(Builder builder) { - setAppid(builder.appid); - setMchId(builder.mchId); - setSubAppId(builder.subAppId); - setSubMchId(builder.subMchId); - setNonceStr(builder.nonceStr); - setSign(builder.sign); - mchAppid = builder.mchAppid; - setMchId(builder.mchId); - setDeviceInfo(builder.deviceInfo); - setPartnerTradeNo(builder.partnerTradeNo); - setOpenid(builder.openid); - setCheckName(builder.checkName); - setReUserName(builder.reUserName); - setAmount(builder.amount); - setDescription(builder.description); - setSpbillCreateIp(builder.spbillCreateIp); - } - - public static Builder newBuilder() { - return new Builder(); - } - - @Override - protected void checkConstraints() { - - } - - @Override - public String getAppid() { - return this.mchAppid; - } - - @Override - public void setAppid(String appid) { - this.mchAppid = appid; - } - - @Override - public String getMchId() { - return this.mchId; - } - - @Override - public void setMchId(String mchId) { - this.mchId = mchId; - } - - public String getDeviceInfo() { - return this.deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public String getPartnerTradeNo() { - return this.partnerTradeNo; - } - - public void setPartnerTradeNo(String partnerTradeNo) { - this.partnerTradeNo = partnerTradeNo; - } - - public String getOpenid() { - return this.openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getCheckName() { - return this.checkName; - } - - public void setCheckName(String checkName) { - this.checkName = checkName; - } - - public String getReUserName() { - return this.reUserName; - } - - public void setReUserName(String reUserName) { - this.reUserName = reUserName; - } - - public Integer getAmount() { - return this.amount; - } - - public void setAmount(Integer amount) { - this.amount = amount; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getSpbillCreateIp() { - return this.spbillCreateIp; - } - - public void setSpbillCreateIp(String spbillCreateIp) { - this.spbillCreateIp = spbillCreateIp; - } - - @Override - public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public static final class Builder { - private String appid; - private String mchId; - private String deviceInfo; - private String partnerTradeNo; - private String openid; - private String checkName; - private String reUserName; - private Integer amount; - private String description; - private String spbillCreateIp; - private String subAppId; - private String subMchId; - private String nonceStr; - private String sign; - private String mchAppid; - - private Builder() { - } - - public Builder appid(String appid) { - this.appid = appid; - return this; - } - - public Builder mchId(String mchId) { - this.mchId = mchId; - return this; - } - - public Builder deviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - return this; - } - - public Builder partnerTradeNo(String partnerTradeNo) { - this.partnerTradeNo = partnerTradeNo; - return this; - } - - public Builder openid(String openid) { - this.openid = openid; - return this; - } - - public Builder checkName(String checkName) { - this.checkName = checkName; - return this; - } - - public Builder reUserName(String reUserName) { - this.reUserName = reUserName; - return this; - } - - public Builder amount(Integer amount) { - this.amount = amount; - return this; - } - - public Builder description(String description) { - this.description = description; - return this; - } - - public Builder spbillCreateIp(String spbillCreateIp) { - this.spbillCreateIp = spbillCreateIp; - return this; - } - - public WxEntPayRequest build() { - return new WxEntPayRequest(this); - } - - public Builder subAppId(String subAppId) { - this.subAppId = subAppId; - return this; - } - - public Builder subMchId(String subMchId) { - this.subMchId = subMchId; - return this; - } - - public Builder nonceStr(String nonceStr) { - this.nonceStr = nonceStr; - return this; - } - - public Builder sign(String sign) { - this.sign = sign; - return this; - } - - public Builder mchAppid(String mchAppid) { - this.mchAppid = mchAppid; - return this; - } - } -} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java index 594fa4960d..3b156407db 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java @@ -1,16 +1,23 @@ package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.*; /** *
      * 授权码查询openid接口请求对象类
      * Created by Binary Wang on 2017-3-27.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayAuthcode2OpenidRequest extends WxPayBaseRequest { +public class WxPayAuthcode2OpenidRequest extends BaseWxPayRequest { /** *
    @@ -24,21 +31,6 @@ public class WxPayAuthcode2OpenidRequest extends WxPayBaseRequest {
       @XStreamAlias("auth_code")
       private String authCode;
     
    -  public WxPayAuthcode2OpenidRequest() {
    -  }
    -
    -  public WxPayAuthcode2OpenidRequest(String authCode) {
    -    this.authCode = authCode;
    -  }
    -
    -  public String getAuthCode() {
    -    return this.authCode;
    -  }
    -
    -  public void setAuthCode(String authCode) {
    -    this.authCode = authCode;
    -  }
    -
       @Override
       protected void checkConstraints() {
         // nothing to do
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
    index ff36bfaad7..e44a6111e7 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
    @@ -11,9 +11,14 @@
      * @author Binary Wang
      */
     @XStreamAlias("xml")
    -public class WxPayDefaultRequest extends WxPayBaseRequest {
    +public class WxPayDefaultRequest extends BaseWxPayRequest {
       @Override
       protected void checkConstraints() {
         //do nothing
       }
    +
    +  @Override
    +  protected boolean ignoreAppid() {
    +    return true;
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
    index 33e410cdd8..e616224db7 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
    @@ -3,6 +3,7 @@
     import com.github.binarywang.wxpay.constant.WxPayConstants.BillType;
     import com.github.binarywang.wxpay.exception.WxPayException;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     import me.chanjar.weixin.common.annotation.Required;
     import org.apache.commons.lang3.ArrayUtils;
     import org.apache.commons.lang3.StringUtils;
    @@ -13,11 +14,17 @@
      * 
      *   微信支付下载对账单请求参数类
      * Created by Binary Wang on 2017-01-11.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayDownloadBillRequest extends WxPayBaseRequest { +public class WxPayDownloadBillRequest extends BaseWxPayRequest { private static final String[] BILL_TYPES = new String[]{BillType.ALL, BillType.SUCCESS, BillType.REFUND, BillType.RECHARGE_REFUND}; private static final String TAR_TYPE_GZIP = "GZIP"; @@ -34,19 +41,6 @@ public class WxPayDownloadBillRequest extends WxPayBaseRequest { @XStreamAlias("device_info") private String deviceInfo; - /** - *
    -   * 签名类型
    -   * sign_type
    -   * 否
    -   * String(32)
    -   * HMAC-SHA256
    -   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
    -   * 
    - */ - @XStreamAlias("sign_type") - private String signType; - /** *
        * 账单类型
    @@ -90,46 +84,6 @@ public class WxPayDownloadBillRequest extends WxPayBaseRequest {
       @XStreamAlias("tar_type")
       private String tarType;
     
    -  public String getDeviceInfo() {
    -    return deviceInfo;
    -  }
    -
    -  public void setDeviceInfo(String deviceInfo) {
    -    this.deviceInfo = deviceInfo;
    -  }
    -
    -  public String getSignType() {
    -    return signType;
    -  }
    -
    -  public void setSignType(String signType) {
    -    this.signType = signType;
    -  }
    -
    -  public String getBillType() {
    -    return billType;
    -  }
    -
    -  public void setBillType(String billType) {
    -    this.billType = billType;
    -  }
    -
    -  public String getBillDate() {
    -    return billDate;
    -  }
    -
    -  public void setBillDate(String billDate) {
    -    this.billDate = billDate;
    -  }
    -
    -  public String getTarType() {
    -    return tarType;
    -  }
    -
    -  public void setTarType(String tarType) {
    -    this.tarType = tarType;
    -  }
    -
       @Override
       protected void checkConstraints() throws WxPayException {
         if (StringUtils.isNotBlank(this.getTarType()) && !TAR_TYPE_GZIP.equals(this.getTarType())) {
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
    new file mode 100644
    index 0000000000..8ce06238e6
    --- /dev/null
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
    @@ -0,0 +1,90 @@
    +package com.github.binarywang.wxpay.bean.request;
    +
    +import com.github.binarywang.wxpay.constant.WxPayConstants.AccountType;
    +import com.github.binarywang.wxpay.exception.WxPayException;
    +import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
    +import me.chanjar.weixin.common.annotation.Required;
    +import org.apache.commons.lang3.ArrayUtils;
    +import org.apache.commons.lang3.StringUtils;
    +
    +import java.util.Arrays;
    +
    +/**
    + * 
    + *   微信支付下载资金账单请求参数类
    + * Created by cwivan on 2018-08-02.
    + * 
    + * + * @author cwivan + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +@XStreamAlias("xml") +public class WxPayDownloadFundFlowRequest extends BaseWxPayRequest { + private static final String[] ACCOUNT_TYPES = new String[]{AccountType.BASIC, AccountType.OPERATION, AccountType.FEES}; + private static final String SIGN_TYPE_HMAC_SHA256 = "HMAC-SHA256"; + private static final String TAR_TYPE_GZIP = "GZIP"; + + /** + *
    +   * 对账单日期
    +   * bill_date
    +   * 是
    +   * String(8)
    +   * 20140603
    +   * 下载对账单的日期,格式:20140603
    +   * 
    + */ + @Required + @XStreamAlias("bill_date") + private String billDate; + + /** + *
    +   * 资金账户类型
    +   * account_type
    +   * 是
    +   * Basic
    +   * String(8)
    +   * --Basic,基本账户
    +   * --Operation,运营账户
    +   * --Fees,手续费账户
    +   * 
    + */ + @Required + @XStreamAlias("account_type") + private String accountType; + + /** + *
    +   * 压缩账单
    +   * tar_type
    +   * 否
    +   * String(8)
    +   * GZIP
    +   * 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。
    +   * 
    + */ + @XStreamAlias("tar_type") + private String tarType; + + @Override + protected void checkConstraints() throws WxPayException { + if (StringUtils.isNotBlank(this.getTarType()) && !TAR_TYPE_GZIP.equals(this.getTarType())) { + throw new WxPayException("tar_type值如果存在,只能为GZIP"); + } + + if (!ArrayUtils.contains(ACCOUNT_TYPES, this.getAccountType())) { + throw new WxPayException(String.format("account_type必须为%s其中之一,实际值:%s", + Arrays.toString(ACCOUNT_TYPES), this.getAccountType())); + } + /** + * 目前仅支持HMAC-SHA256 + */ + this.setSignType(SIGN_TYPE_HMAC_SHA256); + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java index a025337806..8cec4f0bd7 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java @@ -1,37 +1,47 @@ package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.*; import me.chanjar.weixin.common.annotation.Required; /** *
      *  提交刷卡支付请求对象类
      * Created by Binary Wang on 2017-3-23.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayMicropayRequest extends WxPayBaseRequest { +public class WxPayMicropayRequest extends BaseWxPayRequest { /** *
    -   * 签名类型
    -   * sign_type
    -   * 否
    -   * String(32)
    -   * HMAC-SHA256
    -   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
    -   **/
    -  @XStreamAlias("sign_type")
    -  private String signType;
    +   * 字段名:接口版本号.
    +   * 变量名:version
    +   * 是否必填:单品优惠必填
    +   * 类型:String(32)
    +   * 示例值:1.0
    +   * 描述:单品优惠新增字段,区分原接口,固定填写1.0
    +   * 更多信息,详见文档:https://pay.weixin.qq.com/wiki/doc/api/danpin.php?chapter=9_101&index=1
    +   * 
    + */ + @XStreamAlias("version") + private String version; /** *
    -   * 商品描述
    -   * body
    -   * 是
    -   * String(128)
    -   * image形象店-深圳腾大- QQ公仔
    -   * 商品简单描述,该字段须严格按照规范传递,具体请见参数规定
    +   * 字段名:商品描述.
    +   * 变量名:body
    +   * 是否必填:是
    +   * 类型:String(128)
    +   * 示例值:image形象店-深圳腾大- QQ公仔
    +   * 描述:商品简单描述,该字段须严格按照规范传递,具体请见参数规定
    +   * 
    **/ @Required @XStreamAlias("body") @@ -39,36 +49,38 @@ public class WxPayMicropayRequest extends WxPayBaseRequest { /** *
    -   * 商品详情
    -   * detail
    -   * 否
    -   * String(6000)
    -   *
    -   * 单品优惠功能字段,需要接入请见详细说明
    +   * 字段名:商品详情.
    +   * 变量名:detail
    +   * 是否必填:否
    +   * 类型:String(6000)
    +   * 示例值:
    +   * 描述:单品优惠功能字段,需要接入请见详细说明
    **/ @XStreamAlias("detail") private String detail; /** *
    -   * 附加数据
    -   * attach
    -   * 否
    -   * String(127)
    -   * 说明
    -   * 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
    +   * 字段名:附加数据.
    +   * 变量名:attach
    +   * 是否必填:否
    +   * 类型:String(127)
    +   * 示例值:说明
    +   * 描述:附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
    +   * 
    **/ @XStreamAlias("attach") private String attach; /** *
    -   * 商户订单号
    -   * out_trade_no
    -   * 是
    -   * String(32)
    -   * 1217752501201407033233368018
    -   * 商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号
    +   * 字段名:商户订单号.
    +   * 变量名:out_trade_no
    +   * 是否必填:是
    +   * 类型:String(32)
    +   * 示例值:1217752501201407033233368018
    +   * 描述:商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号
    +   * 
    **/ @Required @XStreamAlias("out_trade_no") @@ -76,12 +88,13 @@ public class WxPayMicropayRequest extends WxPayBaseRequest { /** *
    -   * 订单金额
    -   * total_fee
    -   * 是
    -   * Int
    -   * 888
    -   * 订单总金额,单位为分,只能为整数,详见支付金额
    +   * 字段名:订单金额.
    +   * 变量名:total_fee
    +   * 是否必填:是
    +   * 类型:Int
    +   * 示例值:888
    +   * 描述:订单总金额,单位为分,只能为整数,详见支付金额
    +   * 
    **/ @Required @XStreamAlias("total_fee") @@ -89,24 +102,26 @@ public class WxPayMicropayRequest extends WxPayBaseRequest { /** *
    -   * 货币类型
    -   * fee_type
    -   * 否
    -   * String(16)
    -   * CNY
    -   * 符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 字段名:货币类型.
    +   * 变量名:fee_type
    +   * 是否必填:否
    +   * 类型:String(16)
    +   * 示例值:CNY
    +   * 描述:符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 
    **/ @XStreamAlias("fee_type") private String feeType; /** *
    -   * 终端IP
    -   * spbill_create_ip
    -   * 是
    -   * String(16)
    -   * 8.8.8.8
    -   * 调用微信支付API的机器IP
    +   * 字段名:终端IP.
    +   * 变量名:spbill_create_ip
    +   * 是否必填:是
    +   * 类型:String(16)
    +   * 示例值:8.8.8.8
    +   * 描述:调用微信支付API的机器IP
    +   * 
    **/ @Required @XStreamAlias("spbill_create_ip") @@ -114,267 +129,91 @@ public class WxPayMicropayRequest extends WxPayBaseRequest { /** *
    -   * 商品标记
    -   * goods_tag
    -   * 否
    -   * String(32)
    -   * 1234
    -   * 商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
    +   * 字段名:商品标记.
    +   * 变量名:goods_tag
    +   * 是否必填:否
    +   * 类型:String(32)
    +   * 示例值:1234
    +   * 描述:商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
    +   * 
    **/ @XStreamAlias("goods_tag") private String goodsTag; /** *
    -   * 指定支付方式
    -   * limit_pay
    -   * 否
    -   * String(32)
    -   * no_credit
    -   * no_credit--指定不能使用信用卡支付
    +   * 字段名:指定支付方式.
    +   * 变量名:limit_pay
    +   * 是否必填:否
    +   * 类型:String(32)
    +   * 示例值:no_credit
    +   * 描述:no_credit--指定不能使用信用卡支付
    +   * 
    **/ @XStreamAlias("limit_pay") private String limitPay; /** *
    -   * 授权码
    -   * auth_code
    -   * 是
    -   * String(128)
    -   * 120061098828009406
    -   * 扫码支付授权码,设备读取用户微信中的条码或者二维码信息注:用户刷卡条形码规则:18位纯数字,以10、11、12、13、14、15开头)
    +   * 字段名:交易起始时间.
    +   * 变量名:time_start
    +   * 是否必填:否
    +   * 类型:String(14)
    +   * 示例值:20091225091010
    +   * 描述:订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
    +   * 
    + */ + @XStreamAlias("time_start") + private String timeStart; + + /** + *
    +   * 字段名:交易结束时间.
    +   * 变量名:time_expire
    +   * 是否必填:否
    +   * 类型:String(14)
    +   * 示例值:20091227091010
    +   * 描述:订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
    +   * 注意:最短失效时间间隔必须大于5分钟
    +   * 
    + */ + @XStreamAlias("time_expire") + private String timeExpire; + + /** + *
    +   * 字段名:授权码.
    +   * 变量名:auth_code
    +   * 是否必填:是
    +   * 类型:String(128)
    +   * 示例值:120061098828009406
    +   * 描述:扫码支付授权码,设备读取用户微信中的条码或者二维码信息注:用户刷卡条形码规则:18位纯数字,以10、11、12、13、14、15开头)
    +   * 
    **/ @Required @XStreamAlias("auth_code") private String authCode; - private WxPayMicropayRequest(Builder builder) { - setSignType(builder.signType); - setBody(builder.body); - setAppid(builder.appid); - setDetail(builder.detail); - setMchId(builder.mchId); - setAttach(builder.attach); - setSubAppId(builder.subAppId); - setOutTradeNo(builder.outTradeNo); - setSubMchId(builder.subMchId); - setTotalFee(builder.totalFee); - setNonceStr(builder.nonceStr); - setFeeType(builder.feeType); - setSign(builder.sign); - setSpbillCreateIp(builder.spbillCreateIp); - setGoodsTag(builder.goodsTag); - setLimitPay(builder.limitPay); - setAuthCode(builder.authCode); - } - - public static Builder newBuilder() { - return new Builder(); - } - - public String getSignType() { - return this.signType; - } - - public void setSignType(String signType) { - this.signType = signType; - } - - public String getBody() { - return this.body; - } - - public void setBody(String body) { - this.body = body; - } - - public String getDetail() { - return this.detail; - } - - public void setDetail(String detail) { - this.detail = detail; - } - - public String getAttach() { - return this.attach; - } - - public void setAttach(String attach) { - this.attach = attach; - } - - public String getOutTradeNo() { - return this.outTradeNo; - } - - public void setOutTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - } - - public Integer getTotalFee() { - return this.totalFee; - } - - public void setTotalFee(Integer totalFee) { - this.totalFee = totalFee; - } - - public String getFeeType() { - return this.feeType; - } - - public void setFeeType(String feeType) { - this.feeType = feeType; - } - - public String getSpbillCreateIp() { - return this.spbillCreateIp; - } - - public void setSpbillCreateIp(String spbillCreateIp) { - this.spbillCreateIp = spbillCreateIp; - } - - public String getGoodsTag() { - return this.goodsTag; - } - - public void setGoodsTag(String goodsTag) { - this.goodsTag = goodsTag; - } - - public String getLimitPay() { - return this.limitPay; - } - - public void setLimitPay(String limitPay) { - this.limitPay = limitPay; - } - - public String getAuthCode() { - return this.authCode; - } - - public void setAuthCode(String authCode) { - this.authCode = authCode; - } + /** + *
    +   * 字段名:场景信息.
    +   * 变量名:scene_info
    +   * 是否必填:否
    +   * 类型:String(256)
    +   * 示例值:{"store_info" : {
    +   * "id": "SZTX001",
    +   * "name": "腾大餐厅",
    +   * "area_code": "440305",
    +   * "address": "科技园中一路腾讯大厦" }}
    +   * 描述:该字段用于上报场景信息,目前支持上报实际门店信息。该字段为JSON对象数据,对象格式为{"store_info":{"id": "门店ID","name": "名称","area_code": "编码","address": "地址" }}
    +   * 
    + */ + @XStreamAlias("scene_info") + private String sceneInfo; @Override protected void checkConstraints() { //do nothing } - public static final class Builder { - private String signType; - private String body; - private String appid; - private String detail; - private String mchId; - private String attach; - private String subAppId; - private String outTradeNo; - private String subMchId; - private Integer totalFee; - private String nonceStr; - private String feeType; - private String sign; - private String spbillCreateIp; - private String goodsTag; - private String limitPay; - private String authCode; - - private Builder() { - } - - public Builder signType(String signType) { - this.signType = signType; - return this; - } - - public Builder body(String body) { - this.body = body; - return this; - } - - public Builder appid(String appid) { - this.appid = appid; - return this; - } - - public Builder detail(String detail) { - this.detail = detail; - return this; - } - - public Builder mchId(String mchId) { - this.mchId = mchId; - return this; - } - - public Builder attach(String attach) { - this.attach = attach; - return this; - } - - public Builder subAppId(String subAppId) { - this.subAppId = subAppId; - return this; - } - - public Builder outTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - return this; - } - - public Builder subMchId(String subMchId) { - this.subMchId = subMchId; - return this; - } - - public Builder totalFee(Integer totalFee) { - this.totalFee = totalFee; - return this; - } - - public Builder nonceStr(String nonceStr) { - this.nonceStr = nonceStr; - return this; - } - - public Builder feeType(String feeType) { - this.feeType = feeType; - return this; - } - - public Builder sign(String sign) { - this.sign = sign; - return this; - } - - public Builder spbillCreateIp(String spbillCreateIp) { - this.spbillCreateIp = spbillCreateIp; - return this; - } - - public Builder goodsTag(String goodsTag) { - this.goodsTag = goodsTag; - return this; - } - - public Builder limitPay(String limitPay) { - this.limitPay = limitPay; - return this; - } - - public Builder authCode(String authCode) { - this.authCode = authCode; - return this; - } - - public WxPayMicropayRequest build() { - return new WxPayMicropayRequest(this); - } - } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java index 21968ac983..e430460e39 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java @@ -1,16 +1,23 @@ package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.*; /** *
      *  关闭订单请求对象类
      * Created by Binary Wang on 2016-10-27.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayOrderCloseRequest extends WxPayBaseRequest { +public class WxPayOrderCloseRequest extends BaseWxPayRequest { /** *
    @@ -25,14 +32,6 @@ public class WxPayOrderCloseRequest extends WxPayBaseRequest {
       @XStreamAlias("out_trade_no")
       private String outTradeNo;
     
    -  public String getOutTradeNo() {
    -    return this.outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
       @Override
       protected void checkConstraints() {
     
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    index e7767da607..221b04f172 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
    @@ -2,6 +2,7 @@
     
     import com.github.binarywang.wxpay.exception.WxPayException;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     import org.apache.commons.lang3.StringUtils;
     
     /**
    @@ -17,10 +18,30 @@
      * 
  • 描述 *
  • * - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayOrderQueryRequest extends WxPayBaseRequest { +public class WxPayOrderQueryRequest extends BaseWxPayRequest { + + /** + *
    +   * 字段名:接口版本号.
    +   * 变量名:version
    +   * 是否必填:单品优惠必填
    +   * 类型:String(32)
    +   * 示例值:1.0
    +   * 描述:单品优惠新增字段,区分原接口,固定填写1.0,
    +   * 查单接口上传version后查询结果才返回单品信息,不上传不返回单品信息。
    +   * 更多信息,详见文档:https://pay.weixin.qq.com/wiki/doc/api/danpin.php?chapter=9_102&index=2
    +   * 
    + */ + @XStreamAlias("version") + private String version; /** *
    @@ -48,22 +69,6 @@ public class WxPayOrderQueryRequest extends WxPayBaseRequest {
       @XStreamAlias("out_trade_no")
       private String outTradeNo;
     
    -  public String getTransactionId() {
    -    return this.transactionId;
    -  }
    -
    -  public void setTransactionId(String transactionId) {
    -    this.transactionId = transactionId;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return this.outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
       @Override
       protected void checkConstraints() throws WxPayException {
         if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)) ||
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
    index 075295238e..5394631b3c 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
    @@ -2,17 +2,24 @@
     
     import com.github.binarywang.wxpay.exception.WxPayException;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     import org.apache.commons.lang3.StringUtils;
     
     /**
      * 
      * 撤销订单请求类
      * Created by Binary Wang on 2017-3-23.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayOrderReverseRequest extends WxPayBaseRequest { +public class WxPayOrderReverseRequest extends BaseWxPayRequest { /** *
    @@ -39,58 +46,6 @@ public class WxPayOrderReverseRequest extends WxPayBaseRequest {
       @XStreamAlias("out_trade_no")
       private String outTradeNo;
     
    -  /**
    -   * 
    -   * 签名类型
    -   * sign_type
    -   * 否
    -   * String(32)
    -   * HMAC-SHA256
    -   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
    -   **/
    -  @XStreamAlias("sign_type")
    -  private String signType;
    -
    -  private WxPayOrderReverseRequest(Builder builder) {
    -    setTransactionId(builder.transactionId);
    -    setAppid(builder.appid);
    -    setOutTradeNo(builder.outTradeNo);
    -    setMchId(builder.mchId);
    -    setSignType(builder.signType);
    -    setSubAppId(builder.subAppId);
    -    setSubMchId(builder.subMchId);
    -    setNonceStr(builder.nonceStr);
    -    setSign(builder.sign);
    -  }
    -
    -  public static Builder newBuilder() {
    -    return new Builder();
    -  }
    -
    -  public String getTransactionId() {
    -    return this.transactionId;
    -  }
    -
    -  public void setTransactionId(String transactionId) {
    -    this.transactionId = transactionId;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return this.outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
    -  public String getSignType() {
    -    return this.signType;
    -  }
    -
    -  public void setSignType(String signType) {
    -    this.signType = signType;
    -  }
    -
       @Override
       protected void checkConstraints() throws WxPayException {
         if (StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)) {
    @@ -98,67 +53,4 @@ protected void checkConstraints() throws WxPayException {
         }
       }
     
    -  public static final class Builder {
    -    private String transactionId;
    -    private String appid;
    -    private String outTradeNo;
    -    private String mchId;
    -    private String signType;
    -    private String subAppId;
    -    private String subMchId;
    -    private String nonceStr;
    -    private String sign;
    -
    -    private Builder() {
    -    }
    -
    -    public Builder transactionId(String transactionId) {
    -      this.transactionId = transactionId;
    -      return this;
    -    }
    -
    -    public Builder appid(String appid) {
    -      this.appid = appid;
    -      return this;
    -    }
    -
    -    public Builder outTradeNo(String outTradeNo) {
    -      this.outTradeNo = outTradeNo;
    -      return this;
    -    }
    -
    -    public Builder mchId(String mchId) {
    -      this.mchId = mchId;
    -      return this;
    -    }
    -
    -    public Builder signType(String signType) {
    -      this.signType = signType;
    -      return this;
    -    }
    -
    -    public Builder subAppId(String subAppId) {
    -      this.subAppId = subAppId;
    -      return this;
    -    }
    -
    -    public Builder subMchId(String subMchId) {
    -      this.subMchId = subMchId;
    -      return this;
    -    }
    -
    -    public Builder nonceStr(String nonceStr) {
    -      this.nonceStr = nonceStr;
    -      return this;
    -    }
    -
    -    public Builder sign(String sign) {
    -      this.sign = sign;
    -      return this;
    -    }
    -
    -    public WxPayOrderReverseRequest build() {
    -      return new WxPayOrderReverseRequest(this);
    -    }
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
    index 1bdbf9bf4e..6b81aeed48 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
    @@ -2,21 +2,29 @@
     
     import com.github.binarywang.wxpay.exception.WxPayException;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     import me.chanjar.weixin.common.annotation.Required;
     
     /**
      * 
    - *  拉取订单评价数据接口的请求参数封装类
    + *  拉取订单评价数据接口的请求参数封装类.
      *  Created by BinaryWang on 2017/9/2.
      * 
    * * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayQueryCommentRequest extends WxPayBaseRequest { +public class WxPayQueryCommentRequest extends BaseWxPayRequest { + private static final long serialVersionUID = 2633600418272768186L; + /** *
    -   * 字段名:开始时间
    +   * 字段名:开始时间.
        * 变量名:begin_time
        * 是否必填:是
        * 类型:String(19)
    @@ -30,7 +38,7 @@ public class WxPayQueryCommentRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:结束时间
    +   * 字段名:结束时间.
        * 变量名:end_time
        * 是否必填:是
        * 类型:String(19)
    @@ -44,7 +52,7 @@ public class WxPayQueryCommentRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:位移
    +   * 字段名:位移.
        * 变量名:offset
        * 是否必填:是
        * 类型:uint(64)
    @@ -58,7 +66,7 @@ public class WxPayQueryCommentRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:条数
    +   * 字段名:条数.
        * 变量名:limit
        * 是否必填:否
        * 类型:uint(32)
    @@ -70,43 +78,14 @@ public class WxPayQueryCommentRequest extends WxPayBaseRequest {
       private Integer limit;
     
       /**
    -   * 检查约束情况
    +   * 检查约束情况.
        */
       @Override
       protected void checkConstraints() throws WxPayException {
    -
    -  }
    -
    -  public String getBeginTime() {
    -    return beginTime;
    -  }
    -
    -  public void setBeginTime(String beginTime) {
    -    this.beginTime = beginTime;
    -  }
    -
    -  public String getEndTime() {
    -    return endTime;
    -  }
    -
    -  public void setEndTime(String endTime) {
    -    this.endTime = endTime;
    -  }
    -
    -  public Integer getOffset() {
    -    return offset;
    -  }
    -
    -  public void setOffset(Integer offset) {
    -    this.offset = offset;
       }
     
    -  public Integer getLimit() {
    -    return limit;
    -  }
    -
    -  public void setLimit(Integer limit) {
    -    this.limit = limit;
    +  @Override
    +  protected String[] getIgnoredParamsForSign() {
    +    return new String[]{"limit","sign_type"};
       }
    -
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
    index 191db46975..4bbee5aaf2 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java
    @@ -1,6 +1,7 @@
     package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     
     /**
      * 
    @@ -12,11 +13,17 @@
      *   类型
      *   说明
      * Created by Binary Wang on 2016-11-28.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayRedpackQueryRequest extends WxPayBaseRequest { +public class WxPayRedpackQueryRequest extends BaseWxPayRequest { /** * 商户订单号 * mch_billno @@ -39,22 +46,6 @@ public class WxPayRedpackQueryRequest extends WxPayBaseRequest { @XStreamAlias("bill_type") private String billType; - public String getBillType() { - return billType; - } - - public void setBillType(String billType) { - this.billType = billType; - } - - public String getMchBillNo() { - return mchBillNo; - } - - public void setMchBillNo(String mchBillNo) { - this.mchBillNo = mchBillNo; - } - @Override protected void checkConstraints() { diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java index 00545f004c..4df8a63db9 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java @@ -2,16 +2,23 @@ import com.github.binarywang.wxpay.exception.WxPayException; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.*; import org.apache.commons.lang3.StringUtils; /** *
      * Created by Binary Wang on 2016-11-24.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayRefundQueryRequest extends WxPayBaseRequest { +public class WxPayRefundQueryRequest extends BaseWxPayRequest { /** *
        * 设备号
    @@ -25,19 +32,6 @@ public class WxPayRefundQueryRequest extends WxPayBaseRequest {
       @XStreamAlias("device_info")
       private String deviceInfo;
     
    -  /**
    -   * 
    -   * 签名类型
    -   * sign_type
    -   * 否
    -   * String(32)
    -   * HMAC-SHA256
    -   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
    -   * 
    - */ - @XStreamAlias("sign_type") - private String signType; - //************以下四选一************ /** *
    @@ -87,54 +81,6 @@ public class WxPayRefundQueryRequest extends WxPayBaseRequest {
       @XStreamAlias("refund_id")
       private String refundId;
     
    -  public String getDeviceInfo() {
    -    return deviceInfo;
    -  }
    -
    -  public void setDeviceInfo(String deviceInfo) {
    -    this.deviceInfo = deviceInfo;
    -  }
    -
    -  public String getSignType() {
    -    return signType;
    -  }
    -
    -  public void setSignType(String signType) {
    -    this.signType = signType;
    -  }
    -
    -  public String getTransactionId() {
    -    return transactionId;
    -  }
    -
    -  public void setTransactionId(String transactionId) {
    -    this.transactionId = transactionId;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
    -  public String getOutRefundNo() {
    -    return outRefundNo;
    -  }
    -
    -  public void setOutRefundNo(String outRefundNo) {
    -    this.outRefundNo = outRefundNo;
    -  }
    -
    -  public String getRefundId() {
    -    return refundId;
    -  }
    -
    -  public void setRefundId(String refundId) {
    -    this.refundId = refundId;
    -  }
    -
       @Override
       protected void checkConstraints() throws WxPayException {
         if ((StringUtils.isBlank(transactionId) && StringUtils.isBlank(outTradeNo)
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    index 66808738ca..1383e4f5b1 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
    @@ -1,8 +1,10 @@
     package com.github.binarywang.wxpay.bean.request;
     
     import com.github.binarywang.wxpay.config.WxPayConfig;
    +import com.github.binarywang.wxpay.constant.WxPayConstants.RefundAccountSource;
     import com.github.binarywang.wxpay.exception.WxPayException;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     import me.chanjar.weixin.common.annotation.Required;
     import org.apache.commons.lang3.ArrayUtils;
     import org.apache.commons.lang3.StringUtils;
    @@ -12,66 +14,65 @@
     /**
      * 
      * 微信支付-申请退款请求参数
    - * 注释中各行每个字段描述对应如下:
    - * 
  • 字段名 - *
  • 变量名 - *
  • 是否必填 - *
  • 类型 - *
  • 示例值 - *
  • 描述 * Created by Binary Wang on 2016-10-08. *
  • * - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayRefundRequest extends WxPayBaseRequest { - private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS", - "REFUND_SOURCE_UNSETTLED_FUNDS"}; +public class WxPayRefundRequest extends BaseWxPayRequest { + private static final String[] REFUND_ACCOUNT = new String[]{ + RefundAccountSource.RECHARGE_FUNDS, RefundAccountSource.UNSETTLED_FUNDS}; + /** *
    -   * 设备号
    -   * device_info
    -   * 否
    -   * String(32)
    -   * 13467007045764
    -   * 终端设备号
    +   * 字段名:设备号.
    +   * 变量名:device_info
    +   * 是否必填:否
    +   * 类型:String(32)
    +   * 示例值:13467007045764
    +   * 描述:终端设备号
        * 
    */ @XStreamAlias("device_info") private String deviceInfo; /** *
    -   * 微信订单号
    -   * transaction_id
    -   * 跟out_trade_no二选一
    -   * String(28)
    -   * 1217752501201400000000000000
    -   * 微信生成的订单号,在支付通知中有返回
    +   * 字段名:微信订单号.
    +   * 变量名:transaction_id
    +   * 是否必填:跟out_trade_no二选一
    +   * 类型:String(28)
    +   * 示例值:1217752501201400000000000000
    +   * 描述:微信生成的订单号,在支付通知中有返回
        * 
    */ @XStreamAlias("transaction_id") private String transactionId; /** *
    -   * 商户订单号
    -   * out_trade_no
    -   * 跟transaction_id二选一
    -   * String(32)
    -   * 1217752501201400000000000000
    -   * 商户侧传给微信的订单号
    +   * 字段名:商户订单号.
    +   * 变量名:out_trade_no
    +   * 是否必填:跟transaction_id二选一
    +   * 类型:String(32)
    +   * 示例值:1217752501201400000000000000
    +   * 描述:商户侧传给微信的订单号
        * 
    */ @XStreamAlias("out_trade_no") private String outTradeNo; /** *
    -   * 商户退款单号
    -   * out_refund_no
    -   * 是
    -   * String(32)
    -   * 1217752501201400000000000000
    -   * 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
    +   * 字段名:商户退款单号.
    +   * 变量名:out_refund_no
    +   * 是否必填:是
    +   * 类型:String(32)
    +   * 示例值:1217752501201400000000000000
    +   * 描述:商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
        * 
    */ @Required @@ -79,12 +80,12 @@ public class WxPayRefundRequest extends WxPayBaseRequest { private String outRefundNo; /** *
    -   * 订单金额
    -   * total_fee
    -   * 是
    -   * Int
    -   * 100
    -   * 订单总金额,单位为分,只能为整数,详见支付金额
    +   * 字段名:订单金额.
    +   * 变量名:total_fee
    +   * 是否必填:是
    +   * 类型:Int
    +   * 示例值:100
    +   * 描述:订单总金额,单位为分,只能为整数,详见支付金额
        * 
    */ @Required @@ -92,12 +93,12 @@ public class WxPayRefundRequest extends WxPayBaseRequest { private Integer totalFee; /** *
    -   * 退款金额
    -   * refund_fee
    -   * 是
    -   * Int
    -   * 100
    -   * 退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
    +   * 字段名:退款金额.
    +   * 变量名:refund_fee
    +   * 是否必填:是
    +   * 类型:Int
    +   * 示例值:100
    +   * 描述:退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
        * 
    */ @Required @@ -105,24 +106,24 @@ public class WxPayRefundRequest extends WxPayBaseRequest { private Integer refundFee; /** *
    -   * 货币种类
    -   * refund_fee_type
    -   * 否
    -   * String(8)
    -   * CNY
    -   * 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 字段名:货币种类.
    +   * 变量名:refund_fee_type
    +   * 是否必填:否
    +   * 类型:String(8)
    +   * 示例值:CNY
    +   * 描述:货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
        * 
    */ @XStreamAlias("refund_fee_type") private String refundFeeType; /** *
    -   * 操作员
    -   * op_user_id
    -   * 是
    -   * String(32)
    -   * 1900000109
    -   * 操作员帐号, 默认为商户号
    +   * 字段名:操作员.
    +   * 变量名:op_user_id
    +   * 是否必填:是
    +   * 类型:String(32)
    +   * 示例值:1900000109
    +   * 描述:操作员帐号, 默认为商户号
        * 
    */ //@Required @@ -130,136 +131,45 @@ public class WxPayRefundRequest extends WxPayBaseRequest { private String opUserId; /** *
    -   * 退款资金来源
    -   * refund_account
    -   * 否
    -   * String(30)
    -   * REFUND_SOURCE_RECHARGE_FUNDS
    -   * 仅针对老资金流商户使用,
    +   * 字段名:退款资金来源.
    +   * 变量名:refund_account
    +   * 是否必填:否
    +   * 类型:String(30)
    +   * 示例值:REFUND_SOURCE_RECHARGE_FUNDS
    +   * 描述:仅针对老资金流商户使用,
        * 
  • REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款(默认使用未结算资金退款), *
  • REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款 *
  • */ @XStreamAlias("refund_account") private String refundAccount; + /** *
    -   * 退款原因
    -   * refund_account
    -   * 否
    -   * String(80)
    -   * 商品已售完
    -   * 若商户传入,会在下发给用户的退款消息中体现退款原因
    +   * 字段名:退款原因.
    +   * 变量名:refund_account
    +   * 是否必填:否
    +   * 类型:String(80)
    +   * 示例值:商品已售完
    +   * 描述:若商户传入,会在下发给用户的退款消息中体现退款原因
        * 
    */ @XStreamAlias("refund_desc") private String refundDesc; - private WxPayRefundRequest(Builder builder) { - setDeviceInfo(builder.deviceInfo); - setAppid(builder.appid); - setTransactionId(builder.transactionId); - setMchId(builder.mchId); - setSubAppId(builder.subAppId); - setOutTradeNo(builder.outTradeNo); - setSubMchId(builder.subMchId); - setOutRefundNo(builder.outRefundNo); - setNonceStr(builder.nonceStr); - setTotalFee(builder.totalFee); - setSign(builder.sign); - setRefundFee(builder.refundFee); - setRefundFeeType(builder.refundFeeType); - setOpUserId(builder.opUserId); - setRefundAccount(builder.refundAccount); - setRefundDesc(builder.refundDesc); - } - - public static Builder newBuilder() { - return new Builder(); - } - - public String getDeviceInfo() { - return this.deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public String getTransactionId() { - return this.transactionId; - } - - public void setTransactionId(String transactionId) { - this.transactionId = transactionId; - } - - public String getOutTradeNo() { - return this.outTradeNo; - } - - public void setOutTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - } - - public String getOutRefundNo() { - return this.outRefundNo; - } - - public void setOutRefundNo(String outRefundNo) { - this.outRefundNo = outRefundNo; - } - - public Integer getTotalFee() { - return this.totalFee; - } - - public void setTotalFee(Integer totalFee) { - this.totalFee = totalFee; - } - - public Integer getRefundFee() { - return this.refundFee; - } - - public void setRefundFee(Integer refundFee) { - this.refundFee = refundFee; - } - - public String getRefundFeeType() { - return this.refundFeeType; - } - - public void setRefundFeeType(String refundFeeType) { - this.refundFeeType = refundFeeType; - } - - public String getOpUserId() { - return this.opUserId; - } - - public void setOpUserId(String opUserId) { - this.opUserId = opUserId; - } - - public String getRefundAccount() { - return this.refundAccount; - } - - public void setRefundAccount(String refundAccount) { - this.refundAccount = refundAccount; - } - - public String getRefundDesc() { - return this.refundDesc; - } - - public void setRefundDesc(String refundDesc) { - this.refundDesc = refundDesc; - } - - public WxPayRefundRequest() { - } + /** + *
    +   * 字段名:退款结果通知url.
    +   * 变量名:notify_url
    +   * 是否必填:否
    +   * 类型:String(256)
    +   * 示例值:https://weixin.qq.com/notify/
    +   * 描述:	异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数
    +   如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。
    +   * 
    + */ + @XStreamAlias("notify_url") + private String notifyUrl; @Override public void checkAndSign(WxPayConfig config) throws WxPayException { @@ -274,8 +184,8 @@ public void checkAndSign(WxPayConfig config) throws WxPayException { protected void checkConstraints() throws WxPayException { if (StringUtils.isNotBlank(this.getRefundAccount())) { if (!ArrayUtils.contains(REFUND_ACCOUNT, this.getRefundAccount())) { - throw new WxPayException(String.format("refund_account目前必须为%s其中之一,实际值:%s", - Arrays.toString(REFUND_ACCOUNT), this.getRefundAccount())); + throw new WxPayException( + String.format("refund_account目前必须为%s其中之一,实际值:%s", Arrays.toString(REFUND_ACCOUNT), this.getRefundAccount())); } } @@ -284,109 +194,4 @@ protected void checkConstraints() throws WxPayException { } } - public static final class Builder { - private String deviceInfo; - private String appid; - private String transactionId; - private String mchId; - private String subAppId; - private String outTradeNo; - private String subMchId; - private String outRefundNo; - private String nonceStr; - private Integer totalFee; - private String sign; - private Integer refundFee; - private String refundFeeType; - private String opUserId; - private String refundAccount; - private String refundDesc; - - private Builder() { - } - - public Builder deviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - return this; - } - - public Builder appid(String appid) { - this.appid = appid; - return this; - } - - public Builder transactionId(String transactionId) { - this.transactionId = transactionId; - return this; - } - - public Builder mchId(String mchId) { - this.mchId = mchId; - return this; - } - - public Builder subAppId(String subAppId) { - this.subAppId = subAppId; - return this; - } - - public Builder outTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - return this; - } - - public Builder subMchId(String subMchId) { - this.subMchId = subMchId; - return this; - } - - public Builder outRefundNo(String outRefundNo) { - this.outRefundNo = outRefundNo; - return this; - } - - public Builder nonceStr(String nonceStr) { - this.nonceStr = nonceStr; - return this; - } - - public Builder totalFee(Integer totalFee) { - this.totalFee = totalFee; - return this; - } - - public Builder sign(String sign) { - this.sign = sign; - return this; - } - - public Builder refundFee(Integer refundFee) { - this.refundFee = refundFee; - return this; - } - - public Builder refundFeeType(String refundFeeType) { - this.refundFeeType = refundFeeType; - return this; - } - - public Builder opUserId(String opUserId) { - this.opUserId = opUserId; - return this; - } - - public Builder refundAccount(String refundAccount) { - this.refundAccount = refundAccount; - return this; - } - - public Builder refundDesc(String refundDesc) { - this.refundDesc = refundDesc; - return this; - } - - public WxPayRefundRequest build() { - return new WxPayRefundRequest(this); - } - } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java index 8b3f88b9c9..494ac1f325 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java @@ -1,6 +1,7 @@ package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.*; import me.chanjar.weixin.common.annotation.Required; /** @@ -15,10 +16,15 @@ *
  • 描述 *
  • * - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayReportRequest extends WxPayBaseRequest { +public class WxPayReportRequest extends BaseWxPayRequest { /** *
        * 设备号
    @@ -32,19 +38,6 @@ public class WxPayReportRequest extends WxPayBaseRequest {
       @XStreamAlias("device_info")
       private String deviceInfo;
     
    -  /**
    -   * 
    -   * 签名类型
    -   * sign_type
    -   * 否
    -   * String(32)
    -   * HMAC-SHA256
    -   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
    -   * 
    - */ - @XStreamAlias("sign_type") - private String signType; - /** *
        * 接口URL
    @@ -175,102 +168,6 @@ public class WxPayReportRequest extends WxPayBaseRequest {
       @XStreamAlias("time")
       private String time;
     
    -  public String getDeviceInfo() {
    -    return deviceInfo;
    -  }
    -
    -  public void setDeviceInfo(String deviceInfo) {
    -    this.deviceInfo = deviceInfo;
    -  }
    -
    -  public String getSignType() {
    -    return signType;
    -  }
    -
    -  public void setSignType(String signType) {
    -    this.signType = signType;
    -  }
    -
    -  public String getInterfaceUrl() {
    -    return interfaceUrl;
    -  }
    -
    -  public void setInterfaceUrl(String interfaceUrl) {
    -    this.interfaceUrl = interfaceUrl;
    -  }
    -
    -  public Integer getExecuteTime() {
    -    return executeTime;
    -  }
    -
    -  public void setExecuteTime(Integer executeTime) {
    -    this.executeTime = executeTime;
    -  }
    -
    -  public String getReturnCode() {
    -    return returnCode;
    -  }
    -
    -  public void setReturnCode(String returnCode) {
    -    this.returnCode = returnCode;
    -  }
    -
    -  public String getReturnMsg() {
    -    return returnMsg;
    -  }
    -
    -  public void setReturnMsg(String returnMsg) {
    -    this.returnMsg = returnMsg;
    -  }
    -
    -  public String getResultCode() {
    -    return resultCode;
    -  }
    -
    -  public void setResultCode(String resultCode) {
    -    this.resultCode = resultCode;
    -  }
    -
    -  public String getErrCode() {
    -    return errCode;
    -  }
    -
    -  public void setErrCode(String errCode) {
    -    this.errCode = errCode;
    -  }
    -
    -  public String getErrCodeDes() {
    -    return errCodeDes;
    -  }
    -
    -  public void setErrCodeDes(String errCodeDes) {
    -    this.errCodeDes = errCodeDes;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
    -  public String getUserIp() {
    -    return userIp;
    -  }
    -
    -  public void setUserIp(String userIp) {
    -    this.userIp = userIp;
    -  }
    -
    -  public String getTime() {
    -    return time;
    -  }
    -
    -  public void setTime(String time) {
    -    this.time = time;
    -  }
    -
       @Override
       protected void checkConstraints() {
         //do nothing
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
    index f7082fc3da..4b868a95dc 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java
    @@ -1,24 +1,40 @@
     package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.AllArgsConstructor;
    +import lombok.Builder;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
    +import lombok.NoArgsConstructor;
     
     /**
    - * 发送红包请求参数对象
    + * 发送红包请求参数对象.
      * Created by Binary Wang on 2016/9/24.
      *
    - * @author binarywang (https://github.com/binarywang)
    + * @author Binary Wang
      */
    +@Data
    +@EqualsAndHashCode(callSuper = true)
    +@Builder(builderMethodName = "newBuilder")
    +@NoArgsConstructor
    +@AllArgsConstructor
     @XStreamAlias("xml")
    -public class WxPaySendRedpackRequest extends WxPayBaseRequest {
    +public class WxPaySendRedpackRequest extends BaseWxPayRequest {
    +  @Override
    +  protected String[] getIgnoredParamsForSign() {
    +    return new String[]{"sign_type"};
    +  }
    +
       /**
    -   * mch_billno
    -   * 商户订单号(每个订单号必须唯一)  组成:mch_id+yyyymmdd+10位一天内不能重复的数字。  接口根据商户订单号支持重入,如出现超时可再调用。
    +   * mch_billno.
    +   * 商户订单号(每个订单号必须唯一)
    +   * 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。  接口根据商户订单号支持重入,如出现超时可再调用。
        */
       @XStreamAlias("mch_billno")
       private String mchBillNo;
     
       /**
    -   * send_name
    +   * send_name.
        * 商户名称
        * 红包发送者名称
        */
    @@ -26,14 +42,14 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
       private String sendName;
     
       /**
    -   * re_openid
    +   * re_openid.
        * 接受红包的用户   用户在wxappid下的openid
        */
       @XStreamAlias("re_openid")
       private String reOpenid;
     
       /**
    -   * total_amount
    +   * total_amount.
        * 红包总额
        */
       @XStreamAlias("total_amount")
    @@ -47,7 +63,7 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
       private Integer totalNum;
     
       /**
    -   * amt_type
    +   * amt_type.
        * 红包金额设置方式
        * ALL_RAND—全部随机,商户指定总金额和红包发放总人数,由微信支付随机计算出各红包金额
        * 裂变红包必填
    @@ -56,14 +72,14 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
       private String amtType;
     
       /**
    -   * wishing
    +   * wishing.
        * 红包祝福语
        */
       @XStreamAlias("wishing")
       private String wishing;
     
       /**
    -   * client_ip
    +   * client_ip.
        * 服务器Ip地址
        * 调用接口的机器Ip地址
        */
    @@ -71,21 +87,21 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
       private String clientIp;
     
       /**
    -   * act_name
    +   * act_name.
        * 活动名称
        */
       @XStreamAlias("act_name")
       private String actName;
     
       /**
    -   * remark
    +   * remark.
        * 备注
        */
       @XStreamAlias("remark")
       private String remark;
     
       /**
    -   * wxappid
    +   * wxappid.
        * 微信分配的公众账号ID(企业号corpid即为此appId)。接口传入的所有appid应该为公众号的appid(在mp.weixin.qq.com申请的),不能为APP的appid(在open.weixin.qq.com申请的)
        */
       @XStreamAlias("wxappid")
    @@ -93,7 +109,7 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * scene_id
    +   * scene_id.
        * 场景id
        * PRODUCT_1:商品促销
        * PRODUCT_2:抽奖
    @@ -111,7 +127,7 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * risk_info
    +   * risk_info.
        * 活动信息
        * posttime:用户操作的时间戳
        * mobile:业务系统账号的手机号,国家代码-手机号。不需要+号
    @@ -127,7 +143,7 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * consume_mch_id
    +   * consume_mch_id.
        * 资金授权商户号
        * 资金授权商户号
        * 服务商替特约商户发放时使用
    @@ -137,85 +153,6 @@ public class WxPaySendRedpackRequest extends WxPayBaseRequest {
       @XStreamAlias("consume_mch_id")
       private String consumeMchId;
     
    -  public String getMchBillNo() {
    -    return mchBillNo;
    -  }
    -
    -  public void setMchBillNo(String mchBillNo) {
    -    this.mchBillNo = mchBillNo;
    -  }
    -
    -  public String getSendName() {
    -    return this.sendName;
    -  }
    -
    -  public void setSendName(String sendName) {
    -    this.sendName = sendName;
    -  }
    -
    -  public String getReOpenid() {
    -    return this.reOpenid;
    -  }
    -
    -  public void setReOpenid(String reOpenid) {
    -    this.reOpenid = reOpenid;
    -  }
    -
    -  public Integer getTotalAmount() {
    -    return this.totalAmount;
    -  }
    -
    -  public void setTotalAmount(Integer totalAmount) {
    -    this.totalAmount = totalAmount;
    -  }
    -
    -  public Integer getTotalNum() {
    -    return this.totalNum;
    -  }
    -
    -  public void setTotalNum(Integer totalNum) {
    -    this.totalNum = totalNum;
    -  }
    -
    -  public String getAmtType() {
    -    return this.amtType;
    -  }
    -
    -  public void setAmtType(String amtType) {
    -    this.amtType = amtType;
    -  }
    -
    -  public String getWishing() {
    -    return this.wishing;
    -  }
    -
    -  public void setWishing(String wishing) {
    -    this.wishing = wishing;
    -  }
    -
    -  public String getClientIp() {
    -    return this.clientIp;
    -  }
    -
    -  public void setClientIp(String clientIp) {
    -    this.clientIp = clientIp;
    -  }
    -
    -  public String getActName() {
    -    return this.actName;
    -  }
    -
    -  public void setActName(String actName) {
    -    this.actName = actName;
    -  }
    -
    -  public String getRemark() {
    -    return this.remark;
    -  }
    -
    -  public void setRemark(String remark) {
    -    this.remark = remark;
    -  }
     
       @Override
       protected void checkConstraints() {
    @@ -232,28 +169,4 @@ public void setAppid(String appid) {
         this.wxAppid = appid;
       }
     
    -  public String getSceneId() {
    -    return this.sceneId;
    -  }
    -
    -  public void setSceneId(String sceneId) {
    -    this.sceneId = sceneId;
    -  }
    -
    -  public String getRiskInfo() {
    -    return this.riskInfo;
    -  }
    -
    -  public void setRiskInfo(String riskInfo) {
    -    this.riskInfo = riskInfo;
    -  }
    -
    -  public String getConsumeMchId() {
    -    return this.consumeMchId;
    -  }
    -
    -  public void setConsumeMchId(String consumeMchId) {
    -    this.consumeMchId = consumeMchId;
    -  }
    -
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
    index 714e07ea43..87ac41054b 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
    @@ -1,16 +1,23 @@
     package com.github.binarywang.wxpay.bean.request;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     
     /**
      * 
      * 转换短链接请求对象类
      * Created by Binary Wang on 2017-3-27.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayShorturlRequest extends WxPayBaseRequest { +public class WxPayShorturlRequest extends BaseWxPayRequest { /** *
        * URL链接
    @@ -24,21 +31,6 @@ public class WxPayShorturlRequest extends WxPayBaseRequest {
       @XStreamAlias("long_url")
       private String longUrl;
     
    -  public WxPayShorturlRequest() {
    -  }
    -
    -  public WxPayShorturlRequest(String longUrl) {
    -    this.longUrl = longUrl;
    -  }
    -
    -  public String getLongUrl() {
    -    return this.longUrl;
    -  }
    -
    -  public void setLongUrl(String longUrl) {
    -    this.longUrl = longUrl;
    -  }
    -
       @Override
       protected void checkConstraints() {
         //do nothing
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
    index 8061556cc7..4ef7ab446a 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
    @@ -1,27 +1,49 @@
     package com.github.binarywang.wxpay.bean.request;
     
     import com.github.binarywang.wxpay.config.WxPayConfig;
    +import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType;
     import com.github.binarywang.wxpay.exception.WxPayException;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.*;
     import me.chanjar.weixin.common.annotation.Required;
     import org.apache.commons.lang3.StringUtils;
     
     /**
      * 
    - * 统一下单请求参数对象
    + * 统一下单请求参数对象.
      * 参考文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
    - * 
    * Created by Binary Wang on 2016/9/25. + *
    * - * @author binarywang (https://github.com/binarywang) + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor @XStreamAlias("xml") -public class WxPayUnifiedOrderRequest extends WxPayBaseRequest { - private static final String[] TRADE_TYPES = new String[]{"JSAPI", "NATIVE", "APP", "MWEB"}; +public class WxPayUnifiedOrderRequest extends BaseWxPayRequest { + private static final long serialVersionUID = 4611350167813931828L; /** *
    -   * 字段名:设备号
    +   * 字段名:接口版本号.
    +   * 变量名:version
    +   * 是否必填:单品优惠必填
    +   * 类型:String(32)
    +   * 示例值:1.0
    +   * 描述:单品优惠新增字段,接口版本号,区分原接口,默认填写1.0。
    +   * 入参新增version后,则支付通知接口也将返回单品优惠信息字段promotion_detail,请确保支付通知的签名验证能通过。
    +   * 更多信息,详见文档:https://pay.weixin.qq.com/wiki/doc/api/danpin.php?chapter=9_102&index=2
    +   * 
    + */ + @XStreamAlias("version") + private String version; + + /** + *
    +   * 字段名:设备号.
        * 变量名:device_info
        * 是否必填:否
        * 类型:String(32)
    @@ -34,7 +56,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:商品描述
    +   * 字段名:商品描述.
        * 变量名:body
        * 是否必填:是
        * 类型:String(128)
    @@ -48,7 +70,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:商品详情
    +   * 字段名:商品详情.
        * 变量名:detail
        * 是否必填:否
        * 类型:String(6000)
    @@ -89,7 +111,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:附加数据
    +   * 字段名:附加数据.
        * 变量名:attach
        * 是否必填:否
        * 类型:String(127)
    @@ -102,7 +124,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:商户订单号
    +   * 字段名:商户订单号.
        * 变量名:out_trade_no
        * 是否必填:是
        * 类型:String(32)
    @@ -116,7 +138,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:货币类型
    +   * 字段名:货币类型.
        * 变量名:fee_type
        * 是否必填:否
        * 类型:String(16)
    @@ -129,7 +151,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:总金额
    +   * 字段名:总金额.
        * 变量名:total_fee
        * 是否必填:是
        * 类型:Int
    @@ -143,7 +165,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:终端IP
    +   * 字段名:终端IP.
        * 变量名:spbill_create_ip
        * 是否必填:是
        * 类型:String(16)
    @@ -157,7 +179,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:交易起始时间
    +   * 字段名:交易起始时间.
        * 变量名:time_start
        * 是否必填:否
        * 类型:String(14)
    @@ -170,7 +192,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:交易结束时间
    +   * 字段名:交易结束时间.
        * 变量名:time_expire
        * 是否必填:否
        * 类型:String(14)
    @@ -184,7 +206,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:商品标记
    +   * 字段名:商品标记.
        * 变量名:goods_tag
        * 是否必填:否
        * 类型:String(32)
    @@ -197,7 +219,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:通知地址
    +   * 字段名:通知地址.
        * 变量名:notify_url
        * 是否必填:是
        * 类型:String(256)
    @@ -207,11 +229,11 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
        */
       @Required
       @XStreamAlias("notify_url")
    -  private String notifyURL;
    +  private String notifyUrl;
     
       /**
        * 
    -   * 字段名:交易类型
    +   * 字段名:交易类型.
        * 变量名:trade_type
        * 是否必填:是
        * 类型:String(16)
    @@ -226,7 +248,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:商品Id
    +   * 字段名:商品Id.
        * 变量名:product_id
        * 是否必填:否
        * 类型:String(32)
    @@ -239,7 +261,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:指定支付方式
    +   * 字段名:指定支付方式.
        * 变量名:limit_pay
        * 是否必填:否
        * 类型:String(32)
    @@ -252,7 +274,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:用户标识
    +   * 字段名:用户标识.
        * 变量名:openid
        * 是否必填:否
        * 类型:String(128)
    @@ -267,7 +289,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:用户子标识
    +   * 字段名:用户子标识.
        * 变量名:sub_openid
        * 是否必填:否
        * 类型:String(128)
    @@ -282,7 +304,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
     
       /**
        * 
    -   * 字段名:场景信息
    +   * 字段名:场景信息.
        * 变量名:scene_info
        * 是否必填:否,对H5支付来说是必填
        * 类型:String(256)
    @@ -301,7 +323,7 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
       private String sceneInfo;
       /**
        * 
    -   * 字段名:浏览器指纹
    +   * 字段名:浏览器指纹.
        * 变量名:fingerprint
        * 是否必填:否
        * 详细参考 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_7&index=6
    @@ -310,148 +332,17 @@ public class WxPayUnifiedOrderRequest extends WxPayBaseRequest {
       @XStreamAlias("fingerprint")
       private String fingerprint;
     
    -  public WxPayUnifiedOrderRequest() {
    -  }
    -
    -  private WxPayUnifiedOrderRequest(Builder builder) {
    -    setDeviceInfo(builder.deviceInfo);
    -    setAppid(builder.appid);
    -    setBody(builder.body);
    -    setMchId(builder.mchId);
    -    setSubAppId(builder.subAppId);
    -    setSubMchId(builder.subMchId);
    -    setNonceStr(builder.nonceStr);
    -    setSign(builder.sign);
    -    setDetail(builder.detail);
    -    setAttach(builder.attach);
    -    setOutTradeNo(builder.outTradeNo);
    -    setFeeType(builder.feeType);
    -    setTotalFee(builder.totalFee);
    -    setSpbillCreateIp(builder.spbillCreateIp);
    -    setTimeStart(builder.timeStart);
    -    setTimeExpire(builder.timeExpire);
    -    setGoodsTag(builder.goodsTag);
    -    setNotifyURL(builder.notifyURL);
    -    setTradeType(builder.tradeType);
    -    setProductId(builder.productId);
    -    setLimitPay(builder.limitPay);
    -    setOpenid(builder.openid);
    -    setSubOpenid(builder.subOpenid);
    -    setSceneInfo(builder.sceneInfo);
    -    fingerprint = builder.fingerprint;
    -  }
    -
    -  public static Builder newBuilder() {
    -    return new Builder();
    -  }
    -
    -  public String getDeviceInfo() {
    -    return this.deviceInfo;
    -  }
    -
    -  public void setDeviceInfo(String deviceInfo) {
    -    this.deviceInfo = deviceInfo;
    -  }
    -
    -  public String getBody() {
    -    return this.body;
    -  }
    -
    -  public void setBody(String body) {
    -    this.body = body;
    -  }
    -
    -  public String getDetail() {
    -    return this.detail;
    -  }
    -
    -  public void setDetail(String detail) {
    -    this.detail = detail;
    -  }
    -
    -  public String getAttach() {
    -    return this.attach;
    -  }
    -
    -  public void setAttach(String attach) {
    -    this.attach = attach;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return this.outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
    -  public String getFeeType() {
    -    return this.feeType;
    -  }
    -
    -  public void setFeeType(String feeType) {
    -    this.feeType = feeType;
    -  }
    -
    -  public Integer getTotalFee() {
    -    return this.totalFee;
    -  }
    -
    -  public void setTotalFee(Integer totalFee) {
    -    this.totalFee = totalFee;
    -  }
    -
    -  public String getSpbillCreateIp() {
    -    return this.spbillCreateIp;
    -  }
    -
    -  public void setSpbillCreateIp(String spbillCreateIp) {
    -    this.spbillCreateIp = spbillCreateIp;
    -  }
    -
    -  public String getTimeStart() {
    -    return this.timeStart;
    -  }
    -
    -  public void setTimeStart(String timeStart) {
    -    this.timeStart = timeStart;
    -  }
    -
    -  public String getTimeExpire() {
    -    return this.timeExpire;
    -  }
    -
    -  public void setTimeExpire(String timeExpire) {
    -    this.timeExpire = timeExpire;
    -  }
    -
    -  public String getGoodsTag() {
    -    return this.goodsTag;
    -  }
    -
    -  public void setGoodsTag(String goodsTag) {
    -    this.goodsTag = goodsTag;
    -  }
    -
    -  public String getNotifyURL() {
    -    return this.notifyURL;
    -  }
    -
       /**
    -   * 如果配置中已经设置,可以不设置值
    +   * 如果配置中已经设置,可以不设置值.
        *
    -   * @param notifyURL
    +   * @param notifyUrl 支付回调通知地址
        */
    -  public void setNotifyURL(String notifyURL) {
    -    this.notifyURL = notifyURL;
    -  }
    -
    -  public String getTradeType() {
    -    return this.tradeType;
    +  public void setNotifyUrl(String notifyUrl) {
    +    this.notifyUrl = notifyUrl;
       }
     
       /**
    -   * 如果配置中已经设置,可以不设置值
    +   * 如果配置中已经设置,可以不设置值.
        *
        * @param tradeType 交易类型
        */
    @@ -459,66 +350,17 @@ public void setTradeType(String tradeType) {
         this.tradeType = tradeType;
       }
     
    -  public String getProductId() {
    -    return this.productId;
    -  }
    -
    -  public void setProductId(String productId) {
    -    this.productId = productId;
    -  }
    -
    -  public String getLimitPay() {
    -    return this.limitPay;
    -  }
    -
    -  public void setLimitPay(String limitPay) {
    -    this.limitPay = limitPay;
    -  }
    -
    -  public String getOpenid() {
    -    return this.openid;
    -  }
    -
    -  public void setOpenid(String openid) {
    -    this.openid = openid;
    -  }
    -
    -  public String getSubOpenid() {
    -    return this.subOpenid;
    -  }
    -
    -  public void setSubOpenid(String subOpenid) {
    -    this.subOpenid = subOpenid;
    -  }
    -
    -  public String getSceneInfo() {
    -    return this.sceneInfo;
    -  }
    -
    -  public void setSceneInfo(String sceneInfo) {
    -    this.sceneInfo = sceneInfo;
    -  }
    -
       @Override
       protected void checkConstraints() throws WxPayException {
    -//    if (!ArrayUtils.contains(TRADE_TYPES, this.getTradeType())) {
    -//      throw new WxPayException(String.format("trade_type目前必须为%s其中之一,实际值:%s",
    -//        Arrays.toString(TRADE_TYPES), this.getTradeType()));
    -//    }
    -
    -    if ("JSAPI".equals(this.getTradeType()) && this.getOpenid() == null) {
    -      throw new WxPayException("当 trade_type是'JSAPI'时未指定openid");
    -    }
    -
    -    if ("NATIVE".equals(this.getTradeType()) && this.getProductId() == null) {
    -      throw new WxPayException("当 trade_type是'NATIVE'时未指定product_id");
    +    if (TradeType.NATIVE.equals(this.getTradeType()) && StringUtils.isBlank(this.getProductId())) {
    +      throw new WxPayException("当trade_type是'NATIVE'时,需指定非空的product_id值");
         }
       }
     
       @Override
       public void checkAndSign(WxPayConfig config) throws WxPayException {
    -    if (StringUtils.isBlank(this.getNotifyURL())) {
    -      this.setNotifyURL(config.getNotifyUrl());
    +    if (StringUtils.isBlank(this.getNotifyUrl())) {
    +      this.setNotifyUrl(config.getNotifyUrl());
         }
     
         if (StringUtils.isBlank(this.getTradeType())) {
    @@ -528,163 +370,4 @@ public void checkAndSign(WxPayConfig config) throws WxPayException {
         super.checkAndSign(config);
       }
     
    -  public static final class Builder {
    -    private String appid;
    -    private String mchId;
    -    private String subAppId;
    -    private String subMchId;
    -    private String nonceStr;
    -    private String sign;
    -    private String deviceInfo;
    -    private String body;
    -    private String detail;
    -    private String attach;
    -    private String outTradeNo;
    -    private String feeType;
    -    private Integer totalFee;
    -    private String spbillCreateIp;
    -    private String timeStart;
    -    private String timeExpire;
    -    private String goodsTag;
    -    private String notifyURL;
    -    private String tradeType;
    -    private String productId;
    -    private String limitPay;
    -    private String openid;
    -    private String subOpenid;
    -    private String sceneInfo;
    -    private String fingerprint;
    -
    -    private Builder() {
    -    }
    -
    -    public Builder appid(String appid) {
    -      this.appid = appid;
    -      return this;
    -    }
    -
    -    public Builder mchId(String mchId) {
    -      this.mchId = mchId;
    -      return this;
    -    }
    -
    -    public Builder subAppId(String subAppId) {
    -      this.subAppId = subAppId;
    -      return this;
    -    }
    -
    -    public Builder subMchId(String subMchId) {
    -      this.subMchId = subMchId;
    -      return this;
    -    }
    -
    -    public Builder nonceStr(String nonceStr) {
    -      this.nonceStr = nonceStr;
    -      return this;
    -    }
    -
    -    public Builder sign(String sign) {
    -      this.sign = sign;
    -      return this;
    -    }
    -
    -    public Builder deviceInfo(String deviceInfo) {
    -      this.deviceInfo = deviceInfo;
    -      return this;
    -    }
    -
    -    public Builder body(String body) {
    -      this.body = body;
    -      return this;
    -    }
    -
    -    public Builder detail(String detail) {
    -      this.detail = detail;
    -      return this;
    -    }
    -
    -    public Builder attach(String attach) {
    -      this.attach = attach;
    -      return this;
    -    }
    -
    -    public Builder outTradeNo(String outTradeNo) {
    -      this.outTradeNo = outTradeNo;
    -      return this;
    -    }
    -
    -    public Builder feeType(String feeType) {
    -      this.feeType = feeType;
    -      return this;
    -    }
    -
    -    public Builder totalFee(Integer totalFee) {
    -      this.totalFee = totalFee;
    -      return this;
    -    }
    -
    -    public Builder spbillCreateIp(String spbillCreateIp) {
    -      this.spbillCreateIp = spbillCreateIp;
    -      return this;
    -    }
    -
    -    public Builder timeStart(String timeStart) {
    -      this.timeStart = timeStart;
    -      return this;
    -    }
    -
    -    public Builder timeExpire(String timeExpire) {
    -      this.timeExpire = timeExpire;
    -      return this;
    -    }
    -
    -    public Builder goodsTag(String goodsTag) {
    -      this.goodsTag = goodsTag;
    -      return this;
    -    }
    -
    -    public Builder notifyURL(String notifyURL) {
    -      this.notifyURL = notifyURL;
    -      return this;
    -    }
    -
    -    public Builder tradeType(String tradeType) {
    -      this.tradeType = tradeType;
    -      return this;
    -    }
    -
    -    public Builder productId(String productId) {
    -      this.productId = productId;
    -      return this;
    -    }
    -
    -    public Builder limitPay(String limitPay) {
    -      this.limitPay = limitPay;
    -      return this;
    -    }
    -
    -    public Builder openid(String openid) {
    -      this.openid = openid;
    -      return this;
    -    }
    -
    -    public Builder subOpenid(String subOpenid) {
    -      this.subOpenid = subOpenid;
    -      return this;
    -    }
    -
    -    public Builder sceneInfo(String sceneInfo) {
    -      this.sceneInfo = sceneInfo;
    -      return this;
    -    }
    -
    -    public Builder fingerprint(String fingerprint) {
    -      this.fingerprint = fingerprint;
    -      return this;
    -    }
    -
    -    public WxPayUnifiedOrderRequest build() {
    -      return new WxPayUnifiedOrderRequest(this);
    -    }
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java
    similarity index 51%
    rename from weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java
    index d4b96dc408..ad014fc2a9 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java
    @@ -1,46 +1,54 @@
     package com.github.binarywang.wxpay.bean.result;
     
    -import com.github.binarywang.wxpay.exception.WxPayException;
    -import com.github.binarywang.wxpay.service.impl.WxPayServiceAbstractImpl;
    -import com.github.binarywang.wxpay.util.SignUtils;
    -import com.google.common.base.Joiner;
    -import com.google.common.collect.Maps;
    -import com.thoughtworks.xstream.XStream;
    -import com.thoughtworks.xstream.annotations.XStreamAlias;
    -import me.chanjar.weixin.common.util.ToStringUtils;
    -import me.chanjar.weixin.common.util.xml.XStreamInitializer;
    +import java.io.ByteArrayInputStream;
    +import java.io.IOException;
    +import java.io.Serializable;
    +import java.math.BigDecimal;
    +import java.util.List;
    +import java.util.Map;
    +import javax.xml.parsers.DocumentBuilderFactory;
    +import javax.xml.parsers.ParserConfigurationException;
    +import javax.xml.xpath.XPathConstants;
    +import javax.xml.xpath.XPathExpressionException;
    +import javax.xml.xpath.XPathFactory;
    +
     import org.apache.commons.lang3.StringUtils;
    +import org.apache.commons.lang3.builder.ToStringBuilder;
    +import org.apache.commons.lang3.builder.ToStringStyle;
     import org.slf4j.Logger;
     import org.slf4j.LoggerFactory;
     import org.w3c.dom.Document;
     import org.w3c.dom.NodeList;
     import org.xml.sax.SAXException;
     
    -import javax.xml.parsers.DocumentBuilderFactory;
    -import javax.xml.parsers.ParserConfigurationException;
    -import javax.xml.xpath.XPathConstants;
    -import javax.xml.xpath.XPathExpressionException;
    -import javax.xml.xpath.XPathFactory;
    -import java.io.ByteArrayInputStream;
    -import java.io.IOException;
    -import java.math.BigDecimal;
    -import java.util.Map;
    +import com.github.binarywang.wxpay.exception.WxPayException;
    +import com.github.binarywang.wxpay.service.WxPayService;
    +import com.github.binarywang.wxpay.util.SignUtils;
    +import com.google.common.base.Joiner;
    +import com.google.common.collect.Lists;
    +import com.google.common.collect.Maps;
    +import com.thoughtworks.xstream.XStream;
    +import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.Data;
    +import me.chanjar.weixin.common.util.xml.XStreamInitializer;
     
     /**
      * 
    - * 微信支付结果共用属性类
    + * 微信支付结果共用属性类.
      * Created by Binary Wang on 2016-10-24.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ -public abstract class WxPayBaseResult { +@Data +public abstract class BaseWxPayResult implements Serializable { /** - * 返回状态码 + * 返回状态码. */ @XStreamAlias("return_code") protected String returnCode; /** - * 返回信息 + * 返回信息. */ @XStreamAlias("return_msg") protected String returnMsg; @@ -48,75 +56,81 @@ public abstract class WxPayBaseResult { //当return_code为SUCCESS的时候,还会包括以下字段: /** - * 业务结果 + * 业务结果. */ @XStreamAlias("result_code") private String resultCode; /** - * 错误代码 + * 错误代码. */ @XStreamAlias("err_code") private String errCode; /** - * 错误代码描述 + * 错误代码描述. */ @XStreamAlias("err_code_des") private String errCodeDes; /** - * 公众账号ID + * 公众账号ID. */ @XStreamAlias("appid") private String appid; /** - * 商户号 + * 商户号. */ @XStreamAlias("mch_id") private String mchId; /** - * 服务商模式下的子公众账号ID + * 服务商模式下的子公众账号ID. */ @XStreamAlias("sub_appid") private String subAppId; /** - * 服务商模式下的子商户号 + * 服务商模式下的子商户号. */ @XStreamAlias("sub_mch_id") private String subMchId; /** - * 随机字符串 + * 随机字符串. */ @XStreamAlias("nonce_str") private String nonceStr; /** - * 签名 + * 签名. */ @XStreamAlias("sign") private String sign; //以下为辅助属性 /** - * xml字符串 + * xml字符串. */ private String xmlString; /** - * xml的Document对象,用于解析xml文本 + * xml的Document对象,用于解析xml文本. */ private Document xmlDoc; /** - * 将单位分转换成单位圆 + * 将单位分转换成单位圆. * - * @param fee 将要被转换为元的分的数值 + * @param fen 将要被转换为元的分的数值 + * @return the string */ - public static String feeToYuan(Integer fee) { - return new BigDecimal(Double.valueOf(fee) / 100).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); + public static String fenToYuan(Integer fen) { + return BigDecimal.valueOf(Double.valueOf(fen) / 100).setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString(); } /** - * 从xml字符串创建bean对象 + * 从xml字符串创建bean对象. + * + * @param the type parameter + * @param xmlString the xml string + * @param clz the clz + * @return the t */ - public static T fromXML(String xmlString, Class clz) { + public static T fromXML(String xmlString, Class clz) { XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(clz); T result = (T) xstream.fromXML(xmlString); @@ -124,113 +138,24 @@ public static T fromXML(String xmlString, Class c return result; } - public String getXmlString() { - return this.xmlString; - } - - public void setXmlString(String xmlString) { - this.xmlString = xmlString; - } - + /** + * Gets logger. + * + * @return the logger + */ protected Logger getLogger() { return LoggerFactory.getLogger(this.getClass()); } @Override public String toString() { - return ToStringUtils.toSimpleString(this); - } - - public String getReturnCode() { - return this.returnCode; - } - - public void setReturnCode(String returnCode) { - this.returnCode = returnCode; - } - - public String getReturnMsg() { - return this.returnMsg; - } - - public void setReturnMsg(String returnMsg) { - this.returnMsg = returnMsg; - } - - public String getResultCode() { - return this.resultCode; - } - - public void setResultCode(String resultCode) { - this.resultCode = resultCode; - } - - public String getErrCode() { - return this.errCode; - } - - public void setErrCode(String errCode) { - this.errCode = errCode; - } - - public String getErrCodeDes() { - return this.errCodeDes; - } - - public void setErrCodeDes(String errCodeDes) { - this.errCodeDes = errCodeDes; - } - - public String getAppid() { - return this.appid; - } - - public void setAppid(String appid) { - this.appid = appid; - } - - public String getMchId() { - return this.mchId; - } - - public void setMchId(String mchId) { - this.mchId = mchId; - } - - public String getNonceStr() { - return this.nonceStr; - } - - public void setNonceStr(String nonceStr) { - this.nonceStr = nonceStr; - } - - public String getSign() { - return this.sign; - } - - public void setSign(String sign) { - this.sign = sign; - } - - public String getSubAppId() { - return subAppId; - } - - public void setSubAppId(String subAppId) { - this.subAppId = subAppId; - } - - public String getSubMchId() { - return subMchId; - } - - public void setSubMchId(String subMchId) { - this.subMchId = subMchId; + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); } /** - * 将bean通过保存的xml字符串转换成map + * 将bean通过保存的xml字符串转换成map. + * + * @return the map */ public Map toMap() { if (StringUtils.isBlank(this.xmlString)) { @@ -256,9 +181,9 @@ public Map toMap() { } /** - * 将xml字符串转换成Document对象,以便读取其元素值 + * 将xml字符串转换成Document对象,以便读取其元素值. */ - protected Document getXmlDoc() { + private Document getXmlDoc() { if (this.xmlDoc != null) { return this.xmlDoc; } @@ -276,9 +201,12 @@ protected Document getXmlDoc() { } /** - * 获取xml中元素的值 + * 获取xml中元素的值. + * + * @param path the path + * @return the xml value */ - protected String getXmlValue(String... path) { + String getXmlValue(String... path) { Document doc = this.getXmlDoc(); String expression = String.format("/%s//text()", Joiner.on("/").join(path)); try { @@ -293,9 +221,12 @@ protected String getXmlValue(String... path) { } /** - * 获取xml中元素的值,作为int值返回 + * 获取xml中元素的值,作为int值返回. + * + * @param path the path + * @return the xml value as int */ - protected Integer getXmlValueAsInt(String... path) { + Integer getXmlValueAsInt(String... path) { String result = this.getXmlValue(path); if (StringUtils.isBlank(result)) { return null; @@ -305,38 +236,46 @@ protected Integer getXmlValueAsInt(String... path) { } /** - * 校验返回结果签名 + * 校验返回结果签名. + * + * @param wxPayService the wx pay service + * @param signType 签名类型 + * @param checkSuccess 是否同时检查结果是否成功 + * @throws WxPayException the wx pay exception */ - public void checkResult(WxPayServiceAbstractImpl wxPayService) throws WxPayException { + public void checkResult(WxPayService wxPayService, String signType, boolean checkSuccess) throws WxPayException { //校验返回结果签名 Map map = toMap(); - if (getSign() != null && !SignUtils.checkSign(map, wxPayService.getConfig().getMchKey())) { + if (getSign() != null && !SignUtils.checkSign(map, signType, wxPayService.getConfig().getMchKey())) { this.getLogger().debug("校验结果签名失败,参数:{}", map); throw new WxPayException("参数格式校验错误!"); } //校验结果是否成功 - if (!StringUtils.equalsAny(StringUtils.trimToEmpty(getReturnCode()).toUpperCase(), "SUCCESS", "") - || !StringUtils.equalsAny(StringUtils.trimToEmpty(getResultCode()).toUpperCase(), "SUCCESS", "")) { - StringBuilder errorMsg = new StringBuilder(); - if (getReturnCode() != null) { - errorMsg.append("返回代码:").append(getReturnCode()); + if (checkSuccess) { + List successStrings = Lists.newArrayList("SUCCESS", ""); + if (!successStrings.contains(StringUtils.trimToEmpty(getReturnCode()).toUpperCase()) + || !successStrings.contains(StringUtils.trimToEmpty(getResultCode()).toUpperCase())) { + StringBuilder errorMsg = new StringBuilder(); + if (getReturnCode() != null) { + errorMsg.append("返回代码:").append(getReturnCode()); + } + if (getReturnMsg() != null) { + errorMsg.append(",返回信息:").append(getReturnMsg()); + } + if (getResultCode() != null) { + errorMsg.append(",结果代码:").append(getResultCode()); + } + if (getErrCode() != null) { + errorMsg.append(",错误代码:").append(getErrCode()); + } + if (getErrCodeDes() != null) { + errorMsg.append(",错误详情:").append(getErrCodeDes()); + } + + this.getLogger().error("\n结果业务代码异常,返回结果:{},\n{}", map, errorMsg.toString()); + throw WxPayException.from(this); } - if (getReturnMsg() != null) { - errorMsg.append(",返回信息:").append(getReturnMsg()); - } - if (getResultCode() != null) { - errorMsg.append(",结果代码:").append(getResultCode()); - } - if (getErrCode() != null) { - errorMsg.append(",错误代码:").append(getErrCode()); - } - if (getErrCodeDes() != null) { - errorMsg.append(",错误详情:").append(getErrCodeDes()); - } - - this.getLogger().error("\n结果业务代码异常,返回結果:{},\n{}", map, errorMsg.toString()); - throw WxPayException.from(this); } } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayQueryResult.java deleted file mode 100644 index dac69e17c4..0000000000 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayQueryResult.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.github.binarywang.wxpay.bean.result; - -import com.thoughtworks.xstream.annotations.XStreamAlias; - -/** - * 企业付款查询返回结果 - * Created by Binary Wang on 2016/10/19. - * - * @author binarywang (https://github.com/binarywang) - */ -@XStreamAlias("xml") -public class WxEntPayQueryResult extends WxPayBaseResult { - - /** - * 商户订单号 - */ - @XStreamAlias("partner_trade_no") - private String partnerTradeNo; - - /** - * 付款单号 - */ - @XStreamAlias("detail_id") - private String detailId; - - /** - * 转账状态 - */ - @XStreamAlias("status") - private String status; - - /** - * 失败原因 - */ - @XStreamAlias("reason") - private String reason; - - /** - * 收款用户openid - */ - @XStreamAlias("openid") - private String openid; - - /** - * 收款用户姓名 - */ - @XStreamAlias("transfer_name") - private String transferName; - - /** - * 付款金额 - */ - @XStreamAlias("payment_amount") - private Integer paymentAmount; - - /** - * 转账时间 - */ - @XStreamAlias("transfer_time") - private String transferTime; - - /** - * 付款描述 - */ - @XStreamAlias("desc") - private String desc; - - public String getPartnerTradeNo() { - return this.partnerTradeNo; - } - - public void setPartnerTradeNo(String partnerTradeNo) { - this.partnerTradeNo = partnerTradeNo; - } - - public String getDetailId() { - return this.detailId; - } - - public void setDetailId(String detailId) { - this.detailId = detailId; - } - - public String getStatus() { - return this.status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getReason() { - return this.reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - - public String getOpenid() { - return this.openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public String getTransferName() { - return this.transferName; - } - - public void setTransferName(String transferName) { - this.transferName = transferName; - } - - public Integer getPaymentAmount() { - return this.paymentAmount; - } - - public void setPaymentAmount(Integer paymentAmount) { - this.paymentAmount = paymentAmount; - } - - public String getTransferTime() { - return this.transferTime; - } - - public void setTransferTime(String transferTime) { - this.transferTime = transferTime; - } - - public String getDesc() { - return this.desc; - } - - public void setDesc(String desc) { - this.desc = desc; - } -} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayResult.java deleted file mode 100644 index fa0a4e5fdc..0000000000 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxEntPayResult.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.github.binarywang.wxpay.bean.result; - -import com.thoughtworks.xstream.annotations.XStreamAlias; - -/** - * 企业付款返回结果 - * Created by Binary Wang on 2016/10/02. - * - * @author binarywang (https://github.com/binarywang) - */ -@XStreamAlias("xml") -public class WxEntPayResult extends WxPayBaseResult { - - /** - * 商户appid - */ - @XStreamAlias("mch_appid") - private String mchAppid; - - /** - * 设备号 - */ - @XStreamAlias("device_info") - private String deviceInfo; - - //############以下字段在return_code 和result_code都为SUCCESS的时候有返回############## - /** - * 商户订单号 - */ - @XStreamAlias("partner_trade_no") - private String partnerTradeNo; - - /** - * 微信订单号 - */ - @XStreamAlias("payment_no") - private String paymentNo; - - /** - * 微信支付成功时间 - */ - @XStreamAlias("payment_time") - private String paymentTime; - - public String getMchAppid() { - return this.mchAppid; - } - - public void setMchAppid(String mchAppid) { - this.mchAppid = mchAppid; - } - - public String getDeviceInfo() { - return this.deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public String getPartnerTradeNo() { - return this.partnerTradeNo; - } - - public void setPartnerTradeNo(String partnerTradeNo) { - this.partnerTradeNo = partnerTradeNo; - } - - public String getPaymentNo() { - return this.paymentNo; - } - - public void setPaymentNo(String paymentNo) { - this.paymentNo = paymentNo; - } - - public String getPaymentTime() { - return this.paymentTime; - } - - public void setPaymentTime(String paymentTime) { - this.paymentTime = paymentTime; - } -} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java index f56c61a77f..2c36d32f03 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java @@ -1,19 +1,26 @@ package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; /** *
      *  授权码查询openid接口请求结果类
      * Created by Binary Wang on 2017-3-27.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayAuthcode2OpenidResult extends WxPayBaseResult { +public class WxPayAuthcode2OpenidResult extends BaseWxPayResult { /** *
    -   *   用户标识
    +   *   用户标识.
        *   openid
        *   是
        *   String(128)
    @@ -23,18 +30,4 @@ public class WxPayAuthcode2OpenidResult extends WxPayBaseResult {
       @XStreamAlias("openid")
       private String openid;
     
    -  public WxPayAuthcode2OpenidResult() {
    -  }
    -
    -  public WxPayAuthcode2OpenidResult(String openid) {
    -    this.openid = openid;
    -  }
    -
    -  public String getOpenid() {
    -    return this.openid;
    -  }
    -
    -  public void setOpenid(String openid) {
    -    this.openid = openid;
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillBaseResult.java
    index e469ff4538..a9b3e46c21 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillBaseResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillBaseResult.java
    @@ -2,304 +2,124 @@
     
     import java.io.Serializable;
     
    +import org.apache.commons.lang3.builder.ToStringBuilder;
    +import org.apache.commons.lang3.builder.ToStringStyle;
    +
    +import lombok.Data;
    +import lombok.NoArgsConstructor;
    +
    +/**
    + * 交易时间:2017-04-06 01:00:02 公众账号ID: 商户号: 子商户号:0 设备号:WEB 微信订单号: 商户订单号:2017040519091071873216 用户标识: 交易类型:NATIVE
    + * 交易状态:REFUND 付款银行:CFT 货币种类:CNY 总金额:0.00 企业红包金额:0.00 微信退款单号: 商户退款单号:20170406010000933 退款金额:0.01 企业红包退款金额:0.00
    + * 退款类型:ORIGINAL 退款状态:SUCCESS 商品名称: 商户数据包: 手续费:0.00000 费率 :0.60%
    + *
    + * @author BinaryWang
    + */
    +@Data
    +@NoArgsConstructor
     public class WxPayBillBaseResult implements Serializable {
    -  /*
    -   * 交易时间:2017-04-06 01:00:02 公众账号ID: 商户号: 子商户号:0 设备号:WEB 微信订单号: 商户订单号:2017040519091071873216 用户标识: 交易类型:NATIVE
    -   * 交易状态:REFUND 付款银行:CFT 货币种类:CNY 总金额:0.00 企业红包金额:0.00 微信退款单号: 商户退款单号:20170406010000933 退款金额:0.01 企业红包退款金额:0.00
    -   * 退款类型:ORIGINAL 退款状态:SUCCESS 商品名称: 商户数据包: 手续费:0.00000 费率 :0.60%
    -   */
    -  private static final long serialVersionUID = 1L;
    +  private static final long serialVersionUID = 2226245109137435453L;
    +
    +  @Override
    +  public String toString() {
    +    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
    +  }
    +
       /**
    -   * 交易时间
    +   * 交易时间.
        */
       private String tradeTime;
       /**
    -   * 公众账号ID
    +   * 公众账号ID.
        */
       private String appId;
       /**
    -   * 商户号
    +   * 商户号.
        */
       private String mchId;
       /**
    -   * 子商户号
    +   * 子商户号.
        */
       private String subMchId;
       /**
    -   * 设备号
    +   * 设备号.
        */
       private String deviceInfo;
       /**
    -   * 微信订单号
    +   * 微信订单号.
        */
    -  private String transationId;
    +  private String transactionId;
       /**
    -   * 商户订单号
    +   * 商户订单号.
        */
       private String outTradeNo;
       /**
    -   * 用户标识
    +   * 用户标识.
        */
       private String openId;
       /**
    -   * 交易类型
    +   * 交易类型.
        */
       private String tradeType;
       /**
    -   * 交易状态
    +   * 交易状态.
        */
       private String tradeState;
       /**
    -   * 付款银行
    +   * 付款银行.
        */
       private String bankType;
       /**
    -   * 货币种类
    +   * 货币种类.
        */
       private String feeType;
       /**
    -   * 总金额
    +   * 总金额.
        */
       private String totalFee;
       /**
    -   * 企业红包金额
    +   * 企业红包金额.
        */
       private String couponFee;
       /**
    -   * 微信退款单号
    +   * 微信退款单号.
        */
       private String refundId;
       /**
    -   * 商户退款单号
    +   * 商户退款单号.
        */
       private String outRefundNo;
       /**
    -   * 退款金额
    +   * 退款金额.
        */
       private String settlementRefundFee;
       /**
    -   * 企业红包退款金额
    +   * 企业红包退款金额.
        */
       private String couponRefundFee;
       /**
    -   * 退款类型
    +   * 退款类型.
        */
       private String refundChannel;
       /**
    -   * 退款状态
    +   * 退款状态.
        */
       private String refundState;
       /**
    -   * 商品名称
    +   * 商品名称.
        */
       private String body;
       /**
    -   * 商户数据包
    +   * 商户数据包.
        */
       private String attach;
       /**
    -   * 手续费
    +   * 手续费.
        */
       private String poundage;
       /**
    -   * 费率
    +   * 费率.
        */
       private String poundageRate;
     
    -  public static long getSerialversionuid() {
    -    return serialVersionUID;
    -  }
    -
    -  public String getTradeTime() {
    -    return tradeTime;
    -  }
    -
    -  public void setTradeTime(String tradeTime) {
    -    this.tradeTime = tradeTime;
    -  }
    -
    -  public String getAppId() {
    -    return appId;
    -  }
    -
    -  public void setAppId(String appId) {
    -    this.appId = appId;
    -  }
    -
    -  public String getMchId() {
    -    return mchId;
    -  }
    -
    -  public void setMchId(String mchId) {
    -    this.mchId = mchId;
    -  }
    -
    -  public String getSubMchId() {
    -    return subMchId;
    -  }
    -
    -  public void setSubMchId(String subMchId) {
    -    this.subMchId = subMchId;
    -  }
    -
    -  public String getDeviceInfo() {
    -    return deviceInfo;
    -  }
    -
    -  public void setDeviceInfo(String deviceInfo) {
    -    this.deviceInfo = deviceInfo;
    -  }
    -
    -  public String getTransationId() {
    -    return transationId;
    -  }
    -
    -  public void setTransationId(String transationId) {
    -    this.transationId = transationId;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
    -  public String getOpenId() {
    -    return openId;
    -  }
    -
    -  public void setOpenId(String openId) {
    -    this.openId = openId;
    -  }
    -
    -  public String getTradeType() {
    -    return tradeType;
    -  }
    -
    -  public void setTradeType(String tradeType) {
    -    this.tradeType = tradeType;
    -  }
    -
    -  public String getTradeState() {
    -    return tradeState;
    -  }
    -
    -  public void setTradeState(String tradeState) {
    -    this.tradeState = tradeState;
    -  }
    -
    -  public String getBankType() {
    -    return bankType;
    -  }
    -
    -  public void setBankType(String bankType) {
    -    this.bankType = bankType;
    -  }
    -
    -  public String getFeeType() {
    -    return feeType;
    -  }
    -
    -  public void setFeeType(String feeType) {
    -    this.feeType = feeType;
    -  }
    -
    -  public String getTotalFee() {
    -    return totalFee;
    -  }
    -
    -  public void setTotalFee(String totalFee) {
    -    this.totalFee = totalFee;
    -  }
    -
    -  public String getCouponFee() {
    -    return couponFee;
    -  }
    -
    -  public void setCouponFee(String couponFee) {
    -    this.couponFee = couponFee;
    -  }
    -
    -  public String getRefundId() {
    -    return refundId;
    -  }
    -
    -  public void setRefundId(String refundId) {
    -    this.refundId = refundId;
    -  }
    -
    -  public String getOutRefundNo() {
    -    return outRefundNo;
    -  }
    -
    -  public void setOutRefundNo(String outRefundNo) {
    -    this.outRefundNo = outRefundNo;
    -  }
    -
    -  public String getSettlementRefundFee() {
    -    return settlementRefundFee;
    -  }
    -
    -  public void setSettlementRefundFee(String settlementRefundFee) {
    -    this.settlementRefundFee = settlementRefundFee;
    -  }
    -
    -  public String getCouponRefundFee() {
    -    return couponRefundFee;
    -  }
    -
    -  public void setCouponRefundFee(String couponRefundFee) {
    -    this.couponRefundFee = couponRefundFee;
    -  }
    -
    -  public String getRefundChannel() {
    -    return refundChannel;
    -  }
    -
    -  public void setRefundChannel(String refundChannel) {
    -    this.refundChannel = refundChannel;
    -  }
    -
    -  public String getRefundState() {
    -    return refundState;
    -  }
    -
    -  public void setRefundState(String refundState) {
    -    this.refundState = refundState;
    -  }
    -
    -  public String getBody() {
    -    return body;
    -  }
    -
    -  public void setBody(String body) {
    -    this.body = body;
    -  }
    -
    -  public String getAttach() {
    -    return attach;
    -  }
    -
    -  public void setAttach(String attach) {
    -    this.attach = attach;
    -  }
    -
    -  public String getPoundage() {
    -    return poundage;
    -  }
    -
    -  public void setPoundage(String poundage) {
    -    this.poundage = poundage;
    -  }
    -
    -  public String getPoundageRate() {
    -    return poundageRate;
    -  }
    -
    -  public void setPoundageRate(String poundageRate) {
    -    this.poundageRate = poundageRate;
    -  }
    -
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java
    index a7fb25bef2..a8f9f7c5b3 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java
    @@ -3,81 +3,50 @@
     import java.io.Serializable;
     import java.util.List;
     
    +import org.apache.commons.lang3.builder.ToStringBuilder;
    +import org.apache.commons.lang3.builder.ToStringStyle;
    +
    +import lombok.Data;
    +import lombok.NoArgsConstructor;
    +
    +/**
    + * The type Wx pay bill result.
    + *
    + * @author BinaryWang
    + */
    +@Data
    +@NoArgsConstructor
     public class WxPayBillResult implements Serializable {
    +  private static final long serialVersionUID = -7687458652694204070L;
    +
    +  @Override
    +  public String toString() {
    +    return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
    +  }
    +
       /**
    -   * 对账返回对象
    +   * 对账返回对象.
        */
    -  private static final long serialVersionUID = 1L;
    -
       private List wxPayBillBaseResultLst;
       /**
    -   * 总交易单数
    +   * 总交易单数.
        */
       private String totalRecord;
       /**
    -   * 总交易额
    +   * 总交易额.
        */
       private String totalFee;
       /**
    -   * 总退款金额
    +   * 总退款金额.
        */
       private String totalRefundFee;
       /**
    -   * 总代金券或立减优惠退款金额
    +   * 总代金券或立减优惠退款金额.
        */
       private String totalCouponFee;
       /**
    -   * 手续费总金额
    +   * 手续费总金额.
        */
       private String totalPoundageFee;
     
    -  public List getWxPayBillBaseResultLst() {
    -    return wxPayBillBaseResultLst;
    -  }
    -
    -  public void setWxPayBillBaseResultLst(List wxPayBillBaseResultLst) {
    -    this.wxPayBillBaseResultLst = wxPayBillBaseResultLst;
    -  }
    -
    -  public String getTotalRecord() {
    -    return totalRecord;
    -  }
    -
    -  public void setTotalRecord(String totalRecord) {
    -    this.totalRecord = totalRecord;
    -  }
    -
    -  public String getTotalFee() {
    -    return totalFee;
    -  }
    -
    -  public void setTotalFee(String totalFee) {
    -    this.totalFee = totalFee;
    -  }
    -
    -  public String getTotalRefundFee() {
    -    return totalRefundFee;
    -  }
    -
    -  public void setTotalRefundFee(String totalRefundFee) {
    -    this.totalRefundFee = totalRefundFee;
    -  }
    -
    -  public String getTotalCouponFee() {
    -    return totalCouponFee;
    -  }
    -
    -  public void setTotalCouponFee(String totalCouponFee) {
    -    this.totalCouponFee = totalCouponFee;
    -  }
    -
    -  public String getTotalPoundageFee() {
    -    return totalPoundageFee;
    -  }
    -
    -  public void setTotalPoundageFee(String totalPoundageFee) {
    -    this.totalPoundageFee = totalPoundageFee;
    -  }
    -
    -
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
    index 1fc4d30940..cc0a3a6edc 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
    @@ -6,10 +6,10 @@
      * 
      * 微信支付结果仅包含有return 和result等相关信息的的属性类
      * Created by Binary Wang on 2017-01-09.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ - @XStreamAlias("xml") -public class WxPayCommonResult extends WxPayBaseResult { +public class WxPayCommonResult extends BaseWxPayResult { } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFundFlowBaseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFundFlowBaseResult.java new file mode 100644 index 0000000000..dc631314b1 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFundFlowBaseResult.java @@ -0,0 +1,71 @@ +package com.github.binarywang.wxpay.bean.result; + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; + +/** + * 记账时间:2018-02-01 04:21:23 微信支付业务单号:50000305742018020103387128253 资金流水单号:1900009231201802015884652186 业务名称:退款 + * 业务类型:退款 收支类型:支出 收支金额(元):0.02 账户结余(元):0.17 资金变更提交申请人:system 备注:缺货 业务凭证号:REF4200000068201801293084726067 + * + * @author cwivan + */ +@Data +@NoArgsConstructor +public class WxPayFundFlowBaseResult implements Serializable { + private static final long serialVersionUID = 4474557532904682718L; + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + /** + * 记账时间 + */ + private String BillingTime; + /** + * 微信支付业务单号 + */ + private String bizTransactionId; + /** + * 资金流水单号 + */ + private String fundFlowId; + /** + * 业务名称 + */ + private String bizName; + /** + * 业务类型 + */ + private String bizType; + /** + * 收支类型 + */ + private String financialType; + /** + * 收支金额(元) + */ + private String financialFee; + /** + * 账户结余(元) + */ + private String AccountBalance; + /** + * 资金变更提交申请人 + */ + private String fundApplicant; + /** + * 备注 + */ + private String memo; + /** + * 业务凭证号 + */ + private String bizVoucherId; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFundFlowResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFundFlowResult.java new file mode 100644 index 0000000000..ba32550484 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFundFlowResult.java @@ -0,0 +1,60 @@ +package com.github.binarywang.wxpay.bean.result; + +import java.io.Serializable; +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *
    + * 下载资金账单接口响应结果对象类
    + * Created by cwivan on 2018-08-02.
    + * 
    + * + * @author cwivan + */ +@Data +@NoArgsConstructor +public class WxPayFundFlowResult implements Serializable{ + private static final long serialVersionUID = 8371500036495349207L; + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + /** + * 资金流水返回对象 + */ + private List wxPayFundFlowBaseResultList; + + /** + * 资金流水总笔数 + */ + private String totalRecord; + + /** + * 收入笔数 + */ + private String incomeRecord; + + /** + * 收入金额 + */ + private String incomeAmount; + + /** + * 支出笔数 + */ + private String expenditureRecord; + + /** + * 支出金额 + */ + private String expenditureAmount; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java index 2f8842af82..87aad5f436 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java @@ -1,16 +1,23 @@ package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; /** *
      * 提交刷卡支付接口响应结果对象类
      * Created by Binary Wang on 2017-3-23.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayMicropayResult extends WxPayBaseResult { +public class WxPayMicropayResult extends BaseWxPayResult { /** *
        * 用户标识
    @@ -206,123 +213,4 @@ public class WxPayMicropayResult extends WxPayBaseResult {
       @XStreamAlias("promotion_detail")
       private String promotionDetail;
     
    -  public String getOpenid() {
    -    return this.openid;
    -  }
    -
    -  public void setOpenid(String openid) {
    -    this.openid = openid;
    -  }
    -
    -  public String getIsSubscribe() {
    -    return this.isSubscribe;
    -  }
    -
    -  public void setIsSubscribe(String isSubscribe) {
    -    this.isSubscribe = isSubscribe;
    -  }
    -
    -  public String getTradeType() {
    -    return this.tradeType;
    -  }
    -
    -  public void setTradeType(String tradeType) {
    -    this.tradeType = tradeType;
    -  }
    -
    -  public String getBankType() {
    -    return this.bankType;
    -  }
    -
    -  public void setBankType(String bankType) {
    -    this.bankType = bankType;
    -  }
    -
    -  public String getFeeType() {
    -    return this.feeType;
    -  }
    -
    -  public void setFeeType(String feeType) {
    -    this.feeType = feeType;
    -  }
    -
    -  public String getTotalFee() {
    -    return this.totalFee;
    -  }
    -
    -  public void setTotalFee(String totalFee) {
    -    this.totalFee = totalFee;
    -  }
    -
    -  public Integer getSettlementTotalFee() {
    -    return this.settlementTotalFee;
    -  }
    -
    -  public void setSettlementTotalFee(Integer settlementTotalFee) {
    -    this.settlementTotalFee = settlementTotalFee;
    -  }
    -
    -  public Integer getCouponFee() {
    -    return this.couponFee;
    -  }
    -
    -  public void setCouponFee(Integer couponFee) {
    -    this.couponFee = couponFee;
    -  }
    -
    -  public String getCashFeeType() {
    -    return this.cashFeeType;
    -  }
    -
    -  public void setCashFeeType(String cashFeeType) {
    -    this.cashFeeType = cashFeeType;
    -  }
    -
    -  public Integer getCashFee() {
    -    return this.cashFee;
    -  }
    -
    -  public void setCashFee(Integer cashFee) {
    -    this.cashFee = cashFee;
    -  }
    -
    -  public String getTransactionId() {
    -    return this.transactionId;
    -  }
    -
    -  public void setTransactionId(String transactionId) {
    -    this.transactionId = transactionId;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return this.outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
    -  public String getAttach() {
    -    return this.attach;
    -  }
    -
    -  public void setAttach(String attach) {
    -    this.attach = attach;
    -  }
    -
    -  public String getTimeEnd() {
    -    return this.timeEnd;
    -  }
    -
    -  public void setTimeEnd(String timeEnd) {
    -    this.timeEnd = timeEnd;
    -  }
    -
    -  public String getPromotionDetail() {
    -    return this.promotionDetail;
    -  }
    -
    -  public void setPromotionDetail(String promotionDetail) {
    -    this.promotionDetail = promotionDetail;
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
    index 7221251f10..a71c8ab7ed 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
    @@ -1,16 +1,23 @@
     package com.github.binarywang.wxpay.bean.result;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
    +import lombok.NoArgsConstructor;
     
     /**
      * 
      * 关闭订单结果对象类
      * Created by Binary Wang on 2016-10-27.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayOrderCloseResult extends WxPayBaseResult { +public class WxPayOrderCloseResult extends BaseWxPayResult { /** * 业务结果描述 @@ -18,11 +25,4 @@ public class WxPayOrderCloseResult extends WxPayBaseResult { @XStreamAlias("result_msg") private String resultMsg; - public String getResultMsg() { - return this.resultMsg; - } - - public void setResultMsg(String resultMsg) { - this.resultMsg = resultMsg; - } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java index ff087bf010..c54c5368b0 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java @@ -2,6 +2,7 @@ import com.google.common.collect.Lists; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.*; import java.util.List; @@ -18,10 +19,26 @@ *
  • 描述 *
  • * - * @author binarywang(Binary Wang) + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayOrderQueryResult extends WxPayBaseResult { +public class WxPayOrderQueryResult extends BaseWxPayResult { + + /** + *
    +   * 字段名:营销详情.
    +   * 变量名:promotion_detail
    +   * 是否必填:否,单品优惠才有
    +   * 类型:String(6000)
    +   * 示例值:[{"promotion_detail":[{"promotion_id":"109519","name":"单品惠-6","scope":"SINGLE","type":"DISCOUNT","amount":5,"activity_id":"931386","wxpay_contribute":0,"merchant_contribute":0,"other_contribute":5,"goods_detail":[{"goods_id":"a_goods1","goods_remark":"商品备注","quantity":7,"price":1,"discount_amount":4},{"goods_id":"a_goods2","goods_remark":"商品备注","quantity":1,"price":2,"discount_amount":1}]}]}
    +   * 描述:单品优惠专用参数,详见https://pay.weixin.qq.com/wiki/doc/api/danpin.php?chapter=9_201&index=3
    +   * 
    + */ + @XStreamAlias("promotion_detail") + private String promotionDetail; /** *
    设备号
    @@ -236,158 +253,6 @@ public class WxPayOrderQueryResult extends WxPayBaseResult {
       @XStreamAlias("trade_state_desc")
       private String tradeStateDesc;
     
    -  public String getDeviceInfo() {
    -    return this.deviceInfo;
    -  }
    -
    -  public void setDeviceInfo(String deviceInfo) {
    -    this.deviceInfo = deviceInfo;
    -  }
    -
    -  public String getOpenid() {
    -    return this.openid;
    -  }
    -
    -  public void setOpenid(String openid) {
    -    this.openid = openid;
    -  }
    -
    -  public String getIsSubscribe() {
    -    return this.isSubscribe;
    -  }
    -
    -  public void setIsSubscribe(String isSubscribe) {
    -    this.isSubscribe = isSubscribe;
    -  }
    -
    -  public String getTradeType() {
    -    return this.tradeType;
    -  }
    -
    -  public void setTradeType(String tradeType) {
    -    this.tradeType = tradeType;
    -  }
    -
    -  public String getTradeState() {
    -    return this.tradeState;
    -  }
    -
    -  public void setTradeState(String tradeState) {
    -    this.tradeState = tradeState;
    -  }
    -
    -  public String getBankType() {
    -    return this.bankType;
    -  }
    -
    -  public void setBankType(String bankType) {
    -    this.bankType = bankType;
    -  }
    -
    -  public Integer getTotalFee() {
    -    return this.totalFee;
    -  }
    -
    -  public void setTotalFee(Integer totalFee) {
    -    this.totalFee = totalFee;
    -  }
    -
    -  public Integer getSettlementTotalFee() {
    -    return this.settlementTotalFee;
    -  }
    -
    -  public void setSettlementTotalFee(Integer settlementTotalFee) {
    -    this.settlementTotalFee = settlementTotalFee;
    -  }
    -
    -  public String getFeeType() {
    -    return this.feeType;
    -  }
    -
    -  public void setFeeType(String feeType) {
    -    this.feeType = feeType;
    -  }
    -
    -  public Integer getCashFee() {
    -    return this.cashFee;
    -  }
    -
    -  public void setCashFee(Integer cashFee) {
    -    this.cashFee = cashFee;
    -  }
    -
    -  public String getCashFeeType() {
    -    return this.cashFeeType;
    -  }
    -
    -  public void setCashFeeType(String cashFeeType) {
    -    this.cashFeeType = cashFeeType;
    -  }
    -
    -  public Integer getCouponFee() {
    -    return this.couponFee;
    -  }
    -
    -  public void setCouponFee(Integer couponFee) {
    -    this.couponFee = couponFee;
    -  }
    -
    -  public Integer getCouponCount() {
    -    return this.couponCount;
    -  }
    -
    -  public void setCouponCount(Integer couponCount) {
    -    this.couponCount = couponCount;
    -  }
    -
    -  public List getCoupons() {
    -    return this.coupons;
    -  }
    -
    -  public void setCoupons(List coupons) {
    -    this.coupons = coupons;
    -  }
    -
    -  public String getTransactionId() {
    -    return this.transactionId;
    -  }
    -
    -  public void setTransactionId(String transactionId) {
    -    this.transactionId = transactionId;
    -  }
    -
    -  public String getOutTradeNo() {
    -    return this.outTradeNo;
    -  }
    -
    -  public void setOutTradeNo(String outTradeNo) {
    -    this.outTradeNo = outTradeNo;
    -  }
    -
    -  public String getAttach() {
    -    return this.attach;
    -  }
    -
    -  public void setAttach(String attach) {
    -    this.attach = attach;
    -  }
    -
    -  public String getTimeEnd() {
    -    return this.timeEnd;
    -  }
    -
    -  public void setTimeEnd(String timeEnd) {
    -    this.timeEnd = timeEnd;
    -  }
    -
    -  public String getTradeStateDesc() {
    -    return this.tradeStateDesc;
    -  }
    -
    -  public void setTradeStateDesc(String tradeStateDesc) {
    -    this.tradeStateDesc = tradeStateDesc;
    -  }
    -
       /**
        * 通过xml组装coupons属性内容
        */
    @@ -402,6 +267,12 @@ public void composeCoupons() {
         }
       }
     
    +  /**
    +   * The type Coupon.
    +   */
    +  @Data
    +  @Builder(builderMethodName = "newBuilder")
    +  @AllArgsConstructor
       public static class Coupon {
         /**
          * 
    代金券类型
    @@ -438,35 +309,5 @@ public static class Coupon {
          */
         private Integer couponFee;
     
    -    public Coupon(String couponType, String couponId, Integer couponFee) {
    -      this.couponType = couponType;
    -      this.couponId = couponId;
    -      this.couponFee = couponFee;
    -    }
    -
    -    public String getCouponType() {
    -      return this.couponType;
    -    }
    -
    -    public void setCouponType(String couponType) {
    -      this.couponType = couponType;
    -    }
    -
    -    public String getCouponId() {
    -      return this.couponId;
    -    }
    -
    -    public void setCouponId(String couponId) {
    -      this.couponId = couponId;
    -    }
    -
    -    public Integer getCouponFee() {
    -      return this.couponFee;
    -    }
    -
    -    public void setCouponFee(Integer couponFee) {
    -      this.couponFee = couponFee;
    -    }
    -
       }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
    index c80b72d216..578139929e 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
    @@ -1,16 +1,23 @@
     package com.github.binarywang.wxpay.bean.result;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
    +import lombok.NoArgsConstructor;
     
     /**
      * 
      * 撤销订单响应结果类
      * Created by Binary Wang on 2017-3-23.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayOrderReverseResult extends WxPayBaseResult { +public class WxPayOrderReverseResult extends BaseWxPayResult { /** *
    @@ -25,11 +32,4 @@ public class WxPayOrderReverseResult extends WxPayBaseResult {
       @XStreamAlias("recall")
       private String isRecall;
     
    -  public String getIsRecall() {
    -    return this.isRecall;
    -  }
    -
    -  public void setIsRecall(String isRecall) {
    -    this.isRecall = isRecall;
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
    index e0b86732fd..4f05bfde68 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
    @@ -1,31 +1,35 @@
     package com.github.binarywang.wxpay.bean.result;
     
    +import java.io.Serializable;
    +import java.util.List;
    +
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
    +import lombok.NoArgsConstructor;
     
     /**
      * 
    - *   注释中各行对应含义:
    - *   字段名
    - *   字段
    - *   必填
    - *   示例值
    - *   类型
    - *   说明
      * Created by Binary Wang on 2016-11-28.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayRedpackQueryResult extends WxPayBaseResult { +public class WxPayRedpackQueryResult extends BaseWxPayResult { + private static final long serialVersionUID = -3849864122189552906L; /** *
    -   * 商户订单号
    -   * mch_billno
    -   * 是
    -   * 10000098201411111234567890
    -   * String(28)
    -   * 商户使用查询API填写的商户单号的原路返回
    +   * 字段含义:商户订单号.
    +   * 字段名:mch_billno
    +   * 是否必填:是
    +   * 示例值:10000098201411111234567890
    +   * 类型:String(28)
    +   * 字段说明:商户使用查询API填写的商户单号的原路返回
        * 
    */ @XStreamAlias("mch_billno") @@ -33,12 +37,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包单号
    -   * detail_id
    -   * 是
    -   * 1000000000201503283103439304
    -   * String(32)
    -   * 使用API发放现金红包时返回的红包单号
    +   * 字段含义:红包单号.
    +   * 字段名:detail_id
    +   * 是否必填:是
    +   * 示例值:1000000000201503283103439304
    +   * 类型:String(32)
    +   * 字段说明:使用API发放现金红包时返回的红包单号
        * 
    */ @XStreamAlias("detail_id") @@ -46,12 +50,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包状态
    -   * status
    -   * 是
    -   * RECEIVED
    -   * string(16)
    -   * SENDING:发放中,
    +   * 字段含义:红包状态.
    +   * 字段名:status
    +   * 是否必填:是
    +   * 示例值:RECEIVED
    +   * 类型:string(16)
    +   * 字段说明:SENDING:发放中,
        * SENT:已发放待领取,
        * FAILED:发放失败,
        * RECEIVED:已领取,
    @@ -64,12 +68,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult {
     
       /**
        * 
    -   * 发放类型
    -   * send_type
    -   * 是
    -   * API
    -   * String(32)
    -   *  API:通过API接口发放,
    +   * 字段含义:发放类型.
    +   * 字段名:send_type
    +   * 是否必填:是
    +   * 示例值:API
    +   * 类型:String(32)
    +   * 字段说明:API:通过API接口发放,
        *  UPLOAD:通过上传文件方式发放,
        *  ACTIVITY:通过活动方式发放
        * 
    @@ -79,12 +83,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包类型
    -   * hb_type
    -   * 是
    -   * GROUP
    -   * String(32)
    -   *  GROUP:裂变红包,
    +   * 字段含义:红包类型.
    +   * 字段名:hb_type
    +   * 是否必填:是
    +   * 示例值:GROUP
    +   * 类型:String(32)
    +   * 字段说明:GROUP:裂变红包,
        *  NORMAL:普通红包
        * 
    */ @@ -93,12 +97,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包个数
    -   * total_num
    -   * 是
    -   * 1
    -   * int
    -   * 红包个数
    +   * 字段含义:红包个数.
    +   * 字段名:total_num
    +   * 是否必填:是
    +   * 示例值:1
    +   * 类型:int
    +   * 字段说明:红包个数
        * 
    */ @XStreamAlias("total_num") @@ -106,12 +110,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包金额
    -   * total_amount
    -   * 是
    -   * 5000
    -   * int
    -   * 红包总金额(单位分)
    +   * 字段含义:红包金额.
    +   * 字段名:total_amount
    +   * 是否必填:是
    +   * 示例值:5000
    +   * 类型:int
    +   * 字段说明:红包总金额(单位分)
        * 
    */ @XStreamAlias("total_amount") @@ -119,12 +123,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 失败原因
    -   * reason
    -   * 否
    -   * 余额不足
    -   * String(32)
    -   * 发送失败原因
    +   * 字段含义:失败原因.
    +   * 字段名:reason
    +   * 是否必填:否
    +   * 示例值:余额不足
    +   * 类型:String(32)
    +   * 字段说明:发送失败原因
        * 
    */ @XStreamAlias("reason") @@ -132,12 +136,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包发送时间
    -   * send_time
    -   * 是
    -   * 2015-04-21 20:00:00
    -   * String(32)
    -   * 红包的发送时间
    +   * 字段含义:红包发送时间.
    +   * 字段名:send_time
    +   * 是否必填:是
    +   * 示例值:2015-04-21 20:00:00
    +   * 类型:String(32)
    +   * 字段说明:红包的发送时间
        * 
    */ @XStreamAlias("send_time") @@ -145,12 +149,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包退款时间
    -   * refund_time
    -   * 否
    -   * 2015-04-21 23:03:00
    -   * String(32)
    -   * 红包的退款时间(如果其未领取的退款)
    +   * 字段含义:红包退款时间.
    +   * 字段名: refund_time
    +   * 是否必填:否
    +   * 示例值:2015-04-21 23:03:00
    +   * 类型:String(32)
    +   * 字段说明:红包的退款时间(如果其未领取的退款)
        * 
    */ @XStreamAlias("refund_time") @@ -158,12 +162,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 红包退款金额
    -   * refund_amount
    -   * 否
    -   * 8000
    -   * Int
    -   * 红包退款金额
    +   * 字段含义:红包退款金额.
    +   * 字段名:refund_amount
    +   * 是否必填:否
    +   * 示例值:8000
    +   * 类型:Int
    +   * 字段说明:红包退款金额
        * 
    */ @XStreamAlias("refund_amount") @@ -171,12 +175,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 祝福语
    -   * wishing
    -   * 否
    -   * 新年快乐
    -   * String(128)
    -   * 祝福语
    +   * 字段含义:祝福语.
    +   * 字段名:wishing
    +   * 是否必填:否
    +   * 示例值:新年快乐
    +   * 类型:String(128)
    +   * 字段说明:祝福语
        * 
    */ @XStreamAlias("wishing") @@ -184,12 +188,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 活动描述
    -   * remark
    -   * 否
    -   * 新年红包
    -   * String(256)
    -   * 活动描述,低版本微信可见
    +   * 字段含义:活动描述.
    +   * 字段名:remark
    +   * 是否必填:否
    +   * 示例值:新年红包
    +   * 类型:String(256)
    +   * 字段说明:活动描述,低版本微信可见
        * 
    */ @XStreamAlias("remark") @@ -197,12 +201,12 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 活动名称
    -   * act_name
    -   * 否
    -   * 新年红包
    -   * String(32)
    -   * 发红包的活动名称
    +   * 字段含义:活动名称.
    +   * 字段名:act_name
    +   * 是否必填:否
    +   * 示例值:新年红包
    +   * 类型:String(32)
    +   * 字段说明:发红包的活动名称
        * 
    */ @XStreamAlias("act_name") @@ -210,197 +214,60 @@ public class WxPayRedpackQueryResult extends WxPayBaseResult { /** *
    -   * 裂变红包领取列表
    -   * hblist
    -   * 否
    -   *
    -   *
    -   * 裂变红包的领取列表
    +   * 字段含义:裂变红包领取列表.
    +   * 字段名:redpackList
    +   * 是否必填:否
    +   * 字段说明: 裂变红包的领取列表
        * 
    */ @XStreamAlias("hblist") - private String hblist; + private List redpackList; /** - *
    -   * 领取红包的Openid
    -   * openid
    -   * 是
    -   * ohO4GtzOAAYMp2yapORH3dQB3W18
    -   * String(32)
    -   * 领取红包的openid
    -   * 
    + * The type Redpack info. */ - @XStreamAlias("openid") - private String openid; - - /** - *
    -   * 金额
    -   * amount
    -   * 是
    -   * 100
    -   * int
    -   * 领取金额
    -   * 
    - */ - @XStreamAlias("amount") - private Integer amount; - - /** - *
    -   * 接收时间
    -   * rcv_time
    -   * 是
    -   * 2015-04-21 20:00:00
    -   * String(32)
    -   * 领取红包的时间
    -   * 
    - */ - @XStreamAlias("rcv_time") - private String receiveTime; - - public String getMchBillNo() { - return mchBillNo; - } - - public void setMchBillNo(String mchBillNo) { - this.mchBillNo = mchBillNo; - } - - public String getDetailId() { - return detailId; - } - - public void setDetailId(String detailId) { - this.detailId = detailId; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public String getSendType() { - return sendType; - } - - public void setSendType(String sendType) { - this.sendType = sendType; - } - - public String getHbType() { - return hbType; - } - - public void setHbType(String hbType) { - this.hbType = hbType; - } - - public Integer getTotalNum() { - return totalNum; - } - - public void setTotalNum(Integer totalNum) { - this.totalNum = totalNum; - } - - public Integer getTotalAmount() { - return totalAmount; - } - - public void setTotalAmount(Integer totalAmount) { - this.totalAmount = totalAmount; - } - - public String getReason() { - return reason; + @Data + @XStreamAlias("hbinfo") + public static class RedpackInfo implements Serializable { + private static final long serialVersionUID = 7829773321457772100L; + /** + *
    +     * 字段含义:领取红包的Openid.
    +     * 字段名: openid
    +     * 是否必填:是
    +     * 示例值:ohO4GtzOAAYMp2yapORH3dQB3W18
    +     * 类型:String(32)
    +     * 字段说明:领取红包的openid
    +     * 
    + */ + @XStreamAlias("openid") + private String openid; + + /** + *
    +     * 字段含义:金额.
    +     * 字段名: amount
    +     * 是否必填:是
    +     * 示例值:100
    +     * 类型:int
    +     * 字段说明:领取金额
    +     * 
    + */ + @XStreamAlias("amount") + private Integer amount; + + /** + *
    +     * 字段含义:接收时间.
    +     * 字段名: rcv_time
    +     * 是否必填:是
    +     * 示例值:2015-04-21 20:00:00
    +     * 类型:String(32)
    +     * 字段说明:领取红包的时间
    +     * 
    + */ + @XStreamAlias("rcv_time") + private String receiveTime; } - public void setReason(String reason) { - this.reason = reason; - } - - public String getSendTime() { - return sendTime; - } - - public void setSendTime(String sendTime) { - this.sendTime = sendTime; - } - - public String getRefundTime() { - return refundTime; - } - - public void setRefundTime(String refundTime) { - this.refundTime = refundTime; - } - - public Integer getRefundAmount() { - return refundAmount; - } - - public void setRefundAmount(Integer refundAmount) { - this.refundAmount = refundAmount; - } - - public String getWishing() { - return wishing; - } - - public void setWishing(String wishing) { - this.wishing = wishing; - } - - public String getRemark() { - return remark; - } - - public void setRemark(String remark) { - this.remark = remark; - } - - public String getActName() { - return actName; - } - - public void setActName(String actName) { - this.actName = actName; - } - - public String getHblist() { - return hblist; - } - - public void setHblist(String hblist) { - this.hblist = hblist; - } - - public String getOpenid() { - return openid; - } - - public void setOpenid(String openid) { - this.openid = openid; - } - - public Integer getAmount() { - return amount; - } - - public void setAmount(Integer amount) { - this.amount = amount; - } - - public String getReceiveTime() { - return receiveTime; - } - - public void setReceiveTime(String receiveTime) { - this.receiveTime = receiveTime; - } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundCouponInfo.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundCouponInfo.java new file mode 100644 index 0000000000..290e472313 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundCouponInfo.java @@ -0,0 +1,61 @@ +package com.github.binarywang.wxpay.bean.result; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *
    + *  退款代金券信息.
    + *  Created by BinaryWang on 2018/4/21.
    + * 
    + * + * @author Binary Wang + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class WxPayRefundCouponInfo { + /** + *
    +   * 字段名:退款代金券ID.
    +   * 变量名:coupon_refund_id_$n_$m
    +   * 是否必填:否
    +   * 类型:String(20)
    +   * 示例值:10000
    +   * 描述:退款代金券ID, $n为下标,$m为下标,从0开始编号
    +   * 
    + */ + @XStreamAlias("coupon_refund_id") + private String couponRefundId; + + /** + *
    +   * 字段名:单个退款代金券支付金额.
    +   * 变量名:coupon_refund_fee_$n_$m
    +   * 是否必填:否
    +   * 类型:Int
    +   * 示例值:100
    +   * 描述:单个退款代金券支付金额, $n为下标,$m为下标,从0开始编号
    +   * 
    + */ + @XStreamAlias("coupon_refund_fee") + private Integer couponRefundFee; + + /** + *
    +   * 字段名:代金券类型.
    +   * 变量名:coupon_type_$n_$m
    +   * 是否必填:否
    +   * 类型:String(8)
    +   * 示例值:CASH
    +   * 描述:CASH--充值代金券 , NO_CASH---非充值代金券。
    +   * 开通免充值券功能,并且订单使用了优惠券后有返回(取值:CASH、NO_CASH)。
    +   * $n为下标,$m为下标,从0开始编号,举例:coupon_type_$0_$1
    +   * 
    + */ + @XStreamAlias("coupon_type") + private String couponType; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java index 1916fdb9e7..3bc6a2b4b6 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java @@ -1,190 +1,136 @@ package com.github.binarywang.wxpay.bean.result; +import java.util.List; + import com.google.common.collect.Lists; import com.thoughtworks.xstream.annotations.XStreamAlias; - -import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; /** *
    + * 微信支付-退款查询返回结果
      * Created by Binary Wang on 2016-11-24.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayRefundQueryResult extends WxPayBaseResult { +public class WxPayRefundQueryResult extends BaseWxPayResult { /** *
    -   * 设备号
    -   * device_info
    -   * 否
    -   * String(32)
    -   * 013467007045764
    -   * 终端设备号
    +   * 字段名:设备号.
    +   * 变量名:device_info
    +   * 是否必填:否
    +   * 类型:String(32)
    +   * 示例值:013467007045764
    +   * 描述:终端设备号
    +   * 
    */ @XStreamAlias("device_info") private String deviceInfo; /** *
    -   * 微信订单号
    -   * transaction_id
    -   * 是
    -   * String(32)
    -   * 1217752501201407033233368018
    -   * 微信订单号
    +   * 字段名:微信订单号.
    +   * 变量名:transaction_id
    +   * 是否必填:是
    +   * 类型:String(32)
    +   * 示例值:1217752501201407033233368018
    +   * 描述:微信订单号
    +   * 
    */ @XStreamAlias("transaction_id") private String transactionId; /** *
    -   * 商户订单号
    -   * out_trade_no
    -   * 是
    -   * String(32)
    -   * 1217752501201407033233368018
    -   * 商户系统内部的订单号
    +   * 字段名:商户订单号.
    +   * 变量名:out_trade_no
    +   * 是否必填:是
    +   * 类型:String(32)
    +   * 示例值:1217752501201407033233368018
    +   * 描述:商户系统内部的订单号
    +   * 
    */ @XStreamAlias("out_trade_no") private String outTradeNo; /** *
    -   * 订单金额
    -   * total_fee
    -   * 是
    -   * Int
    -   * 100
    -   * 订单总金额,单位为分,只能为整数,详见支付金额
    +   * 字段名:订单金额.
    +   * 变量名:total_fee
    +   * 是否必填:是
    +   * 类型:Int
    +   * 示例值:100
    +   * 描述:订单总金额,单位为分,只能为整数,详见支付金额
    +   * 
    */ @XStreamAlias("total_fee") private Integer totalFee; /** *
    -   * 应结订单金额
    -   * settlement_total_fee
    -   * 否
    -   * Int
    -   * 100
    -   * 应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
    +   * 字段名:应结订单金额.
    +   * 变量名:settlement_total_fee
    +   * 是否必填:否
    +   * 类型:Int
    +   * 示例值:100
    +   * 描述:应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额。
    +   * 
    */ @XStreamAlias("settlement_total_fee") private Integer settlementTotalFee; /** *
    -   * 货币种类
    -   * fee_type
    -   * 否
    -   * String(8)
    -   * CNY
    -   * 订单金额货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 字段名:货币种类.
    +   * 变量名:fee_type
    +   * 是否必填:否
    +   * 类型:String(8)
    +   * 示例值:CNY
    +   * 描述:订单金额货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
    +   * 
    */ @XStreamAlias("fee_type") private String feeType; /** *
    -   * 现金支付金额
    -   * cash_fee
    -   * 是
    -   * Int
    -   * 100
    -   * 现金支付金额,单位为分,只能为整数,详见支付金额
    +   * 字段名:现金支付金额.
    +   * 变量名:cash_fee
    +   * 是否必填:是
    +   * 类型:Int
    +   * 示例值:100
    +   * 描述:现金支付金额,单位为分,只能为整数,详见支付金额
    +   * 
    */ @XStreamAlias("cash_fee") private Integer cashFee; /** *
    -   * 退款笔数
    -   * refund_count
    -   * 是
    -   * Int
    -   * 1
    -   * 退款记录数
    +   * 字段名:退款笔数.
    +   * 变量名:refund_count
    +   * 是否必填:是
    +   * 类型:Int
    +   * 示例值:1
    +   * 描述:退款记录数
    +   * 
    */ @XStreamAlias("refund_count") private Integer refundCount; private List refundRecords; - public String getDeviceInfo() { - return deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public String getTransactionId() { - return transactionId; - } - - public void setTransactionId(String transactionId) { - this.transactionId = transactionId; - } - - public String getOutTradeNo() { - return outTradeNo; - } - - public void setOutTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - } - - public Integer getTotalFee() { - return totalFee; - } - - public void setTotalFee(Integer totalFee) { - this.totalFee = totalFee; - } - - public Integer getSettlementTotalFee() { - return settlementTotalFee; - } - - public void setSettlementTotalFee(Integer settlementTotalFee) { - this.settlementTotalFee = settlementTotalFee; - } - - public String getFeeType() { - return feeType; - } - - public void setFeeType(String feeType) { - this.feeType = feeType; - } - - public Integer getCashFee() { - return cashFee; - } - - public void setCashFee(Integer cashFee) { - this.cashFee = cashFee; - } - - public Integer getRefundCount() { - return refundCount; - } - - public void setRefundCount(Integer refundCount) { - this.refundCount = refundCount; - } - - public List getRefundRecords() { - return refundRecords; - } - - public void setRefundRecords(List refundRecords) { - this.refundRecords = refundRecords; - } - /** - * 组装生成退款记录属性的内容 + * 组装生成退款记录属性的内容. */ public void composeRefundRecords() { if (this.refundCount != null && this.refundCount > 0) { @@ -199,39 +145,49 @@ public void composeRefundRecords() { refundRecord.setRefundChannel(this.getXmlValue("xml/refund_channel_" + i)); refundRecord.setRefundFee(this.getXmlValueAsInt("xml/refund_fee_" + i)); refundRecord.setSettlementRefundFee(this.getXmlValueAsInt("xml/settlement_refund_fee_" + i)); - refundRecord.setCouponType(this.getXmlValue("xml/coupon_type_" + i)); refundRecord.setCouponRefundFee(this.getXmlValueAsInt("xml/coupon_refund_fee_" + i)); refundRecord.setCouponRefundCount(this.getXmlValueAsInt("xml/coupon_refund_count_" + i)); refundRecord.setRefundStatus(this.getXmlValue("xml/refund_status_" + i)); - refundRecord.setRefundRecvAccout(this.getXmlValue("xml/refund_recv_accout_" + i)); + refundRecord.setRefundRecvAccount(this.getXmlValue("xml/refund_recv_accout_" + i)); + refundRecord.setRefundSuccessTime(this.getXmlValue("xml/refund_success_time_" + i)); if (refundRecord.getCouponRefundCount() == null || refundRecord.getCouponRefundCount() == 0) { continue; } - List coupons = Lists.newArrayList(); + List coupons = Lists.newArrayList(); for (int j = 0; j < refundRecord.getCouponRefundCount(); j++) { coupons.add( - new RefundRecord.RefundCoupon( + new WxPayRefundCouponInfo( this.getXmlValue("xml/coupon_refund_id_" + i + "_" + j), - this.getXmlValueAsInt("xml/coupon_refund_fee_" + i + "_" + j) + this.getXmlValueAsInt("xml/coupon_refund_fee_" + i + "_" + j), + this.getXmlValue("xml/coupon_type_" + i + "_" + j) ) ); } + + refundRecord.setRefundCoupons(coupons); } } } + /** + * The type Refund record. + */ + @Data + @Builder(builderMethodName = "newBuilder") + @NoArgsConstructor + @AllArgsConstructor public static class RefundRecord { /** *
    -     * 商户退款单号
    -     * out_refund_no_$n
    -     * 是
    -     * String(32)
    -     * 1217752501201407033233368018
    -     * 商户退款单号
    +     * 字段名:商户退款单号.
    +     * 变量名:out_refund_no_$n
    +     * 是否必填:是
    +     * 类型:String(32)
    +     * 示例值:1217752501201407033233368018
    +     * 描述:商户退款单号
          * 
    */ @XStreamAlias("out_refund_no") @@ -239,12 +195,12 @@ public static class RefundRecord { /** *
    -     * 微信退款单号
    -     * refund_id_$n
    -     * 是
    -     * String(28)
    -     * 1217752501201407033233368018
    -     * 微信退款单号
    +     * 字段名:微信退款单号.
    +     * 变量名:refund_id_$n
    +     * 是否必填:是
    +     * 类型:String(28)
    +     * 示例值:1217752501201407033233368018
    +     * 描述:微信退款单号
          * 
    */ @XStreamAlias("refund_id") @@ -252,12 +208,12 @@ public static class RefundRecord { /** *
    -     * 退款渠道
    -     * refund_channel_$n
    -     * 否
    -     * String(16)
    -     * ORIGINAL
    -     * ORIGINAL—原路退款 BALANCE—退回到余额
    +     * 字段名:退款渠道.
    +     * 变量名:refund_channel_$n
    +     * 是否必填:否
    +     * 类型:String(16)
    +     * 示例值:ORIGINAL
    +     * 描述:ORIGINAL—原路退款 BALANCE—退回到余额
          * 
    */ @XStreamAlias("refund_channel") @@ -265,12 +221,12 @@ public static class RefundRecord { /** *
    -     * 申请退款金额
    -     * refund_fee_$n
    -     * 是
    -     * Int
    -     * 100
    -     * 退款总金额,单位为分,可以做部分退款
    +     * 字段名:申请退款金额.
    +     * 变量名:refund_fee_$n
    +     * 是否必填:是
    +     * 类型:Int
    +     * 示例值:100
    +     * 描述:退款总金额,单位为分,可以做部分退款
          * 
    */ @XStreamAlias("refund_fee") @@ -278,12 +234,12 @@ public static class RefundRecord { /** *
    -     * 退款金额
    -     * settlement_refund_fee_$n
    -     * 否
    -     * Int
    -     * 100
    -     * 退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额
    +     * 字段名:退款金额.
    +     * 变量名:settlement_refund_fee_$n
    +     * 是否必填:否
    +     * 类型:Int
    +     * 示例值:100
    +     * 描述:退款金额=申请退款金额-非充值代金券退款金额,退款金额<=申请退款金额
          * 
    */ @XStreamAlias("settlement_refund_fee") @@ -291,12 +247,12 @@ public static class RefundRecord { /** *
    -     * 退款资金来源
    -     * refund_account
    -     * 否
    -     * String(30)
    -     * REFUND_SOURCE_RECHARGE_FUNDS
    -     * REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款/基本账户, REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款
    +     * 字段名:退款资金来源.
    +     * 变量名:refund_account
    +     * 是否必填:否
    +     * 类型:String(30)
    +     * 示例值:REFUND_SOURCE_RECHARGE_FUNDS
    +     * 描述:REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款/基本账户, REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款
          * 
    */ @XStreamAlias("refund_account") @@ -304,25 +260,12 @@ public static class RefundRecord { /** *
    -     * 代金券类型
    -     * coupon_type_$n
    -     * 否
    -     * Int
    -     * CASH
    -     * CASH--充值代金券 , NO_CASH---非充值代金券。订单使用代金券时有返回(取值:CASH、NO_CASH)。$n为下标,从0开始编号,举例:coupon_type_$0
    -     * 
    - */ - @XStreamAlias("coupon_type") - private String couponType; - - /** - *
    -     * 代金券退款金额
    -     * coupon_refund_fee_$n
    -     * 否
    -     * Int
    -     * 100
    -     * 代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
    +     * 字段名:代金券退款金额.
    +     * 变量名:coupon_refund_fee_$n
    +     * 是否必填:否
    +     * 类型:Int
    +     * 示例值:100
    +     * 描述:代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
          * 
    */ @XStreamAlias("coupon_refund_fee") @@ -330,27 +273,27 @@ public static class RefundRecord { /** *
    -     * 退款代金券使用数量
    -     * coupon_refund_count_$n
    -     * 否
    -     * Int
    -     * 1
    -     * 退款代金券使用数量 ,$n为下标,从0开始编号
    +     * 字段名:退款代金券使用数量.
    +     * 变量名:coupon_refund_count_$n
    +     * 是否必填:否
    +     * 类型:Int
    +     * 示例值:1
    +     * 描述:退款代金券使用数量 ,$n为下标,从0开始编号
          * 
    */ @XStreamAlias("coupon_refund_count") private Integer couponRefundCount; - private List refundCoupons; + private List refundCoupons; /** *
    -     * 退款状态
    -     * refund_status_$n
    -     * 是
    -     * String(16)
    -     * SUCCESS
    -     * 退款状态:
    +     * 字段名:退款状态.
    +     * 变量名:refund_status_$n
    +     * 是否必填:是
    +     * 类型:String(16)
    +     * 示例值:SUCCESS
    +     * 描述:退款状态:
          *  SUCCESS—退款成功,
          *  FAIL—退款失败,
          *  PROCESSING—退款处理中,
    @@ -360,169 +303,32 @@ public static class RefundRecord {
          */
         @XStreamAlias("refund_status")
         private String refundStatus;
    +
         /**
          * 
    -     * 退款入账账户
    -     * refund_recv_accout_$n
    -     * 是
    -     * String(64)
    -     * 招商银行信用卡0403
    -     * 取当前退款单的退款入账方,1)退回银行卡:{银行名称}{卡类型}{卡尾号},2)退回支付用户零钱:支付用户零钱
    +     * 字段名:退款入账账户.
    +     * 变量名:refund_recv_accout_$n
    +     * 是否必填:是
    +     * 类型:String(64)
    +     * 示例值:招商银行信用卡0403
    +     * 描述:取当前退款单的退款入账方,1)退回银行卡:{银行名称}{卡类型}{卡尾号},2)退回支付用户零钱:支付用户零钱
          * 
    */ @XStreamAlias("refund_recv_accout") - private String refundRecvAccout; - - public String getOutRefundNo() { - return outRefundNo; - } - - public void setOutRefundNo(String outRefundNo) { - this.outRefundNo = outRefundNo; - } + private String refundRecvAccount; - public String getRefundId() { - return refundId; - } - - public void setRefundId(String refundId) { - this.refundId = refundId; - } - - public String getRefundChannel() { - return refundChannel; - } - - public void setRefundChannel(String refundChannel) { - this.refundChannel = refundChannel; - } - - public Integer getRefundFee() { - return refundFee; - } - - public void setRefundFee(Integer refundFee) { - this.refundFee = refundFee; - } - - public Integer getSettlementRefundFee() { - return settlementRefundFee; - } - - public void setSettlementRefundFee(Integer settlementRefundFee) { - this.settlementRefundFee = settlementRefundFee; - } - - public String getRefundAccount() { - return refundAccount; - } - - public void setRefundAccount(String refundAccount) { - this.refundAccount = refundAccount; - } - - public String getCouponType() { - return couponType; - } - - public void setCouponType(String couponType) { - this.couponType = couponType; - } - - public Integer getCouponRefundFee() { - return couponRefundFee; - } - - public void setCouponRefundFee(Integer couponRefundFee) { - this.couponRefundFee = couponRefundFee; - } - - public Integer getCouponRefundCount() { - return couponRefundCount; - } - - public void setCouponRefundCount(Integer couponRefundCount) { - this.couponRefundCount = couponRefundCount; - } - - public List getRefundCoupons() { - return refundCoupons; - } - - public void setRefundCoupons(List refundCoupons) { - this.refundCoupons = refundCoupons; - } - - public String getRefundStatus() { - return refundStatus; - } - - public void setRefundStatus(String refundStatus) { - this.refundStatus = refundStatus; - } - - public String getRefundRecvAccout() { - return refundRecvAccout; - } - - public void setRefundRecvAccout(String refundRecvAccout) { - this.refundRecvAccout = refundRecvAccout; - } - - public static class RefundCoupon { - /** - *
    -       * 退款代金券批次ID
    -       * coupon_refund_batch_id_$n_$m
    -       * 否
    -       * String(20)
    -       * 100
    -       * 退款代金券批次ID ,$n为下标,$m为下标,从0开始编号
    -       * 
    - * - * @deprecated 貌似是被去掉了,但不知是何时! - */ - @XStreamAlias("coupon_refund_batch_id") - private String couponRefundBatchId; - - /** - *
    -       * 退款代金券ID
    -       * coupon_refund_id_$n_$m
    -       * 否
    -       * String(20)
    -       * 10000
    -       * 退款代金券ID, $n为下标,$m为下标,从0开始编号
    -       * 
    - */ - @XStreamAlias("coupon_refund_id") - private String couponRefundId; - - /** - *
    -       * 单个退款代金券支付金额
    -       * coupon_refund_fee_$n_$m
    -       * 否
    -       * Int
    -       * 100
    -       * 单个退款代金券支付金额, $n为下标,$m为下标,从0开始编号
    -       * 
    - */ - @XStreamAlias("coupon_refund_fee") - private Integer couponRefundFee; - - public RefundCoupon(String couponRefundId, Integer couponRefundFee) { - this.couponRefundId = couponRefundId; - this.couponRefundFee = couponRefundFee; - } - - @Deprecated - public RefundCoupon(String couponRefundBatchId, String couponRefundId, Integer couponRefundFee) { - this.couponRefundBatchId = couponRefundBatchId; - this.couponRefundId = couponRefundId; - this.couponRefundFee = couponRefundFee; - } - } + /** + *
    +     * 字段名:退款成功时间.
    +     * 变量名:refund_success_time_$n
    +     * 是否必填:否
    +     * 类型:String(20)
    +     * 示例值:2016-07-25 15:26:26
    +     * 描述:退款成功时间,当退款状态为退款成功时有返回。$n为下标,从0开始编号。
    +     * 
    + */ + @XStreamAlias("refund_success_time") + private String refundSuccessTime; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java index 1e6126b210..18ce1fc830 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java @@ -1,173 +1,142 @@ package com.github.binarywang.wxpay.bean.result; -import com.thoughtworks.xstream.annotations.XStreamAlias; - import java.io.Serializable; +import java.util.List; + +import com.google.common.collect.Lists; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; /** *
    - * 微信支付-申请退款返回结果
    + * 微信支付-申请退款返回结果.
      * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
      * 
    * - * @author liukaitj + * @author liukaitj & Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayRefundResult extends WxPayBaseResult implements Serializable { - private static final long serialVersionUID = 1L; - - @XStreamAlias("device_info") - private String deviceInfo; - +public class WxPayRefundResult extends BaseWxPayResult implements Serializable { + private static final long serialVersionUID = -3392333879907788033L; + /** + * 微信订单号. + */ @XStreamAlias("transaction_id") private String transactionId; + /** + * 商户订单号. + */ @XStreamAlias("out_trade_no") private String outTradeNo; + /** + * 商户退款单号. + */ @XStreamAlias("out_refund_no") private String outRefundNo; + /** + * 微信退款单号. + */ @XStreamAlias("refund_id") private String refundId; - @XStreamAlias("refund_channel") - private String refundChannel; - + /** + * 退款金额. + */ @XStreamAlias("refund_fee") - private String refundFee; + private Integer refundFee; + /** + * 应结退款金额. + */ + @XStreamAlias("settlement_refund_fee") + private Integer settlementRefundFee; + + /** + * 标价金额. + */ @XStreamAlias("total_fee") - private String totalFee; + private Integer totalFee; + + /** + * 应结订单金额. + */ + @XStreamAlias("settlement_total_fee") + private Integer settlementTotalFee; + /** + * 标价币种. + */ @XStreamAlias("fee_type") private String feeType; + /** + * 现金支付金额. + */ @XStreamAlias("cash_fee") - private String cashFee; + private Integer cashFee; + /** + * 现金支付币种. + */ + @XStreamAlias("cash_fee_type") + private String cashFeeType; + + /** + * 现金退款金额. + */ @XStreamAlias("cash_refund_fee") private String cashRefundFee; - @XStreamAlias("coupon_refund_fee") - private String couponRefundFee; - + /** + * 退款代金券使用数量. + */ @XStreamAlias("coupon_refund_count") - private String couponRefundCount; - - @XStreamAlias("coupon_refund_id") - private String couponRefundId; - - public String getDeviceInfo() { - return this.deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public String getTransactionId() { - return this.transactionId; - } - - public void setTransactionId(String transactionId) { - this.transactionId = transactionId; - } - - public String getOutTradeNo() { - return this.outTradeNo; - } - - public void setOutTradeNo(String outTradeNo) { - this.outTradeNo = outTradeNo; - } - - public String getOutRefundNo() { - return this.outRefundNo; - } - - public void setOutRefundNo(String outRefundNo) { - this.outRefundNo = outRefundNo; - } - - public String getRefundId() { - return this.refundId; - } - - public void setRefundId(String refundId) { - this.refundId = refundId; - } - - public String getRefundChannel() { - return this.refundChannel; - } - - public void setRefundChannel(String refundChannel) { - this.refundChannel = refundChannel; - } - - public String getRefundFee() { - return this.refundFee; - } - - public void setRefundFee(String refundFee) { - this.refundFee = refundFee; - } - - public String getTotalFee() { - return this.totalFee; - } - - public void setTotalFee(String totalFee) { - this.totalFee = totalFee; - } - - public String getFeeType() { - return this.feeType; - } - - public void setFeeType(String feeType) { - this.feeType = feeType; - } - - public String getCashFee() { - return this.cashFee; - } - - public void setCashFee(String cashFee) { - this.cashFee = cashFee; - } - - public String getCashRefundFee() { - return this.cashRefundFee; - } - - public void setCashRefundFee(String cashRefundFee) { - this.cashRefundFee = cashRefundFee; - } - - public String getCouponRefundFee() { - return this.couponRefundFee; - } - - public void setCouponRefundFee(String couponRefundFee) { - this.couponRefundFee = couponRefundFee; - } - - public String getCouponRefundCount() { - return this.couponRefundCount; - } - - public void setCouponRefundCount(String couponRefundCount) { - this.couponRefundCount = couponRefundCount; - } - - public String getCouponRefundId() { - return this.couponRefundId; - } - - public void setCouponRefundId(String couponRefundId) { - this.couponRefundId = couponRefundId; + private Integer couponRefundCount; + + /** + *
    +   * 字段名:代金券退款总金额.
    +   * 变量名:coupon_refund_fee
    +   * 是否必填:否
    +   * 类型:Int
    +   * 示例值:100
    +   * 描述:代金券退款金额<=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见代金券或立减优惠
    +   * 
    + */ + @XStreamAlias("coupon_refund_fee") + private Integer couponRefundFee; + + private List refundCoupons; + + /** + * 组装生成退款代金券信息. + */ + public void composeRefundCoupons() { + List coupons = Lists.newArrayList(); + Integer refundCount = this.getCouponRefundCount(); + if (refundCount == null) { + //无退款代金券信息 + return; + } + + for (int i = 0; i < refundCount; i++) { + coupons.add( + new WxPayRefundCouponInfo( + this.getXmlValue("xml/coupon_refund_id_" + i), + this.getXmlValueAsInt("xml/coupon_refund_fee_" + i), + this.getXmlValue("xml/coupon_type_" + i) + ) + ); + } + + this.setRefundCoupons(coupons); } - } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java index 6326f694d3..cf3f9355db 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java @@ -1,6 +1,9 @@ package com.github.binarywang.wxpay.bean.result; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; /** *
    @@ -9,8 +12,11 @@
      *
      * @author Binary Wang
      */
    +@Data
    +@EqualsAndHashCode(callSuper = true)
    +@NoArgsConstructor
     @XStreamAlias("xml")
    -public class WxPaySandboxSignKeyResult extends WxPayBaseResult {
    +public class WxPaySandboxSignKeyResult extends BaseWxPayResult {
     
       /**
        * 
    @@ -25,11 +31,4 @@ public class WxPaySandboxSignKeyResult extends WxPayBaseResult {
       @XStreamAlias("sandbox_signkey")
       private String sandboxSignKey;
     
    -  public String getSandboxSignKey() {
    -    return sandboxSignKey;
    -  }
    -
    -  public void setSandboxSignKey(String sandboxSignKey) {
    -    this.sandboxSignKey = sandboxSignKey;
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
    index 868f089b74..2855daef79 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
    @@ -1,6 +1,9 @@
     package com.github.binarywang.wxpay.bean.result;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
    +import lombok.NoArgsConstructor;
     
     import java.io.Serializable;
     
    @@ -10,8 +13,11 @@
      *
      * @author kane
      */
    +@Data
    +@EqualsAndHashCode(callSuper = true)
    +@NoArgsConstructor
     @XStreamAlias("xml")
    -public class WxPaySendRedpackResult extends WxPayBaseResult implements Serializable {
    +public class WxPaySendRedpackResult extends BaseWxPayResult implements Serializable {
       private static final long serialVersionUID = -4837415036337132073L;
     
       @XStreamAlias("mch_billno")
    @@ -32,51 +38,4 @@ public class WxPaySendRedpackResult extends WxPayBaseResult implements Serializa
       @XStreamAlias("send_listid")
       private String sendListid;
     
    -  public String getMchBillno() {
    -    return this.mchBillno;
    -  }
    -
    -  public void setMchBillno(String mchBillno) {
    -    this.mchBillno = mchBillno;
    -  }
    -
    -  public String getWxappid() {
    -    return this.wxappid;
    -  }
    -
    -  public void setWxappid(String wxappid) {
    -    this.wxappid = wxappid;
    -  }
    -
    -  public String getReOpenid() {
    -    return this.reOpenid;
    -  }
    -
    -  public void setReOpenid(String reOpenid) {
    -    this.reOpenid = reOpenid;
    -  }
    -
    -  public int getTotalAmount() {
    -    return this.totalAmount;
    -  }
    -
    -  public void setTotalAmount(int totalAmount) {
    -    this.totalAmount = totalAmount;
    -  }
    -
    -  public String getSendTime() {
    -    return this.sendTime;
    -  }
    -
    -  public void setSendTime(String sendTime) {
    -    this.sendTime = sendTime;
    -  }
    -
    -  public String getSendListid() {
    -    return this.sendListid;
    -  }
    -
    -  public void setSendListid(String sendListid) {
    -    this.sendListid = sendListid;
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
    index 2f93cb81bf..1937004f47 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
    @@ -1,16 +1,23 @@
     package com.github.binarywang.wxpay.bean.result;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
    +import lombok.NoArgsConstructor;
     
     /**
      * 
      * 转换短链接结果对象类
      * Created by Binary Wang on 2017-3-27.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author Binary Wang */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor @XStreamAlias("xml") -public class WxPayShorturlResult extends WxPayBaseResult { +public class WxPayShorturlResult extends BaseWxPayResult { /** *
        * URL链接
    @@ -24,11 +31,4 @@ public class WxPayShorturlResult extends WxPayBaseResult {
       @XStreamAlias("short_url")
       private String shortUrl;
     
    -  public String getShortUrl() {
    -    return this.shortUrl;
    -  }
    -
    -  public void setShortUrl(String shortUrl) {
    -    this.shortUrl = shortUrl;
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
    index d8ab2ab6df..cf97f75abc 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
    @@ -1,6 +1,9 @@
     package com.github.binarywang.wxpay.bean.result;
     
     import com.thoughtworks.xstream.annotations.XStreamAlias;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
    +import lombok.NoArgsConstructor;
     
     /**
      * 
    @@ -10,8 +13,11 @@
      *
      * @author chanjarster
      */
    +@Data
    +@EqualsAndHashCode(callSuper = true)
    +@NoArgsConstructor
     @XStreamAlias("xml")
    -public class WxPayUnifiedOrderResult extends WxPayBaseResult {
    +public class WxPayUnifiedOrderResult extends BaseWxPayResult {
     
       /**
        * 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
    @@ -37,35 +43,4 @@ public class WxPayUnifiedOrderResult extends WxPayBaseResult {
       @XStreamAlias("code_url")
       private String codeURL;
     
    -  public String getPrepayId() {
    -    return this.prepayId;
    -  }
    -
    -  public void setPrepayId(String prepayId) {
    -    this.prepayId = prepayId;
    -  }
    -
    -  public String getTradeType() {
    -    return this.tradeType;
    -  }
    -
    -  public void setTradeType(String tradeType) {
    -    this.tradeType = tradeType;
    -  }
    -
    -  public String getCodeURL() {
    -    return this.codeURL;
    -  }
    -
    -  public void setCodeURL(String codeURL) {
    -    this.codeURL = codeURL;
    -  }
    -
    -  public String getMwebUrl() {
    -    return mwebUrl;
    -  }
    -
    -  public void setMwebUrl(String mwebUrl) {
    -    this.mwebUrl = mwebUrl;
    -  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxScanPayNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxScanPayNotifyResult.java
    deleted file mode 100644
    index cdb94a9b79..0000000000
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxScanPayNotifyResult.java
    +++ /dev/null
    @@ -1,24 +0,0 @@
    -package com.github.binarywang.wxpay.bean.result;
    -
    -import com.thoughtworks.xstream.annotations.XStreamAlias;
    -
    -import java.io.Serializable;
    -
    -public class WxScanPayNotifyResult extends WxPayBaseResult implements Serializable {
    -  private static final long serialVersionUID = 3381324564266118986L;
    -
    -  /**
    -   * 预支付ID
    -   */
    -  @XStreamAlias("prepay_id")
    -  private String prepayId;
    -
    -  public String getPrepayId() {
    -    return prepayId;
    -  }
    -
    -  public void setPrepayId(String prepayId) {
    -    this.prepayId = prepayId;
    -  }
    -
    -}
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java
    index 7d8cd5e1e3..e35d0b25c3 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java
    @@ -1,199 +1,140 @@
     package com.github.binarywang.wxpay.config;
     
    -import com.github.binarywang.wxpay.exception.WxPayException;
    -import org.apache.commons.io.IOUtils;
    -import org.apache.commons.lang3.StringUtils;
    -import org.apache.http.ssl.SSLContexts;
    -
    -import javax.net.ssl.SSLContext;
    +import java.io.ByteArrayInputStream;
     import java.io.File;
     import java.io.FileInputStream;
     import java.io.IOException;
     import java.io.InputStream;
     import java.security.KeyStore;
    +import javax.net.ssl.SSLContext;
    +
    +import org.apache.commons.io.IOUtils;
    +import org.apache.commons.lang3.StringUtils;
    +import org.apache.http.ssl.SSLContexts;
    +
    +import com.github.binarywang.wxpay.exception.WxPayException;
    +import lombok.Data;
     
     /**
      * 微信支付配置
      *
      * @author Binary Wang (https://github.com/binarywang)
      */
    +@Data
     public class WxPayConfig {
     
       /**
    -   * http请求连接超时时间
    +   * http请求连接超时时间.
        */
       private int httpConnectionTimeout = 5000;
     
       /**
    -   * http请求数据读取等待时间
    +   * http请求数据读取等待时间.
        */
       private int httpTimeout = 10000;
     
    -  private String appId;
    -  private String subAppId;
    -  private String mchId;
    -  private String mchKey;
    -  private String subMchId;
    -  private String notifyUrl;
    -  private String tradeType;
    -  private SSLContext sslContext;
    -  private String keyPath;
    -  private boolean useSandboxEnv = false;
    -  private String httpProxyHost;
    -  private Integer httpProxyPort;
    -  private String httpProxyUsername;
    -  private String httpProxyPassword;
    -
    -  public String getKeyPath() {
    -    return keyPath;
    -  }
    -
    -  /**
    -   * 设置证书
    -   *
    -   * @param keyPath apiclient_cert.p12的文件的绝对路径
    -   */
    -  public void setKeyPath(String keyPath) {
    -    this.keyPath = keyPath;
    -  }
    -
       /**
    -   * 商户号
    +   * 公众号appid.
        */
    -  public String getMchId() {
    -    return this.mchId;
    -  }
    -
    -  public void setMchId(String mchId) {
    -    this.mchId = mchId;
    -  }
    -
    +  private String appId;
       /**
    -   * 商户密钥
    +   * 服务商模式下的子商户公众账号ID.
        */
    -  public String getMchKey() {
    -    return this.mchKey;
    -  }
    -
    -  public void setMchKey(String mchKey) {
    -    this.mchKey = mchKey;
    -  }
    -
    +  private String subAppId;
       /**
    -   * 公众号appid
    +   * 商户号.
        */
    -  public String getAppId() {
    -    return this.appId;
    -  }
    -
    -  public void setAppId(String appId) {
    -    this.appId = appId;
    -  }
    -
    +  private String mchId;
       /**
    -   * 服务商模式下的子商户公众账号ID
    +   * 商户密钥.
        */
    -  public String getSubAppId() {
    -    return this.subAppId;
    -  }
    -
    -  public void setSubAppId(String subAppId) {
    -    this.subAppId = subAppId;
    -  }
    -
    +  private String mchKey;
       /**
    -   * 服务商模式下的子商户号
    +   * 服务商模式下的子商户号.
        */
    -  public String getSubMchId() {
    -    return this.subMchId;
    -  }
    -
    -  public void setSubMchId(String subMchId) {
    -    this.subMchId = subMchId;
    -  }
    -
    +  private String subMchId;
       /**
    -   * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数。
    +   * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数.
        */
    -  public String getNotifyUrl() {
    -    return this.notifyUrl;
    -  }
    -
    -  public void setNotifyUrl(String notifyUrl) {
    -    this.notifyUrl = notifyUrl;
    -  }
    -
    +  private String notifyUrl;
       /**
    -   * 交易类型
    +   * 交易类型.
        * 
        * JSAPI--公众号支付
        * NATIVE--原生扫码支付
        * APP--app支付
        * 
    */ - public String getTradeType() { - return this.tradeType; - } - - public void setTradeType(String tradeType) { - this.tradeType = tradeType; - } - - public SSLContext getSslContext() { - return this.sslContext; - } - - public void setSslContext(SSLContext sslContext) { - this.sslContext = sslContext; - } + private String tradeType; + /** + * 签名方式. + * 有两种HMAC_SHA256 和MD5 + * + * @see com.github.binarywang.wxpay.constant.WxPayConstants.SignType + */ + private String signType; + private SSLContext sslContext; + /** + * p12证书文件的绝对路径或者以classpath:开头的类路径. + */ + private String keyPath; /** - * 微信支付是否使用仿真测试环境 + * p12证书文件内容的字节数组. + */ + private byte[] keyContent; + /** + * 微信支付是否使用仿真测试环境. * 默认不使用 */ - public boolean useSandbox() { - return this.useSandboxEnv; - } + private boolean useSandboxEnv = false; + private String httpProxyHost; + private Integer httpProxyPort; + private String httpProxyUsername; + private String httpProxyPassword; /** - * 设置是否使用沙箱仿真测试环境 + * 初始化ssl. + * + * @return the ssl context + * @throws WxPayException the wx pay exception */ - public void setUseSandboxEnv(boolean useSandboxEnv) { - this.useSandboxEnv = useSandboxEnv; - } - public SSLContext initSSLContext() throws WxPayException { if (StringUtils.isBlank(this.getMchId())) { throw new WxPayException("请确保商户号mchId已设置"); } - if (StringUtils.isBlank(this.getKeyPath())) { - throw new WxPayException("请确保证书文件地址keyPath已配置"); - } - InputStream inputStream; - final String prefix = "classpath:"; - String fileHasProblemMsg = "证书文件【" + this.getKeyPath() + "】有问题,请核实!"; - String fileNotFoundMsg = "证书文件【" + this.getKeyPath() + "】不存在,请核实!"; - if (this.getKeyPath().startsWith(prefix)) { - String path = StringUtils.removeFirst(this.getKeyPath(), prefix); - if (!path.startsWith("/")) { - path = "/" + path; - } - inputStream = WxPayConfig.class.getResourceAsStream(path); - if (inputStream == null) { - throw new WxPayException(fileNotFoundMsg); - } + if (this.keyContent != null) { + inputStream = new ByteArrayInputStream(this.keyContent); } else { - try { - File file = new File(this.getKeyPath()); - if (!file.exists()) { + if (StringUtils.isBlank(this.getKeyPath())) { + throw new WxPayException("请确保证书文件地址keyPath已配置"); + } + + final String prefix = "classpath:"; + String fileHasProblemMsg = "证书文件【" + this.getKeyPath() + "】有问题,请核实!"; + String fileNotFoundMsg = "证书文件【" + this.getKeyPath() + "】不存在,请核实!"; + if (this.getKeyPath().startsWith(prefix)) { + String path = StringUtils.removeFirst(this.getKeyPath(), prefix); + if (!path.startsWith("/")) { + path = "/" + path; + } + inputStream = WxPayConfig.class.getResourceAsStream(path); + if (inputStream == null) { throw new WxPayException(fileNotFoundMsg); } - - inputStream = new FileInputStream(file); - } catch (IOException e) { - throw new WxPayException(fileHasProblemMsg, e); + } else { + try { + File file = new File(this.getKeyPath()); + if (!file.exists()) { + throw new WxPayException(fileNotFoundMsg); + } + + inputStream = new FileInputStream(file); + } catch (IOException e) { + throw new WxPayException(fileHasProblemMsg, e); + } } } @@ -204,63 +145,10 @@ public SSLContext initSSLContext() throws WxPayException { this.sslContext = SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build(); return this.sslContext; } catch (Exception e) { - throw new WxPayException(fileHasProblemMsg, e); + throw new WxPayException("证书文件有问题,请核实!", e); } finally { IOUtils.closeQuietly(inputStream); } } - /** - * http请求连接超时时间 - */ - public int getHttpConnectionTimeout() { - return this.httpConnectionTimeout; - } - - public void setHttpConnectionTimeout(int httpConnectionTimeout) { - this.httpConnectionTimeout = httpConnectionTimeout; - } - - /** - * http请求数据读取等待时间 - */ - public int getHttpTimeout() { - return this.httpTimeout; - } - - public void setHttpTimeout(int httpTimeout) { - this.httpTimeout = httpTimeout; - } - - public String getHttpProxyHost() { - return httpProxyHost; - } - - public void setHttpProxyHost(String httpProxyHost) { - this.httpProxyHost = httpProxyHost; - } - - public Integer getHttpProxyPort() { - return httpProxyPort; - } - - public void setHttpProxyPort(Integer httpProxyPort) { - this.httpProxyPort = httpProxyPort; - } - - public String getHttpProxyUsername() { - return httpProxyUsername; - } - - public void setHttpProxyUsername(String httpProxyUsername) { - this.httpProxyUsername = httpProxyUsername; - } - - public String getHttpProxyPassword() { - return httpProxyPassword; - } - - public void setHttpProxyPassword(String httpProxyPassword) { - this.httpProxyPassword = httpProxyPassword; - } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java index 47f636d0fc..01753c0e51 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/constant/WxPayConstants.java @@ -1,6 +1,10 @@ package com.github.binarywang.wxpay.constant; -import java.text.SimpleDateFormat; +import com.google.common.collect.Lists; +import org.apache.commons.lang3.time.FastDateFormat; + +import java.text.Format; +import java.util.List; /** *
    @@ -13,99 +17,304 @@
     public class WxPayConstants {
     
       /**
    -   * 拉取订单评价数据接口的参数中日期格式
    +   * 拉取订单评价数据接口的参数中日期格式.
        */
    -  public static final SimpleDateFormat QUERY_COMMENT_DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
    +  public static final Format QUERY_COMMENT_DATE_FORMAT =  FastDateFormat.getInstance("yyyyMMddHHmmss");
     
       /**
    -   * 校验用户姓名选项,企业付款时使用
    +   * 校验用户姓名选项,企业付款时使用.
        */
       public static class CheckNameOption {
         /**
    -     * 不校验真实姓名
    +     * 不校验真实姓名.
          */
         public static final String NO_CHECK = "NO_CHECK";
     
         /**
    -     * 强校验真实姓名
    +     * 强校验真实姓名.
          */
         public static final String FORCE_CHECK = "FORCE_CHECK";
       }
     
       /**
    -   * 订单类型
    +   * 压缩账单的类型.
    +   */
    +  public static class TarType {
    +    /**
    +     * 固定值:GZIP,返回格式为.gzip的压缩包账单.
    +     */
    +    public static final String GZIP = "GZIP";
    +  }
    +
    +  /**
    +   * 账单类型.
        */
       public static class BillType {
         /**
    -     * 查询红包时使用:通过商户订单号获取红包信息
    +     * 查询红包时使用:通过商户订单号获取红包信息.
          */
         public static final String MCHT = "MCHT";
     
         //以下为下载对账单时的账单类型
         /**
    -     * 返回当日所有订单信息,默认值
    +     * 返回当日所有订单信息,默认值.
          */
         public static final String ALL = "ALL";
         /**
    -     * 返回当日成功支付的订单
    +     * 返回当日成功支付的订单.
          */
         public static final String SUCCESS = "SUCCESS";
         /**
    -     * 返回当日退款订单
    +     * 返回当日退款订单.
          */
         public static final String REFUND = "REFUND";
         /**
    -     * 返回当日充值退款订单(相比其他对账单多一栏“返还手续费”)
    +     * 返回当日充值退款订单(相比其他对账单多一栏“返还手续费”).
          */
         public static final String RECHARGE_REFUND = "RECHARGE_REFUND";
       }
     
       /**
    -   * 交易类型
    +   * 交易类型.
        */
       public static class TradeType {
         /**
    -     * 原生扫码支付
    +     * 原生扫码支付.
          */
         public static final String NATIVE = "NATIVE";
     
         /**
    -     * App支付
    +     * App支付.
          */
         public static final String APP = "APP";
     
         /**
    -     * 公众号支付
    +     * 公众号支付.
          */
         public static final String JSAPI = "JSAPI";
     
         /**
    -     * H5支付
    +     * H5支付.
          */
         public static final String MWEB = "MWEB";
     
         /**
    -     * 刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口
    +     * 刷卡支付.
    +     * 刷卡支付有单独的支付接口,不调用统一下单接口
          */
         public static final String MICROPAY = "MICROPAY";
       }
     
       /**
    -   * 签名类型
    +   * 账户类型
    +   */
    +  public static class AccountType{
    +    /**
    +     * 基本账户
    +     */
    +    public static final String BASIC = "Basic";
    +    /**
    +     * 运营账户
    +     */
    +    public static final String OPERATION = "Operation";
    +    /**
    +     * Fees
    +     */
    +    public static final String FEES = "Fees";
    +  }
    +
    +  /**
    +   * 签名类型.
        */
       public static class SignType {
    +    /**
    +     * The constant HMAC_SHA256.
    +     */
         public static final String HMAC_SHA256 = "HMAC-SHA256";
    +    /**
    +     * The constant MD5.
    +     */
         public static final String MD5 = "MD5";
    +    /**
    +     * The constant ALL_SIGN_TYPES.
    +     */
    +    public static final List ALL_SIGN_TYPES = Lists.newArrayList(HMAC_SHA256, MD5);
       }
     
    -
       /**
    -   * 限定支付方式
    +   * 限定支付方式.
        */
       public static class LimitPay {
         /**
    -     * no_credit--指定不能使用信用卡支付
    +     * no_credit--指定不能使用信用卡支付.
          */
         public static final String NO_CREDIT = "no_credit";
       }
    +
    +  /**
    +   * 业务结果代码.
    +   */
    +  public static class ResultCode {
    +    /**
    +     * 成功.
    +     */
    +    public static final String SUCCESS = "SUCCESS";
    +
    +    /**
    +     * 失败.
    +     */
    +    public static final String FAIL = "FAIL";
    +  }
    +
    +  /**
    +   * 退款资金来源.
    +   */
    +  public static class RefundAccountSource {
    +    /**
    +     * 可用余额退款/基本账户.
    +     */
    +    public static final String RECHARGE_FUNDS = "REFUND_SOURCE_RECHARGE_FUNDS";
    +
    +    /**
    +     * 未结算资金退款.
    +     */
    +    public static final String UNSETTLED_FUNDS = "REFUND_SOURCE_UNSETTLED_FUNDS";
    +
    +  }
    +
    +  /**
    +   * 退款渠道.
    +   */
    +  public static class RefundChannel {
    +    /**
    +     * 原路退款.
    +     */
    +    public static final String ORIGINAL = "ORIGINAL";
    +
    +    /**
    +     * 退回到余额.
    +     */
    +    public static final String BALANCE = "BALANCE";
    +
    +    /**
    +     * 原账户异常退到其他余额账户.
    +     */
    +    public static final String OTHER_BALANCE = "OTHER_BALANCE";
    +
    +    /**
    +     * 原银行卡异常退到其他银行卡.
    +     */
    +    public static final String OTHER_BANKCARD = "OTHER_BANKCARD";
    +  }
    +
    +  /**
    +   * 交易状态.
    +   */
    +  public static class WxpayTradeStatus {
    +    /**
    +     * 支付成功.
    +     */
    +    public static final String SUCCESS = "SUCCESS";
    +
    +    /**
    +     * 支付失败(其他原因,如银行返回失败).
    +     */
    +    public static final String PAY_ERROR = "PAYERROR";
    +
    +    /**
    +     * 用户支付中.
    +     */
    +    public static final String USER_PAYING = "USERPAYING";
    +
    +    /**
    +     * 已关闭.
    +     */
    +    public static final String CLOSED = "CLOSED";
    +
    +    /**
    +     * 未支付.
    +     */
    +    public static final String NOTPAY = "NOTPAY";
    +
    +    /**
    +     * 转入退款.
    +     */
    +    public static final String REFUND = "REFUND";
    +
    +    /**
    +     * 已撤销(刷卡支付).
    +     */
    +    public static final String REVOKED = "REVOKED";
    +  }
    +
    +  /**
    +   * 退款状态.
    +   */
    +  public static class RefundStatus {
    +    /**
    +     * 退款成功.
    +     */
    +    public static final String SUCCESS = "SUCCESS";
    +
    +    /**
    +     * 退款关闭.
    +     */
    +    public static final String REFUND_CLOSE = "REFUNDCLOSE";
    +
    +    /**
    +     * 退款处理中.
    +     */
    +    public static final String PROCESSING = "PROCESSING";
    +
    +    /**
    +     * 退款异常.
    +     * 退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败,可前往商户平台(pay.weixin.qq.com)-交易中心,手动处理此笔退款。
    +     */
    +    public static final String CHANGE = "CHANGE";
    +  }
    +
    +  /**
    +   * 关闭订单结果错误代码.
    +   */
    +  public static class OrderCloseResultErrorCode {
    +    /**
    +     * 订单已支付.
    +     */
    +    public static final String ORDER_PAID = "ORDERPAID";
    +
    +    /**
    +     * 系统错误.
    +     */
    +    public static final String SYSTEM_ERROR = "SYSTEMERROR";
    +
    +    /**
    +     * 订单不存在.
    +     */
    +    public static final String ORDER_NOT_EXIST = "ORDERNOTEXIST";
    +
    +    /**
    +     * 订单已关闭.
    +     */
    +    public static final String ORDER_CLOSED = "ORDERCLOSED";
    +
    +    /**
    +     * 签名错误.
    +     */
    +    public static final String SIGN_ERROR = "SIGNERROR";
    +
    +    /**
    +     * 未使用POST传递参数.
    +     */
    +    public static final String REQUIRE_POST_METHOD = "REQUIRE_POST_METHOD";
    +
    +    /**
    +     * XML格式错误.
    +     */
    +    public static final String XML_FORMAT_ERROR = "XML_FORMAT_ERROR";
    +
    +    /**
    +     * 订单状态错误.
    +     */
    +    public static final String TRADE_STATE_ERROR = "TRADE_STATE_ERROR";
    +  }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter/WxPayOrderNotifyResultConverter.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter/WxPayOrderNotifyResultConverter.java
    index fe35ed2129..cc8a80dad1 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter/WxPayOrderNotifyResultConverter.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/converter/WxPayOrderNotifyResultConverter.java
    @@ -1,8 +1,18 @@
     package com.github.binarywang.wxpay.converter;
     
    +import java.beans.PropertyDescriptor;
    +import java.lang.reflect.Field;
    +import java.util.ArrayList;
    +import java.util.Arrays;
    +import java.util.List;
    +import java.util.Map;
    +
    +import org.apache.commons.lang3.StringUtils;
    +
     import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyCoupon;
     import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
     import com.google.common.base.Function;
    +import com.google.common.collect.Lists;
     import com.google.common.collect.Maps;
     import com.thoughtworks.xstream.annotations.XStreamAlias;
     import com.thoughtworks.xstream.converters.MarshallingContext;
    @@ -12,17 +22,20 @@
     import com.thoughtworks.xstream.io.HierarchicalStreamReader;
     import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
     import com.thoughtworks.xstream.mapper.Mapper;
    -import org.apache.commons.lang3.StringUtils;
    -
    -import java.beans.PropertyDescriptor;
    -import java.lang.reflect.Field;
    -import java.util.ArrayList;
    -import java.util.Arrays;
    -import java.util.List;
    -import java.util.Map;
     
    +/**
    + * The type Wxpay order notify result converter.
    + *
    + * @author aimilin
    + */
     public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter {
     
    +  /**
    +   * Instantiates a new Wx pay order notify result converter.
    +   *
    +   * @param mapper             the mapper
    +   * @param reflectionProvider the reflection provider
    +   */
       public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
         super(mapper, reflectionProvider);
       }
    @@ -57,11 +70,11 @@ public void marshal(Object original, HierarchicalStreamWriter writer, Marshallin
     
       @Override
       protected void marshallField(MarshallingContext context, Object newObj, Field field) {
    -    if (field.getName().equals("couponList")) {
    +    if ("couponList".equals(field.getName())) {
           return;
    -    } else {
    -      super.marshallField(context, newObj, field);
         }
    +
    +    super.marshallField(context, newObj, field);
       }
     
       @Override
    @@ -72,26 +85,26 @@ public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext co
         fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields()));
         Map fieldMap = getFieldMap(fields);
     
    -    List coupons = new ArrayList<>(10);
    +    Map coupons = Maps.newTreeMap();
         while (reader.hasMoreChildren()) {
           reader.moveDown();
           if (fieldMap.containsKey(reader.getNodeName())) {
             Field field = fieldMap.get(reader.getNodeName());
    -        setFieldValue(context, obj, field);
    +        this.setFieldValue(context, obj, field);
           } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) {
             String id = (String) context.convertAnother(obj, String.class);
    -        getIndex(coupons, reader.getNodeName()).setCouponId(id);
    +        this.getElement(coupons, reader.getNodeName()).setCouponId(id);
           } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) {
             String type = (String) context.convertAnother(obj, String.class);
    -        getIndex(coupons, reader.getNodeName()).setCouponType(type);
    +        this.getElement(coupons, reader.getNodeName()).setCouponType(type);
           } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) {
             Integer fee = (Integer) context.convertAnother(obj, Integer.class);
    -        getIndex(coupons, reader.getNodeName()).setCouponFee(fee);
    +        this.getElement(coupons, reader.getNodeName()).setCouponFee(fee);
           }
           reader.moveUp();
         }
     
    -    obj.setCouponList(coupons);
    +    obj.setCouponList(Lists.newArrayList(coupons.values()));
         return obj;
       }
     
    @@ -102,12 +115,12 @@ private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult
             PropertyDescriptor pd = new PropertyDescriptor(field.getName(), obj.getClass());
             pd.getWriteMethod().invoke(obj, val);
           }
    -    } catch (Exception e) {
    +    } catch (Exception ignored) {
         }
       }
     
       private Map getFieldMap(List fields) {
    -    Map fieldMap = Maps.uniqueIndex(fields, new Function() {
    +    return Maps.uniqueIndex(fields, new Function() {
           @Override
           public String apply(Field field) {
             if (field.isAnnotationPresent(XStreamAlias.class)) {
    @@ -116,14 +129,14 @@ public String apply(Field field) {
             return field.getName();
           }
         });
    -    return fieldMap;
       }
     
    -  private WxPayOrderNotifyCoupon getIndex(List coupons, String nodeName) {
    -    Integer index = Integer.valueOf(StringUtils.substring(nodeName, nodeName.lastIndexOf("_") + 1));
    -    if (index >= coupons.size() || coupons.get(index) == null) {
    -      coupons.add(index, new WxPayOrderNotifyCoupon());
    +  private WxPayOrderNotifyCoupon getElement(Map coupons, String nodeName) {
    +    Integer index = Integer.valueOf(StringUtils.substringAfterLast(nodeName, "_"));
    +    if (coupons.get(index) == null) {
    +      coupons.put(index, new WxPayOrderNotifyCoupon());
         }
    +
         return coupons.get(index);
       }
     }
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/exception/WxPayException.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/exception/WxPayException.java
    index 948c7a4995..a5a2552b3c 100644
    --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/exception/WxPayException.java
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/exception/WxPayException.java
    @@ -1,50 +1,72 @@
     package com.github.binarywang.wxpay.exception;
     
    -import com.github.binarywang.wxpay.bean.result.WxPayBaseResult;
    +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
     import com.google.common.base.Joiner;
    +import lombok.Data;
    +import lombok.EqualsAndHashCode;
     
     /**
      * 
      * 微信支付异常结果类
      * Created by Binary Wang on 2017-6-6.
      * 
    + * + * @author BinaryWang */ +@Data +@EqualsAndHashCode(callSuper = false) public class WxPayException extends Exception { + private static final long serialVersionUID = 2214381471513460742L; + + /** + * 自定义错误讯息. + */ private String customErrorMsg; /** - * 返回状态码 + * 返回状态码. */ private String returnCode; /** - * 返回信息 + * 返回信息. */ private String returnMsg; /** - * 业务结果 + * 业务结果. */ private String resultCode; /** - * 错误代码 + * 错误代码. */ private String errCode; /** - * 错误代码描述 + * 错误代码描述. */ private String errCodeDes; /** - * 微信支付返回的结果xml字符串 + * 微信支付返回的结果xml字符串. */ private String xmlString; + /** + * Instantiates a new Wx pay exception. + * + * @param customErrorMsg the custom error msg + */ public WxPayException(String customErrorMsg) { super(customErrorMsg); this.customErrorMsg = customErrorMsg; } + /** + * Instantiates a new Wx pay exception. + * + * @param customErrorMsg the custom error msg + * @param tr the tr + */ public WxPayException(String customErrorMsg, Throwable tr) { super(customErrorMsg, tr); this.customErrorMsg = customErrorMsg; @@ -60,7 +82,13 @@ private WxPayException(Builder builder) { xmlString = builder.xmlString; } - public static WxPayException from(WxPayBaseResult payBaseResult) { + /** + * 通过BaseWxPayResult生成异常对象. + * + * @param payBaseResult the pay base result + * @return the wx pay exception + */ + public static WxPayException from(BaseWxPayResult payBaseResult) { return WxPayException.newBuilder() .xmlString(payBaseResult.getXmlString()) .returnMsg(payBaseResult.getReturnMsg()) @@ -71,34 +99,18 @@ public static WxPayException from(WxPayBaseResult payBaseResult) { .build(); } - public String getXmlString() { - return this.xmlString; - } - - public String getReturnCode() { - return this.returnCode; - } - - public String getReturnMsg() { - return this.returnMsg; - } - - public String getResultCode() { - return this.resultCode; - } - - public String getErrCode() { - return this.errCode; - } - - public String getErrCodeDes() { - return this.errCodeDes; - } - + /** + * New builder builder. + * + * @return the builder + */ public static Builder newBuilder() { return new Builder(); } + /** + * The type Builder. + */ public static final class Builder { private String returnCode; private String returnMsg; @@ -110,49 +122,95 @@ public static final class Builder { private Builder() { } + /** + * Return code builder. + * + * @param returnCode the return code + * @return the builder + */ public Builder returnCode(String returnCode) { this.returnCode = returnCode; return this; } + /** + * Return msg builder. + * + * @param returnMsg the return msg + * @return the builder + */ public Builder returnMsg(String returnMsg) { this.returnMsg = returnMsg; return this; } + /** + * Result code builder. + * + * @param resultCode the result code + * @return the builder + */ public Builder resultCode(String resultCode) { this.resultCode = resultCode; return this; } + /** + * Err code builder. + * + * @param errCode the err code + * @return the builder + */ public Builder errCode(String errCode) { this.errCode = errCode; return this; } + /** + * Err code des builder. + * + * @param errCodeDes the err code des + * @return the builder + */ public Builder errCodeDes(String errCodeDes) { this.errCodeDes = errCodeDes; return this; } + /** + * Xml string builder. + * + * @param xmlString the xml string + * @return the builder + */ public Builder xmlString(String xmlString) { this.xmlString = xmlString; return this; } + /** + * Build wx pay exception. + * + * @return the wx pay exception + */ public WxPayException build() { return new WxPayException(this); } + /** + * Build error msg string. + * + * @return the string + */ public String buildErrorMsg() { - return Joiner.on(",").skipNulls().join(new String[]{ + return Joiner.on(",").skipNulls().join( returnCode == null ? null : String.format("返回代码:[%s]", returnCode), returnMsg == null ? null : String.format("返回信息:[%s]", returnMsg), resultCode == null ? null : String.format("结果代码:[%s]", resultCode), errCode == null ? null : String.format("错误代码:[%s]", errCode), errCodeDes == null ? null : String.format("错误详情:[%s]", errCodeDes), - xmlString == null ? null : "微信返回的原始报文:\n" + xmlString, - }); + xmlString == null ? null : "微信返回的原始报文:\n" + xmlString + ); } } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EntPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EntPayService.java new file mode 100644 index 0000000000..43162f79d3 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EntPayService.java @@ -0,0 +1,95 @@ +package com.github.binarywang.wxpay.service; + +import com.github.binarywang.wxpay.bean.entpay.*; +import com.github.binarywang.wxpay.exception.WxPayException; + +/** + *
    + *  企业付款相关服务类.
    + *  Created by BinaryWang on 2017/12/19.
    + * 
    + * + * @author Binary Wang + */ +public interface EntPayService { + /** + *
    +   * 企业付款API.
    +   * 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。
    +   * 比如目前的保险行业向客户退保、给付、理赔。
    +   * 企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”https://pay.weixin.qq.com/进行操作。
    +   * 注意:与商户微信支付收款资金并非同一账户,需要单独充值。
    +   * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
    +   * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
    +   * 
    + * + * @param request 请求对象 + * @return the ent pay result + * @throws WxPayException the wx pay exception + */ + EntPayResult entPay(EntPayRequest request) throws WxPayException; + + /** + *
    +   * 查询企业付款API.
    +   * 用于商户的企业付款操作进行结果查询,返回付款操作详细结果。
    +   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
    +   * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo
    +   * 
    + * + * @param partnerTradeNo 商户订单号 + * @return the ent pay query result + * @throws WxPayException the wx pay exception + */ + EntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException; + + /** + *
    +   * 获取RSA加密公钥API.
    +   * RSA算法使用说明(非对称加密算法,算法采用RSA/ECB/OAEPPadding模式)
    +   * 1、 调用获取RSA公钥API获取RSA公钥,落地成本地文件,假设为public.pem
    +   * 2、 确定public.pem文件的存放路径,同时修改代码中文件的输入路径,加载RSA公钥
    +   * 3、 用标准的RSA加密库对敏感信息进行加密,选择RSA_PKCS1_OAEP_PADDING填充模式
    +   * (eg:Java的填充方式要选 " RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING")
    +   * 4、 得到进行rsa加密并转base64之后的密文
    +   * 5、 将密文传给微信侧相应字段,如付款接口(enc_bank_no/enc_true_name)
    +   *
    +   * 接口默认输出PKCS#1格式的公钥,商户需根据自己开发的语言选择公钥格式
    +   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4
    +   * 接口链接:https://fraud.mch.weixin.qq.com/risk/getpublickey
    +   * 
    + * + * @return the public key + * @throws WxPayException the wx pay exception + */ + String getPublicKey() throws WxPayException; + + /** + * 企业付款到银行卡. + *
    +   * 用于企业向微信用户银行卡付款
    +   * 目前支持接口API的方式向指定微信用户的银行卡付款。
    +   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_2
    +   * 接口链接:https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank
    +   * 
    + * + * @param request 请求对象 + * @return the ent pay bank result + * @throws WxPayException the wx pay exception + */ + EntPayBankResult payBank(EntPayBankRequest request) throws WxPayException; + + /** + * 企业付款到银行卡查询. + *
    +   * 用于对商户企业付款到银行卡操作进行结果查询,返回付款操作详细结果。
    +   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_3
    +   * 接口链接:https://api.mch.weixin.qq.com/mmpaysptrans/query_bank
    +   * 
    + * + * @param partnerTradeNo 商户订单号 + * @return the ent pay bank query result + * @throws WxPayException the wx pay exception + */ + EntPayBankQueryResult queryPayBank(String partnerTradeNo) throws WxPayException; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index ae058e1478..7e2dff7b53 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -1,31 +1,103 @@ package com.github.binarywang.wxpay.service; +import java.io.File; +import java.util.Date; +import java.util.Map; + import com.github.binarywang.wxpay.bean.WxPayApiData; -import com.github.binarywang.wxpay.bean.coupon.*; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryResult; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendResult; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryResult; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; -import com.github.binarywang.wxpay.bean.request.*; -import com.github.binarywang.wxpay.bean.result.*; +import com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResult; +import com.github.binarywang.wxpay.bean.request.WxPayAuthcode2OpenidRequest; +import com.github.binarywang.wxpay.bean.request.WxPayDownloadBillRequest; +import com.github.binarywang.wxpay.bean.request.WxPayDownloadFundFlowRequest; +import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderCloseRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderReverseRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRefundQueryRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; +import com.github.binarywang.wxpay.bean.request.WxPayReportRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; +import com.github.binarywang.wxpay.bean.request.WxPayShorturlRequest; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.result.WxPayBillResult; +import com.github.binarywang.wxpay.bean.result.WxPayFundFlowResult; +import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderReverseResult; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; -import java.io.File; -import java.util.Date; -import java.util.Map; - /** *
    - * 微信支付相关接口
    + * 微信支付相关接口.
      * Created by Binary Wang on 2016/7/28.
      * 
    * - * @author binarywang (https://github.com/binarywang) + * @author Binary Wang */ public interface WxPayService { + /** + * 获取微信支付请求url前缀,沙箱环境可能不一样. + * + * @return the pay base url + */ + String getPayBaseUrl(); + + /** + * 发送post请求,得到响应字节数组. + * + * @param url 请求地址 + * @param requestStr 请求信息 + * @param useKey 是否使用证书 + * @return 返回请求结果字节数组 byte [ ] + * @throws WxPayException the wx pay exception + */ + byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException; + + /** + * 发送post请求,得到响应字符串. + * + * @param url 请求地址 + * @param requestStr 请求信息 + * @param useKey 是否使用证书 + * @return 返回请求结果字符串 string + * @throws WxPayException the wx pay exception + */ + String post(String url, String requestStr, boolean useKey) throws WxPayException; + + /** + * 获取企业付款服务类. + * + * @return the ent pay service + */ + EntPayService getEntPayService(); + + /** + * 设置企业付款服务类,允许开发者自定义实现类. + * + * @param entPayService the ent pay service + */ + void setEntPayService(EntPayService entPayService); + /** *
    -   * 查询订单(详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
    +   * 查询订单.
    +   * 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
        * 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
        * 需要调用查询接口的情况:
        * ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
    @@ -37,12 +109,33 @@ public interface WxPayService {
        *
        * @param transactionId 微信订单号
        * @param outTradeNo    商户系统内部的订单号,当没提供transactionId时需要传这个。
    +   * @return the wx pay order query result
    +   * @throws WxPayException the wx pay exception
        */
       WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxPayException;
     
       /**
        * 
    -   * 关闭订单
    +   * 查询订单(适合于需要自定义子商户号和子商户appid的情形).
    +   * 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
    +   * 该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。
    +   * 需要调用查询接口的情况:
    +   * ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
    +   * ◆ 调用支付接口后,返回系统错误或未知交易状态情况;
    +   * ◆ 调用被扫支付API,返回USERPAYING的状态;
    +   * ◆ 调用关单或撤销接口API之前,需确认支付状态;
    +   * 接口地址:https://api.mch.weixin.qq.com/pay/orderquery
    +   * 
    + * + * @param request 查询订单请求对象 + * @return the wx pay order query result + * @throws WxPayException the wx pay exception + */ + WxPayOrderQueryResult queryOrder(WxPayOrderQueryRequest request) throws WxPayException; + + /** + *
    +   * 关闭订单.
        * 应用场景
        * 以下情况需要调用关单接口:
        * 1. 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;
    @@ -53,51 +146,92 @@ public interface WxPayService {
        * 
    * * @param outTradeNo 商户系统内部的订单号 + * @return the wx pay order close result + * @throws WxPayException the wx pay exception */ WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxPayException; + /** + *
    +   * 关闭订单(适合于需要自定义子商户号和子商户appid的情形).
    +   * 应用场景
    +   * 以下情况需要调用关单接口:
    +   * 1. 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;
    +   * 2. 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。
    +   * 注意:订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。
    +   * 接口地址:https://api.mch.weixin.qq.com/pay/closeorder
    +   * 是否需要证书:   不需要。
    +   * 
    + * + * @param request 关闭订单请求对象 + * @return the wx pay order close result + * @throws WxPayException the wx pay exception + */ + WxPayOrderCloseResult closeOrder(WxPayOrderCloseRequest request) throws WxPayException; + + /** + * 调用统一下单接口,并组装生成支付所需参数对象. + * + * @param 请使用{@link com.github.binarywang.wxpay.bean.order}包下的类 + * @param request 统一下单请求参数 + * @return 返回 {@link com.github.binarywang.wxpay.bean.order}包下的类对象 + * @throws WxPayException the wx pay exception + */ + T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException; + /** * 统一下单(详见https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1) * 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识" * 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder * * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置) + * @return the wx pay unified order result + * @throws WxPayException the wx pay exception */ WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) throws WxPayException; /** - * 该接口调用“统一下单”接口,并拼装发起支付请求需要的参数 + * 该接口调用“统一下单”接口,并拼装发起支付请求需要的参数. * 详见https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5 * * @param request 请求对象,注意一些参数如appid、mchid等不用设置,方法内会自动从配置对象中获取到(前提是对应配置中已经设置) + * @return the pay info + * @throws WxPayException the wx pay exception + * @deprecated 建议使用 {@link com.github.binarywang.wxpay.service.WxPayService#createOrder(WxPayUnifiedOrderRequest)} */ + @Deprecated Map getPayInfo(WxPayUnifiedOrderRequest request) throws WxPayException; /** - * 获取配置 + * 获取配置. + * + * @return the config */ WxPayConfig getConfig(); /** - * 设置配置对象 + * 设置配置对象. + * + * @param config the config */ void setConfig(WxPayConfig config); /** *
    -   * 微信支付-申请退款
    +   * 微信支付-申请退款.
        * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
        * 接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
        * 
    * * @param request 请求对象 - * @return 退款操作结果 + * @return 退款操作结果 wx pay refund result + * @throws WxPayException the wx pay exception */ WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException; /** *
    -   * 微信支付-查询退款
    +   * 微信支付-查询退款.
        * 应用场景:
        *  提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,
        *  银行卡支付的退款3个工作日后重新查询退款状态。
    @@ -110,32 +244,60 @@ public interface WxPayService {
        * @param outTradeNo    商户订单号
        * @param outRefundNo   商户退款单号
        * @param refundId      微信退款单号
    -   * @return 退款信息
    +   * @return 退款信息 wx pay refund query result
    +   * @throws WxPayException the wx pay exception
        */
       WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, String outRefundNo, String refundId)
         throws WxPayException;
     
       /**
    -   * @see WxPayService#parseOrderNotifyResult(String)
    -   * @deprecated use WxPayService#parseOrderNotifyResult(String) instead
    +   * 
    +   * 微信支付-查询退款(适合于需要自定义子商户号和子商户appid的情形).
    +   * 应用场景:
    +   *  提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,
    +   *  银行卡支付的退款3个工作日后重新查询退款状态。
    +   * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_5
    +   * 接口链接:https://api.mch.weixin.qq.com/pay/refundquery
    +   * 
    + * + * @param request 微信退款单号 + * @return 退款信息 wx pay refund query result + * @throws WxPayException the wx pay exception */ - @Deprecated - WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxPayException; + WxPayRefundQueryResult refundQuery(WxPayRefundQueryRequest request) throws WxPayException; /** - * 解析支付结果通知 + * 解析支付结果通知. * 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 + * + * @param xmlData the xml data + * @return the wx pay order notify result + * @throws WxPayException the wx pay exception */ WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData) throws WxPayException; /** * 解析退款结果通知 * 详见https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=9 + * + * @param xmlData the xml data + * @return the wx pay refund notify result + * @throws WxPayException the wx pay exception */ WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws WxPayException; /** - * 发送微信红包给个人用户 + * 解析扫码支付回调通知 + * 详见https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_4 + * + * @param xmlData the xml data + * @return the wx scan pay notify result + * @throws WxPayException the wx pay exception + */ + WxScanPayNotifyResult parseScanPayNotifyResult(String xmlData) throws WxPayException; + + /** + * 发送微信红包给个人用户. *
        * 文档详见:
        * 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
    @@ -145,51 +307,29 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 
    * * @param request 请求对象 + * @return the wx pay send redpack result + * @throws WxPayException the wx pay exception */ WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException; /** *
    -   *   查询红包记录
    +   *   查询红包记录.
        *   用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
    -   *   请求Url	https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
    -   *   是否需要证书	是(证书及使用说明详见商户证书)
    -   *   请求方式	POST
    +   *   请求Url:https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
    +   *   是否需要证书:是(证书及使用说明详见商户证书)
    +   *   请求方式:POST
        * 
    * * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890 + * @return the wx pay redpack query result + * @throws WxPayException the wx pay exception */ WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException; /** *
    -   * 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。
    -   * 比如目前的保险行业向客户退保、给付、理赔。
    -   * 企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”https://pay.weixin.qq.com/进行操作。
    -   * 注意:与商户微信支付收款资金并非同一账户,需要单独充值。
    -   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
    -   * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
    -   * 
    - * - * @param request 请求对象 - */ - WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException; - - /** - *
    -   * 查询企业付款API
    -   * 用于商户的企业付款操作进行结果查询,返回付款操作详细结果。
    -   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
    -   * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo
    -   * 
    - * - * @param partnerTradeNo 商户订单号 - */ - WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException; - - /** - *
    -   * 扫码支付模式一生成二维码的方法
    +   * 扫码支付模式一生成二维码的方法。
        * 二维码中的内容为链接,形式为:
        * weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
        * 其中XXXXX为商户需要填写的内容,商户将该链接生成二维码,如需要打印发布二维码,需要采用此格式。商户可调用第三方库生成二维码图片。
    @@ -197,15 +337,15 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 
    * * @param productId 产品Id - * @param sideLength 要生成的二维码的边长,如果为空,则取默认值400 * @param logoFile 商户logo图片的文件对象,可以为空 - * @return 生成的二维码的字节数组 + * @param sideLength 要生成的二维码的边长,如果为空,则取默认值400 + * @return 生成的二维码的字节数组 byte [ ] */ byte[] createScanPayQrcodeMode1(String productId, File logoFile, Integer sideLength); /** *
    -   * 扫码支付模式一生成二维码的方法
    +   * 扫码支付模式一生成二维码的方法.
        * 二维码中的内容为链接,形式为:
        * weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
        * 其中XXXXX为商户需要填写的内容,商户将该链接生成二维码,如需要打印发布二维码,需要采用此格式。商户可调用第三方库生成二维码图片。
    @@ -213,13 +353,13 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 
    * * @param productId 产品Id - * @return 生成的二维码URL连接 + * @return 生成的二维码URL连接 string */ String createScanPayQrcodeMode1(String productId); /** *
    -   * 扫码支付模式二生成二维码的方法
    +   * 扫码支付模式二生成二维码的方法.
        * 对应链接格式:weixin://wxpay/bizpayurl?sr=XXXXX。请商户调用第三方库将code_url生成二维码图片。
        * 该模式链接较短,生成的二维码打印到结账小票上的识别率较高。
        * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5
    @@ -228,13 +368,13 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * @param codeUrl    微信返回的交易会话的二维码链接
        * @param logoFile   商户logo图片的文件对象,可以为空
        * @param sideLength 要生成的二维码的边长,如果为空,则取默认值400
    -   * @return 生成的二维码的字节数组
    +   * @return 生成的二维码的字节数组 byte [ ]
        */
       byte[] createScanPayQrcodeMode2(String codeUrl, File logoFile, Integer sideLength);
     
       /**
        * 
    -   * 交易保障
    +   * 交易保障.
        * 应用场景:
        *  商户在调用微信支付提供的相关接口时,会得到微信支付返回的相关信息以及获得整个接口的响应时间。
        *  为提高整体的服务水平,协助商户一起提高服务质量,微信支付提供了相关接口调用耗时和返回信息的主动上报接口,
    @@ -242,12 +382,15 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 接口地址: https://api.mch.weixin.qq.com/payitil/report
        * 是否需要证书:不需要
        * 
    + * + * @param request the request + * @throws WxPayException the wx pay exception */ void report(WxPayReportRequest request) throws WxPayException; /** *
    -   * 下载对账单
    +   * 下载对账单.
        * 商户可以通过该接口下载历史交易清单。比如掉单、系统错误等导致商户侧和微信侧数据不一致,通过对账单核对后可校正支付状态。
        * 注意:
        * 1、微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致,bill_type为REVOKED;
    @@ -258,17 +401,75 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 详情请见: 下载对账单
        * 
    * - * @param billDate 对账单日期 bill_date 下载对账单的日期,格式:20140603 - * @param billType 账单类型 bill_type ALL,返回当日所有订单信息,默认值,SUCCESS,返回当日成功支付的订单,REFUND,返回当日退款订单 - * @param tarType 压缩账单 tar_type 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。 - * @param deviceInfo 设备号 device_info 非必传参数,终端设备号 - * @return 保存到本地的临时文件 + * @param billDate 对账单日期 bill_date 下载对账单的日期,格式:20140603 + * @param billType 账单类型 bill_type ALL,返回当日所有订单信息,默认值,SUCCESS,返回当日成功支付的订单,REFUND,返回当日退款订单 + * @param tarType 压缩账单 tar_type 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。 + * @param deviceInfo 设备号 device_info 非必传参数,终端设备号 + * @return WxPayBillResult对象 wx pay bill result + * @throws WxPayException the wx pay exception */ WxPayBillResult downloadBill(String billDate, String billType, String tarType, String deviceInfo) throws WxPayException; /** *
    -   * 提交刷卡支付
    +   * 下载对账单(适合于需要自定义子商户号和子商户appid的情形).
    +   * 商户可以通过该接口下载历史交易清单。比如掉单、系统错误等导致商户侧和微信侧数据不一致,通过对账单核对后可校正支付状态。
    +   * 注意:
    +   * 1、微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致,bill_type为REVOKED;
    +   * 2、微信在次日9点启动生成前一天的对账单,建议商户10点后再获取;
    +   * 3、对账单中涉及金额的字段单位为“元”。
    +   * 4、对账单接口只能下载三个月以内的账单。
    +   * 接口链接:https://api.mch.weixin.qq.com/pay/downloadbill
    +   * 详情请见: 下载对账单
    +   * 
    + * + * @param request 下载对账单请求 + * @return WxPayBillResult对象 wx pay bill result + * @throws WxPayException the wx pay exception + */ + WxPayBillResult downloadBill(WxPayDownloadBillRequest request) throws WxPayException; + + /** + *
    +   * 下载资金账单.
    +   * 商户可以通过该接口下载自2017年6月1日起 的历史资金流水账单。
    +   * 注意:
    +   * 1、资金账单中的数据反映的是商户微信账户资金变动情况;
    +   * 2、当日账单在次日上午9点开始生成,建议商户在上午10点以后获取;
    +   * 3、资金账单中涉及金额的字段单位为“元”。
    +   * 接口链接:https://api.mch.weixin.qq.com/pay/downloadfundflow
    +   * 详情请见: 下载对账单
    +   * 
    + * + * @param billDate 资金账单日期 bill_date 下载对账单的日期,格式:20140603 + * @param accountType 资金账户类型 account_type Basic,基本账户,Operation,运营账户,Fees,手续费账户 + * @param tarType 压缩账单 tar_type 非必传参数,固定值:GZIP,返回格式为.gzip的压缩包账单。不传则默认为数据流形式。 + * @return WxPayFundFlowResult对象 wx pay fund flow result + * @throws WxPayException the wx pay exception + */ + WxPayFundFlowResult downloadFundFlow(String billDate, String accountType, String tarType) throws WxPayException; + + /** + *
    +   * 下载资金账单.
    +   * 商户可以通过该接口下载自2017年6月1日起 的历史资金流水账单。
    +   * 注意:
    +   * 1、资金账单中的数据反映的是商户微信账户资金变动情况;
    +   * 2、当日账单在次日上午9点开始生成,建议商户在上午10点以后获取;
    +   * 3、资金账单中涉及金额的字段单位为“元”。
    +   * 接口链接:https://api.mch.weixin.qq.com/pay/downloadfundflow
    +   * 详情请见: 下载对账单
    +   * 
    + * + * @param request 下载资金流水请求 + * @return WxPayFundFlowResult对象 wx pay fund flow result + * @throws WxPayException the wx pay exception + */ + WxPayFundFlowResult downloadFundFlow(WxPayDownloadFundFlowRequest request) throws WxPayException; + + /** + *
    +   * 提交刷卡支付.
        * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
        * 应用场景:
        * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,由商户收银台或者商户后台调用该接口发起支付。
    @@ -277,12 +478,16 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 接口地址:   https://api.mch.weixin.qq.com/pay/micropay
        * 是否需要证书:不需要。
        * 
    + * + * @param request the request + * @return the wx pay micropay result + * @throws WxPayException the wx pay exception */ WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxPayException; /** *
    -   * 撤销订单API
    +   * 撤销订单API.
        * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
        * 应用场景:
        *  支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,微信支付系统会将此订单关闭;
    @@ -293,12 +498,16 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        *  接口链接 :https://api.mch.weixin.qq.com/secapi/pay/reverse
        *  是否需要证书:请求需要双向证书。
        * 
    + * + * @param request the request + * @return the wx pay order reverse result + * @throws WxPayException the wx pay exception */ WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxPayException; /** *
    -   *  转换短链接
    +   *  转换短链接.
        *  文档地址:
        *     https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_9&index=8
        *  应用场景:
    @@ -308,22 +517,26 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 
    * * @param request 请求对象 + * @return the string + * @throws WxPayException the wx pay exception */ String shorturl(WxPayShorturlRequest request) throws WxPayException; /** *
    -   *  转换短链接
    +   *  转换短链接.
        * 
    * * @param longUrl 需要被压缩的网址 - * @see WxPayService#shorturl(WxPayShorturlRequest) + * @return the string + * @throws WxPayException the wx pay exception + * @see WxPayService#shorturl(WxPayShorturlRequest) WxPayService#shorturl(WxPayShorturlRequest) */ String shorturl(String longUrl) throws WxPayException; /** *
    -   * 授权码查询OPENID接口
    +   * 授权码查询OPENID接口.
        *    通过授权码查询公众号Openid,调用查询后,该授权码只能由此商户号发起扣款,直至授权码更新。
        * 文档地址:
        *    https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9
    @@ -332,29 +545,34 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 
    * * @param request 请求对象 - * @return openid + * @return openid string + * @throws WxPayException the wx pay exception */ String authcode2Openid(WxPayAuthcode2OpenidRequest request) throws WxPayException; /** *
    -   * 授权码查询OPENID接口
    +   * 授权码查询OPENID接口.
        * 
    * * @param authCode 授权码 - * @return openid - * @see WxPayService#authcode2Openid(WxPayAuthcode2OpenidRequest) + * @return openid string + * @throws WxPayException the wx pay exception + * @see WxPayService#authcode2Openid(WxPayAuthcode2OpenidRequest) WxPayService#authcode2Openid(WxPayAuthcode2OpenidRequest) */ String authcode2Openid(String authCode) throws WxPayException; /** *
    -   * 获取仿真测试系统的验签密钥
    +   * 获取仿真测试系统的验签密钥.
        * 请求Url: https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey
        * 是否需要证书: 否
        * 请求方式: POST
        * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_1
        * 
    + * + * @return the sandbox sign key + * @throws WxPayException the wx pay exception */ String getSandboxSignKey() throws WxPayException; @@ -365,35 +583,49 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri * 是否需要证书:请求需要双向证书。 * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_3 *
    + * + * @param request the request + * @return the wx pay coupon send result + * @throws WxPayException the wx pay exception */ WxPayCouponSendResult sendCoupon(WxPayCouponSendRequest request) throws WxPayException; /** *
    -   * 查询代金券批次
    +   * 查询代金券批次.
        * 接口请求链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock
        * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_4
        * 
    + * + * @param request the request + * @return the wx pay coupon stock query result + * @throws WxPayException the wx pay exception */ WxPayCouponStockQueryResult queryCouponStock(WxPayCouponStockQueryRequest request) throws WxPayException; /** *
    -   * 查询代金券信息
    +   * 查询代金券信息.
        * 接口请求链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/querycouponsinfo
        * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_5
        * 
    + * + * @param request the request + * @return the wx pay coupon info query result + * @throws WxPayException the wx pay exception */ WxPayCouponInfoQueryResult queryCouponInfo(WxPayCouponInfoQueryRequest request) throws WxPayException; /** - * 获取微信请求数据,方便接口调用方获取处理 + * 获取微信请求数据,方便接口调用方获取处理. + * + * @return the wx api data */ WxPayApiData getWxApiData(); /** *
    -   * 拉取订单评价数据
    +   * 拉取订单评价数据.
        * 商户可以通过该接口拉取用户在微信支付交易记录中针对你的支付记录进行的评价内容。商户可结合商户系统逻辑对该内容数据进行存储、分析、展示、客服回访以及其他使用。如商户业务对评价内容有依赖,可主动引导用户进入微信支付交易记录进行评价。
        * 注意:
        * 1. 该内容所有权为提供内容的微信用户,商户在使用内容的过程中应遵从用户意愿
    @@ -403,10 +635,13 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
        * 是否需要证书:需要
        * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_17&index=10
        * 
    + * * @param beginDate 开始时间 * @param endDate 结束时间 * @param offset 位移 - * @param limit 条数 + * @param limit 条数,建议填null,否则接口会报签名错误 + * @return the string + * @throws WxPayException the wx pay exception */ String queryComment(Date beginDate, Date endDate, Integer offset, Integer limit) throws WxPayException; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java similarity index 55% rename from weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImpl.java rename to weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index e77d3e1fc8..591b4a2427 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -1,31 +1,84 @@ package com.github.binarywang.wxpay.service.impl; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipException; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.github.binarywang.utils.qrcode.QrcodeUtils; import com.github.binarywang.wxpay.bean.WxPayApiData; -import com.github.binarywang.wxpay.bean.coupon.*; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryResult; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendResult; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryResult; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; +import com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResult; import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult; import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; +import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult; import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult; -import com.github.binarywang.wxpay.bean.request.*; -import com.github.binarywang.wxpay.bean.result.*; +import com.github.binarywang.wxpay.bean.request.WxPayAuthcode2OpenidRequest; +import com.github.binarywang.wxpay.bean.request.WxPayDefaultRequest; +import com.github.binarywang.wxpay.bean.request.WxPayDownloadBillRequest; +import com.github.binarywang.wxpay.bean.request.WxPayDownloadFundFlowRequest; +import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderCloseRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderReverseRequest; +import com.github.binarywang.wxpay.bean.request.WxPayQueryCommentRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRedpackQueryRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRefundQueryRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; +import com.github.binarywang.wxpay.bean.request.WxPayReportRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; +import com.github.binarywang.wxpay.bean.request.WxPayShorturlRequest; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.github.binarywang.wxpay.bean.result.WxPayAuthcode2OpenidResult; +import com.github.binarywang.wxpay.bean.result.WxPayBillBaseResult; +import com.github.binarywang.wxpay.bean.result.WxPayBillResult; +import com.github.binarywang.wxpay.bean.result.WxPayCommonResult; +import com.github.binarywang.wxpay.bean.result.WxPayFundFlowBaseResult; +import com.github.binarywang.wxpay.bean.result.WxPayFundFlowResult; +import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderReverseResult; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; +import com.github.binarywang.wxpay.bean.result.WxPaySandboxSignKeyResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; +import com.github.binarywang.wxpay.bean.result.WxPayShorturlResult; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.constant.WxPayConstants.BillType; import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.EntPayService; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.util.SignUtils; +import com.google.common.base.Joiner; import com.google.common.collect.Maps; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.util.*; +import jodd.io.ZipUtil; import static com.github.binarywang.wxpay.constant.WxPayConstants.QUERY_COMMENT_DATE_FORMAT; +import static com.github.binarywang.wxpay.constant.WxPayConstants.TarType; /** *
    @@ -35,13 +88,34 @@
      *
      * @author Binary Wang
      */
    -public abstract class WxPayServiceAbstractImpl implements WxPayService {
    +public abstract class BaseWxPayServiceImpl implements WxPayService {
       private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com";
    +  /**
    +   * The Log.
    +   */
       protected final Logger log = LoggerFactory.getLogger(this.getClass());
    +  /**
    +   * The constant wxApiData.
    +   */
       protected static ThreadLocal wxApiData = new ThreadLocal<>();
     
    +  private EntPayService entPayService = new EntPayServiceImpl(this);
    +
    +  /**
    +   * The Config.
    +   */
       protected WxPayConfig config;
     
    +  @Override
    +  public EntPayService getEntPayService() {
    +    return entPayService;
    +  }
    +
    +  @Override
    +  public void setEntPayService(EntPayService entPayService) {
    +    this.entPayService = entPayService;
    +  }
    +
       @Override
       public WxPayConfig getConfig() {
         return this.config;
    @@ -52,32 +126,24 @@ public void setConfig(WxPayConfig config) {
         this.config = config;
       }
     
    -  private String getPayBaseUrl() {
    -    if (this.getConfig().useSandbox()) {
    +  @Override
    +  public String getPayBaseUrl() {
    +    if (this.getConfig().isUseSandboxEnv()) {
           return PAY_BASE_URL + "/sandboxnew";
         }
     
         return PAY_BASE_URL;
       }
     
    -  /**
    -   * 发送post请求
    -   *
    -   * @param url        请求地址
    -   * @param requestStr 请求信息
    -   * @param useKey     是否使用证书
    -   * @return 返回请求结果字符串
    -   */
    -  protected abstract String post(String url, String requestStr, boolean useKey) throws WxPayException;
    -
       @Override
       public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
     
         String url = this.getPayBaseUrl() + "/secapi/pay/refund";
         String responseContent = this.post(url, request.toXML(), true);
    -    WxPayRefundResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundResult.class);
    -    result.checkResult(this);
    +    WxPayRefundResult result = BaseWxPayResult.fromXML(responseContent, WxPayRefundResult.class);
    +    result.composeRefundCoupons();
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -90,29 +156,28 @@ public WxPayRefundQueryResult refundQuery(String transactionId, String outTradeN
         request.setOutRefundNo(StringUtils.trimToNull(outRefundNo));
         request.setRefundId(StringUtils.trimToNull(refundId));
     
    +    return this.refundQuery(request);
    +  }
    +
    +  @Override
    +  public WxPayRefundQueryResult refundQuery(WxPayRefundQueryRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
     
         String url = this.getPayBaseUrl() + "/pay/refundquery";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayRefundQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRefundQueryResult.class);
    +    WxPayRefundQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayRefundQueryResult.class);
         result.composeRefundRecords();
    -    result.checkResult(this);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    -  @Override
    -  @Deprecated
    -  public WxPayOrderNotifyResult getOrderNotifyResult(String xmlData) throws WxPayException {
    -    return this.parseOrderNotifyResult(xmlData);
    -  }
    -
       @Override
       public WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData) throws WxPayException {
         try {
           log.debug("微信支付异步通知请求参数:{}", xmlData);
           WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlData);
           log.debug("微信支付异步通知请求解析后的对象:{}", result);
    -      result.checkResult(this);
    +      result.checkResult(this, this.getConfig().getSignType(), false);
           return result;
         } catch (WxPayException e) {
           log.error(e.getMessage(), e);
    @@ -136,6 +201,24 @@ public WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws Wx
         }
       }
     
    +  @Override
    +  public WxScanPayNotifyResult parseScanPayNotifyResult(String xmlData) throws WxPayException {
    +    try {
    +      log.debug("扫码支付回调通知请求参数:{}", xmlData);
    +      WxScanPayNotifyResult result = BaseWxPayResult.fromXML(xmlData, WxScanPayNotifyResult.class);
    +      log.debug("扫码支付回调通知解析后的对象:{}", result);
    +      result.checkResult(this, this.getConfig().getSignType(), false);
    +      return result;
    +    } catch (WxPayException e) {
    +      log.error(e.getMessage(), e);
    +      throw e;
    +    } catch (Exception e) {
    +      log.error(e.getMessage(), e);
    +      throw new WxPayException("发生异常," + e.getMessage(), e);
    +    }
    +
    +  }
    +
       @Override
       public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
    @@ -147,10 +230,8 @@ public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throw
         }
     
         String responseContent = this.post(url, request.toXML(), true);
    -    WxPaySendRedpackResult result = WxPayBaseResult.fromXML(responseContent, WxPaySendRedpackResult.class);
    -    //毋须校验,因为没有返回签名信息
    -    // this.checkResult(result);
    -    return result;
    +    //无需校验,因为没有返回签名信息
    +    return BaseWxPayResult.fromXML(responseContent, WxPaySendRedpackResult.class);
       }
     
       @Override
    @@ -162,8 +243,8 @@ public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayExcept
     
         String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo";
         String responseContent = this.post(url, request.toXML(), true);
    -    WxPayRedpackQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayRedpackQueryResult.class);
    -    result.checkResult(this);
    +    WxPayRedpackQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayRedpackQueryResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -172,6 +253,12 @@ public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo)
         WxPayOrderQueryRequest request = new WxPayOrderQueryRequest();
         request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
         request.setTransactionId(StringUtils.trimToNull(transactionId));
    +
    +    return this.queryOrder(request);
    +  }
    +
    +  @Override
    +  public WxPayOrderQueryResult queryOrder(WxPayOrderQueryRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
     
         String url = this.getPayBaseUrl() + "/pay/orderquery";
    @@ -180,9 +267,9 @@ public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo)
           throw new WxPayException("无响应结果");
         }
     
    -    WxPayOrderQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderQueryResult.class);
    +    WxPayOrderQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayOrderQueryResult.class);
         result.composeCoupons();
    -    result.checkResult(this);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -194,39 +281,58 @@ public WxPayOrderCloseResult closeOrder(String outTradeNo) throws WxPayException
     
         WxPayOrderCloseRequest request = new WxPayOrderCloseRequest();
         request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
    +
    +    return this.closeOrder(request);
    +  }
    +
    +  @Override
    +  public WxPayOrderCloseResult closeOrder(WxPayOrderCloseRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
     
         String url = this.getPayBaseUrl() + "/pay/closeorder";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayOrderCloseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderCloseResult.class);
    -    result.checkResult(this);
    +    WxPayOrderCloseResult result = BaseWxPayResult.fromXML(responseContent, WxPayOrderCloseResult.class);
    +    result.checkResult(this, request.getSignType(), true);
     
         return result;
       }
     
    +  @Override
       public  T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
         WxPayUnifiedOrderResult unifiedOrderResult = this.unifiedOrder(request);
         String prepayId = unifiedOrderResult.getPrepayId();
         if (StringUtils.isBlank(prepayId)) {
    -      throw new RuntimeException(String.format("无法获取prepay id,错误代码: '%s',信息:%s。",
    +      throw new WxPayException(String.format("无法获取prepay id,错误代码: '%s',信息:%s。",
             unifiedOrderResult.getErrCode(), unifiedOrderResult.getErrCodeDes()));
         }
     
         String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
         String nonceStr = String.valueOf(System.currentTimeMillis());
    -    Object payResult = null;
         switch (request.getTradeType()) {
    +      case TradeType.MWEB: {
    +        return (T) new WxPayMwebOrderResult(unifiedOrderResult.getMwebUrl());
    +      }
    +
           case TradeType.NATIVE: {
    -        payResult = WxPayNativeOrderResult.newBuilder().codeUrl(unifiedOrderResult.getCodeURL())
    -          .build();
    -        break;
    +        return (T) new WxPayNativeOrderResult(unifiedOrderResult.getCodeURL());
           }
    +
           case TradeType.APP: {
             // APP支付绑定的是微信开放平台上的账号,APPID为开放平台上绑定APP后发放的参数
    -        String appId = this.getConfig().getAppId();
    -        Map configMap = new HashMap<>();
    +        String appId = unifiedOrderResult.getAppid();
    +        if (StringUtils.isNotEmpty(unifiedOrderResult.getSubAppId())) {
    +          appId = unifiedOrderResult.getSubAppId();
    +        }
    +
    +        Map configMap = new HashMap<>(8);
             // 此map用于参与调起sdk支付的二次签名,格式全小写,timestamp只能是10位,格式固定,切勿修改
    -        String partnerId = getConfig().getMchId();
    +        String partnerId;
    +        if (StringUtils.isEmpty(request.getMchId())) {
    +          partnerId = this.getConfig().getMchId();
    +        } else {
    +          partnerId = request.getMchId();
    +        }
    +
             configMap.put("prepayid", prepayId);
             configMap.put("partnerid", partnerId);
             String packageValue = "Sign=WXPay";
    @@ -235,8 +341,8 @@ public  T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException
             configMap.put("noncestr", nonceStr);
             configMap.put("appid", appId);
     
    -        payResult = WxPayAppOrderResult.newBuilder()
    -          .sign(SignUtils.createSign(configMap, this.getConfig().getMchKey(), null))
    +        final WxPayAppOrderResult result = WxPayAppOrderResult.builder()
    +          .sign(SignUtils.createSign(configMap, null, this.getConfig().getMchKey(), null))
               .prepayId(prepayId)
               .partnerId(partnerId)
               .appId(appId)
    @@ -244,23 +350,33 @@ public  T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException
               .timeStamp(timestamp)
               .nonceStr(nonceStr)
               .build();
    -        break;
    +        return (T) result;
           }
    +
           case TradeType.JSAPI: {
    -        payResult = WxPayMpOrderResult.newBuilder()
    -          .appId(unifiedOrderResult.getAppid())
    +        String signType = SignType.MD5;
    +        String appid = unifiedOrderResult.getAppid();
    +        if (StringUtils.isNotEmpty(unifiedOrderResult.getSubAppId())) {
    +          appid = unifiedOrderResult.getSubAppId();
    +        }
    +
    +        WxPayMpOrderResult payResult = WxPayMpOrderResult.builder()
    +          .appId(appid)
               .timeStamp(timestamp)
               .nonceStr(nonceStr)
               .packageValue("prepay_id=" + prepayId)
    -          .signType(SignType.MD5)
    +          .signType(signType)
               .build();
    -        ((WxPayMpOrderResult) payResult)
    -          .setPaySign(SignUtils.createSign(payResult, this.getConfig().getMchKey(), null));
    -        break;
    +
    +        payResult.setPaySign(SignUtils.createSign(payResult, signType, this.getConfig().getMchKey(), null));
    +        return (T) payResult;
    +      }
    +
    +      default: {
    +        throw new WxPayException("该交易类型暂不支持");
           }
         }
     
    -    return (T) payResult;
       }
     
       @Override
    @@ -269,12 +385,13 @@ public WxPayUnifiedOrderResult unifiedOrder(WxPayUnifiedOrderRequest request) th
     
         String url = this.getPayBaseUrl() + "/pay/unifiedorder";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayUnifiedOrderResult result = WxPayBaseResult.fromXML(responseContent, WxPayUnifiedOrderResult.class);
    -    result.checkResult(this);
    +    WxPayUnifiedOrderResult result = BaseWxPayResult.fromXML(responseContent, WxPayUnifiedOrderResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
       @Override
    +  @Deprecated
       public Map getPayInfo(WxPayUnifiedOrderRequest request) throws WxPayException {
         WxPayUnifiedOrderResult unifiedOrderResult = this.unifiedOrder(request);
         String prepayId = unifiedOrderResult.getPrepayId();
    @@ -302,7 +419,7 @@ public Map getPayInfo(WxPayUnifiedOrderRequest request) throws W
           configMap.put("noncestr", nonceStr);
           configMap.put("appid", appId);
           // 此map用于客户端与微信服务器交互
    -      payInfo.put("sign", SignUtils.createSign(configMap, this.getConfig().getMchKey(), null));
    +      payInfo.put("sign", SignUtils.createSign(configMap, null, this.getConfig().getMchKey(), null));
           payInfo.put("prepayId", prepayId);
           payInfo.put("partnerId", partnerId);
           payInfo.put("appId", appId);
    @@ -316,36 +433,12 @@ public Map getPayInfo(WxPayUnifiedOrderRequest request) throws W
           payInfo.put("nonceStr", nonceStr);
           payInfo.put("package", "prepay_id=" + prepayId);
           payInfo.put("signType", SignType.MD5);
    -      payInfo.put("paySign", SignUtils.createSign(payInfo, this.getConfig().getMchKey(), null));
    +      payInfo.put("paySign", SignUtils.createSign(payInfo, null, this.getConfig().getMchKey(), null));
         }
     
         return payInfo;
       }
     
    -  @Override
    -  public WxEntPayResult entPay(WxEntPayRequest request) throws WxPayException {
    -    request.checkAndSign(this.getConfig());
    -    String url = this.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers";
    -
    -    String responseContent = this.post(url, request.toXML(), true);
    -    WxEntPayResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayResult.class);
    -    result.checkResult(this);
    -    return result;
    -  }
    -
    -  @Override
    -  public WxEntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException {
    -    WxEntPayQueryRequest request = new WxEntPayQueryRequest();
    -    request.setPartnerTradeNo(partnerTradeNo);
    -    request.checkAndSign(this.getConfig());
    -
    -    String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo";
    -    String responseContent = this.post(url, request.toXML(), true);
    -    WxEntPayQueryResult result = WxPayBaseResult.fromXML(responseContent, WxEntPayQueryResult.class);
    -    result.checkResult(this);
    -    return result;
    -  }
    -
       @Override
       public byte[] createScanPayQrcodeMode1(String productId, File logoFile, Integer sideLength) {
         String content = this.createScanPayQrcodeMode1(productId);
    @@ -360,14 +453,15 @@ public String createScanPayQrcodeMode1(String productId) {
         params.put("appid", this.getConfig().getAppId());
         params.put("mch_id", this.getConfig().getMchId());
         params.put("product_id", productId);
    -    params.put("time_stamp", String.valueOf(System.currentTimeMillis() / 1000));//这里需要秒,10位数字
    +    //这里需要秒,10位数字
    +    params.put("time_stamp", String.valueOf(System.currentTimeMillis() / 1000));
         params.put("nonce_str", String.valueOf(System.currentTimeMillis()));
     
    -    String sign = SignUtils.createSign(params, this.getConfig().getMchKey(), null);
    +    String sign = SignUtils.createSign(params, null, this.getConfig().getMchKey(), null);
         params.put("sign", sign);
     
         for (String key : params.keySet()) {
    -      codeUrl.append(key + "=" + params.get(key) + "&");
    +      codeUrl.append(key).append("=").append(params.get(key)).append("&");
         }
     
         String content = codeUrl.toString().substring(0, codeUrl.length() - 1);
    @@ -388,35 +482,83 @@ private byte[] createQrcode(String content, File logoFile, Integer sideLength) {
         return QrcodeUtils.createQrcode(content, sideLength, logoFile);
       }
     
    +  @Override
       public void report(WxPayReportRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
     
         String url = this.getPayBaseUrl() + "/payitil/report";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayCommonResult result = WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class);
    -    result.checkResult(this);
    +    WxPayCommonResult result = BaseWxPayResult.fromXML(responseContent, WxPayCommonResult.class);
    +    result.checkResult(this, request.getSignType(), true);
       }
     
       @Override
       public WxPayBillResult downloadBill(String billDate, String billType, String tarType, String deviceInfo) throws WxPayException {
    +    if (!BillType.ALL.equals(billType)) {
    +      throw new WxPayException("目前仅支持ALL类型的对账单下载");
    +    }
    +
         WxPayDownloadBillRequest request = new WxPayDownloadBillRequest();
         request.setBillType(billType);
         request.setBillDate(billDate);
         request.setTarType(tarType);
         request.setDeviceInfo(deviceInfo);
     
    +    return this.downloadBill(request);
    +  }
    +
    +  @Override
    +  public WxPayBillResult downloadBill(WxPayDownloadBillRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
     
         String url = this.getPayBaseUrl() + "/pay/downloadbill";
    -    String responseContent = this.post(url, request.toXML(), false);
    -    if (responseContent.startsWith("<")) {
    -      throw WxPayException.from(WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class));
    +
    +    String responseContent;
    +    if (TarType.GZIP.equals(request.getTarType())) {
    +      responseContent = this.handleGzipBill(url, request.toXML());
         } else {
    -      return this.handleBillInformation(responseContent);
    +      responseContent = this.post(url, request.toXML(), false);
    +      if (responseContent.startsWith("<")) {
    +        throw WxPayException.from(BaseWxPayResult.fromXML(responseContent, WxPayCommonResult.class));
    +      }
         }
    +
    +    return this.handleBill(request.getBillType(), responseContent);
    +  }
    +
    +  private WxPayBillResult handleBill(String billType, String responseContent) {
    +    if (!BillType.ALL.equals(billType)) {
    +      return null;
    +    }
    +
    +    return this.handleAllBill(responseContent);
       }
     
    -  private WxPayBillResult handleBillInformation(String responseContent) {
    +  private String handleGzipBill(String url, String requestStr) throws WxPayException {
    +    try {
    +      byte[] responseBytes = this.postForBytes(url, requestStr, false);
    +      Path tempDirectory = Files.createTempDirectory("bill");
    +      Path path = Paths.get(tempDirectory.toString(), System.currentTimeMillis() + ".gzip");
    +      Files.write(path, responseBytes);
    +      try {
    +        List allLines = Files.readAllLines(ZipUtil.ungzip(path.toFile()).toPath(), StandardCharsets.UTF_8);
    +        return Joiner.on("\n").join(allLines);
    +      } catch (ZipException e) {
    +        if (e.getMessage().contains("Not in GZIP format")) {
    +          throw WxPayException.from(BaseWxPayResult.fromXML(new String(responseBytes, StandardCharsets.UTF_8),
    +            WxPayCommonResult.class));
    +        } else {
    +          this.log.error("解压zip文件出错", e);
    +        }
    +      }
    +    } catch (Exception e) {
    +      this.log.error("解析对账单文件时出错", e);
    +    }
    +
    +    return null;
    +  }
    +
    +  private WxPayBillResult handleAllBill(String responseContent) {
         WxPayBillResult wxPayBillResult = new WxPayBillResult();
     
         String listStr = "";
    @@ -433,11 +575,16 @@ private WxPayBillResult handleBillInformation(String responseContent) {
          * 参考以上格式进行取值
          */
         List wxPayBillBaseResultLst = new LinkedList<>();
    -    String newStr = listStr.replaceAll(",", " "); // 去空格
    -    String[] tempStr = newStr.split("`"); // 数据分组
    -    String[] t = tempStr[0].split(" ");// 分组标题
    -    int j = tempStr.length / t.length; // 计算循环次数
    -    int k = 1; // 纪录数组下标
    +    // 去空格
    +    String newStr = listStr.replaceAll(",", " ");
    +    // 数据分组
    +    String[] tempStr = newStr.split("`");
    +    // 分组标题
    +    String[] t = tempStr[0].split(" ");
    +    // 计算循环次数
    +    int j = tempStr.length / t.length;
    +    // 纪录数组下标
    +    int k = 1;
         for (int i = 0; i < j; i++) {
           WxPayBillBaseResult wxPayBillBaseResult = new WxPayBillBaseResult();
     
    @@ -446,7 +593,7 @@ private WxPayBillResult handleBillInformation(String responseContent) {
           wxPayBillBaseResult.setMchId(tempStr[k + 2].trim());
           wxPayBillBaseResult.setSubMchId(tempStr[k + 3].trim());
           wxPayBillBaseResult.setDeviceInfo(tempStr[k + 4].trim());
    -      wxPayBillBaseResult.setTransationId(tempStr[k + 5].trim());
    +      wxPayBillBaseResult.setTransactionId(tempStr[k + 5].trim());
           wxPayBillBaseResult.setOutTradeNo(tempStr[k + 6].trim());
           wxPayBillBaseResult.setOpenId(tempStr[k + 7].trim());
           wxPayBillBaseResult.setTradeType(tempStr[k + 8].trim());
    @@ -485,14 +632,133 @@ private WxPayBillResult handleBillInformation(String responseContent) {
         return wxPayBillResult;
       }
     
    +  @Override
    +  public WxPayFundFlowResult downloadFundFlow(String billDate, String accountType, String tarType) throws WxPayException {
    +
    +    WxPayDownloadFundFlowRequest request = new WxPayDownloadFundFlowRequest();
    +    request.setBillDate(billDate);
    +    request.setAccountType(accountType);
    +    request.setTarType(tarType);
    +
    +    return this.downloadFundFlow(request);
    +  }
    +
    +  @Override
    +  public WxPayFundFlowResult downloadFundFlow(WxPayDownloadFundFlowRequest request) throws WxPayException {
    +    request.checkAndSign(this.getConfig());
    +
    +    String url = this.getPayBaseUrl() + "/pay/downloadfundflow";
    +
    +    String responseContent;
    +    if (TarType.GZIP.equals(request.getTarType())) {
    +      responseContent = this.handleGzipFundFlow(url, request.toXML());
    +    } else {
    +      responseContent = this.post(url, request.toXML(), true);
    +      if (responseContent.startsWith("<")) {
    +        throw WxPayException.from(BaseWxPayResult.fromXML(responseContent, WxPayCommonResult.class));
    +      }
    +    }
    +
    +    return this.handleFundFlow(responseContent);
    +  }
    +
    +  private String handleGzipFundFlow(String url, String requestStr) throws WxPayException {
    +    try {
    +      byte[] responseBytes = this.postForBytes(url, requestStr, true);
    +      Path tempDirectory = Files.createTempDirectory("fundFlow");
    +      Path path = Paths.get(tempDirectory.toString(), System.currentTimeMillis() + ".gzip");
    +      Files.write(path, responseBytes);
    +
    +      try {
    +        List allLines = Files.readAllLines(ZipUtil.ungzip(path.toFile()).toPath(), StandardCharsets.UTF_8);
    +        return Joiner.on("\n").join(allLines);
    +      } catch (ZipException e) {
    +        if (e.getMessage().contains("Not in GZIP format")) {
    +          throw WxPayException.from(BaseWxPayResult.fromXML(new String(responseBytes, StandardCharsets.UTF_8),
    +            WxPayCommonResult.class));
    +        } else {
    +          this.log.error("解压zip文件出错", e);
    +          throw new WxPayException("解压zip文件出错");
    +        }
    +      }
    +    } catch (WxPayException wxPayException) {
    +      throw wxPayException;
    +    } catch (Exception e) {
    +      this.log.error("解析对账单文件时出错", e);
    +      throw new WxPayException("解压zip文件出错");
    +    }
    +  }
    +
    +  private WxPayFundFlowResult handleFundFlow(String responseContent) {
    +    WxPayFundFlowResult wxPayFundFlowResult = new WxPayFundFlowResult();
    +
    +    String listStr = "";
    +    String objStr = "";
    +
    +    if (StringUtils.isNotBlank(responseContent) && responseContent.contains("资金流水总笔数")) {
    +      listStr = responseContent.substring(0, responseContent.indexOf("资金流水总笔数"));
    +      objStr = responseContent.substring(responseContent.indexOf("资金流水总笔数"));
    +    }
    +    /*
    +     * 记账时间:2018-02-01 04:21:23 微信支付业务单号:50000305742018020103387128253 资金流水单号:1900009231201802015884652186 业务名称:退款
    +     * 业务类型:退款 收支类型:支出 收支金额(元):0.02 账户结余(元):0.17 资金变更提交申请人:system 备注:缺货 业务凭证号:REF4200000068201801293084726067
    +     * 参考以上格式进行取值
    +     */
    +    List wxPayFundFlowBaseResultList = new LinkedList<>();
    +    // 去空格
    +    String newStr = listStr.replaceAll(",", " ");
    +    // 数据分组
    +    String[] tempStr = newStr.split("`");
    +    // 分组标题
    +    String[] t = tempStr[0].split(" ");
    +    // 计算循环次数
    +    int j = tempStr.length / t.length;
    +    // 纪录数组下标
    +    int k = 1;
    +    for (int i = 0; i < j; i++) {
    +      WxPayFundFlowBaseResult wxPayFundFlowBaseResult = new WxPayFundFlowBaseResult();
    +
    +      wxPayFundFlowBaseResult.setBillingTime(tempStr[k].trim());
    +      wxPayFundFlowBaseResult.setBizTransactionId(tempStr[k + 1].trim());
    +      wxPayFundFlowBaseResult.setFundFlowId(tempStr[k + 2].trim());
    +      wxPayFundFlowBaseResult.setBizName(tempStr[k + 3].trim());
    +      wxPayFundFlowBaseResult.setBizType(tempStr[k + 4].trim());
    +      wxPayFundFlowBaseResult.setFinancialType(tempStr[k + 5].trim());
    +      wxPayFundFlowBaseResult.setFinancialFee(tempStr[k + 6].trim());
    +      wxPayFundFlowBaseResult.setAccountBalance(tempStr[k + 7].trim());
    +      wxPayFundFlowBaseResult.setFundApplicant(tempStr[k + 8].trim());
    +      wxPayFundFlowBaseResult.setMemo(tempStr[k + 9].trim());
    +      wxPayFundFlowBaseResult.setBizVoucherId(tempStr[k + 10].trim());
    +
    +      wxPayFundFlowBaseResultList.add(wxPayFundFlowBaseResult);
    +      k += t.length;
    +    }
    +    wxPayFundFlowResult.setWxPayFundFlowBaseResultList(wxPayFundFlowBaseResultList);
    +
    +    /*
    +     * 资金流水总笔数,收入笔数,收入金额,支出笔数,支出金额 `20.0,`17.0,`0.35,`3.0,`0.18
    +     * 参考以上格式进行取值
    +     */
    +    String totalStr = objStr.replaceAll(",", " ");
    +    String[] totalTempStr = totalStr.split("`");
    +    wxPayFundFlowResult.setTotalRecord(totalTempStr[1]);
    +    wxPayFundFlowResult.setIncomeRecord(totalTempStr[2]);
    +    wxPayFundFlowResult.setIncomeAmount(totalTempStr[3]);
    +    wxPayFundFlowResult.setExpenditureRecord(totalTempStr[4]);
    +    wxPayFundFlowResult.setExpenditureAmount(totalTempStr[5]);
    +
    +    return wxPayFundFlowResult;
    +
    +  }
    +
       @Override
       public WxPayMicropayResult micropay(WxPayMicropayRequest request) throws WxPayException {
         request.checkAndSign(this.getConfig());
     
         String url = this.getPayBaseUrl() + "/pay/micropay";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayMicropayResult result = WxPayBaseResult.fromXML(responseContent, WxPayMicropayResult.class);
    -    result.checkResult(this);
    +    WxPayMicropayResult result = BaseWxPayResult.fromXML(responseContent, WxPayMicropayResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -502,8 +768,8 @@ public WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) th
     
         String url = this.getPayBaseUrl() + "/secapi/pay/reverse";
         String responseContent = this.post(url, request.toXML(), true);
    -    WxPayOrderReverseResult result = WxPayBaseResult.fromXML(responseContent, WxPayOrderReverseResult.class);
    -    result.checkResult(this);
    +    WxPayOrderReverseResult result = BaseWxPayResult.fromXML(responseContent, WxPayOrderReverseResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -513,8 +779,8 @@ public String shorturl(WxPayShorturlRequest request) throws WxPayException {
     
         String url = this.getPayBaseUrl() + "/tools/shorturl";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayShorturlResult result = WxPayBaseResult.fromXML(responseContent, WxPayShorturlResult.class);
    -    result.checkResult(this);
    +    WxPayShorturlResult result = BaseWxPayResult.fromXML(responseContent, WxPayShorturlResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result.getShortUrl();
       }
     
    @@ -529,8 +795,8 @@ public String authcode2Openid(WxPayAuthcode2OpenidRequest request) throws WxPayE
     
         String url = this.getPayBaseUrl() + "/tools/authcodetoopenid";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayAuthcode2OpenidResult result = WxPayBaseResult.fromXML(responseContent, WxPayAuthcode2OpenidResult.class);
    -    result.checkResult(this);
    +    WxPayAuthcode2OpenidResult result = BaseWxPayResult.fromXML(responseContent, WxPayAuthcode2OpenidResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result.getOpenid();
       }
     
    @@ -546,8 +812,8 @@ public String getSandboxSignKey() throws WxPayException {
     
         String url = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPaySandboxSignKeyResult result = WxPayBaseResult.fromXML(responseContent, WxPaySandboxSignKeyResult.class);
    -    result.checkResult(this);
    +    WxPaySandboxSignKeyResult result = BaseWxPayResult.fromXML(responseContent, WxPaySandboxSignKeyResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result.getSandboxSignKey();
       }
     
    @@ -557,8 +823,8 @@ public WxPayCouponSendResult sendCoupon(WxPayCouponSendRequest request) throws W
     
         String url = this.getPayBaseUrl() + "/mmpaymkttransfers/send_coupon";
         String responseContent = this.post(url, request.toXML(), true);
    -    WxPayCouponSendResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponSendResult.class);
    -    result.checkResult(this);
    +    WxPayCouponSendResult result = BaseWxPayResult.fromXML(responseContent, WxPayCouponSendResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -568,8 +834,8 @@ public WxPayCouponStockQueryResult queryCouponStock(WxPayCouponStockQueryRequest
     
         String url = this.getPayBaseUrl() + "/mmpaymkttransfers/query_coupon_stock";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayCouponStockQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponStockQueryResult.class);
    -    result.checkResult(this);
    +    WxPayCouponStockQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayCouponStockQueryResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -579,8 +845,8 @@ public WxPayCouponInfoQueryResult queryCouponInfo(WxPayCouponInfoQueryRequest re
     
         String url = this.getPayBaseUrl() + "/mmpaymkttransfers/querycouponsinfo";
         String responseContent = this.post(url, request.toXML(), false);
    -    WxPayCouponInfoQueryResult result = WxPayBaseResult.fromXML(responseContent, WxPayCouponInfoQueryResult.class);
    -    result.checkResult(this);
    +    WxPayCouponInfoQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayCouponInfoQueryResult.class);
    +    result.checkResult(this, request.getSignType(), true);
         return result;
       }
     
    @@ -610,7 +876,7 @@ public String queryComment(Date beginDate, Date endDate, Integer offset, Integer
     
         String responseContent = this.post(url, request.toXML(), true);
         if (responseContent.startsWith("<")) {
    -      throw WxPayException.from(WxPayBaseResult.fromXML(responseContent, WxPayCommonResult.class));
    +      throw WxPayException.from(BaseWxPayResult.fromXML(responseContent, WxPayCommonResult.class));
         }
     
         return responseContent;
    diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java
    new file mode 100644
    index 0000000000..5be2113b39
    --- /dev/null
    +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java
    @@ -0,0 +1,169 @@
    +package com.github.binarywang.wxpay.service.impl;
    +
    +import java.io.File;
    +import java.io.FileReader;
    +import java.io.IOException;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import javax.crypto.Cipher;
    +
    +import org.apache.commons.codec.binary.Base64;
    +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
    +
    +import com.github.binarywang.wxpay.bean.entpay.EntPayBankQueryRequest;
    +import com.github.binarywang.wxpay.bean.entpay.EntPayBankQueryResult;
    +import com.github.binarywang.wxpay.bean.entpay.EntPayBankRequest;
    +import com.github.binarywang.wxpay.bean.entpay.EntPayBankResult;
    +import com.github.binarywang.wxpay.bean.entpay.EntPayQueryRequest;
    +import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult;
    +import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
    +import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
    +import com.github.binarywang.wxpay.bean.entpay.GetPublicKeyResult;
    +import com.github.binarywang.wxpay.bean.request.WxPayDefaultRequest;
    +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
    +import com.github.binarywang.wxpay.exception.WxPayException;
    +import com.github.binarywang.wxpay.service.EntPayService;
    +import com.github.binarywang.wxpay.service.WxPayService;
    +
    +/**
    + * 
    + *  Created by BinaryWang on 2017/12/19.
    + * 
    + * + * @author Binary Wang + */ +public class EntPayServiceImpl implements EntPayService { + private WxPayService payService; + + /** + * Instantiates a new Ent pay service. + * + * @param payService the pay service + */ + public EntPayServiceImpl(WxPayService payService) { + this.payService = payService; + } + + @Override + public EntPayResult entPay(EntPayRequest request) throws WxPayException { + request.checkAndSign(this.payService.getConfig()); + String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/promotion/transfers"; + + String responseContent = this.payService.post(url, request.toXML(), true); + EntPayResult result = BaseWxPayResult.fromXML(responseContent, EntPayResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + + @Override + public EntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException { + EntPayQueryRequest request = new EntPayQueryRequest(); + request.setPartnerTradeNo(partnerTradeNo); + request.checkAndSign(this.payService.getConfig()); + + String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo"; + String responseContent = this.payService.post(url, request.toXML(), true); + EntPayQueryResult result = BaseWxPayResult.fromXML(responseContent, EntPayQueryResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + + @Override + public String getPublicKey() throws WxPayException { + WxPayDefaultRequest request = new WxPayDefaultRequest(); + request.setMchId(this.payService.getConfig().getMchId()); + request.setNonceStr(String.valueOf(System.currentTimeMillis())); + + request.checkAndSign(this.payService.getConfig()); + + String url = "https://fraud.mch.weixin.qq.com/risk/getpublickey"; + String responseContent = this.payService.post(url, request.toXML(), true); + GetPublicKeyResult result = BaseWxPayResult.fromXML(responseContent, GetPublicKeyResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result.getPubKey(); + } + + @Override + public EntPayBankResult payBank(EntPayBankRequest request) throws WxPayException { + File publicKeyFile = this.buildPublicKeyFile(); + request.setEncBankNo(this.encryptRSA(publicKeyFile, request.getEncBankNo())); + request.setEncTrueName(this.encryptRSA(publicKeyFile, request.getEncTrueName())); + publicKeyFile.deleteOnExit(); + + request.checkAndSign(this.payService.getConfig()); + + String url = this.payService.getPayBaseUrl() + "/mmpaysptrans/pay_bank"; + String responseContent = this.payService.post(url, request.toXML(), true); + EntPayBankResult result = BaseWxPayResult.fromXML(responseContent, EntPayBankResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + + @Override + public EntPayBankQueryResult queryPayBank(String partnerTradeNo) throws WxPayException { + EntPayBankQueryRequest request = new EntPayBankQueryRequest(); + request.setPartnerTradeNo(partnerTradeNo); + request.checkAndSign(this.payService.getConfig()); + + String url = this.payService.getPayBaseUrl() + "/mmpaysptrans/query_bank"; + String responseContent = this.payService.post(url, request.toXML(), true); + EntPayBankQueryResult result = BaseWxPayResult.fromXML(responseContent, EntPayBankQueryResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + + private String encryptRSA(File publicKeyFile, String srcString) throws WxPayException { + try { + Security.addProvider(new BouncyCastleProvider()); + Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); + try (PEMParser reader = new PEMParser(new FileReader(publicKeyFile))) { + final PublicKey publicKey = new JcaPEMKeyConverter().setProvider("BC") + .getPublicKey((SubjectPublicKeyInfo) reader.readObject()); + + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] encrypt = cipher.doFinal(srcString.getBytes()); + return Base64.encodeBase64String(encrypt); + } + } catch (Exception e) { + throw new WxPayException("加密出错", e); + } + } + + private File buildPublicKeyFile() throws WxPayException { + try { + String publicKeyStr = this.getPublicKey(); + Path tmpFile = Files.createTempFile("payToBank", ".pem"); + Files.write(tmpFile, publicKeyStr.getBytes()); + return tmpFile.toFile(); + } catch (Exception e) { + throw new WxPayException("生成加密公钥文件时发生异常", e); + } + } + + /** + * The entry point of application. + * + * @param args the input arguments + * @throws WxPayException the wx pay exception + * @throws IOException the io exception + */ + public static void main(String[] args) throws WxPayException, IOException { + String key = "-----BEGIN RSA PUBLIC KEY-----\n" + + "MIIBCgKCAQEAtEeUSop/YGqZ53Y++R9NapFSZmorj+SL/brmJUU7+hyClEnPOeG/\n" + + "v6/ZrX9qo25JAojrBDbqaW9L+HtzI141vusarRYIGPvVqTV30L5db0Yq7AmX7Hs9\n" + + "s+nEtoMAwMWUzQPXLUs2mt6rpu85HwAIK3F4Xb+OFIbXCJTbDvWYtQssn07lr+IY\n" + + "jPA00sON71egmuRrCoQClkhf0vgrhj7eHUCRZRJ2zf4UU31fHv+kO441hVD5TTP8\n" + + "bjJvFm6TW3sgQE8aCDbomtu+syk4Tv/4ONCqxG8d/kF1TlU+idGWEU179uR/KSjP\n" + + "p7kM7BoaY2goFgYAe4DsI8Fh33dCOiKyVwIDAQAB\n" + + "-----END RSA PUBLIC KEY-----"; + Path tmpFile = Files.createTempFile("payToBank", ".pem"); + Files.write(tmpFile, key.getBytes()); + System.out.println(new EntPayServiceImpl(null).encryptRSA(tmpFile.toFile(), "111111")); + } + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java index 1b3284f95f..753652f4d9 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java @@ -2,7 +2,9 @@ import com.github.binarywang.wxpay.bean.WxPayApiData; import com.github.binarywang.wxpay.exception.WxPayException; +import jodd.util.Base64; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; @@ -19,54 +21,48 @@ import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; +import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; /** *
    - * 微信支付请求实现类,apache httpclient实现
    + * 微信支付请求实现类,apache httpclient实现.
      * Created by Binary Wang on 2016/7/28.
      * 
    * - * @author binarywang (https://github.com/binarywang) + * @author Binary Wang */ -public class WxPayServiceApacheHttpImpl extends WxPayServiceAbstractImpl { - +public class WxPayServiceApacheHttpImpl extends BaseWxPayServiceImpl { @Override - protected String post(String url, String requestStr, boolean useKey) throws WxPayException { + public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { try { - HttpClientBuilder httpClientBuilder = HttpClients.custom(); - if (useKey) { - SSLContext sslContext = this.getConfig().getSslContext(); - if (null == sslContext) { - sslContext = this.getConfig().initSSLContext(); + HttpClientBuilder httpClientBuilder = createHttpClientBuilder(useKey); + HttpPost httpPost = this.createHttpPost(url, requestStr); + try (CloseableHttpClient httpClient = httpClientBuilder.build()) { + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + final byte[] bytes = EntityUtils.toByteArray(response.getEntity()); + final String responseData = Base64.encodeToString(bytes); + this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据(Base64编码后)】:{}", url, requestStr, responseData); + wxApiData.set(new WxPayApiData(url, requestStr, responseData, null)); + return bytes; } - - SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, - new String[]{"TLSv1"}, null, new DefaultHostnameVerifier()); - httpClientBuilder.setSSLSocketFactory(sslsf); - } - - HttpPost httpPost = new HttpPost(url); - - httpPost.setConfig(RequestConfig.custom() - .setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout()) - .setConnectTimeout(this.getConfig().getHttpConnectionTimeout()) - .setSocketTimeout(this.getConfig().getHttpTimeout()) - .build()); - - if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) - && this.getConfig().getHttpProxyPort() > 0) { - // 使用代理服务器 需要用户认证的代理服务器 - CredentialsProvider provider = new BasicCredentialsProvider(); - provider.setCredentials( - new AuthScope(this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort()), - new UsernamePasswordCredentials(this.getConfig().getHttpProxyUsername(), this.getConfig().getHttpProxyPassword())); - httpClientBuilder.setDefaultCredentialsProvider(provider); + } finally { + httpPost.releaseConnection(); } + } catch (Exception e) { + this.log.error("\n【请求地址】:{}\n【请求数据】:{}\n【异常信息】:{}", url, requestStr, e.getMessage()); + wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage())); + throw new WxPayException(e.getMessage(), e); + } + } - try (CloseableHttpClient httpclient = httpClientBuilder.build()) { - httpPost.setEntity(new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1))); - try (CloseableHttpResponse response = httpclient.execute(httpPost)) { + @Override + public String post(String url, String requestStr, boolean useKey) throws WxPayException { + try { + HttpClientBuilder httpClientBuilder = this.createHttpClientBuilder(useKey); + HttpPost httpPost = this.createHttpPost(url, requestStr); + try (CloseableHttpClient httpClient = httpClientBuilder.build()) { + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { String responseString = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", url, requestStr, responseString); wxApiData.set(new WxPayApiData(url, requestStr, responseString, null)); @@ -82,4 +78,55 @@ protected String post(String url, String requestStr, boolean useKey) throws WxPa } } + private StringEntity createEntry(String requestStr) { + try { + return new StringEntity(new String(requestStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); + } catch (UnsupportedEncodingException e) { + //cannot happen + this.log.error(e.getMessage(), e); + return null; + } + } + + private HttpClientBuilder createHttpClientBuilder(boolean useKey) throws WxPayException { + HttpClientBuilder httpClientBuilder = HttpClients.custom(); + if (useKey) { + this.initSSLContext(httpClientBuilder); + } + + if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) && this.getConfig().getHttpProxyPort() > 0) { + // 使用代理服务器 需要用户认证的代理服务器 + CredentialsProvider provider = new BasicCredentialsProvider(); + provider.setCredentials(new AuthScope(this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort()), + new UsernamePasswordCredentials(this.getConfig().getHttpProxyUsername(), this.getConfig().getHttpProxyPassword())); + httpClientBuilder.setDefaultCredentialsProvider(provider); + httpClientBuilder.setProxy(new HttpHost(this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort())); + } + return httpClientBuilder; + } + + private HttpPost createHttpPost(String url, String requestStr) { + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(this.createEntry(requestStr)); + + httpPost.setConfig(RequestConfig.custom() + .setConnectionRequestTimeout(this.getConfig().getHttpConnectionTimeout()) + .setConnectTimeout(this.getConfig().getHttpConnectionTimeout()) + .setSocketTimeout(this.getConfig().getHttpTimeout()) + .build()); + + return httpPost; + } + + private void initSSLContext(HttpClientBuilder httpClientBuilder) throws WxPayException { + SSLContext sslContext = this.getConfig().getSslContext(); + if (null == sslContext) { + sslContext = this.getConfig().initSSLContext(); + } + + SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, + new String[]{"TLSv1"}, null, new DefaultHostnameVerifier()); + httpClientBuilder.setSSLSocketFactory(connectionSocketFactory); + } + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java index bbe024a309..1c7b315db1 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java @@ -1,5 +1,10 @@ package com.github.binarywang.wxpay.service.impl; +import java.nio.charset.StandardCharsets; +import javax.net.ssl.SSLContext; + +import org.apache.commons.lang3.StringUtils; + import com.github.binarywang.wxpay.bean.WxPayApiData; import com.github.binarywang.wxpay.exception.WxPayException; import jodd.http.HttpConnectionProvider; @@ -9,48 +14,35 @@ import jodd.http.ProxyInfo.ProxyType; import jodd.http.net.SSLSocketHttpConnectionProvider; import jodd.http.net.SocketHttpConnectionProvider; -import org.apache.commons.lang3.StringUtils; - -import javax.net.ssl.SSLContext; -import java.nio.charset.StandardCharsets; +import jodd.util.Base64; /** - * 微信支付请求实现类,jodd-http实现 + * 微信支付请求实现类,jodd-http实现. * Created by Binary Wang on 2016/7/28. * - * @author binarywang (https://github.com/binarywang) + * @author Binary Wang */ -public class WxPayServiceJoddHttpImpl extends WxPayServiceAbstractImpl { - +public class WxPayServiceJoddHttpImpl extends BaseWxPayServiceImpl { @Override - protected String post(String url, String requestStr, boolean useKey) throws WxPayException { + public byte[] postForBytes(String url, String requestStr, boolean useKey) throws WxPayException { try { - HttpRequest request = HttpRequest - .post(url) - .timeout(this.getConfig().getHttpTimeout()) - .connectionTimeout(this.getConfig().getHttpConnectionTimeout()) - .bodyText(requestStr); - - if (useKey) { - SSLContext sslContext = this.getConfig().getSslContext(); - if (null == sslContext) { - sslContext = this.getConfig().initSSLContext(); - } - final SSLSocketHttpConnectionProvider provider = new SSLSocketHttpConnectionProvider(sslContext); - request.withConnectionProvider(provider); - } - - if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) && this.getConfig().getHttpProxyPort() > 0) { - ProxyInfo httpProxy = new ProxyInfo(ProxyType.HTTP, this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort(), - this.getConfig().getHttpProxyUsername(), this.getConfig().getHttpProxyPassword()); - HttpConnectionProvider provider = request.connectionProvider(); - if (null == provider) { - provider = new SocketHttpConnectionProvider(); - } - provider.useProxy(httpProxy); - request.withConnectionProvider(provider); - } + HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); + byte[] responseBytes = request.send().bodyBytes(); + final String responseString = Base64.encodeToString(responseBytes); + this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据(Base64编码后)】:{}", url, requestStr, responseString); + wxApiData.set(new WxPayApiData(url, requestStr, responseString, null)); + return responseBytes; + } catch (Exception e) { + this.log.error("\n【请求地址】:{}\n【请求数据】:{}\n【异常信息】:{}", url, requestStr, e.getMessage()); + wxApiData.set(new WxPayApiData(url, requestStr, null, e.getMessage())); + throw new WxPayException(e.getMessage(), e); + } + } + @Override + public String post(String url, String requestStr, boolean useKey) throws WxPayException { + try { + HttpRequest request = this.buildHttpRequest(url, requestStr, useKey); String responseString = this.getResponseString(request.send()); this.log.info("\n【请求地址】:{}\n【请求数据】:{}\n【响应数据】:{}", url, requestStr, responseString); @@ -63,11 +55,40 @@ protected String post(String url, String requestStr, boolean useKey) throws WxPa } } + private HttpRequest buildHttpRequest(String url, String requestStr, boolean useKey) throws WxPayException { + HttpRequest request = HttpRequest + .post(url) + .timeout(this.getConfig().getHttpTimeout()) + .connectionTimeout(this.getConfig().getHttpConnectionTimeout()) + .bodyText(requestStr); + + if (useKey) { + SSLContext sslContext = this.getConfig().getSslContext(); + if (null == sslContext) { + sslContext = this.getConfig().initSSLContext(); + } + final SSLSocketHttpConnectionProvider provider = new SSLSocketHttpConnectionProvider(sslContext); + request.withConnectionProvider(provider); + } + + if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) && this.getConfig().getHttpProxyPort() > 0) { + ProxyInfo httpProxy = new ProxyInfo(ProxyType.HTTP, this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort(), + this.getConfig().getHttpProxyUsername(), this.getConfig().getHttpProxyPassword()); + HttpConnectionProvider provider = request.connectionProvider(); + if (null == provider) { + provider = new SocketHttpConnectionProvider(); + } + provider.useProxy(httpProxy); + request.withConnectionProvider(provider); + } + return request; + } + private String getResponseString(HttpResponse response) throws WxPayException { try { this.log.debug("【微信服务器响应头信息】:\n{}", response.toString(false)); } catch (NullPointerException e) { - throw new WxPayException("response.toString() 居然抛出空指针异常了", e); + this.log.warn("HttpResponse.toString() 居然抛出空指针异常了", e); } String responseString = response.bodyText(); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java index b13175a724..2883c8b1a0 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java @@ -1,111 +1,173 @@ package com.github.binarywang.wxpay.util; -import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; -import me.chanjar.weixin.common.util.BeanUtils; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.StringUtils; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.extern.slf4j.Slf4j; + /** *
    - * 签名相关工具类
    + * 签名相关工具类.
      * Created by Binary Wang on 2017-3-23.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author binarywang(Binary Wang) */ +@Slf4j public class SignUtils { + /** + * 请参考并使用 {@link #createSign(Object, String, String, String[])}. + * + * @param xmlBean the xml bean + * @param signKey the sign key + * @return the string + */ + @Deprecated + public static String createSign(Object xmlBean, String signKey) { + return createSign(xmlBean2Map(xmlBean), signKey); + } /** - * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) + * 请参考并使用 {@link #createSign(Map, String, String, String[])} . * - * @param xmlBean Bean需要标记有XML注解 - * @param signKey 签名Key - * @param signType 签名类型,如果为空,则默认为MD5 - * @return 签名字符串 + * @param params the params + * @param signKey the sign key + * @return the string */ - public static String createSign(Object xmlBean, String signKey, String signType) { - return createSign(BeanUtils.xmlBean2Map(xmlBean), signKey, signType); + @Deprecated + public static String createSign(Map params, String signKey) { + return createSign(params, null, signKey, new String[0]); } /** - * 微信公众号支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3) + * 微信支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3). * - * @param params 参数信息 - * @param signKey 签名Key - * @param signType 签名类型,如果为空,则默认为md5 - * @return 签名字符串 + * @param xmlBean Bean里的属性如果存在XML注解,则使用其作为key,否则使用变量名 + * @param signType 签名类型,如果为空,则默认为MD5 + * @param signKey 签名Key + * @param ignoredParams 签名时需要忽略的特殊参数 + * @return 签名字符串 string */ - public static String createSign(Map params, String signKey, String signType) { -// if (this.getConfig().useSandbox()) { -// //使用仿真测试环境 -// //TODO 目前测试发现,以下两行代码都会出问题,所以暂不建议使用仿真测试环境 -// signKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; -// //return "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456"; -// } + public static String createSign(Object xmlBean, String signType, String signKey, String[] ignoredParams) { + return createSign(xmlBean2Map(xmlBean), signType, signKey, ignoredParams); + } + /** + * 微信支付签名算法(详见:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3). + * + * @param params 参数信息 + * @param signType 签名类型,如果为空,则默认为MD5 + * @param signKey 签名Key + * @param ignoredParams 签名时需要忽略的特殊参数 + * @return 签名字符串 string + */ + public static String createSign(Map params, String signType, String signKey, String[] ignoredParams) { SortedMap sortedMap = new TreeMap<>(params); StringBuilder toSign = new StringBuilder(); for (String key : sortedMap.keySet()) { String value = params.get(key); - if (StringUtils.isNotEmpty(value) - && !StringUtils.equalsAny(key, "sign", "key", "sign_type")) { + boolean shouldSign = false; + if (StringUtils.isNotEmpty(value) && !ArrayUtils.contains(ignoredParams, key) + && !Lists.newArrayList("sign", "key", "xmlString", "xmlDoc", "couponList").contains(key)) { + shouldSign = true; + } + + if (shouldSign) { toSign.append(key).append("=").append(value).append("&"); } } toSign.append("key=").append(signKey); if (SignType.HMAC_SHA256.equals(signType)) { - return createHMACSha256Sign(toSign.toString(), signKey); + return me.chanjar.weixin.common.util.SignUtils.createHmacSha256Sign(toSign.toString(), signKey); } else { return DigestUtils.md5Hex(toSign.toString()).toUpperCase(); } } - private static String createHMACSha256Sign(String message, String key) { - try { - Mac hmacSHA256 = Mac.getInstance("HmacSHA256"); - SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256"); - hmacSHA256.init(secretKeySpec); - byte[] bytes = hmacSHA256.doFinal(message.getBytes()); - return Hex.encodeHexString(bytes).toUpperCase(); - } catch (NoSuchAlgorithmException | InvalidKeyException e) { - e.printStackTrace(); - } - - return null; - } - /** - * 校验签名是否正确 + * 校验签名是否正确. * - * @param xmlBean Bean需要标记有XML注解 - * @param signKey 校验的签名Key + * @param xmlBean Bean需要标记有XML注解 + * @param signType 签名类型,如果为空,则默认为MD5 + * @param signKey 校验的签名Key * @return true - 签名校验成功,false - 签名校验失败 - * @see #checkSign(Map, String) */ - public static boolean checkSign(Object xmlBean, String signKey) { - return checkSign(BeanUtils.xmlBean2Map(xmlBean), signKey); + public static boolean checkSign(Object xmlBean, String signType, String signKey) { + return checkSign(xmlBean2Map(xmlBean), signType, signKey); } /** - * 校验签名是否正确 + * 校验签名是否正确. * - * @param params 需要校验的参数Map - * @param signKey 校验的签名Key + * @param params 需要校验的参数Map + * @param signType 签名类型,如果为空,则默认为MD5 + * @param signKey 校验的签名Key * @return true - 签名校验成功,false - 签名校验失败 - * @see #checkSign(Map, String) */ - public static boolean checkSign(Map params, String signKey) { - String sign = createSign(params, signKey, null); + public static boolean checkSign(Map params, String signType, String signKey) { + String sign = createSign(params, signType, signKey, new String[0]); return sign.equals(params.get("sign")); } + + /** + * 将bean按照@XStreamAlias标识的字符串内容生成以之为key的map对象. + * + * @param bean 包含@XStreamAlias的xml bean对象 + * @return map对象 map + */ + public static Map xmlBean2Map(Object bean) { + Map result = Maps.newHashMap(); + List fields = new ArrayList<>(Arrays.asList(bean.getClass().getDeclaredFields())); + fields.addAll(Arrays.asList(bean.getClass().getSuperclass().getDeclaredFields())); + if (bean.getClass().getSuperclass().getSuperclass() == BaseWxPayRequest.class) { + fields.addAll(Arrays.asList(BaseWxPayRequest.class.getDeclaredFields())); + } + + if (bean.getClass().getSuperclass().getSuperclass() == BaseWxPayResult.class) { + fields.addAll(Arrays.asList(BaseWxPayResult.class.getDeclaredFields())); + } + + for (Field field : fields) { + try { + boolean isAccessible = field.isAccessible(); + field.setAccessible(true); + if (field.get(bean) == null) { + field.setAccessible(isAccessible); + continue; + } + + if (field.isAnnotationPresent(XStreamAlias.class)) { + result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString()); + } else if (!Modifier.isStatic(field.getModifiers())) { + //忽略掉静态成员变量 + result.put(field.getName(), field.get(bean).toString()); + } + + field.setAccessible(isAccessible); + } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { + log.error(e.getMessage(), e); + } + + } + + return result; + } } diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java index 384de4c983..a22916dea7 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java @@ -1,18 +1,21 @@ package com.github.binarywang.wxpay.bean.notify; -import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import org.testng.*; import org.testng.annotations.*; /** *
      * Created by Binary Wang on 2017-6-15.
    - * @author Binary Wang
      * 
    + * + * @author Binary Wang */ public class WxPayOrderNotifyResultTest { + /** + * Test from xml. + */ @Test - public void testFromXML() throws Exception { + public void testFromXML() { String xmlString = "\n" + " \n" + " \n" + @@ -32,12 +35,12 @@ public void testFromXML() throws Exception { " \n" + " \n" + " 2\n" + - " \n" + - " 10000\n" + - " 100\n" + " \n" + " 10001\n" + " 200\n" + + " \n" + + " 10000\n" + + " 100\n" + ""; WxPayOrderNotifyResult result = WxPayOrderNotifyResult.fromXML(xmlString); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java index cd1777f836..4b99b7693d 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java @@ -28,6 +28,11 @@ public class WxPayRefundNotifyResultTest { @Inject private WxPayConfig wxPayConfig; + /** + * Test from xml. + * + * @throws WxPayException the wx pay exception + */ public void testFromXML() throws WxPayException { String xmlString = "" + "SUCCESS" + @@ -42,6 +47,11 @@ public void testFromXML() throws WxPayException { System.out.println(refundNotifyResult); } + /** + * Encode req info. + * + * @throws Exception the exception + */ public void encodeReqInfo() throws Exception { String xml = "\n" + "\n" + diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java new file mode 100644 index 0000000000..04853e15a2 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java @@ -0,0 +1,53 @@ +package com.github.binarywang.wxpay.bean.notify; + +import org.testng.annotations.*; + +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
    + *
    + * Created by Binary Wang on 2018/2/2.
    + * 
    + * + * @author Binary Wang + */ +public class WxScanPayNotifyResultTest { + + /** + * Test to map. + */ + @Test + public void testToMap() { + } + + /** + * Test from xml. + */ + @Test + public void testFromXML() { + String xmlString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + WxScanPayNotifyResult result = BaseWxPayResult.fromXML(xmlString, WxScanPayNotifyResult.class); + + assertThat(result).isNotNull(); + + assertThat(result.getAppid()).isEqualTo("wx8888888888888888"); + assertThat(result.getOpenid()).isEqualTo("o8GeHuLAsgefS_80exEr1cTqekUs"); + assertThat(result.getMchId()).isEqualTo("1900000109"); + assertThat(result.getNonceStr()).isEqualTo("5K8264ILTKCH16CQ2502SI8ZNMTM67VS"); + assertThat(result.getProductId()).isEqualTo("88888"); + assertThat(result.getSign()).isEqualTo("C380BEC2BFD727A4B6845133519F3AD6"); + } + +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResultTest.java similarity index 87% rename from weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java rename to weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResultTest.java index d6a1f7b827..83fcc5f365 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBaseResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResultTest.java @@ -1,26 +1,42 @@ package com.github.binarywang.wxpay.bean.result; +import java.util.Map; + import org.testng.*; import org.testng.annotations.*; -import java.util.Map; - /** *
      * Created by Binary Wang on 2017-01-04.
    - * @author binarywang(Binary Wang)
      * 
    + * + * @author binarywang(Binary Wang) */ -public class WxPayBaseResultTest { +public class BaseWxPayResultTest { + /** + * Test get xml value. + * + * @throws Exception the exception + */ @Test public void testGetXmlValue() throws Exception { } + /** + * Test xml 2 doc. + * + * @throws Exception the exception + */ @Test public void testXml2Doc() throws Exception { } + /** + * Test to map. + * + * @throws Exception the exception + */ @Test public void testToMap() throws Exception { WxPayOrderQueryResult result = new WxPayOrderQueryResult(); @@ -53,6 +69,9 @@ public void testToMap() throws Exception { } + /** + * Test to map with empty xml string. + */ @Test(expectedExceptions = {RuntimeException.class}) public void testToMap_with_empty_xmlString() { WxPayOrderQueryResult result = new WxPayOrderQueryResult(); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResultTest.java index d847a155b9..c930b7ccb8 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResultTest.java @@ -6,13 +6,17 @@ /** *
      * Created by Binary Wang on 2017-01-04.
    + *  
    + * * @author binarywang(Binary Wang) - *
    */ public class WxPayOrderQueryResultTest { + /** + * Test compose coupons. + */ @Test - public void testComposeCoupons() throws Exception { - /** + public void testComposeCoupons() { + /* * xml样例字符串来自于官方文档,并稍加改造加入了coupon相关的数据便于测试 */ String xmlString = "\n" + diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java new file mode 100644 index 0000000000..b771cbb1d5 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java @@ -0,0 +1,54 @@ +package com.github.binarywang.wxpay.bean.result; + +import org.testng.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
    + *
    + * Created by Binary Wang on 2018/1/24.
    + * 
    + * + * @author Binary Wang + */ +public class WxPayRedpackQueryResultTest { + /** + * Test from xml. + */ + @Test + public void testFromXML() { + String xmlString = "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "1\n" + + "100\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "100\n" + + "\n" + + "\n" + + "\n" + + ""; + + WxPayRedpackQueryResult orderQueryResult = WxPayRedpackQueryResult.fromXML(xmlString, WxPayRedpackQueryResult.class); + System.out.println(orderQueryResult); + assertThat(orderQueryResult).isNotNull(); + + assertThat(orderQueryResult.getRedpackList()).isNotEmpty(); + assertThat(orderQueryResult.getRedpackList().get(0).getAmount()).isEqualTo(100); + assertThat(orderQueryResult.getRedpackList().get(0).getOpenid()).isEqualTo("o3yHF0uHuckI3yE6lwWiFQBQdVDI"); + assertThat(orderQueryResult.getRedpackList().get(0).getReceiveTime()).isEqualTo("2018-01-23 13:45:31"); + } +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResultTest.java index 6ca4192a71..e9e8e80bf7 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResultTest.java @@ -7,10 +7,16 @@ /** *
      * Created by Binary Wang on 2016-12-29.
    + *  
    + * * @author binarywang(Binary Wang) - *
    */ public class WxPayRefundQueryResultTest { + /** + * Compose refund records. + * + * @throws Exception the exception + */ @Test public void composeRefundRecords() throws Exception { /* diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java new file mode 100644 index 0000000000..f4f87f4095 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java @@ -0,0 +1,54 @@ +package com.github.binarywang.wxpay.bean.result; + +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
    + *  Created by BinaryWang on 2018/4/22.
    + * 
    + * + * @author Binary Wang + */ +public class WxPayRefundResultTest { + + /** + * Test compose refund coupons. + */ + @Test + public void testComposeRefundCoupons() { + /* + 该xml字符串来自于官方文档示例,稍加改造,加上代金卷 + refund_channel 是个什么鬼,官方文档只字不提 + */ + String xmlString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 1\n" + + " 123\n" + + " 1\n" + + " \n" + + " 2 \n" + + ""; + + WxPayRefundResult result = WxPayRefundResult.fromXML(xmlString, WxPayRefundResult.class); + result.composeRefundCoupons(); + + assertThat(result.getRefundCoupons()).isNotEmpty(); + assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123"); + assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH"); + assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1); + } +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResultTest.java index 1985c924d0..206703b850 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResultTest.java @@ -1,20 +1,30 @@ package com.github.binarywang.wxpay.bean.result; -import com.thoughtworks.xstream.XStream; -import me.chanjar.weixin.common.util.xml.XStreamInitializer; import org.testng.*; import org.testng.annotations.*; +import com.thoughtworks.xstream.XStream; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; + +/** + * The type Wx pay send redpack result test. + */ public class WxPaySendRedpackResultTest { private XStream xstream; + /** + * Sets . + */ @BeforeTest public void setup() { this.xstream = XStreamInitializer.getInstance(); this.xstream.processAnnotations(WxPaySendRedpackResult.class); } + /** + * Load success result. + */ @Test public void loadSuccessResult() { final String successSample = "\n" + @@ -37,6 +47,9 @@ public void loadSuccessResult() { Assert.assertEquals("20150520102602", wxMpRedpackResult.getSendTime()); } + /** + * Load failure result. + */ @Test public void loadFailureResult() { final String failureSample = "\n" + diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/config/WxPayConfigTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/config/WxPayConfigTest.java index 83bcbf2c17..3edc2c3268 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/config/WxPayConfigTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/config/WxPayConfigTest.java @@ -14,6 +14,11 @@ public class WxPayConfigTest { private WxPayConfig payConfig = new WxPayConfig(); + /** + * Test init ssl context. + * + * @throws Exception the exception + */ @Test public void testInitSSLContext() throws Exception { payConfig.setMchId("123"); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java new file mode 100644 index 0000000000..13a507d9e5 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java @@ -0,0 +1,635 @@ +package com.github.binarywang.wxpay.service.impl; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Calendar; +import java.util.Date; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.*; + +import com.github.binarywang.utils.qrcode.QrcodeUtils; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryResult; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendResult; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryRequest; +import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryResult; +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResultTest; +import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult; +import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; +import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult; +import com.github.binarywang.wxpay.bean.request.WxPayAuthcode2OpenidRequest; +import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest; +import com.github.binarywang.wxpay.bean.request.WxPayOrderReverseRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; +import com.github.binarywang.wxpay.bean.request.WxPayReportRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; +import com.github.binarywang.wxpay.bean.request.WxPayShorturlRequest; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; +import com.github.binarywang.wxpay.bean.result.WxPayBillResult; +import com.github.binarywang.wxpay.bean.result.WxPayFundFlowResult; +import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult; +import com.github.binarywang.wxpay.bean.result.WxPayOrderReverseResult; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; +import com.github.binarywang.wxpay.constant.WxPayConstants.AccountType; +import com.github.binarywang.wxpay.constant.WxPayConstants.BillType; +import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; +import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; +import com.google.inject.Inject; + +import static com.github.binarywang.wxpay.constant.WxPayConstants.TarType; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.*; + +/** + * 测试支付相关接口 + * Created by Binary Wang on 2016/7/28. + * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class BaseWxPayServiceImplTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Inject + private WxPayService payService; + + /** + * Test method for {@link WxPayService#unifiedOrder(WxPayUnifiedOrderRequest)}. + * + * @throws WxPayException the wx pay exception + */ + @Test + public void testUnifiedOrder() throws WxPayException { + WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder() + .body("我去") + .totalFee(1) + .spbillCreateIp("11.1.11.1") + .notifyUrl("111111") + .tradeType(TradeType.JSAPI) + .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) + .outTradeNo("1111112") + .build(); + request.setSignType(SignType.HMAC_SHA256); + WxPayUnifiedOrderResult result = this.payService.unifiedOrder(request); + this.logger.info(result.toString()); + this.logger.warn(this.payService.getWxApiData().toString()); + } + + /** + * Test create order. + * + * @throws Exception the exception + */ + @Test + public void testCreateOrder() throws Exception { + //see other tests with method name starting with 'testCreateOrder_' + } + + /** + * Test create order jsapi. + * + * @throws Exception the exception + */ + @Test + public void testCreateOrder_jsapi() throws Exception { + WxPayMpOrderResult result = this.payService + .createOrder(WxPayUnifiedOrderRequest.newBuilder() + .body("我去") + .totalFee(1) + .spbillCreateIp("11.1.11.1") + .notifyUrl("111111") + .tradeType(TradeType.JSAPI) + .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) + .outTradeNo("1111112") + .build()); + this.logger.info(result.toString()); + this.logger.warn(this.payService.getWxApiData().toString()); + } + + /** + * Test create order app. + * + * @throws Exception the exception + */ + @Test + public void testCreateOrder_app() throws Exception { + WxPayAppOrderResult result = this.payService + .createOrder(WxPayUnifiedOrderRequest.newBuilder() + .body("我去") + .totalFee(1) + .spbillCreateIp("11.1.11.1") + .notifyUrl("111111") + .tradeType(TradeType.APP) + .outTradeNo("1111112") + .build()); + this.logger.info(result.toString()); + this.logger.warn(this.payService.getWxApiData().toString()); + } + + /** + * Test create order native. + * + * @throws Exception the exception + */ + @Test + public void testCreateOrder_native() throws Exception { + WxPayNativeOrderResult result = this.payService + .createOrder(WxPayUnifiedOrderRequest.newBuilder() + .body("我去") + .totalFee(1) + .productId("aaa") + .spbillCreateIp("11.1.11.1") + .notifyUrl("111111") + .tradeType(TradeType.NATIVE) + .outTradeNo("111111290") + .build()); + this.logger.info(result.toString()); + this.logger.warn(this.payService.getWxApiData().toString()); + } + + /** + * Test get pay info. + * + * @throws Exception the exception + */ + @Test + public void testGetPayInfo() throws Exception { + //please use createOrder instead + } + + /** + * Test method for {@link WxPayService#queryOrder(String, String)} . + * + * @throws WxPayException the wx pay exception + */ + @Test + public void testQueryOrder() throws WxPayException { + this.logger.info(this.payService.queryOrder("11212121", null).toString()); + this.logger.info(this.payService.queryOrder(null, "11111").toString()); + } + + /** + * Test method for {@link WxPayService#closeOrder(String)} . + * + * @throws WxPayException the wx pay exception + */ + @Test + public void testCloseOrder() throws WxPayException { + this.logger.info(this.payService.closeOrder("11212121").toString()); + } + + /** + * Billing data object [ ] [ ]. + * + * @return the object [ ] [ ] + */ + @DataProvider + public Object[][] billingData() { + return new Object[][]{ + {"20170831", BillType.ALL, TarType.GZIP, "deviceInfo"}, + {"20170831", BillType.RECHARGE_REFUND, TarType.GZIP, "deviceInfo"}, + {"20170831", BillType.REFUND, TarType.GZIP, "deviceInfo"}, + {"20170831", BillType.SUCCESS, TarType.GZIP, "deviceInfo"}, + {"20170831", BillType.ALL, null, "deviceInfo"}, + {"20170831", BillType.RECHARGE_REFUND, null, "deviceInfo"}, + {"20170831", BillType.REFUND, null, "deviceInfo"}, + {"20170831", BillType.SUCCESS, null, "deviceInfo"} + }; + } + + /** + * Test download bill. + * + * @param billDate the bill date + * @param billType the bill type + * @param tarType the tar type + * @param deviceInfo the device info + * @throws Exception the exception + */ + @Test(dataProvider = "billingData") + public void testDownloadBill(String billDate, String billType, + String tarType, String deviceInfo) throws Exception { + WxPayBillResult billResult = this.payService.downloadBill(billDate, billType, tarType, deviceInfo); + assertThat(billResult).isNotNull(); + this.logger.info(billResult.toString()); + } + + /** + * Test download bill with no params. + * + * @throws Exception the exception + */ + @Test(expectedExceptions = WxPayException.class) + public void testDownloadBill_withNoParams() throws Exception { + //必填字段为空时,抛出异常 + this.payService.downloadBill("", "", "", null); + } + + /** + * Fund flow data object [ ] [ ]. + * + * @return the object [ ] [ ] + */ + @DataProvider + public Object[][] fundFlowData() { + return new Object[][]{ + {"20180819", AccountType.BASIC, TarType.GZIP}, + {"20180819", AccountType.OPERATION, TarType.GZIP}, + {"20180819", AccountType.FEES, TarType.GZIP}, + {"20180819", AccountType.BASIC, null}, + {"20180819", AccountType.OPERATION, null}, + {"20180819", AccountType.FEES, null} + }; + } + + /** + * Test download fund flow. + * + * @param billDate the bill date + * @param accountType the account type + * @param tarType the tar type + * @throws Exception the exception + */ + @Test(dataProvider = "fundFlowData") + public void testDownloadFundFlow(String billDate, String accountType, String tarType) throws Exception { + WxPayFundFlowResult fundFlowResult = this.payService.downloadFundFlow(billDate, accountType, tarType); + assertThat(fundFlowResult).isNotNull(); + this.logger.info(fundFlowResult.toString()); + } + + /** + * Test download fund flow with no params. + * + * @throws Exception the exception + */ + @Test(expectedExceptions = WxPayException.class) + public void testDownloadFundFlow_withNoParams() throws Exception { + //必填字段为空时,抛出异常 + this.payService.downloadFundFlow("", "", null); + } + + /** + * Test report. + * + * @throws Exception the exception + */ + @Test + public void testReport() throws Exception { + WxPayReportRequest request = new WxPayReportRequest(); + request.setInterfaceUrl("hahahah"); + request.setSignType(SignType.HMAC_SHA256);//貌似接口未校验此字段 + request.setExecuteTime(1000); + request.setReturnCode("aaa"); + request.setResultCode("aaa"); + request.setUserIp("8.8.8"); + this.payService.report(request); + } + + /** + * Test method for {@link WxPayService#refund(WxPayRefundRequest)} . + * + * @throws Exception the exception + */ + @Test + public void testRefund() throws Exception { + WxPayRefundResult result = this.payService.refund( + WxPayRefundRequest.newBuilder() + .outRefundNo("aaa") + .outTradeNo("1111") + .totalFee(1222) + .refundFee(111) + .build()); + this.logger.info(result.toString()); + } + + /** + * Test method for {@link WxPayService#refundQuery(String, String, String, String)} . + * + * @throws Exception the exception + */ + @Test + public void testRefundQuery() throws Exception { + WxPayRefundQueryResult result; + + result = this.payService.refundQuery("1", "", "", ""); + this.logger.info(result.toString()); + + result = this.payService.refundQuery("", "2", "", ""); + this.logger.info(result.toString()); + + result = this.payService.refundQuery("", "", "3", ""); + this.logger.info(result.toString()); + + result = this.payService.refundQuery("", "", "", "4"); + this.logger.info(result.toString()); + + //测试四个参数都填的情况,应该报异常的 + result = this.payService.refundQuery("1", "2", "3", "4"); + this.logger.info(result.toString()); + } + + /** + * Test parse refund notify result. + * + * @throws Exception the exception + */ + @Test + public void testParseRefundNotifyResult() throws Exception { + // 请参考com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResultTest里的单元测试 + } + + /** + * Test method for {@link WxPayService#sendRedpack(WxPaySendRedpackRequest)} . + * + * @throws Exception the exception + */ + @Test + public void testSendRedpack() throws Exception { + WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); + request.setActName("abc"); + request.setClientIp("aaa"); + request.setMchBillNo("aaaa"); + request.setWishing("what"); + request.setSendName("111"); + request.setTotalAmount(1); + request.setTotalNum(1); + request.setReOpenid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()); + WxPaySendRedpackResult redpackResult = this.payService.sendRedpack(request); + this.logger.info(redpackResult.toString()); + } + + /** + * Test method for {@link WxPayService#queryRedpack(String)}. + * + * @throws Exception the exception + */ + @Test + public void testQueryRedpack() throws Exception { + WxPayRedpackQueryResult redpackResult = this.payService.queryRedpack("aaaa"); + this.logger.info(redpackResult.toString()); + } + + /** + * Test create scan pay qrcode mode 1. + * + * @throws Exception the exception + */ + @Test + public void testCreateScanPayQrcodeMode1() throws Exception { + String productId = "abc"; + byte[] bytes = this.payService.createScanPayQrcodeMode1(productId, null, null); + Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); + Files.write(qrcodeFilePath, bytes); + String qrcodeContent = QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()); + this.logger.info(qrcodeContent); + + assertTrue(qrcodeContent.startsWith("weixin://wxpay/bizpayurl?")); + assertTrue(qrcodeContent.contains("product_id=" + productId)); + } + + /** + * Test create scan pay qrcode mode 2. + * + * @throws Exception the exception + */ + @Test + public void testCreateScanPayQrcodeMode2() throws Exception { + String qrcodeContent = "abc"; + byte[] bytes = this.payService.createScanPayQrcodeMode2(qrcodeContent, null, null); + Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); + Files.write(qrcodeFilePath, bytes); + assertEquals(QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()), qrcodeContent); + } + + /** + * Test micropay. + * + * @throws Exception the exception + */ + @Test + public void testMicropay() throws Exception { + WxPayMicropayResult result = this.payService.micropay( + WxPayMicropayRequest + .newBuilder() + .body("body") + .outTradeNo("aaaaa") + .totalFee(123) + .spbillCreateIp("127.0.0.1") + .authCode("aaa") + .build()); + this.logger.info(result.toString()); + } + + /** + * Test get config. + * + * @throws Exception the exception + */ + @Test + public void testGetConfig() throws Exception { + // no need to test + } + + /** + * Test set config. + * + * @throws Exception the exception + */ + @Test + public void testSetConfig() throws Exception { + // no need to test + } + + /** + * Test reverse order. + * + * @throws Exception the exception + */ + @Test + public void testReverseOrder() throws Exception { + WxPayOrderReverseResult result = this.payService.reverseOrder( + WxPayOrderReverseRequest + .newBuilder() + .outTradeNo("1111") + .build()); + assertNotNull(result); + this.logger.info(result.toString()); + } + + /** + * Test shorturl. + * + * @throws Exception the exception + */ + @Test + public void testShorturl() throws Exception { + String longUrl = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX"; + + String result = this.payService.shorturl(new WxPayShorturlRequest(longUrl)); + assertNotNull(result); + this.logger.info(result); + + result = this.payService.shorturl(longUrl); + assertNotNull(result); + this.logger.info(result); + } + + /** + * Test authcode 2 openid. + * + * @throws Exception the exception + */ + @Test + public void testAuthcode2Openid() throws Exception { + String authCode = "11111"; + + String result = this.payService.authcode2Openid(new WxPayAuthcode2OpenidRequest(authCode)); + assertNotNull(result); + this.logger.info(result); + + result = this.payService.authcode2Openid(authCode); + assertNotNull(result); + this.logger.info(result); + } + + /** + * Test get sandbox sign key. + * + * @throws Exception the exception + */ + @Test + public void testGetSandboxSignKey() throws Exception { + final String signKey = this.payService.getSandboxSignKey(); + assertNotNull(signKey); + this.logger.info(signKey); + } + + /** + * Test send coupon. + * + * @throws Exception the exception + */ + @Test + public void testSendCoupon() throws Exception { + WxPayCouponSendResult result = this.payService.sendCoupon(WxPayCouponSendRequest.newBuilder() + .couponStockId("123") + .openid("122") + .partnerTradeNo("1212") + .openidCount(1) + .build()); + this.logger.info(result.toString()); + } + + /** + * Test query coupon stock. + * + * @throws Exception the exception + */ + @Test + public void testQueryCouponStock() throws Exception { + WxPayCouponStockQueryResult result = this.payService.queryCouponStock( + WxPayCouponStockQueryRequest + .newBuilder() + .couponStockId("123") + .build()); + this.logger.info(result.toString()); + } + + /** + * Test query coupon info. + * + * @throws Exception the exception + */ + @Test + public void testQueryCouponInfo() throws Exception { + WxPayCouponInfoQueryResult result = this.payService.queryCouponInfo( + WxPayCouponInfoQueryRequest + .newBuilder() + .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") + .couponId("11") + .stockId("1121") + .build()); + this.logger.info(result.toString()); + } + + /** + * 只支持拉取90天内的评论数据 + * + * @throws Exception the exception + */ + @Test + public void testQueryComment() throws Exception { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_MONTH, -1); + Date endDate = calendar.getTime(); + calendar.add(Calendar.DAY_OF_MONTH, -88); + Date beginDate = calendar.getTime(); + String result = this.payService.queryComment(beginDate, endDate, 0, 1); + this.logger.info(result); + } + + /** + * Test parse order notify result. + * + * @throws Exception the exception + * @see WxPayOrderNotifyResultTest#testFromXML() WxPayOrderNotifyResultTest#testFromXML() + */ + @Test + public void testParseOrderNotifyResult() throws Exception { + // 请参考com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResultTest 里的单元测试 + + String xmlString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " 10000\n" + + " 100\n" + + " \n" + + " 10001\n" + + " 200\n" + + ""; + + WxPayOrderNotifyResult result = this.payService.parseOrderNotifyResult(xmlString); + System.out.println(result); + } + + /** + * Test get wx api data. + * + * @throws Exception the exception + */ + @Test + public void testGetWxApiData() throws Exception { + //see test in testUnifiedOrder() + } + +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImplTest.java new file mode 100644 index 0000000000..4c7f6e3246 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImplTest.java @@ -0,0 +1,97 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.entpay.EntPayBankRequest; +import com.github.binarywang.wxpay.bean.entpay.EntPayBankResult; +import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; +import com.github.binarywang.wxpay.constant.WxPayConstants.CheckNameOption; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.google.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.*; + +/** + *
    + *  企业付款测试类.
    + *  Created by BinaryWang on 2017/12/19.
    + * 
    + * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class EntPayServiceImplTest { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Inject + private WxPayService payService; + + /** + * Test ent pay. + * + * @throws WxPayException the wx pay exception + */ + @Test + public void testEntPay() throws WxPayException { + EntPayRequest request = EntPayRequest.newBuilder() + .partnerTradeNo("Eb6Aep7uVTdbkJqrP4") + .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP5") + .amount(100) + .spbillCreateIp("10.10.10.10") + .checkName(CheckNameOption.NO_CHECK) + .description("描述信息") + .build(); + + this.logger.info(this.payService.getEntPayService().entPay(request).toString()); + } + + /** + * Test query ent pay. + * + * @throws WxPayException the wx pay exception + */ + @Test + public void testQueryEntPay() throws WxPayException { + this.logger.info(this.payService.getEntPayService().queryEntPay("11212121").toString()); + } + + /** + * Test get public key. + * + * @throws Exception the exception + */ + @Test + public void testGetPublicKey() throws Exception { + this.logger.info(this.payService.getEntPayService().getPublicKey()); + } + + /** + * Test pay bank. + * + * @throws Exception the exception + */ + @Test + public void testPayBank() throws Exception { + EntPayBankResult result = this.payService.getEntPayService().payBank(EntPayBankRequest.builder() + .bankCode("aa") + .amount(1) + .encBankNo("1") + .encTrueName("2") + .partnerTradeNo("3") + .description("11") + .build()); + this.logger.info(result.toString()); + } + + /** + * Test query pay bank. + * + * @throws Exception the exception + */ + @Test + public void testQueryPayBank() throws Exception { + this.logger.info(this.payService.getEntPayService().queryPayBank("123").toString()); + } +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImplTest.java deleted file mode 100644 index 2fc5354424..0000000000 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/WxPayServiceAbstractImplTest.java +++ /dev/null @@ -1,338 +0,0 @@ -package com.github.binarywang.wxpay.service.impl; - -import com.github.binarywang.utils.qrcode.QrcodeUtils; -import com.github.binarywang.wxpay.bean.coupon.*; -import com.github.binarywang.wxpay.bean.request.*; -import com.github.binarywang.wxpay.bean.result.*; -import com.github.binarywang.wxpay.constant.WxPayConstants; -import com.github.binarywang.wxpay.constant.WxPayConstants.BillType; -import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; -import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; -import com.github.binarywang.wxpay.exception.WxPayException; -import com.github.binarywang.wxpay.service.WxPayService; -import com.github.binarywang.wxpay.testbase.ApiTestModule; -import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; -import com.google.inject.Inject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Calendar; -import java.util.Date; -import java.util.Map; - -import static org.testng.Assert.*; - -/** - * 测试支付相关接口 - * Created by Binary Wang on 2016/7/28. - * - * @author binarywang (https://github.com/binarywang) - */ -@Test -@Guice(modules = ApiTestModule.class) -public class WxPayServiceAbstractImplTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Inject - private WxPayService payService; - - /** - * Test method for {@link WxPayService#unifiedOrder(WxPayUnifiedOrderRequest)}. - */ - @Test - public void testUnifiedOrder() throws WxPayException { - WxPayUnifiedOrderResult result = this.payService - .unifiedOrder(WxPayUnifiedOrderRequest.newBuilder() - .body("我去") - .totalFee(1) - .spbillCreateIp("11.1.11.1") - .notifyURL("111111") - .tradeType(TradeType.JSAPI) - .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) - .outTradeNo("1111112") - .build()); - this.logger.info(result.toString()); - this.logger.warn(this.payService.getWxApiData().toString()); - } - - @Test - public void testGetPayInfo() throws Exception { - Map payInfo = this.payService.getPayInfo(WxPayUnifiedOrderRequest.newBuilder() - .body("我去") - .totalFee(1) - .spbillCreateIp("1.11.1.11") - .notifyURL("111111") - .tradeType(TradeType.JSAPI) - .outTradeNo("1111113") - .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) - .build()); - this.logger.info(payInfo.toString()); - } - - /** - * Test method for {@link WxPayService#queryOrder(String, String)} . - */ - @Test - public void testQueryOrder() throws WxPayException { - this.logger.info(this.payService.queryOrder("11212121", null).toString()); - this.logger.info(this.payService.queryOrder(null, "11111").toString()); - } - - /** - * Test method for {@link WxPayService#closeOrder(String)} . - */ - @Test - public void testCloseOrder() throws WxPayException { - this.logger.info(this.payService.closeOrder("11212121").toString()); - } - - @Test - public void testDownloadBill() throws Exception { - WxPayBillResult wxPayBillResult = this.payService.downloadBill("20170831", BillType.ALL, null, "1111111"); - //前一天没有账单记录返回null - assertNotNull(wxPayBillResult); - //必填字段为空时,抛出异常 - this.payService.downloadBill("", "", "", null); - } - - @Test - public void testReport() throws Exception { - WxPayReportRequest request = new WxPayReportRequest(); - request.setInterfaceUrl("hahahah"); - request.setSignType(SignType.HMAC_SHA256);//貌似接口未校验此字段 - request.setExecuteTime(1000); - request.setReturnCode("aaa"); - request.setResultCode("aaa"); - request.setUserIp("8.8.8"); - this.payService.report(request); - } - - /** - * Test method for {@link WxPayService#refund(WxPayRefundRequest)} . - */ - @Test - public void testRefund() throws Exception { - WxPayRefundResult result = this.payService.refund( - WxPayRefundRequest.newBuilder() - .outRefundNo("aaa") - .outTradeNo("1111") - .totalFee(1222) - .refundFee(111) - .build()); - this.logger.info(result.toString()); - } - - /** - * Test method for {@link WxPayService#refundQuery(String, String, String, String)} . - */ - @Test - public void testRefundQuery() throws Exception { - WxPayRefundQueryResult result; - - result = this.payService.refundQuery("1", "", "", ""); - this.logger.info(result.toString()); - - result = this.payService.refundQuery("", "2", "", ""); - this.logger.info(result.toString()); - - result = this.payService.refundQuery("", "", "3", ""); - this.logger.info(result.toString()); - - result = this.payService.refundQuery("", "", "", "4"); - this.logger.info(result.toString()); - - //测试四个参数都填的情况,应该报异常的 - result = this.payService.refundQuery("1", "2", "3", "4"); - this.logger.info(result.toString()); - } - - @Test - public void testParseRefundNotifyResult() throws Exception { - // 请参考com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResultTest里的单元测试 - } - - /** - * Test method for {@link WxPayService#sendRedpack(WxPaySendRedpackRequest)} . - */ - @Test - public void testSendRedpack() throws Exception { - WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); - request.setActName("abc"); - request.setClientIp("aaa"); - request.setMchBillNo("aaaa"); - request.setReOpenid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()); - WxPaySendRedpackResult redpackResult = this.payService.sendRedpack(request); - this.logger.info(redpackResult.toString()); - } - - /** - * Test method for {@link WxPayService#queryRedpack(String)}. - */ - @Test - public void testQueryRedpack() throws Exception { - WxPayRedpackQueryResult redpackResult = this.payService.queryRedpack("aaaa"); - this.logger.info(redpackResult.toString()); - } - - /** - * Test method for {@link WxPayService#entPay(WxEntPayRequest)}. - */ - @Test - public void testEntPay() throws WxPayException { - WxEntPayRequest request = WxEntPayRequest.newBuilder() - .partnerTradeNo("Eb6Aep7uVTdbkJqrP4") - .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") - .amount(1) - .spbillCreateIp("10.10.10.10") - .checkName(WxPayConstants.CheckNameOption.NO_CHECK) - .description("描述信息") - .build(); - - this.logger.info(this.payService.entPay(request).toString()); - } - - /** - * Test method for {@link WxPayService#queryEntPay(String)}. - */ - @Test - public void testQueryEntPay() throws WxPayException { - this.logger.info(this.payService.queryEntPay("11212121").toString()); - } - - @Test - public void testCreateScanPayQrcodeMode1() throws Exception { - String productId = "abc"; - byte[] bytes = this.payService.createScanPayQrcodeMode1(productId, null, null); - Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); - Files.write(qrcodeFilePath, bytes); - String qrcodeContent = QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()); - this.logger.info(qrcodeContent); - - assertTrue(qrcodeContent.startsWith("weixin://wxpay/bizpayurl?")); - assertTrue(qrcodeContent.contains("product_id=" + productId)); - } - - @Test - public void testCreateScanPayQrcodeMode2() throws Exception { - String qrcodeContent = "abc"; - byte[] bytes = this.payService.createScanPayQrcodeMode2(qrcodeContent, null, null); - Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); - Files.write(qrcodeFilePath, bytes); - assertEquals(QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()), qrcodeContent); - } - - @Test - public void testGetOrderNotifyResult() throws Exception { - } - - @Test - public void testMicropay() throws Exception { - WxPayMicropayResult result = this.payService.micropay(WxPayMicropayRequest.newBuilder() - .body("body") - .outTradeNo("aaaaa") - .totalFee(123) - .spbillCreateIp("127.0.0.1") - .authCode("aaa") - .build()); - this.logger.info(result.toString()); - } - - @Test - public void testGetConfig() throws Exception { - // no need to test - } - - @Test - public void testSetConfig() throws Exception { - // no need to test - } - - @Test - public void testReverseOrder() throws Exception { - WxPayOrderReverseResult result = this.payService.reverseOrder(WxPayOrderReverseRequest.newBuilder() - .outTradeNo("1111") - .build()); - assertNotNull(result); - this.logger.info(result.toString()); - } - - @Test - public void testShorturl() throws Exception { - String longUrl = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX"; - - String result = this.payService.shorturl(new WxPayShorturlRequest(longUrl)); - assertNotNull(result); - this.logger.info(result); - - result = this.payService.shorturl(longUrl); - assertNotNull(result); - this.logger.info(result); - } - - @Test - public void testAuthcode2Openid() throws Exception { - String authCode = "11111"; - - String result = this.payService.authcode2Openid(new WxPayAuthcode2OpenidRequest(authCode)); - assertNotNull(result); - this.logger.info(result); - - result = this.payService.authcode2Openid(authCode); - assertNotNull(result); - this.logger.info(result); - } - - @Test - public void testGetSandboxSignKey() throws Exception { - final String signKey = this.payService.getSandboxSignKey(); - assertNotNull(signKey); - this.logger.info(signKey); - } - - @Test - public void testSendCoupon() throws Exception { - WxPayCouponSendResult result = this.payService.sendCoupon(WxPayCouponSendRequest.newBuilder() - .couponStockId("123") - .openid("122") - .partnerTradeNo("1212") - .openidCount(1) - .build()); - this.logger.info(result.toString()); - } - - @Test - public void testQueryCouponStock() throws Exception { - WxPayCouponStockQueryResult result = this.payService.queryCouponStock(WxPayCouponStockQueryRequest.newBuilder() - .couponStockId("123") - .build()); - this.logger.info(result.toString()); - } - - @Test - public void testQueryCouponInfo() throws Exception { - WxPayCouponInfoQueryResult result = this.payService.queryCouponInfo(WxPayCouponInfoQueryRequest.newBuilder() - .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") - .couponId("11") - .stockId("1121") - .build()); - this.logger.info(result.toString()); - } - - /** - * 目前调用接口总报“系统繁忙,清稍后再试”,怀疑根本没法使用 - */ - @Test - public void testQueryComment() throws Exception { - Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.DAY_OF_MONTH, -2); - Date beginDate = calendar.getTime(); - calendar.add(Calendar.MONTH, -1); - Date endDate = calendar.getTime(); - this.payService.queryComment(beginDate, endDate, 0, null); - } - -} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java index 207dc194f5..d46c98c426 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/ApiTestModule.java @@ -1,5 +1,11 @@ package com.github.binarywang.wxpay.testbase; +import java.io.IOException; +import java.io.InputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; @@ -8,17 +14,18 @@ import com.thoughtworks.xstream.XStream; import me.chanjar.weixin.common.util.xml.XStreamInitializer; -import java.io.IOException; -import java.io.InputStream; - +/** + * The type Api test module. + */ public class ApiTestModule implements Module { + private final Logger log = LoggerFactory.getLogger(this.getClass()); private static final String TEST_CONFIG_XML = "test-config.xml"; @Override public void configure(Binder binder) { try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(TEST_CONFIG_XML)) { if (inputStream == null) { - throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到"); + throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成"); } XmlWxPayConfig config = this.fromXml(XmlWxPayConfig.class, inputStream); @@ -28,8 +35,9 @@ public void configure(Binder binder) { binder.bind(WxPayService.class).toInstance(wxService); binder.bind(WxPayConfig.class).toInstance(config); } catch (IOException e) { - e.printStackTrace(); + this.log.error(e.getMessage(), e); } + } @SuppressWarnings("unchecked") diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java index d029590ad3..bdb394cd29 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/testbase/XmlWxPayConfig.java @@ -3,22 +3,35 @@ import com.github.binarywang.wxpay.config.WxPayConfig; import com.thoughtworks.xstream.annotations.XStreamAlias; +/** + * The type Xml wx pay config. + */ @XStreamAlias("xml") public class XmlWxPayConfig extends WxPayConfig { private String openid; + /** + * Gets openid. + * + * @return the openid + */ public String getOpenid() { return openid; } + /** + * Sets openid. + * + * @param openid the openid + */ public void setOpenid(String openid) { this.openid = openid; } @Override - public boolean useSandbox() { + public boolean isUseSandboxEnv() { //沙箱环境不成熟,有问题无法使用,暂时屏蔽掉 -// return true; + //return true; return false; } } diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java index 23d7088b7b..9247d852c3 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/util/SignUtilsTest.java @@ -1,10 +1,11 @@ package com.github.binarywang.wxpay.util; +import org.testng.annotations.*; + import com.google.common.base.Splitter; -import org.testng.annotations.Test; import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.HMAC_SHA256; -import static org.testng.Assert.assertEquals; +import static org.testng.Assert.*; /** *
    @@ -16,23 +17,38 @@
      * @author Binary Wang
      */
     public class SignUtilsTest {
    +  /**
    +   * Test create sign.
    +   *
    +   * @throws Exception the exception
    +   */
       @Test
       public void testCreateSign() throws Exception {
         String signKey = "192006250b4c09247ec02edce69f6a2d";
         String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
    -    assertEquals(SignUtils.createSign((Splitter.on("&").withKeyValueSeparator("=").split(message)), signKey, null),
    +    assertEquals(SignUtils.createSign((Splitter.on("&").withKeyValueSeparator("=").split(message)), null, signKey, null),
           "9A0A8659F005D6984697E2CA0A9CF3B7");
       }
     
    +  /**
    +   * Test create sign hmacsha 256.
    +   *
    +   * @throws Exception the exception
    +   */
       @Test
       public void testCreateSign_HMACSHA256() throws Exception {
         String signKey = "192006250b4c09247ec02edce69f6a2d";
         final String message = "appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
         String sign = SignUtils.createSign(Splitter.on("&").withKeyValueSeparator("=").split(message),
    -      signKey, HMAC_SHA256);
    +      HMAC_SHA256, signKey, null);
         assertEquals(sign, "6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6");
       }
     
    +  /**
    +   * Test check sign.
    +   *
    +   * @throws Exception the exception
    +   */
       @Test
       public void testCheckSign() throws Exception {
       }