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 a2ef9d6a..3ecbf155 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 @@ -25,7 +25,7 @@ public interface WxMpConfigStorage { public int getExpiresIn(); - public String getOauth2redirectUrl(); + public String getOauth2redirectUri(); public String getHttp_proxy_host(); 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 0f6dd788..4e43dfa1 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 @@ -20,7 +20,7 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected int http_proxy_port; protected String http_proxy_username; protected String http_proxy_password; - protected String oauth2redirectUrl; + protected String oauth2redirectUri; public void updateAccessToken(WxAccessToken accessToken) { updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); @@ -80,12 +80,12 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { } @Override - public String getOauth2redirectUrl() { - return this.oauth2redirectUrl; + public String getOauth2redirectUri() { + return this.oauth2redirectUri; } - public void setOauth2redirectUrl(String oauth2redirectUrl) { - this.oauth2redirectUrl = oauth2redirectUrl; + public void setOauth2redirectUri(String oauth2redirectUri) { + this.oauth2redirectUri = oauth2redirectUri; } public String getHttp_proxy_host() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index 5e07b7c2..93686ef6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -27,13 +27,11 @@ import org.apache.http.client.CredentialsProvider; 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.client.utils.URIUtils; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; -import javax.print.DocFlavor; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -303,7 +301,7 @@ public class WxMpServiceImpl implements WxMpService { public String oauth2buildAuthorizationUrl(String scope, String state) { String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" ; url += "appid=" + wxMpConfigStorage.getAppId(); - url += "&redirect_uri=" + URIUtil.encodeURIComponent(wxMpConfigStorage.getOauth2redirectUrl()); + url += "&redirect_uri=" + URIUtil.encodeURIComponent(wxMpConfigStorage.getOauth2redirectUri()); url += "&response_type=code"; url += "&scope=" + scope; if (state != null) { 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 01c5b99c..88b732f9 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,6 +1,7 @@ package me.chanjar.weixin.mp.bean.result; import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** * Created by qianjia on 14/11/26. @@ -58,7 +59,17 @@ public class WxMpOAuth2AccessToken { } public static WxMpOAuth2AccessToken fromJson(String json) { - return WxGsonBuilder.create().fromJson(json, WxMpOAuth2AccessToken.class); + return WxMpGsonBuilder.create().fromJson(json, WxMpOAuth2AccessToken.class); } + @Override + public String toString() { + return "WxMpOAuth2AccessToken{" + + "accessToken='" + accessToken + '\'' + + ", expiresIn=" + expiresIn + + ", refreshToken='" + refreshToken + '\'' + + ", openId='" + openId + '\'' + + ", scope='" + scope + '\'' + + '}'; + } } 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 fa4aee6d..554a07db 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 @@ -9,7 +9,7 @@ import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; */ public class WxMpUser { - protected boolean subscribe; + protected Boolean subscribe; protected String openId; protected String nickname; protected String sex; @@ -18,13 +18,13 @@ public class WxMpUser { protected String province; protected String country; protected String headImgUrl; - protected long subscribeTime; + protected Long subscribeTime; protected String unionId; - public boolean isSubscribe() { + public Boolean isSubscribe() { return subscribe; } - public void setSubscribe(boolean subscribe) { + public void setSubscribe(Boolean subscribe) { this.subscribe = subscribe; } public String getOpenId() { @@ -75,10 +75,10 @@ public class WxMpUser { public void setHeadImgUrl(String headImgUrl) { this.headImgUrl = headImgUrl; } - public long getSubscribeTime() { + public Long getSubscribeTime() { return subscribeTime; } - public void setSubscribeTime(long subscribeTime) { + public void setSubscribeTime(Long subscribeTime) { this.subscribeTime = subscribeTime; } public String getUnionId() { @@ -91,5 +91,21 @@ public class WxMpUser { public static WxMpUser fromJson(String json) { return WxMpGsonBuilder.INSTANCE.create().fromJson(json, WxMpUser.class); } - + + @Override + public String toString() { + return "WxMpUser{" + + "subscribe=" + subscribe + + ", openId='" + openId + '\'' + + ", nickname='" + nickname + '\'' + + ", sex='" + sex + '\'' + + ", language='" + language + '\'' + + ", city='" + city + '\'' + + ", province='" + province + '\'' + + ", country='" + country + '\'' + + ", headImgUrl='" + headImgUrl + '\'' + + ", subscribeTime=" + subscribeTime + + ", unionId='" + unionId + '\'' + + '}'; + } } 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 7285bc8b..2849a796 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 @@ -4,6 +4,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import me.chanjar.weixin.mp.bean.*; import me.chanjar.weixin.mp.bean.result.*; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; public class WxMpGsonBuilder { @@ -24,6 +25,7 @@ public class WxMpGsonBuilder { INSTANCE.registerTypeAdapter(WxMpQrCodeTicket.class, new WxQrCodeTicketAdapter()); INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter()); INSTANCE.registerTypeAdapter(WxMpSemanticQueryResult.class, new WxMpSemanticQueryResultAdapter()); + INSTANCE.registerTypeAdapter(WxMpOAuth2AccessToken.class, new WxMpOAuth2AccessTokenAdapter()); } public static Gson create() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java new file mode 100644 index 00000000..7ea7a35e --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java @@ -0,0 +1,38 @@ +package me.chanjar.weixin.mp.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; + +import java.lang.reflect.Type; + +/** + * Created by qianjia on 14/11/28. + */ +public class WxMpOAuth2AccessTokenAdapter implements JsonDeserializer { + + public WxMpOAuth2AccessToken deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws + JsonParseException { + WxMpOAuth2AccessToken accessToken = new WxMpOAuth2AccessToken(); + JsonObject accessTokenJsonObject = json.getAsJsonObject(); + + if (accessTokenJsonObject.get("access_token") != null && !accessTokenJsonObject.get("access_token").isJsonNull()) { + accessToken.setAccessToken(GsonHelper.getAsString(accessTokenJsonObject.get("access_token"))); + } + if (accessTokenJsonObject.get("expires_in") != null && !accessTokenJsonObject.get("expires_in").isJsonNull()) { + accessToken.setExpiresIn(GsonHelper.getAsPrimitiveInt(accessTokenJsonObject.get("expires_in"))); + } + if (accessTokenJsonObject.get("refresh_token") != null && !accessTokenJsonObject.get("refresh_token").isJsonNull()) { + accessToken.setRefreshToken(GsonHelper.getAsString(accessTokenJsonObject.get("refresh_token"))); + } + if (accessTokenJsonObject.get("openid") != null && !accessTokenJsonObject.get("openid").isJsonNull()) { + accessToken.setOpenId(GsonHelper.getAsString(accessTokenJsonObject.get("openid"))); + } + if (accessTokenJsonObject.get("scope") != null && !accessTokenJsonObject.get("scope").isJsonNull()) { + accessToken.setScope(GsonHelper.getAsString(accessTokenJsonObject.get("scope"))); + } + return accessToken; + } + +} 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 e0bb6498..922c42a1 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 @@ -1,20 +1,127 @@ package me.chanjar.weixin.mp.demo; +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.mp.api.*; +import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage; +import me.chanjar.weixin.mp.bean.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; +import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.*; + +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; /** * @author Daniel Qian */ public class WxMpDemoServer { + + private static WxMpConfigStorage wxMpConfigStorage; + private static WxMpService wxMpService; + private static WxMpMessageRouter wxMpMessageRouter; + public static void main(String[] args) throws Exception { + initWeixin(); + Server server = new Server(8080); ServletHandler handler = new ServletHandler(); - server.setHandler(handler); - handler.addServletWithMapping(WxMpDemoServlet.class, "/*"); + ServletHolder endpointServletHolder = new ServletHolder(new WxMpEndpointServlt(wxMpConfigStorage, wxMpService, wxMpMessageRouter)); + handler.addServletWithMapping(endpointServletHolder, "/*"); + + ServletHolder oauthServletHolder = new ServletHolder(new WxMpOAuth2Servlet(wxMpService)); + handler.addServletWithMapping(oauthServletHolder, "/oauth2/*"); + + server.setHandler(handler); server.start(); server.join(); } + + private static void initWeixin() { + try { + InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); + WxMpDemoInMemoryConfigStorage config = WxMpDemoInMemoryConfigStorage.fromXml(is1); + + wxMpConfigStorage = config; + wxMpService = new WxMpServiceImpl(); + wxMpService.setWxMpConfigStorage(config); + + WxMpMessageHandler textHandler = new WxMpMessageHandler() { + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, + WxMpService wxMpService) { + WxMpXmlOutTextMessage m + = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName()) + .toUser(wxMessage.getFromUserName()).build(); + return m; + } + }; + + WxMpMessageHandler imageHandler = new WxMpMessageHandler() { + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, + WxMpService wxMpService) { + try { + WxMediaUploadResult wxMediaUploadResult = wxMpService + .mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg")); + WxMpMpXmlOutImageMessage m + = WxMpXmlOutMessage + .IMAGE() + .mediaId(wxMediaUploadResult.getMediaId()) + .fromUser(wxMessage.getToUserName()) + .toUser(wxMessage.getFromUserName()) + .build(); + return m; + } catch (WxErrorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + }; + + WxMpMessageHandler oauth2handler = new WxMpMessageHandler() { + @Override + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, + WxMpService wxMpService) { + String href = "测试oauth2"; + return WxMpXmlOutMessage + .TEXT() + .content(href) + .fromUser(wxMessage.getToUserName()) + .toUser(wxMessage.getFromUserName()).build(); + } + }; + + wxMpMessageRouter = new WxMpMessageRouter(wxMpService); + wxMpMessageRouter + .rule() + .async(false) + .content("哈哈") // 拦截内容为“哈哈”的消息 + .handler(textHandler) + .end() + .rule() + .async(false) + .content("图片") + .handler(imageHandler) + .end() + .rule() + .async(false) + .content("oauth") + .handler(oauth2handler) + .end() + ; + + } catch (JAXBException e) { + throw new RuntimeException(e); + } + } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java similarity index 55% rename from weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java rename to weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java index 122a9fd1..c99cd8b3 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java @@ -22,71 +22,17 @@ import java.util.Map; /** * @author Daniel Qian */ -public class WxMpDemoServlet extends HttpServlet { +public class WxMpEndpointServlt extends HttpServlet { protected WxMpConfigStorage wxMpConfigStorage; protected WxMpService wxMpService; protected WxMpMessageRouter wxMpMessageRouter; - @Override public void init() throws ServletException { - // - super.init(); - try { - InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); - WxMpDemoInMemoryConfigStorage config = WxMpDemoInMemoryConfigStorage.fromXml(is1); - - wxMpConfigStorage = config; - wxMpService = new WxMpServiceImpl(); - wxMpService.setWxMpConfigStorage(config); - - WxMpMessageHandler textHandler = new WxMpMessageHandler() { - @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService) { - WxMpXmlOutTextMessage m - = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage.getToUserName()) - .toUser(wxMessage.getFromUserName()).build(); - return m; - } - }; - - WxMpMessageHandler imageHandler = new WxMpMessageHandler() { - @Override public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map context, WxMpService wxMpService) { - try { - WxMediaUploadResult wxMediaUploadResult = wxMpService - .mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, ClassLoader.getSystemResourceAsStream("mm.jpeg")); - WxMpMpXmlOutImageMessage m - = WxMpXmlOutMessage - .IMAGE() - .mediaId(wxMediaUploadResult.getMediaId()) - .fromUser(wxMessage.getToUserName()) - .toUser(wxMessage.getFromUserName()) - .build(); - return m; - } catch (WxErrorException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - }; - - wxMpMessageRouter = new WxMpMessageRouter(wxMpService); - wxMpMessageRouter - .rule() - .async(false) - .content("哈哈") // 拦截内容为“哈哈”的消息 - .handler(textHandler) - .end() - .rule() - .async(false) - .content("图片") - .handler(imageHandler) - .end() - ; - - } catch (JAXBException e) { - throw new RuntimeException(e); - } + public WxMpEndpointServlt(WxMpConfigStorage wxMpConfigStorage, WxMpService wxMpService, + WxMpMessageRouter wxMpMessageRouter) { + this.wxMpConfigStorage = wxMpConfigStorage; + this.wxMpService = wxMpService; + this.wxMpMessageRouter = wxMpMessageRouter; } @Override protected void service(HttpServletRequest request, HttpServletResponse response) 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 new file mode 100644 index 00000000..0b6a612a --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java @@ -0,0 +1,68 @@ +package me.chanjar.weixin.mp.demo; + +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.util.StringUtils; +import me.chanjar.weixin.mp.api.*; +import me.chanjar.weixin.mp.bean.WxMpMpXmlOutImageMessage; +import me.chanjar.weixin.mp.bean.WxMpXmlMessage; +import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; +import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage; +import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; +import me.chanjar.weixin.mp.bean.result.WxMpUser; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +/** + * @author Daniel Qian + */ +public class WxMpOAuth2Servlet extends HttpServlet { + + protected WxMpService wxMpService; + + public WxMpOAuth2Servlet(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override protected void service(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + response.setContentType("text/html;charset=utf-8"); + response.setStatus(HttpServletResponse.SC_OK); + + String code = request.getParameter("code"); + try { + response.getWriter().println("

code

"); + response.getWriter().println(code); + + WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code); + response.getWriter().println("

access token

"); + response.getWriter().println(wxMpOAuth2AccessToken.toString()); + + WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null); + response.getWriter().println("

user info

"); + response.getWriter().println(wxMpUser.toString()); + + wxMpOAuth2AccessToken = wxMpService.oauth2refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken()); + response.getWriter().println("

after refresh

"); + response.getWriter().println(wxMpOAuth2AccessToken.toString()); + + } catch (WxErrorException e) { + e.printStackTrace(); + } + + response.getWriter().flush(); + response.getWriter().close(); + + } + +} diff --git a/weixin-java-mp/src/test/resources/test-config.sample.xml b/weixin-java-mp/src/test/resources/test-config.sample.xml index 501620cd..19535f3c 100644 --- a/weixin-java-mp/src/test/resources/test-config.sample.xml +++ b/weixin-java-mp/src/test/resources/test-config.sample.xml @@ -6,4 +6,5 @@ 可以不填写 可以不填写 某个加你公众号的用户的openId + 网页授权获取用户信息回调地址