fixed一些bug

This commit is contained in:
jinyu 2015-06-26 00:18:08 +08:00
parent f6b1f76210
commit 663cba9677
10 changed files with 94 additions and 162 deletions

View File

@ -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<Class<?>> 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<Class<?>> findClassesByFile(File dir, String packageName) {
Set<Class<?>> classes = new HashSet<Class<?>>();
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<Class<?>> findClassesByJar(JarFile jar,
String packageName) {
Set<Class<?>> classes = new HashSet<Class<?>>();
Enumeration<JarEntry> 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));
}
}

View File

@ -3,7 +3,11 @@ package com.foxinmy.weixin4j.qy.api;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; 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.model.Consts;
import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.ConfigUtil;
/** /**
@ -57,6 +61,28 @@ public class OauthApi extends QyApi {
} }
return ""; return "";
} }
/**
* 获取企业号管理员登录信息
*
* @param providerToken
* 提供商的token
* @param authCode
* oauth2.0授权企业号管理员登录产生的code
* @return 登陆信息
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86%E5%91%98%E7%99%BB%E5%BD%95%E4%BF%A1%E6%81%AF">授权获取企业号管理员登录信息</a>
* @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)} * @see {@link com.foxinmy.weixin4j.qy.api.OauthApi#getSuiteAuthorizeURL(String,String, String,String)}

View File

@ -239,9 +239,9 @@ public class SuiteApi extends QyApi {
obj.put("auth_corpid", authCorpid); obj.put("auth_corpid", authCorpid);
obj.put("permanent_code", suitePerCodeHolder.getPermanentCode(suiteId)); obj.put("permanent_code", suitePerCodeHolder.getPermanentCode(suiteId));
obj.put("agentid", agentid); obj.put("agentid", agentid);
WeixinResponse response = weixinClient.post(String.format( WeixinResponse response = weixinClient.post(
suite_get_agent_uri, suiteTokenHolder.getAccessToken(), String.format(suite_get_agent_uri,
obj.toJSONString())); suiteTokenHolder.getAccessToken()), obj.toJSONString());
JSONObject jsonObj = response.getAsJson(); JSONObject jsonObj = response.getAsJson();
AgentInfo agent = JSON.toJavaObject(jsonObj, AgentInfo.class); AgentInfo agent = JSON.toJavaObject(jsonObj, AgentInfo.class);
agent.setAllowUsers(JSON.parseArray( agent.setAllowUsers(JSON.parseArray(

View File

@ -29,6 +29,7 @@ import com.foxinmy.weixin4j.handler.MessageHandlerAdapter;
import com.foxinmy.weixin4j.handler.WeixinMessageHandler; import com.foxinmy.weixin4j.handler.WeixinMessageHandler;
import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor; import com.foxinmy.weixin4j.interceptor.WeixinMessageInterceptor;
import com.foxinmy.weixin4j.request.WeixinRequest; import com.foxinmy.weixin4j.request.WeixinRequest;
import com.foxinmy.weixin4j.response.TextResponse;
import com.foxinmy.weixin4j.response.WeixinResponse; import com.foxinmy.weixin4j.response.WeixinResponse;
import com.foxinmy.weixin4j.type.AccountType; import com.foxinmy.weixin4j.type.AccountType;
import com.foxinmy.weixin4j.util.ClassUtil; import com.foxinmy.weixin4j.util.ClassUtil;
@ -89,6 +90,11 @@ public class WeixinMessageDispatcher {
*/ */
private Map<Class<?>, Unmarshaller> messageUnmarshaller; private Map<Class<?>, Unmarshaller> messageUnmarshaller;
/**
* 开启debug:未匹配到MessageHanlder输出消息信息
*/
private boolean isDebug;
public WeixinMessageDispatcher() { public WeixinMessageDispatcher() {
this(new DefaultMessageMatcher()); this(new DefaultMessageMatcher());
} }
@ -105,8 +111,8 @@ public class WeixinMessageDispatcher {
* 上下文环境 * 上下文环境
* @param request * @param request
* 微信请求 * 微信请求
* @param messageKey * @param cruxMessage
* 消息的key * 微信的关键消息
* @throws WeixinException * @throws WeixinException
*/ */
public void doDispatch(final ChannelHandlerContext context, public void doDispatch(final ChannelHandlerContext context,
@ -171,9 +177,15 @@ public class WeixinMessageDispatcher {
*/ */
protected void noHandlerFound(ChannelHandlerContext context, protected void noHandlerFound(ChannelHandlerContext context,
WeixinRequest request, Object message) { WeixinRequest request, Object message) {
context.writeAndFlush( if (isDebug) {
HttpUtil.createHttpResponse(null, NOT_FOUND, null)) context.writeAndFlush(
.addListener(ChannelFutureListener.CLOSE); 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) { if (beanFactory != null) {
for (Class<?> clazz : messageHandlerClass) { for (Class<?> clazz : messageHandlerClass) {
messageHandlerList messageHandlerList.add(0,
.add((WeixinMessageHandler) beanFactory (WeixinMessageHandler) beanFactory
.getBean(clazz)); .getBean(clazz));
} }
} else { } else {
@ -256,8 +268,9 @@ public class WeixinMessageDispatcher {
Constructor<?> ctor = clazz Constructor<?> ctor = clazz
.getDeclaredConstructor(); .getDeclaredConstructor();
ReflectionUtil.makeAccessible(ctor); ReflectionUtil.makeAccessible(ctor);
messageHandlerList.add((WeixinMessageHandler) ctor messageHandlerList.add(0,
.newInstance((Object[]) null)); (WeixinMessageHandler) ctor
.newInstance((Object[]) null));
} catch (Exception ex) { } catch (Exception ex) {
throw new WeixinException(clazz.getName() throw new WeixinException(clazz.getName()
+ " instantiate fail", ex); + " instantiate fail", ex);
@ -293,8 +306,8 @@ public class WeixinMessageDispatcher {
} }
if (beanFactory != null) { if (beanFactory != null) {
for (Class<?> clazz : messageInterceptorClass) { for (Class<?> clazz : messageInterceptorClass) {
messageInterceptorList messageInterceptorList.add(0,
.add((WeixinMessageInterceptor) beanFactory (WeixinMessageInterceptor) beanFactory
.getBean(clazz)); .getBean(clazz));
} }
} else { } else {
@ -307,8 +320,8 @@ public class WeixinMessageDispatcher {
Constructor<?> ctor = clazz Constructor<?> ctor = clazz
.getDeclaredConstructor(); .getDeclaredConstructor();
ReflectionUtil.makeAccessible(ctor); ReflectionUtil.makeAccessible(ctor);
messageInterceptorList messageInterceptorList.add(0,
.add((WeixinMessageInterceptor) ctor (WeixinMessageInterceptor) ctor
.newInstance((Object[]) null)); .newInstance((Object[]) null));
} catch (Exception ex) { } catch (Exception ex) {
throw new WeixinException(clazz.getName() throw new WeixinException(clazz.getName()
@ -432,4 +445,8 @@ public class WeixinMessageDispatcher {
public WeixinMessageMatcher getMessageMatcher() { public WeixinMessageMatcher getMessageMatcher() {
return this.messageMatcher; return this.messageMatcher;
} }
public void openDebugMode() {
isDebug = true;
}
} }

View File

@ -1,6 +1,8 @@
package com.foxinmy.weixin4j.request; package com.foxinmy.weixin4j.request;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
import java.util.Map;
import com.foxinmy.weixin4j.type.EncryptType; import com.foxinmy.weixin4j.type.EncryptType;
import com.foxinmy.weixin4j.util.AesToken; import com.foxinmy.weixin4j.util.AesToken;
@ -65,11 +67,15 @@ public class WeixinRequest implements Serializable, Cloneable {
* aes & token * aes & token
*/ */
private AesToken aesToken; private AesToken aesToken;
/**
* url parameter
*/
private Map<String, List<String>> parameters;
public WeixinRequest(String method, EncryptType encryptType, public WeixinRequest(String method, EncryptType encryptType,
String echoStr, String timeStamp, String nonce, String signature, String echoStr, String timeStamp, String nonce, String signature,
String msgSignature, String originalContent, String encryptContent, String msgSignature, String originalContent, String encryptContent,
AesToken aesToken) { AesToken aesToken, Map<String, List<String>> parameters) {
this.method = method; this.method = method;
this.encryptType = encryptType; this.encryptType = encryptType;
this.echoStr = echoStr; this.echoStr = echoStr;
@ -80,6 +86,7 @@ public class WeixinRequest implements Serializable, Cloneable {
this.originalContent = originalContent; this.originalContent = originalContent;
this.encryptContent = encryptContent; this.encryptContent = encryptContent;
this.aesToken = aesToken; this.aesToken = aesToken;
this.parameters = parameters;
} }
public String getMethod() { public String getMethod() {
@ -122,6 +129,10 @@ public class WeixinRequest implements Serializable, Cloneable {
return aesToken; return aesToken;
} }
public Map<String, List<String>> getParameters() {
return parameters;
}
@Override @Override
public String toString() { public String toString() {
return "WeixinRequest [encryptContent=" + encryptContent return "WeixinRequest [encryptContent=" + encryptContent
@ -129,6 +140,6 @@ public class WeixinRequest implements Serializable, Cloneable {
+ ", timeStamp=" + timeStamp + ", nonce=" + nonce + ", timeStamp=" + timeStamp + ", nonce=" + nonce
+ ", signature=" + signature + ", originalContent=" + ", signature=" + signature + ", originalContent="
+ originalContent + ", method=" + method + ", aesToken=" + originalContent + ", method=" + method + ", aesToken="
+ aesToken + "]"; + aesToken + ", parameters=" + parameters + "]";
} }
} }

View File

@ -67,6 +67,11 @@ public class WeixinMessageDecoder extends
String weixinId = parameters.containsKey("weixin_id") ? parameters.get( String weixinId = parameters.containsKey("weixin_id") ? parameters.get(
"weixin_id").get(0) : null; "weixin_id").get(0) : null;
AesToken aesToken = aesTokenMap.get(weixinId); 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 originalContent = content;
String encryptContent = null; String encryptContent = null;
if (!content.isEmpty() && encryptType == EncryptType.AES) { if (!content.isEmpty() && encryptType == EncryptType.AES) {
@ -81,6 +86,6 @@ public class WeixinMessageDecoder extends
} }
out.add(new WeixinRequest(methodName, encryptType, echoStr, timeStamp, out.add(new WeixinRequest(methodName, encryptType, echoStr, timeStamp,
nonce, signature, msgSignature, originalContent, nonce, signature, msgSignature, originalContent,
encryptContent, aesToken)); encryptContent, aesToken, parameters));
} }
} }

View File

@ -43,10 +43,6 @@ public class WeixinResponseEncoder extends
.attr(Consts.MESSAGE_TRANSFER_KEY).get(); .attr(Consts.MESSAGE_TRANSFER_KEY).get();
AesToken aesToken = messageTransfer.getAesToken(); AesToken aesToken = messageTransfer.getAesToken();
EncryptType encryptType = messageTransfer.getEncryptType(); EncryptType encryptType = messageTransfer.getEncryptType();
String weixinId = aesToken.getWeixinId();
if (StringUtil.isBlank(weixinId)) {
weixinId = messageTransfer.getToUserName();
}
StringBuilder content = new StringBuilder(); StringBuilder content = new StringBuilder();
if (response instanceof BlankResponse) { if (response instanceof BlankResponse) {
content.append(response.toContent()); content.append(response.toContent());
@ -56,7 +52,9 @@ public class WeixinResponseEncoder extends
"<ToUserName><![CDATA[%s]]></ToUserName>", "<ToUserName><![CDATA[%s]]></ToUserName>",
messageTransfer.getFromUserName())); messageTransfer.getFromUserName()));
content.append(String.format( content.append(String.format(
"<FromUserName><![CDATA[%s]]></FromUserName>", weixinId)); "<FromUserName><![CDATA[%s]]></FromUserName>",
StringUtil.isBlank(aesToken.getWeixinId()) ? messageTransfer
.getToUserName() : aesToken.getWeixinId()));
content.append(String.format( content.append(String.format(
"<CreateTime><![CDATA[%d]]></CreateTime>", "<CreateTime><![CDATA[%d]]></CreateTime>",
System.currentTimeMillis() / 1000l)); System.currentTimeMillis() / 1000l));
@ -68,8 +66,9 @@ public class WeixinResponseEncoder extends
String nonce = RandomUtil.generateString(32); String nonce = RandomUtil.generateString(32);
String timestamp = String String timestamp = String
.valueOf(System.currentTimeMillis() / 1000l); .valueOf(System.currentTimeMillis() / 1000l);
String encrtypt = MessageUtil.aesEncrypt(weixinId, String encrtypt = MessageUtil.aesEncrypt(
aesToken.getAesKey(), content.toString()); aesToken.getWeixinId(), aesToken.getAesKey(),
content.toString());
String msgSignature = MessageUtil.signature( String msgSignature = MessageUtil.signature(
aesToken.getToken(), nonce, timestamp, encrtypt); aesToken.getToken(), nonce, timestamp, encrtypt);
content.delete(0, content.length()); content.delete(0, content.length());

View File

@ -61,7 +61,6 @@ public final class WeixinServerBootstrap {
* 消息分发器 * 消息分发器
*/ */
private WeixinMessageDispatcher messageDispatcher; private WeixinMessageDispatcher messageDispatcher;
/** /**
* 消息处理器 * 消息处理器
*/ */
@ -289,4 +288,12 @@ public final class WeixinServerBootstrap {
messageDispatcher.registMessageClass(messageKey, messageClass); messageDispatcher.registMessageClass(messageKey, messageClass);
return this; return this;
} }
/**
* 开启debug:未匹配到MessageHanlder输出消息信息
*/
public WeixinServerBootstrap openDebugMode() {
messageDispatcher.openDebugMode();
return this;
}
} }

View File

@ -11,7 +11,7 @@ import java.io.Serializable;
* @since JDK 1.7 * @since JDK 1.7
* @see * @see
*/ */
public class AesToken implements Serializable { public class AesToken implements Serializable, Cloneable {
private static final long serialVersionUID = -6001008896414323534L; private static final long serialVersionUID = -6001008896414323534L;

View File

@ -145,8 +145,7 @@ public final class MessageUtil {
fromAppId = StringUtil.newStringUtf8(Arrays.copyOfRange(bytes, fromAppId = StringUtil.newStringUtf8(Arrays.copyOfRange(bytes,
20 + xmlLength, bytes.length)); 20 + xmlLength, bytes.length));
} catch (Exception e) { } catch (Exception e) {
throw new WeixinException("-40008", "公众平台发送的xml不合法" throw new WeixinException("-40008", "xml内容不合法" + e.getMessage());
+ e.getMessage());
} }
// 校验appId是否一致 // 校验appId是否一致
if (!fromAppId.trim().equals(appId)) { if (!fromAppId.trim().equals(appId)) {