diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent3.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent3.java index fa4517b7..65552e71 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent3.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent3.java @@ -151,7 +151,7 @@ public class HttpComponent3 extends AbstractHttpClient { StringUtil.join(header.getValue(), ';')); } else { for (String headerValue : header.getValue()) { - httpMethod.addRequestHeader(header.getKey(), + httpMethod.setRequestHeader(header.getKey(), headerValue != null ? headerValue : ""); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent4.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent4.java index 67c83443..e45f321e 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent4.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/HttpComponent4.java @@ -82,11 +82,11 @@ public abstract class HttpComponent4 extends AbstractHttpClient { .entrySet().iterator(); headerIterator.hasNext();) { Entry> header = headerIterator.next(); if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) { - uriRequest.addHeader(header.getKey(), + uriRequest.setHeader(header.getKey(), StringUtil.join(header.getValue(), ';')); } else { for (String headerValue : header.getValue()) { - uriRequest.addHeader(header.getKey(), + uriRequest.setHeader(header.getKey(), headerValue != null ? headerValue : ""); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java index 0fd725ca..3dbfcde8 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/factory/Netty4HttpClient.java @@ -181,7 +181,7 @@ public class Netty4HttpClient extends AbstractHttpClient { for (Iterator>> headerIterator = headers .entrySet().iterator(); headerIterator.hasNext();) { Entry> header = headerIterator.next(); - uriRequest.headers().add(header.getKey(), header.getValue()); + uriRequest.headers().set(header.getKey(), header.getValue()); } uriRequest.headers().set(HttpHeaders.CONNECTION, io.netty.handler.codec.http.HttpHeaders.Values.CLOSE); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml index b6111df5..476c6c90 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/weixin/error.xml @@ -337,6 +337,14 @@ 40092 导入文件存在不合法的内容 + + 40093 + 不合法的跳转target + + + 40094 + 不合法的URL + 40117 分组名字不合法 @@ -463,6 +471,14 @@ 41025 缺少永久授权码 + + 41034 + 缺少login_ticket + + + 41035 + 缺少跳转target + 42001 access_token expired @@ -821,6 +837,30 @@ 60017 不允许设置企业 + + 60019 + 不允许设置应用地理位置上报开关 + + + 60020 + 访问ip不在白名单之中 + + + 60025 + 主页型应用不支持的消息类型 + + + 60027 + 主页型应用不支持调用该接口 + + + 60028 + 应用已授权予第三方,不允许通过分级管理员主页url + + + 60029 + 应用已授权予第三方,不允许通过分级管理员修改可信域名 + 60102 UserID已存在 diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java index c2d26690..0a7f3e09 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Token.java @@ -41,7 +41,7 @@ public class Token implements Serializable { private String originalResult; public Token() { - + this.createTime = System.currentTimeMillis() / 1000l; } public Token(String accessToken) { diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/OauthApi.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/OauthApi.java index f8d4ac68..8758090f 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/OauthApi.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/OauthApi.java @@ -4,6 +4,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; import com.foxinmy.weixin4j.model.Consts; @@ -35,7 +36,8 @@ public class OauthApi extends QyApi { */ public String getUserAuthorizeURL() { String corpId = DEFAULT_WEIXIN_ACCOUNT.getId(); - String redirectUri = Weixin4jConfigUtil.getValue("user.oauth.redirect.uri"); + String redirectUri = Weixin4jConfigUtil + .getValue("user.oauth.redirect.uri"); return getUserAuthorizeURL(corpId, redirectUri, "state"); } @@ -73,7 +75,8 @@ public class OauthApi extends QyApi { */ public String getThirdAuthorizeURL() { String corpId = DEFAULT_WEIXIN_ACCOUNT.getId(); - String redirectUri = Weixin4jConfigUtil.getValue("third.oauth.redirect.uri"); + String redirectUri = Weixin4jConfigUtil + .getValue("third.oauth.redirect.uri"); return getThirdAuthorizeURL(corpId, redirectUri, "state"); } @@ -121,7 +124,12 @@ public class OauthApi extends QyApi { WeixinResponse response = weixinExecutor.post( String.format(oauth_logininfo_uri, providerToken), String.format("{\"auth_code\":\"%s\"}", authCode)); - return JSON.parseObject(response.getAsString(), OUserInfo.class); + JSONObject obj = response.getAsJson(); + OUserInfo oUser = JSON.toJavaObject(obj, OUserInfo.class); + oUser.getRedirectLoginInfo().setAccessToken( + obj.getJSONObject("redirect_login_info").getString( + "login_ticket")); + return oUser; } /** @@ -135,7 +143,8 @@ public class OauthApi extends QyApi { * @return */ public String getSuiteAuthorizeURL(String suiteId, String preAuthCode) { - String redirectUri = Weixin4jConfigUtil.getValue("suite.oauth.redirect.uri"); + String redirectUri = Weixin4jConfigUtil + .getValue("suite.oauth.redirect.uri"); return getSuiteAuthorizeURL(suiteId, preAuthCode, redirectUri, "state"); } diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/AgentSetter.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/AgentSetter.java index cbbc4d1c..c82fbfdb 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/AgentSetter.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/AgentSetter.java @@ -52,10 +52,15 @@ public class AgentSetter implements Serializable { @JSONField(name = "isreportuser") private boolean isReportUser; /** - * 是否上报用户进入应用事件。0:不接收;1:接收 + * 是否上报用户进入应用事件。0:不接收;1:接收。主页型应用无需该参数 */ @JSONField(name = "isreportenter") private boolean isReportEnter; + /** + * 主页型应用url。url必须以http或者https开头。消息型应用无需该参数 + */ + @JSONField(name = "home_url") + private String homeUrl; public AgentSetter(int agentId) { this.agentId = agentId; @@ -85,6 +90,10 @@ public class AgentSetter implements Serializable { return redirectDomain; } + public String getHomeUrl() { + return homeUrl; + } + // ---------- setter 应该全部去掉 public void setReportLocationType(ReportLocationType reportLocationType) { @@ -123,12 +132,17 @@ public class AgentSetter implements Serializable { this.isReportEnter = isReportEnter; } + public void setHomeUrl(String homeUrl) { + this.homeUrl = homeUrl; + } + @Override public String toString() { return "agentId=" + agentId + ", reportLocationType=" + reportLocationType + ", logoMediaId=" + logoMediaId + ", name=" + name + ", description=" + description + ", redirectDomain=" + redirectDomain + ", isReportUser=" - + isReportUser + ", isReportEnter=" + isReportEnter; + + isReportUser + ", isReportEnter=" + isReportEnter + + ", homeUrl=" + homeUrl; } } diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/OUserInfo.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/OUserInfo.java index da7e74dd..1a49b6b8 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/OUserInfo.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/OUserInfo.java @@ -4,6 +4,7 @@ import java.io.Serializable; import java.util.List; import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.qy.type.AgentAuthType; /** @@ -48,6 +49,11 @@ public class OUserInfo implements Serializable { */ @JSONField(name = "auth_info") private AuthInfo authInfo; + /** + * 登录跳转的票据信息 + */ + @JSONField(name = "redirect_login_info") + private Token redirectLoginInfo; public boolean isSysAdmin() { return isSysAdmin; @@ -73,6 +79,10 @@ public class OUserInfo implements Serializable { return authInfo; } + public Token getRedirectLoginInfo() { + return redirectLoginInfo; + } + // ---------- setter 应该全部去掉 public void setSysAdmin(boolean isSysAdmin) { @@ -99,12 +109,16 @@ public class OUserInfo implements Serializable { this.authInfo = authInfo; } + public void setRedirectLoginInfo(Token redirectLoginInfo) { + this.redirectLoginInfo = redirectLoginInfo; + } + @Override public String toString() { return "OUserInfo [isSysAdmin=" + isSysAdmin + ", isInnerAdmin=" + isInnerAdmin + ", adminInfo=" + adminInfo + ", corpInfo=" + corpInfo + ", agentInfo=" + agentInfo + ", authInfo=" - + authInfo + "]"; + + authInfo + ", redirectLoginInfo=" + redirectLoginInfo + "]"; } /** diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java index 452e5699..61780d7b 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/startup/WeixinServerBootstrap.java @@ -7,12 +7,14 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LoggingHandler; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.FutureListener; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -150,8 +152,8 @@ public final class WeixinServerBootstrap { this.aesTokenMap.put(aesToken.getWeixinId(), aesToken); } this.aesTokenMap.put(null, aesTokens[0]); - this.messageHandlerList = new LinkedList(); - this.messageInterceptorList = new LinkedList(); + this.messageHandlerList = new ArrayList(); + this.messageInterceptorList = new ArrayList(); this.messageDispatcher = new WeixinMessageDispatcher(messageMatcher); } @@ -183,7 +185,7 @@ public final class WeixinServerBootstrap { * @return * @throws WeixinException */ - public void startup(int bossThreads, int workerThreads, int serverPort) + public void startup(int bossThreads, int workerThreads, final int serverPort) throws WeixinException { messageDispatcher.setMessageHandlerList(messageHandlerList); messageDispatcher.setMessageInterceptorList(messageInterceptorList); @@ -199,8 +201,20 @@ public final class WeixinServerBootstrap { .childHandler( new WeixinServerInitializer(aesTokenMap, messageDispatcher)); - Channel ch = b.bind(serverPort).sync().channel(); - logger.info("weixin4j server startup OK:{}", serverPort); + Channel ch = b.bind(serverPort) + .addListener(new FutureListener() { + @Override + public void operationComplete(Future future) + throws Exception { + if (future.isSuccess()) { + logger.info("weixin4j server startup OK:{}", + serverPort); + } else { + logger.info("weixin4j server startup FAIL:{}", + serverPort); + } + } + }).sync().channel(); ch.closeFuture().sync(); } catch (WeixinException e) { throw e;