1
0
mirror of synced 2026-02-16 02:00:13 +08:00

#193 增加小程序模块weixin-java-miniapp,支持小程序后台开发

This commit is contained in:
Binary Wang
2017-06-16 00:02:45 +08:00
parent 39e79a2c00
commit 1bd9b15c98
50 changed files with 3641 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
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 org.testng.annotations.Guice;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
/**
* 临时素材接口的测试
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMaMediaServiceImplTest {
@Inject
protected WxMaService wxService;
private String mediaId;
@Test
public void testUploadMedia() throws WxErrorException, IOException {
String mediaType = "image";
String fileType = "png";
String fileName = "tmp.png";
try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName)) {
WxMediaUploadResult res = this.wxService.getMediaService().uploadMedia(mediaType, fileType, inputStream);
assertNotNull(res.getType());
assertNotNull(res.getCreatedAt());
assertTrue(res.getMediaId() != null || res.getThumbMediaId() != null);
this.mediaId = res.getMediaId();
System.out.println(res);
}
}
@Test(dependsOnMethods = {"testUploadMedia"})
public void testGetMedia() throws WxErrorException {
File file = this.wxService.getMediaService().getMedia(this.mediaId);
assertNotNull(file);
System.out.println(file.getAbsolutePath());
}
}

View File

@@ -0,0 +1,76 @@
package cn.binarywang.wx.miniapp.api.impl;
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.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.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 测试客服相关接口
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Test
@Guice(modules = ApiTestModule.class)
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);
}
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超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
this.wxService.getMsgService().sendKefuMsg(message);
}
@Test(invocationCount = 5, threadPoolSize = 3)
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()
.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")))
.templateId(config.getTemplateId())
.emphasisKeyword("keyword1.DATA")
.build();
String msgId = this.wxService.getMsgService().sendTemplateMsg(templateMessage);
Assert.assertNotNull(msgId);
System.out.println(msgId);
}
}

View File

@@ -0,0 +1,26 @@
package cn.binarywang.wx.miniapp.api.impl;
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 <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMaQrcodeServiceImplTest {
@Inject
protected WxMaService wxService;
@Test
public void testCreateQrCode() throws Exception {
final File qrCode = this.wxService.getQrcodeService().createQrcode("111", 122);
System.out.println(qrCode);
}
}

View File

@@ -0,0 +1,35 @@
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.exception.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertTrue;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMaServiceImplTest {
@Inject
private WxMaService wxService;
public void testRefreshAccessToken() throws WxErrorException {
WxMaConfig configStorage = this.wxService.getWxMaConfig();
String before = configStorage.getAccessToken();
this.wxService.getAccessToken(false);
String after = configStorage.getAccessToken();
assertNotEquals(before, after);
assertTrue(StringUtils.isNotBlank(after));
}
}

View File

@@ -0,0 +1,46 @@
package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
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;
/**
* 测试用户相关的接口
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMaUserServiceImplTest {
@Inject
private WxMaService wxService;
@Test
public void testGetSessionKey() throws Exception {
assertNotNull(this.wxService.getUserService().getSessionInfo("aaa"));
}
@Test
public void testGetUserInfo() throws Exception {
WxMaUserInfo userInfo = this.wxService.getUserService().getUserInfo("tiihtNczf5v6AKRyjwEUhQ==",
"CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew==",
"r7BXXKkLb8qrSNn05n0qiA==");
assertNotNull(userInfo);
System.out.println(userInfo.toString());
}
@Test
public void testCheckUserInfo() throws Exception {
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"));
}
}

View File

@@ -0,0 +1,40 @@
package cn.binarywang.wx.miniapp.bean;
import me.chanjar.weixin.common.api.WxConsts;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@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 testTextBuild() {
WxMaKefuMessage reply = WxMaKefuMessage.TEXT().toUser("OPENID").content("sfsfdsdf").build();
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}");
}
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 testImageBuild() {
WxMaKefuMessage reply = WxMaKefuMessage.IMAGE().toUser("OPENID").mediaId("MEDIA_ID").build();
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}");
}
}

View File

@@ -0,0 +1,130 @@
package cn.binarywang.wx.miniapp.bean;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import me.chanjar.weixin.common.api.WxConsts;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Test
public class WxMaMessageTest {
public void testFromXml() {
String xml = "<xml>"
+ "<ToUserName><![CDATA[toUser]]></ToUserName>"
+ "<FromUserName><![CDATA[fromUser]]></FromUserName> "
+ "<CreateTime>1348831860</CreateTime>"
+ "<MsgDataFormat><![CDATA[text]]></MsgDataFormat>"
+ "<Content><![CDATA[this is a test]]></Content>"
+ "<MsgId>1234567890123456</MsgId>"
+ "<PicUrl><![CDATA[this is a url]]></PicUrl>"
+ "<MediaId><![CDATA[media_id]]></MediaId>"
+ "<Format><![CDATA[Format]]></Format>"
+ "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>"
+ "<Location_X>23.134521</Location_X>"
+ "<Location_Y>113.358803</Location_Y>"
+ "<Scale>20</Scale>"
+ "<Label><![CDATA[位置信息]]></Label>"
+ "<Description><![CDATA[公众平台官网链接]]></Description>"
+ "<Url><![CDATA[url]]></Url>"
+ "<Title><![CDATA[公众平台官网链接]]></Title>"
+ "<Event><![CDATA[subscribe]]></Event>"
+ "<EventKey><![CDATA[qrscene_123123]]></EventKey>"
+ "<Ticket><![CDATA[TICKET]]></Ticket>"
+ "<Latitude>23.137466</Latitude>"
+ "<Longitude>113.352425</Longitude>"
+ "<Precision>119.385040</Precision>"
+ "<ScanCodeInfo>"
+ " <ScanType><![CDATA[qrcode]]></ScanType>"
+ " <ScanResult><![CDATA[1]]></ScanResult>"
+ "</ScanCodeInfo>"
+ "<SendPicsInfo>"
+ " <Count>1</Count>\n"
+ " <PicList>"
+ " <item>"
+ " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>"
+ " </item>"
+ " </PicList>"
+ "</SendPicsInfo>"
+ "<SendLocationInfo>"
+ " <Location_X><![CDATA[23]]></Location_X>\n"
+ " <Location_Y><![CDATA[113]]></Location_Y>\n"
+ " <Scale><![CDATA[15]]></Scale>\n"
+ " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n"
+ " <Poiname><![CDATA[wo de poi]]></Poiname>\n"
+ "</SendLocationInfo>"
+ "</xml>";
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.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 = "<xml>"
+ "<ToUserName><![CDATA[toUser]]></ToUserName>"
+ "<FromUserName><![CDATA[fromUser]]></FromUserName> "
+ "<CreateTime>1348831860</CreateTime>"
+ "<MsgDataFormat><![CDATA[text]]></MsgDataFormat>"
+ "<Content><![CDATA[this is a test]]></Content>"
+ "<MsgID>1234567890123456</MsgID>"
+ "<PicUrl><![CDATA[this is a url]]></PicUrl>"
+ "<MediaId><![CDATA[media_id]]></MediaId>"
+ "<Format><![CDATA[Format]]></Format>"
+ "<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>"
+ "<Location_X>23.134521</Location_X>"
+ "<Location_Y>113.358803</Location_Y>"
+ "<Scale>20</Scale>"
+ "<Label><![CDATA[位置信息]]></Label>"
+ "<Description><![CDATA[公众平台官网链接]]></Description>"
+ "<Url><![CDATA[url]]></Url>"
+ "<Title><![CDATA[公众平台官网链接]]></Title>"
+ "<Event><![CDATA[subscribe]]></Event>"
+ "<EventKey><![CDATA[qrscene_123123]]></EventKey>"
+ "<Ticket><![CDATA[TICKET]]></Ticket>"
+ "<Latitude>23.137466</Latitude>"
+ "<Longitude>113.352425</Longitude>"
+ "<Precision>119.385040</Precision>"
+ "<ScanCodeInfo>"
+ " <ScanType><![CDATA[qrcode]]></ScanType>"
+ " <ScanResult><![CDATA[1]]></ScanResult>"
+ "</ScanCodeInfo>"
+ "<SendPicsInfo>"
+ " <Count>1</Count>\n"
+ " <PicList>"
+ " <item>"
+ " <PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>"
+ " </item>"
+ " </PicList>"
+ "</SendPicsInfo>"
+ "<SendLocationInfo>"
+ " <Location_X><![CDATA[23]]></Location_X>\n"
+ " <Location_Y><![CDATA[113]]></Location_Y>\n"
+ " <Scale><![CDATA[15]]></Scale>\n"
+ " <Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>\n"
+ " <Poiname><![CDATA[wo de poi]]></Poiname>\n"
+ "</SendLocationInfo>"
+ "</xml>";
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");
}
}

View File

@@ -0,0 +1,31 @@
package cn.binarywang.wx.miniapp.bean;
import com.google.common.collect.Lists;
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertEquals;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaTemplateMessageTest {
@Test
public void testToJson() throws Exception {
WxMaTemplateMessage tm = WxMaTemplateMessage.newBuilder()
.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")))
.templateId("TEMPLATE_ID")
.emphasisKeyword("keyword1.DATA")
.build();
assertEquals(tm.toJson(), "{\"touser\":\"OPENID\",\"template_id\":\"TEMPLATE_ID\",\"page\":\"index\",\"form_id\":\"FORMID\",\"emphasis_keyword\":\"keyword1.DATA\",\"data\":{\"keyword1\":{\"value\":\"339208499\",\"color\":\"#173177\"},\"keyword2\":{\"value\":\"2015年01月05日12:30\",\"color\":\"#173177\"},\"keyword3\":{\"value\":\"粤海喜来登酒店\",\"color\":\"#173177\"},\"keyword4\":{\"value\":\"广州市天河区天河路208号\",\"color\":\"#173177\"}}}");
}
}

View File

@@ -0,0 +1,144 @@
package cn.binarywang.wx.miniapp.demo;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
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.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 <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaDemoServer {
private static final WxMaMessageHandler logHandler = new WxMaMessageHandler() {
@Override
public void handle(WxMaMessage wxMessage, Map<String, Object> context,
WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
System.out.println("收到消息:" + wxMessage.toString());
service.getMsgService().sendKefuMsg(WxMaKefuMessage.TEXT().content("收到信息为:" + wxMessage.toJson())
.toUser(wxMessage.getFromUser()).build());
}
};
private static final WxMaMessageHandler textHandler = new WxMaMessageHandler() {
@Override
public void handle(WxMaMessage wxMessage, Map<String, Object> context,
WxMaService service, WxSessionManager sessionManager)
throws WxErrorException {
service.getMsgService().sendKefuMsg(WxMaKefuMessage.TEXT().content("回复文本消息")
.toUser(wxMessage.getFromUser()).build());
}
};
private static final WxMaMessageHandler picHandler = new WxMaMessageHandler() {
@Override
public void handle(WxMaMessage wxMessage, Map<String, Object> context,
WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
try {
WxMediaUploadResult uploadResult = service.getMediaService()
.uploadMedia("image", "png",
ClassLoader.getSystemResourceAsStream("tmp.png"));
service.getMsgService().sendKefuMsg(
WxMaKefuMessage
.IMAGE()
.mediaId(uploadResult.getMediaId())
.toUser(wxMessage.getFromUser())
.build());
} catch (WxErrorException e) {
e.printStackTrace();
}
}
};
private static final WxMaMessageHandler qrcodeHandler = new WxMaMessageHandler() {
@Override
public void handle(WxMaMessage wxMessage, Map<String, Object> context,
WxMaService service, WxSessionManager sessionManager) throws WxErrorException {
try {
final File file = service.getQrcodeService().createQrcode("123", 430);
WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
service.getMsgService().sendKefuMsg(
WxMaKefuMessage
.IMAGE()
.mediaId(uploadResult.getMediaId())
.toUser(wxMessage.getFromUser())
.build());
} catch (WxErrorException e) {
e.printStackTrace();
}
}
};
private static final WxMaMessageHandler templateMsgHandler = new WxMaMessageHandler() {
@Override
public void handle(WxMaMessage wxMessage, Map<String, Object> context,
WxMaService service, WxSessionManager sessionManager)
throws WxErrorException {
service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.newBuilder()
.templateId(templateId).data(Lists.newArrayList(
new WxMaTemplateMessage.Data("keyword1", "339208499", "#173177")))
.toUser(wxMessage.getFromUser())
.formId("自己替换可用的formid")
.build());
}
};
private static WxMaConfig config;
private static WxMaService service;
private static WxMaMessageRouter router;
private static String templateId;
public static void main(String[] args) throws Exception {
init();
Server server = new Server(8080);
ServletHandler servletHandler = new ServletHandler();
server.setHandler(servletHandler);
ServletHolder endpointServletHolder = new ServletHolder(new WxMaPortalServlet(config, service, router));
servletHandler.addServletWithMapping(endpointServletHolder, "/*");
server.start();
server.join();
}
private static void init() {
try (InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml")) {
TestConfig config = TestConfig.fromXml(is1);
config.setAccessTokenLock(new ReentrantLock());
templateId = config.getTemplateId();
WxMaDemoServer.config = config;
service = new WxMaServiceImpl();
service.setWxMaConfig(config);
router = new WxMaMessageRouter(service);
router.rule().handler(logHandler).next()
.rule().async(false).content("模板").handler(templateMsgHandler).end()
.rule().async(false).content("文本").handler(textHandler).end()
.rule().async(false).content("图片").handler(picHandler).end()
.rule().async(false).content("二维码").handler(qrcodeHandler).end();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,92 @@
package cn.binarywang.wx.miniapp.demo;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaPortalServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private WxMaConfig wxMaConfig;
private WxMaService wxMaService;
private WxMaMessageRouter wxMaMessageRouter;
WxMaPortalServlet(WxMaConfig wxMaConfig, WxMaService wxMaService,
WxMaMessageRouter wxMaMessageRouter) {
this.wxMaConfig = wxMaConfig;
this.wxMaService = wxMaService;
this.wxMaMessageRouter = wxMaMessageRouter;
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
String signature = request.getParameter("signature");
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
if (!this.wxMaService.checkSignature(timestamp, nonce, signature)) {
// 消息签名不正确,说明不是公众平台发过来的消息
response.getWriter().println("非法请求");
return;
}
String echoStr = request.getParameter("echostr");
if (StringUtils.isNotBlank(echoStr)) {
// 说明是一个仅仅用来验证的请求回显echostr
response.getWriter().println(echoStr);
return;
}
String encryptType = request.getParameter("encrypt_type");
final boolean isJson = Objects.equals(this.wxMaConfig.getMsgDataFormat(), WxMaConstants.MsgDataFormat.JSON);
if (StringUtils.isBlank(encryptType)) {
// 明文传输的消息
WxMaMessage inMessage;
if (isJson) {
inMessage = WxMaMessage.fromJson(IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8));
} else {//xml
inMessage = WxMaMessage.fromXml(request.getInputStream());
}
this.wxMaMessageRouter.route(inMessage);
response.getWriter().write("success");
return;
}
if ("aes".equals(encryptType)) {
// 是aes加密的消息
String msgSignature = request.getParameter("msg_signature");
WxMaMessage inMessage;
if (isJson) {
inMessage = WxMaMessage.fromEncryptedJson(request.getInputStream(), this.wxMaConfig);
} else {//xml
inMessage = WxMaMessage.fromEncryptedXml(request.getInputStream(), this.wxMaConfig, timestamp, nonce, msgSignature);
}
this.wxMaMessageRouter.route(inMessage);
response.getWriter().write("success");
return;
}
response.getWriter().println("不可识别的加密类型");
}
}

View File

@@ -0,0 +1,33 @@
package cn.binarywang.wx.miniapp.test;
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 <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class ApiTestModule implements Module {
@Override
public void configure(Binder binder) {
try (InputStream inputStream = ClassLoader.getSystemResourceAsStream("test-config.xml")) {
TestConfig config = TestConfig.fromXml(inputStream);
config.setAccessTokenLock(new ReentrantLock());
WxMaService wxService = new cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl();
wxService.setWxMaConfig(config);
binder.bind(WxMaService.class).toInstance(wxService);
binder.bind(WxMaConfig.class).toInstance(config);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,61 @@
package cn.binarywang.wx.miniapp.test;
import cn.binarywang.wx.miniapp.config.WxMaInMemoryConfig;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.io.InputStream;
import java.util.concurrent.locks.Lock;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@XStreamAlias("xml")
public class TestConfig extends WxMaInMemoryConfig {
private String openid;
private String kfAccount;
private String templateId;
public static TestConfig fromXml(InputStream is) {
XStream xstream = XStreamInitializer.getInstance();
xstream.processAnnotations(TestConfig.class);
return (TestConfig) xstream.fromXML(is);
}
public String getOpenid() {
return this.openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
public String getKfAccount() {
return this.kfAccount;
}
public void setKfAccount(String kfAccount) {
this.kfAccount = kfAccount;
}
public String getTemplateId() {
return this.templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public void setAccessTokenLock(Lock lock) {
super.accessTokenLock = lock;
}
}

View File

@@ -0,0 +1,14 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %replace(%caller{1}){'Caller', ''} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
<logger name="cn.binarywang.wx.miniapp" level="debug"/>
</configuration>

View File

@@ -0,0 +1,11 @@
<xml>
<msgDataFormat>JSON或者XML</msgDataFormat>
<appid>appid</appid>
<secret>secret</secret>
<token>Token</token>
<aesKey>EncodingAESKey</aesKey>
<accessToken>可以不填写</accessToken>
<expiresTime>可以不填写</expiresTime>
<openid>某个用户的openId</openid>
<templateId>模版消息的模版ID</templateId>
</xml>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB