@@ -27,6 +27,8 @@ public interface WxCpConfigStorage { | |||||
public int getExpiresIn(); | public int getExpiresIn(); | ||||
public String getOauth2redirectUri(); | |||||
public String getHttp_proxy_host(); | public String getHttp_proxy_host(); | ||||
public int getHttp_proxy_port(); | public int getHttp_proxy_port(); | ||||
@@ -18,6 +18,8 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||||
protected String agentId; | protected String agentId; | ||||
protected int expiresIn; | protected int expiresIn; | ||||
protected String oauth2redirectUri; | |||||
protected String http_proxy_host; | protected String http_proxy_host; | ||||
protected int http_proxy_port; | protected int http_proxy_port; | ||||
protected String http_proxy_username; | protected String http_proxy_username; | ||||
@@ -88,6 +90,15 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||||
this.agentId = agentId; | this.agentId = agentId; | ||||
} | } | ||||
@Override | |||||
public String getOauth2redirectUri() { | |||||
return this.oauth2redirectUri; | |||||
} | |||||
public void setOauth2redirectUri(String oauth2redirectUri) { | |||||
this.oauth2redirectUri = oauth2redirectUri; | |||||
} | |||||
public String getHttp_proxy_host() { | public String getHttp_proxy_host() { | ||||
return http_proxy_host; | return http_proxy_host; | ||||
} | } | ||||
@@ -274,6 +274,26 @@ public interface WxCpService { | |||||
*/ | */ | ||||
public void tagAddUsers(String tagId, List<String> userIds) throws WxErrorException; | public void tagAddUsers(String tagId, List<String> userIds) throws WxErrorException; | ||||
/** | |||||
* <pre> | |||||
* 构造oauth2授权的url连接 | |||||
* 详情请见: http://qydev.weixin.qq.com/wiki/index.php?title=企业获取code | |||||
* </pre> | |||||
* @param state | |||||
* @return code | |||||
*/ | |||||
public String oauth2buildAuthorizationUrl(String state); | |||||
/** | |||||
* <pre> | |||||
* 用oauth2获取用户信息 | |||||
* http://qydev.weixin.qq.com/wiki/index.php?title=根据code获取成员信息 | |||||
* </pre> | |||||
* @param code | |||||
* @return [userid, deviceid] | |||||
*/ | |||||
public String[] oauth2getUserInfo(String code) throws WxErrorException; | |||||
/** | /** | ||||
* 移除标签成员 | * 移除标签成员 | ||||
* | * | ||||
@@ -316,6 +316,41 @@ public class WxCpServiceImpl implements WxCpService { | |||||
execute(new SimplePostRequestExecutor(), url, jsonObject.toString()); | execute(new SimplePostRequestExecutor(), url, jsonObject.toString()); | ||||
} | } | ||||
@Override | |||||
public String oauth2buildAuthorizationUrl(String state) { | |||||
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" ; | |||||
url += "appid=" + wxCpConfigStorage.getCorpId(); | |||||
url += "&redirect_uri=" + URIUtil.encodeURIComponent(wxCpConfigStorage.getOauth2redirectUri()); | |||||
url += "&response_type=code"; | |||||
url += "&scope=snsapi_base"; | |||||
if (state != null) { | |||||
url += "&state=" + state; | |||||
} | |||||
url += "#wechat_redirect"; | |||||
return url; | |||||
} | |||||
@Override | |||||
public String[] oauth2getUserInfo(String code) throws WxErrorException { | |||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?"; | |||||
url += "access_token=" + wxCpConfigStorage.getAccessToken(); | |||||
url += "&code=" + code; | |||||
url += "agendid=" + wxCpConfigStorage.getAgentId(); | |||||
try { | |||||
RequestExecutor<String, String> executor = new SimpleGetRequestExecutor(); | |||||
String responseText = executor.execute(getHttpclient(), httpProxy, url, null); | |||||
JsonElement je = Streams.parse(new JsonReader(new StringReader(responseText))); | |||||
JsonObject jo = je.getAsJsonObject(); | |||||
return new String[] {GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId")}; | |||||
} catch (ClientProtocolException e) { | |||||
throw new RuntimeException(e); | |||||
} catch (IOException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
public String get(String url, String queryParam) throws WxErrorException { | public String get(String url, String queryParam) throws WxErrorException { | ||||
return execute(new SimpleGetRequestExecutor(), url, queryParam); | return execute(new SimpleGetRequestExecutor(), url, queryParam); | ||||
} | } | ||||
@@ -1,20 +1,93 @@ | |||||
package me.chanjar.weixin.cp.demo; | package me.chanjar.weixin.cp.demo; | ||||
import me.chanjar.weixin.common.api.WxConsts; | |||||
import me.chanjar.weixin.cp.api.*; | |||||
import me.chanjar.weixin.cp.bean.WxCpXmlMessage; | |||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||||
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage; | |||||
import org.eclipse.jetty.server.Server; | import org.eclipse.jetty.server.Server; | ||||
import org.eclipse.jetty.servlet.ServletHandler; | import org.eclipse.jetty.servlet.ServletHandler; | ||||
import org.eclipse.jetty.servlet.ServletHolder; | |||||
import javax.xml.bind.JAXBException; | |||||
import java.io.InputStream; | |||||
import java.util.Map; | |||||
/** | |||||
* @author Daniel Qian | |||||
*/ | |||||
public class WxCpDemoServer { | public class WxCpDemoServer { | ||||
private static WxCpConfigStorage wxCpConfigStorage; | |||||
private static WxCpService wxCpService; | |||||
private static WxCpMessageRouter wxCpMessageRouter; | |||||
public static void main(String[] args) throws Exception { | public static void main(String[] args) throws Exception { | ||||
Server server = new Server(8080); | Server server = new Server(8080); | ||||
ServletHandler handler = new ServletHandler(); | ServletHandler handler = new ServletHandler(); | ||||
server.setHandler(handler); | server.setHandler(handler); | ||||
handler.addServletWithMapping(WxCpDemoServlet.class, "/*"); | |||||
ServletHolder endpointServletHolder = new ServletHolder(new WxCpEndpointServlet(wxCpConfigStorage, wxCpService, wxCpMessageRouter)); | |||||
handler.addServletWithMapping(endpointServletHolder, "/*"); | |||||
ServletHolder oauthServletHolder = new ServletHolder(new WxCpOAuth2Servlet(wxCpService)); | |||||
handler.addServletWithMapping(oauthServletHolder, "/oauth2/*"); | |||||
server.start(); | server.start(); | ||||
server.join(); | server.join(); | ||||
} | } | ||||
private static void init() { | |||||
try { | |||||
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||||
WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1); | |||||
wxCpConfigStorage = config; | |||||
wxCpService = new WxCpServiceImpl(); | |||||
wxCpService.setWxCpConfigStorage(config); | |||||
WxCpMessageHandler handler = new WxCpMessageHandler() { | |||||
@Override | |||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||||
WxCpService wxCpService) { | |||||
WxCpXmlOutTextMessage m = WxCpXmlOutMessage | |||||
.TEXT() | |||||
.content("测试加密消息") | |||||
.fromUser(wxMessage.getToUserName()) | |||||
.toUser(wxMessage.getFromUserName()) | |||||
.build(); | |||||
return m; | |||||
} | |||||
}; | |||||
WxCpMessageHandler oauth2handler = new WxCpMessageHandler() { | |||||
@Override | |||||
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, | |||||
WxCpService wxCpService) { | |||||
String href = "<a href=\"" + wxCpService.oauth2buildAuthorizationUrl(null) | |||||
+ "\">测试oauth2</a>"; | |||||
return WxCpXmlOutMessage | |||||
.TEXT() | |||||
.content(href) | |||||
.fromUser(wxMessage.getToUserName()) | |||||
.toUser(wxMessage.getFromUserName()).build(); | |||||
} | |||||
}; | |||||
wxCpMessageRouter = new WxCpMessageRouter(wxCpService); | |||||
wxCpMessageRouter | |||||
.rule() | |||||
.async(false) | |||||
.content("哈哈") // 拦截内容为“哈哈”的消息 | |||||
.handler(handler) | |||||
.end() | |||||
.rule() | |||||
.async(false) | |||||
.content("oauth") | |||||
.handler(oauth2handler) | |||||
.end() | |||||
; | |||||
} catch (JAXBException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
} | } |
@@ -19,49 +19,21 @@ import java.util.Map; | |||||
/** | /** | ||||
* @author Daniel Qian | * @author Daniel Qian | ||||
*/ | */ | ||||
public class WxCpDemoServlet extends HttpServlet { | |||||
public class WxCpEndpointServlet extends HttpServlet { | |||||
protected WxCpConfigStorage wxCpConfigStorage; | protected WxCpConfigStorage wxCpConfigStorage; | ||||
protected WxCpService wxCpService; | protected WxCpService wxCpService; | ||||
protected WxCpMessageRouter wxCpMessageRouter; | protected WxCpMessageRouter wxCpMessageRouter; | ||||
@Override public void init() throws ServletException { | |||||
// | |||||
super.init(); | |||||
try { | |||||
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml"); | |||||
WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1); | |||||
wxCpConfigStorage = config; | |||||
wxCpService = new WxCpServiceImpl(); | |||||
wxCpService.setWxCpConfigStorage(config); | |||||
WxCpMessageHandler handler = new WxCpMessageHandler() { | |||||
@Override public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService) { | |||||
WxCpXmlOutTextMessage m = WxCpXmlOutMessage | |||||
.TEXT() | |||||
.content("测试加密消息") | |||||
.fromUser(wxMessage.getToUserName()) | |||||
.toUser(wxMessage.getFromUserName()) | |||||
.build(); | |||||
return m; | |||||
} | |||||
}; | |||||
wxCpMessageRouter = new WxCpMessageRouter(wxCpService); | |||||
wxCpMessageRouter | |||||
.rule() | |||||
.async(false) | |||||
.content("哈哈") // 拦截内容为“哈哈”的消息 | |||||
.handler(handler) | |||||
.end(); | |||||
} catch (JAXBException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
public WxCpEndpointServlet(WxCpConfigStorage wxCpConfigStorage, WxCpService wxCpService, | |||||
WxCpMessageRouter wxCpMessageRouter) { | |||||
this.wxCpConfigStorage = wxCpConfigStorage; | |||||
this.wxCpService = wxCpService; | |||||
this.wxCpMessageRouter = wxCpMessageRouter; | |||||
} | } | ||||
@Override protected void service(HttpServletRequest request, HttpServletResponse response) | |||||
@Override | |||||
protected void service(HttpServletRequest request, HttpServletResponse response) | |||||
throws ServletException, IOException { | throws ServletException, IOException { | ||||
response.setContentType("text/html;charset=utf-8"); | response.setContentType("text/html;charset=utf-8"); | ||||
@@ -85,7 +57,8 @@ public class WxCpDemoServlet extends HttpServlet { | |||||
return; | return; | ||||
} | } | ||||
WxCpXmlMessage inMessage = WxCpXmlMessage.fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||||
WxCpXmlMessage inMessage = WxCpXmlMessage | |||||
.fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature); | |||||
WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage); | WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage); | ||||
if (outMessage != null) { | if (outMessage != null) { | ||||
response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage)); | response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage)); |
@@ -0,0 +1,48 @@ | |||||
package me.chanjar.weixin.cp.demo; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.cp.api.WxCpService; | |||||
import javax.servlet.ServletException; | |||||
import javax.servlet.http.HttpServlet; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
import java.io.IOException; | |||||
import java.util.Arrays; | |||||
/** | |||||
* Created by qianjia on 14/11/28. | |||||
*/ | |||||
public class WxCpOAuth2Servlet extends HttpServlet { | |||||
protected WxCpService wxCpService; | |||||
public WxCpOAuth2Servlet(WxCpService wxCpService) { | |||||
this.wxCpService = wxCpService; | |||||
} | |||||
@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); | |||||
String[] res = wxCpService.oauth2getUserInfo(code); | |||||
response.getWriter().println("<h1>result</h1>"); | |||||
response.getWriter().println(Arrays.toString(res)); | |||||
} catch (WxErrorException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
response.getWriter().flush(); | |||||
response.getWriter().close(); | |||||
} | |||||
} |
@@ -9,4 +9,5 @@ | |||||
<userId>企业号通讯录里的某个userid</userId> | <userId>企业号通讯录里的某个userid</userId> | ||||
<departmentId>企业号通讯录的某个部门id</departmentId> | <departmentId>企业号通讯录的某个部门id</departmentId> | ||||
<tagId>企业号通讯录里的某个tagid</tagId> | <tagId>企业号通讯录里的某个tagid</tagId> | ||||
<oauth2redirectUri>网页授权获取用户信息回调地址</oauth2redirectUri> | |||||
</xml> | </xml> |
@@ -16,11 +16,12 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||||
protected String aesKey; | protected String aesKey; | ||||
protected int expiresIn; | protected int expiresIn; | ||||
protected String oauth2redirectUri; | |||||
protected String http_proxy_host; | protected String http_proxy_host; | ||||
protected int http_proxy_port; | protected int http_proxy_port; | ||||
protected String http_proxy_username; | protected String http_proxy_username; | ||||
protected String http_proxy_password; | protected String http_proxy_password; | ||||
protected String oauth2redirectUri; | |||||
public void updateAccessToken(WxAccessToken accessToken) { | public void updateAccessToken(WxAccessToken accessToken) { | ||||
updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | ||||
@@ -16,9 +16,6 @@ import java.io.IOException; | |||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.util.Map; | import java.util.Map; | ||||
/** | |||||
* @author Daniel Qian | |||||
*/ | |||||
public class WxMpDemoServer { | public class WxMpDemoServer { | ||||
private static WxMpConfigStorage wxMpConfigStorage; | private static WxMpConfigStorage wxMpConfigStorage; | ||||
@@ -22,9 +22,6 @@ import java.io.IOException; | |||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.util.Map; | import java.util.Map; | ||||
/** | |||||
* @author Daniel Qian | |||||
*/ | |||||
public class WxMpOAuth2Servlet extends HttpServlet { | public class WxMpOAuth2Servlet extends HttpServlet { | ||||
protected WxMpService wxMpService; | protected WxMpService wxMpService; | ||||