Procházet zdrojové kódy

issue #39 公众号添加oauth2的支持

master
Daniel Qian před 10 roky
rodič
revize
0d6712f709
11 změnil soubory, kde provedl 267 přidání a 80 odebrání
  1. +1
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
  2. +5
    -5
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
  3. +1
    -3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
  4. +12
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java
  5. +23
    -7
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java
  6. +2
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java
  7. +38
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java
  8. +110
    -3
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
  9. +6
    -60
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java
  10. +68
    -0
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java
  11. +1
    -0
      weixin-java-mp/src/test/resources/test-config.sample.xml

+ 1
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java Zobrazit soubor

@@ -25,7 +25,7 @@ public interface WxMpConfigStorage {

public int getExpiresIn();

public String getOauth2redirectUrl();
public String getOauth2redirectUri();

public String getHttp_proxy_host();



+ 5
- 5
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java Zobrazit soubor

@@ -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() {


+ 1
- 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java Zobrazit soubor

@@ -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) {


+ 12
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpOAuth2AccessToken.java Zobrazit soubor

@@ -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 + '\'' +
'}';
}
}

+ 23
- 7
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpUser.java Zobrazit soubor

@@ -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 + '\'' +
'}';
}
}

+ 2
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java Zobrazit soubor

@@ -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() {


+ 38
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpOAuth2AccessTokenAdapter.java Zobrazit soubor

@@ -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<WxMpOAuth2AccessToken> {

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;
}

}

+ 110
- 3
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java Zobrazit soubor

@@ -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<String, Object> 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<String, Object> 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<String, Object> context,
WxMpService wxMpService) {
String href = "<a href=\"" + wxMpService.oauth2buildAuthorizationUrl(WxConsts.OAUTH2_SCOPE_USER_INFO, null)
+ "\">测试oauth2</a>";
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);
}
}
}

weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServlet.java → weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpEndpointServlt.java Zobrazit soubor

@@ -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<String, Object> 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<String, Object> 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)

+ 68
- 0
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpOAuth2Servlet.java Zobrazit soubor

@@ -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("<h1>code</h1>");
response.getWriter().println(code);

WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
response.getWriter().println("<h1>access token</h1>");
response.getWriter().println(wxMpOAuth2AccessToken.toString());

WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
response.getWriter().println("<h1>user info</h1>");
response.getWriter().println(wxMpUser.toString());

wxMpOAuth2AccessToken = wxMpService.oauth2refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken());
response.getWriter().println("<h1>after refresh</h1>");
response.getWriter().println(wxMpOAuth2AccessToken.toString());

} catch (WxErrorException e) {
e.printStackTrace();
}

response.getWriter().flush();
response.getWriter().close();

}

}

+ 1
- 0
weixin-java-mp/src/test/resources/test-config.sample.xml Zobrazit soubor

@@ -6,4 +6,5 @@
<accessToken>可以不填写</accessToken>
<expiresIn>可以不填写</expiresIn>
<openId>某个加你公众号的用户的openId</openId>
<oauth2redirectUri>网页授权获取用户信息回调地址</oauth2redirectUri>
</xml>

Načítá se…
Zrušit
Uložit