| @@ -27,6 +27,8 @@ public interface WxCpConfigStorage { | |||
| public int getExpiresIn(); | |||
| public String getOauth2redirectUri(); | |||
| public String getHttp_proxy_host(); | |||
| public int getHttp_proxy_port(); | |||
| @@ -18,6 +18,8 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| protected String agentId; | |||
| protected int expiresIn; | |||
| protected String oauth2redirectUri; | |||
| protected String http_proxy_host; | |||
| protected int http_proxy_port; | |||
| protected String http_proxy_username; | |||
| @@ -88,6 +90,15 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { | |||
| this.agentId = agentId; | |||
| } | |||
| @Override | |||
| public String getOauth2redirectUri() { | |||
| return this.oauth2redirectUri; | |||
| } | |||
| public void setOauth2redirectUri(String oauth2redirectUri) { | |||
| this.oauth2redirectUri = oauth2redirectUri; | |||
| } | |||
| public String getHttp_proxy_host() { | |||
| return http_proxy_host; | |||
| } | |||
| @@ -274,6 +274,26 @@ public interface WxCpService { | |||
| */ | |||
| 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()); | |||
| } | |||
| @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 { | |||
| return execute(new SimpleGetRequestExecutor(), url, queryParam); | |||
| } | |||
| @@ -1,20 +1,93 @@ | |||
| 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.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 { | |||
| private static WxCpConfigStorage wxCpConfigStorage; | |||
| private static WxCpService wxCpService; | |||
| private static WxCpMessageRouter wxCpMessageRouter; | |||
| public static void main(String[] args) throws Exception { | |||
| Server server = new Server(8080); | |||
| ServletHandler handler = new ServletHandler(); | |||
| 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.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 | |||
| */ | |||
| public class WxCpDemoServlet extends HttpServlet { | |||
| public class WxCpEndpointServlet extends HttpServlet { | |||
| protected WxCpConfigStorage wxCpConfigStorage; | |||
| protected WxCpService wxCpService; | |||
| 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 { | |||
| response.setContentType("text/html;charset=utf-8"); | |||
| @@ -85,7 +57,8 @@ public class WxCpDemoServlet extends HttpServlet { | |||
| 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); | |||
| if (outMessage != null) { | |||
| 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> | |||
| <departmentId>企业号通讯录的某个部门id</departmentId> | |||
| <tagId>企业号通讯录里的某个tagid</tagId> | |||
| <oauth2redirectUri>网页授权获取用户信息回调地址</oauth2redirectUri> | |||
| </xml> | |||
| @@ -16,11 +16,12 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { | |||
| protected String aesKey; | |||
| protected int expiresIn; | |||
| protected String oauth2redirectUri; | |||
| protected String http_proxy_host; | |||
| protected int http_proxy_port; | |||
| protected String http_proxy_username; | |||
| protected String http_proxy_password; | |||
| protected String oauth2redirectUri; | |||
| public void updateAccessToken(WxAccessToken accessToken) { | |||
| updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
| @@ -16,9 +16,6 @@ import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Map; | |||
| /** | |||
| * @author Daniel Qian | |||
| */ | |||
| public class WxMpDemoServer { | |||
| private static WxMpConfigStorage wxMpConfigStorage; | |||
| @@ -22,9 +22,6 @@ import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.util.Map; | |||
| /** | |||
| * @author Daniel Qian | |||
| */ | |||
| public class WxMpOAuth2Servlet extends HttpServlet { | |||
| protected WxMpService wxMpService; | |||