@@ -25,7 +25,7 @@ public interface WxMpConfigStorage { | |||
public int getExpiresIn(); | |||
public String getOauth2redirectUrl(); | |||
public String getOauth2redirectUri(); | |||
public String getHttp_proxy_host(); | |||
@@ -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() { | |||
@@ -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) { | |||
@@ -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 + '\'' + | |||
'}'; | |||
} | |||
} |
@@ -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 + '\'' + | |||
'}'; | |||
} | |||
} |
@@ -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() { | |||
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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) |
@@ -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(); | |||
} | |||
} |
@@ -6,4 +6,5 @@ | |||
<accessToken>可以不填写</accessToken> | |||
<expiresIn>可以不填写</expiresIn> | |||
<openId>某个加你公众号的用户的openId</openId> | |||
<oauth2redirectUri>网页授权获取用户信息回调地址</oauth2redirectUri> | |||
</xml> |