diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ClassUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ClassUtil.java deleted file mode 100644 index 4368945a..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ClassUtil.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.foxinmy.weixin4j.util; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.net.JarURLConnection; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -import com.alibaba.fastjson.JSON; -import com.foxinmy.weixin4j.model.Consts; - -/** - * 对class的获取 - * - * @className ClassUtil - * @author jy - * @date 2014年10月31日 - * @since JDK 1.7 - * @see - */ -public class ClassUtil { - - /** - * 获取某个包下所有的class信息 - * - * @param _package 包对象 - * @return - */ - public static Set> getClasses(Package _package) { - String packageName = _package.getName(); - String packageFileName = packageName.replace(".", File.separator); - URL fullPath = Thread.currentThread().getContextClassLoader() - .getResource(packageFileName); - String protocol = fullPath.getProtocol(); - if (protocol.equals(Consts.PROTOCOL_FILE)) { - File dir = new File(fullPath.getPath()); - return findClassesByFile(dir, packageName); - } else if (protocol.equals(Consts.PROTOCOL_JAR)) { - try { - return findClassesByJar( - ((JarURLConnection) fullPath.openConnection()) - .getJarFile(), - packageFileName); - } catch (IOException e) { - ; - } - } - return null; - } - - /** - * 实例化目录下所有的class对象 - * - * @param dir 文件目录 - * @param packageName 包的全限类名 - * @return - */ - private static Set> findClassesByFile(File dir, String packageName) { - Set> classes = new HashSet>(); - File[] files = dir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File file, String name) { - return file.isDirectory() || file.getName().endsWith(".class"); - } - }); - for (File file : files) { - if (file.isDirectory()) { - classes.addAll(findClassesByFile(file, - packageName + "." + file.getName())); - } else { - try { - Class clazz = Class.forName(packageName + "." - + file.getName().replace(".class", "")); - if (clazz.isInterface()) { - continue; - } - classes.add(clazz); - } catch (ClassNotFoundException e) { - ; - } - } - } - return classes; - } - - /** - * 实例化jar包下所有的class对象 - * - * @param jar jar包对象 - * @param packageName 包的全限类名 - * @return - */ - private static Set> findClassesByJar(JarFile jar, - String packageName) { - Set> classes = new HashSet>(); - Enumeration jarEntries = jar.entries(); - while (jarEntries.hasMoreElements()) { - JarEntry jarEntry = jarEntries.nextElement(); - if (jarEntry.isDirectory()) { - continue; - } - String entryName = jarEntry.getName(); - if (!entryName.startsWith(packageName)) { - continue; - } - if (!entryName.endsWith(".class")) { - continue; - } - try { - Class clazz = Class.forName(entryName.replaceAll("/", ".") - .replace(".class", "")); - if (clazz.isInterface()) { - continue; - } - classes.add(clazz); - } catch (ClassNotFoundException e) { - ; - } - } - return classes; - } - - public static void main(String[] args) { - Package _package = JSON.class.getPackage(); - System.out.println(getClasses(_package)); - } -} 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 17545aec..4ed7f7e8 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 @@ -3,7 +3,11 @@ package com.foxinmy.weixin4j.qy.api; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import com.alibaba.fastjson.JSON; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.weixin.WeixinResponse; import com.foxinmy.weixin4j.model.Consts; +import com.foxinmy.weixin4j.qy.model.OUserInfo; import com.foxinmy.weixin4j.util.ConfigUtil; /** @@ -57,6 +61,28 @@ public class OauthApi extends QyApi { } return ""; } + + /** + * 获取企业号管理员登录信息 + * + * @param providerToken + * 提供商的token + * @param authCode + * oauth2.0授权企业号管理员登录产生的code + * @return 登陆信息 + * @see 授权获取企业号管理员登录信息 + * @see com.foxinmy.weixin4j.qy.model.OUserInfo + * @throws WeixinException + */ + public OUserInfo getOUserInfoByCode(String providerToken, String authCode) + throws WeixinException { + String oauth_logininfo_uri = getRequestUri("oauth_logininfo_uri"); + WeixinResponse response = weixinClient.post( + String.format(oauth_logininfo_uri, providerToken), + String.format("{\"auth_code\":\"%s\"}", authCode)); + return JSON.parseObject(response.getAsString(), OUserInfo.class); + } /** * @see {@link com.foxinmy.weixin4j.qy.api.OauthApi#getSuiteAuthorizeURL(String,String, String,String)} diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/SuiteApi.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/SuiteApi.java index aa5c5b01..2fa3e5af 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/SuiteApi.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/SuiteApi.java @@ -239,9 +239,9 @@ public class SuiteApi extends QyApi { obj.put("auth_corpid", authCorpid); obj.put("permanent_code", suitePerCodeHolder.getPermanentCode(suiteId)); obj.put("agentid", agentid); - WeixinResponse response = weixinClient.post(String.format( - suite_get_agent_uri, suiteTokenHolder.getAccessToken(), - obj.toJSONString())); + WeixinResponse response = weixinClient.post( + String.format(suite_get_agent_uri, + suiteTokenHolder.getAccessToken()), obj.toJSONString()); JSONObject jsonObj = response.getAsJson(); AgentInfo agent = JSON.toJavaObject(jsonObj, AgentInfo.class); agent.setAllowUsers(JSON.parseArray( diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java index 82d1eb17..20dcde60 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/dispatcher/WeixinMessageDispatcher.java @@ -29,6 +29,7 @@ import com.foxinmy.weixin4j.handler.MessageHandlerAdapter; import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor; import com.foxinmy.weixin4j.request.WeixinRequest; +import com.foxinmy.weixin4j.response.TextResponse; import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.type.AccountType; import com.foxinmy.weixin4j.util.ClassUtil; @@ -89,6 +90,11 @@ public class WeixinMessageDispatcher { */ private Map, Unmarshaller> messageUnmarshaller; + /** + * 开启debug:未匹配到MessageHanlder输出消息信息 + */ + private boolean isDebug; + public WeixinMessageDispatcher() { this(new DefaultMessageMatcher()); } @@ -105,8 +111,8 @@ public class WeixinMessageDispatcher { * 上下文环境 * @param request * 微信请求 - * @param messageKey - * 消息的key + * @param cruxMessage + * 微信的关键消息 * @throws WeixinException */ public void doDispatch(final ChannelHandlerContext context, @@ -171,9 +177,15 @@ public class WeixinMessageDispatcher { */ protected void noHandlerFound(ChannelHandlerContext context, WeixinRequest request, Object message) { - context.writeAndFlush( - HttpUtil.createHttpResponse(null, NOT_FOUND, null)) - .addListener(ChannelFutureListener.CLOSE); + if (isDebug) { + context.writeAndFlush( + new TextResponse(request.getOriginalContent())) + .addListener(ChannelFutureListener.CLOSE); + } else { + context.writeAndFlush( + HttpUtil.createHttpResponse(null, NOT_FOUND, null)) + .addListener(ChannelFutureListener.CLOSE); + } } /** @@ -242,8 +254,8 @@ public class WeixinMessageDispatcher { } if (beanFactory != null) { for (Class clazz : messageHandlerClass) { - messageHandlerList - .add((WeixinMessageHandler) beanFactory + messageHandlerList.add(0, + (WeixinMessageHandler) beanFactory .getBean(clazz)); } } else { @@ -256,8 +268,9 @@ public class WeixinMessageDispatcher { Constructor ctor = clazz .getDeclaredConstructor(); ReflectionUtil.makeAccessible(ctor); - messageHandlerList.add((WeixinMessageHandler) ctor - .newInstance((Object[]) null)); + messageHandlerList.add(0, + (WeixinMessageHandler) ctor + .newInstance((Object[]) null)); } catch (Exception ex) { throw new WeixinException(clazz.getName() + " instantiate fail", ex); @@ -293,8 +306,8 @@ public class WeixinMessageDispatcher { } if (beanFactory != null) { for (Class clazz : messageInterceptorClass) { - messageInterceptorList - .add((WeixinMessageInterceptor) beanFactory + messageInterceptorList.add(0, + (WeixinMessageInterceptor) beanFactory .getBean(clazz)); } } else { @@ -307,8 +320,8 @@ public class WeixinMessageDispatcher { Constructor ctor = clazz .getDeclaredConstructor(); ReflectionUtil.makeAccessible(ctor); - messageInterceptorList - .add((WeixinMessageInterceptor) ctor + messageInterceptorList.add(0, + (WeixinMessageInterceptor) ctor .newInstance((Object[]) null)); } catch (Exception ex) { throw new WeixinException(clazz.getName() @@ -432,4 +445,8 @@ public class WeixinMessageDispatcher { public WeixinMessageMatcher getMessageMatcher() { return this.messageMatcher; } + + public void openDebugMode() { + isDebug = true; + } } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/request/WeixinRequest.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/request/WeixinRequest.java index 57191f91..2dcfbdfd 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/request/WeixinRequest.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/request/WeixinRequest.java @@ -1,6 +1,8 @@ package com.foxinmy.weixin4j.request; import java.io.Serializable; +import java.util.List; +import java.util.Map; import com.foxinmy.weixin4j.type.EncryptType; import com.foxinmy.weixin4j.util.AesToken; @@ -65,11 +67,15 @@ public class WeixinRequest implements Serializable, Cloneable { * aes & token */ private AesToken aesToken; + /** + * url parameter + */ + private Map> parameters; public WeixinRequest(String method, EncryptType encryptType, String echoStr, String timeStamp, String nonce, String signature, String msgSignature, String originalContent, String encryptContent, - AesToken aesToken) { + AesToken aesToken, Map> parameters) { this.method = method; this.encryptType = encryptType; this.echoStr = echoStr; @@ -80,6 +86,7 @@ public class WeixinRequest implements Serializable, Cloneable { this.originalContent = originalContent; this.encryptContent = encryptContent; this.aesToken = aesToken; + this.parameters = parameters; } public String getMethod() { @@ -122,6 +129,10 @@ public class WeixinRequest implements Serializable, Cloneable { return aesToken; } + public Map> getParameters() { + return parameters; + } + @Override public String toString() { return "WeixinRequest [encryptContent=" + encryptContent @@ -129,6 +140,6 @@ public class WeixinRequest implements Serializable, Cloneable { + ", timeStamp=" + timeStamp + ", nonce=" + nonce + ", signature=" + signature + ", originalContent=" + originalContent + ", method=" + method + ", aesToken=" - + aesToken + "]"; + + aesToken + ", parameters=" + parameters + "]"; } } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java index 5d7d3642..bd56acfd 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinMessageDecoder.java @@ -67,6 +67,11 @@ public class WeixinMessageDecoder extends String weixinId = parameters.containsKey("weixin_id") ? parameters.get( "weixin_id").get(0) : null; AesToken aesToken = aesTokenMap.get(weixinId); + if (aesToken == null) { // + AesToken _aesToken = aesTokenMap.get(null); + aesToken = new AesToken(weixinId, _aesToken.getToken(), + _aesToken.getAesKey()); + } String originalContent = content; String encryptContent = null; if (!content.isEmpty() && encryptType == EncryptType.AES) { @@ -81,6 +86,6 @@ public class WeixinMessageDecoder extends } out.add(new WeixinRequest(methodName, encryptType, echoStr, timeStamp, nonce, signature, msgSignature, originalContent, - encryptContent, aesToken)); + encryptContent, aesToken, parameters)); } } diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinResponseEncoder.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinResponseEncoder.java index 8343aa90..23a15d8f 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinResponseEncoder.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/socket/WeixinResponseEncoder.java @@ -43,10 +43,6 @@ public class WeixinResponseEncoder extends .attr(Consts.MESSAGE_TRANSFER_KEY).get(); AesToken aesToken = messageTransfer.getAesToken(); EncryptType encryptType = messageTransfer.getEncryptType(); - String weixinId = aesToken.getWeixinId(); - if (StringUtil.isBlank(weixinId)) { - weixinId = messageTransfer.getToUserName(); - } StringBuilder content = new StringBuilder(); if (response instanceof BlankResponse) { content.append(response.toContent()); @@ -56,7 +52,9 @@ public class WeixinResponseEncoder extends "", messageTransfer.getFromUserName())); content.append(String.format( - "", weixinId)); + "", + StringUtil.isBlank(aesToken.getWeixinId()) ? messageTransfer + .getToUserName() : aesToken.getWeixinId())); content.append(String.format( "", System.currentTimeMillis() / 1000l)); @@ -68,8 +66,9 @@ public class WeixinResponseEncoder extends String nonce = RandomUtil.generateString(32); String timestamp = String .valueOf(System.currentTimeMillis() / 1000l); - String encrtypt = MessageUtil.aesEncrypt(weixinId, - aesToken.getAesKey(), content.toString()); + String encrtypt = MessageUtil.aesEncrypt( + aesToken.getWeixinId(), aesToken.getAesKey(), + content.toString()); String msgSignature = MessageUtil.signature( aesToken.getToken(), nonce, timestamp, encrtypt); content.delete(0, content.length()); 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 7084715c..7d2bb906 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 @@ -61,7 +61,6 @@ public final class WeixinServerBootstrap { * 消息分发器 */ private WeixinMessageDispatcher messageDispatcher; - /** * 消息处理器 */ @@ -289,4 +288,12 @@ public final class WeixinServerBootstrap { messageDispatcher.registMessageClass(messageKey, messageClass); return this; } + + /** + * 开启debug:未匹配到MessageHanlder输出消息信息 + */ + public WeixinServerBootstrap openDebugMode() { + messageDispatcher.openDebugMode(); + return this; + } } \ No newline at end of file diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/AesToken.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/AesToken.java index d05c1f43..f8954d5e 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/AesToken.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/AesToken.java @@ -11,7 +11,7 @@ import java.io.Serializable; * @since JDK 1.7 * @see */ -public class AesToken implements Serializable { +public class AesToken implements Serializable, Cloneable { private static final long serialVersionUID = -6001008896414323534L; diff --git a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java index 7a528817..a9c8d8e6 100644 --- a/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java +++ b/weixin4j-server/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java @@ -145,8 +145,7 @@ public final class MessageUtil { fromAppId = StringUtil.newStringUtf8(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length)); } catch (Exception e) { - throw new WeixinException("-40008", "公众平台发送的xml不合法" - + e.getMessage()); + throw new WeixinException("-40008", "xml内容不合法" + e.getMessage()); } // 校验appId是否一致 if (!fromAppId.trim().equals(appId)) {