• 手把手教你springboot企业微信开发(二)1、企业微信开发第一步2、weixin-java-cp-demo-master1)、引入thymeleaf改造项目2)增加Configuration3)回到企业号4)穿透内外网5)完善 从这一篇开始,开始从实际项目探索...
    @[TOC](手把手教你springboot企业微信开发(二))
    从这一篇开始,开始从实际项目探索企业微信开发。
    # 1、企业微信开发第一步
    看一下企业微信的开发者文档: [企业微信开发者文档](https://qydev.weixin.qq.com/wiki/index.php?title=%E9%A6%96%E9%A1%B5).
    
    在开发文档的首页中,我们看到:企业&定制化服务商开发流程
    
    **1. 获取企业号CorpID&Secret: 企业管理员建立管理组,获取CorpID&Secret
    2. 开发对接相关接口: 开发测试应用,对接企业号接口,接口文档qydev.weixin.qq.com**
    
    企业号的CorpID和Secret,在上一篇已经讲解了,这里不赘述。对接接口的内容,在后面也会使用,暂时按下不表。
    
    看【主动调用】,文档中有个醒目的**获取AccessToken**而且备注是:你应该审慎配置管理组的权限,够用即好,权限过大会增加误操作可能性及信息安全隐患。对于我们开发者而言:做好缓存、注意有时间限制7200s。下面还说频率的问题等等,这个也做到心中有数吧。
    
    我们先把关注点集中在获取access_token上。在项目中,使用get请求获取access_token,请求地址为:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=**id**&corpsecret=**secrect**。
    
    【回调模式】在开发中用的也很多,使用的时候按照文档来吧。
    
    我在一个项目中,写了一个微信开发的```WeixinUtil,java```写的未必那么完美。它的作用就是基于主动调用的,来看一下,这里一个推送的实现:
    ```
    /**
    	 * 企业号推送文章
    	 */
    sentPushMsg(List userIds , PushMsgEntity pushMsg) {
    		String appid = sysConfigService.getWeixinAppid();
        	String secret = sysConfigService.getWeixinSecret();
    		String agentId = sysConfigService.getParamValue("agentId");
    		
    		String qytoken = apiRedis.getWeAccessToken(appid); //从缓存中获取token
    		if(qytoken == null) {
    			TokenResponse tokenResponse = WeixinUtil.token(appid,secret);
    			try {
    				qytoken = tokenResponse.getAccessToken();
    				apiRedis.setWeAccessToken(appid , qytoken);
    			}catch(Exception e) {
    				return R.error(ErrorCode.WEIXIN_API_GET_TOKEN_ERROR, "微信获取AccessToken失败,请重新获取!");
    			}
    		}
    		MessageCustomArticle article = new MessageCustomArticle();
    		
    		article.setTitle(pushMsg.getTitle());
    		article.setDescription(pushMsg.getMessage());
    		article.setUrl(pushMsg.getUrl());
    		article.setPicurl(pushMsg.getPicurl());
    		
    		MessageCustomSendRequest  messageCustomSendRequest  = WeixinUtil.getMessageCustomSendRequest(userIds , article);
    		if(!StringUtil.isBlank(agentId)) {
    			messageCustomSendRequest.setAgentid(new Integer(agentId));
    		}
    		
    		Response res = WeixinUtil.messageCustomSend(qytoken , messageCustomSendRequest);
    		if(res == null) {
    			//....略去了业务代码
    			return R.error( ErrorCode.SENT_TEMPLATE_MSG_ERROR, "消息发送失败");
    		}else {
    			//....略去了业务代码
    			return R.ok(res.getErrMsg()).put("code", res.getErrCode());
    		}
    		
    	}
    ```
    大家在自己的项目中,也一定会有自己封装的方式。
    
    接着上一篇,这里用的是什么呢?我在上一篇里说到,引入weixin-java-cp的Jar包了,这个jar包有非常强悍的作用。
    # 2、weixin-java-cp-demo-master
    ## 1)、引入thymeleaf改造项目
    在pom.xml中引入spring-boot-starter-thymeleaf
    ```java
    		
    		    org.springframework.boot
    		    spring-boot-starter-thymeleaf
    		
    ```
    引入之后,```application.yml```中配置解析html:
    ```java
    spring:
      thymeleaf:
        prefix: classpath:/templates/
        suffix: .html
        mode: HTML5
        encoding: UTF-8
        servlet:
            content-type: text/html
        cache: false
    ```
    稍微解释一下,前缀prefix是地址,工程的相对路径,这边是404错误的根据地了吧,哈哈哈,得注意编译和请求得路径啊;后缀suffix需要spring解析的模板后缀,这里是html。mode、encoding、wevlet、cache就不说了哦。
    
    在thymeleaf目录下,新建一个文件夹,thymeleaf,在文件夹中,新建一个```first.html```,
    ```java
    
    
    
        first
        
    
    
    
    
    
    
    
    
    
    
    
    ```
    看一下文件目录结构:
    
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518155538752.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    新建一个```ThemleafController.java```,内容是:
    ```java
    package com.github.binarywang.demo.wx.cp.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("/thymeleaf")
    public class ThemleafController {
    
    	  @GetMapping(value = "/first")
    	  public String first(Model model) {
    		model.addAttribute("Url", "thymeleaf/first");
    		model.addAttribute("Error", "0");
    		model.addAttribute("Path", "");
    		model.addAttribute("Message", "");
    		model.addAttribute("Exception", "");
    		model.addAttribute("Status", "");
    		model.addAttribute("Timestamp", System.currentTimeMillis());
    	    return "/thymeleaf/first";
    	  }
    
    }
    ```
    改一手```application.yml```
    ```java
    server:
      port: 8080
      ```
    debug模式启动```WxCpDemoApplication.java  ```
    在浏览器中输入http://localhost:8080/thymeleaf/first
    
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518160541119.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    出来它就可以了。
    
    ### 2)增加Configuration
    springboot在很多配置项简洁得让人摸不着头脑,这里是基于springboot不得不说的就是这个,先上代码,然后解释:
    ```java
    package com.github.binarywang.demo.wx.cp.config;
    
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    public class WebMvcConfig implements WebMvcConfigurer{
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        }
    }
    ```
    这个Java文件的意思是以静态资源的形式访问/static/文件夹下的所有文件。
    ```/static/**```使用了**作为通配符。但是,并没有static文件夹,对吗?建立一个static文件夹,看一下项目结构:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518161648909.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    
    在里面放个txt文件文件名叫```who_love_who.txt```,文件里面写上自己喜欢的人的名字,文件名的话用我们的代码来试试看TA对你是否有意,哈哈哈。我的文件里面写的是:```天赐我爱-love-天赐我爱```。写好了测试文件,现在的项目结构是:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020051816242877.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    
    重新debug
    ```WxCpDemoApplication.java  ```
    启动好了之后,在浏览器输入:
    http://localhost:8080/who_love_who.txt
    我这边的是:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518162532954.png#pic_center)
    看到是乱码,我就放心了,她是爱谁谁,与我这单身技术狗无关!差不多了哦!配置起作用了。
    
    ### 3)回到企业号
    回到企业号。找到上篇手把手教你springboot企业微信开发(一)中的应用配置页:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518162956274.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    拉到下面:
    【开发者接口】--》点开【网页授权及JS-SDK】
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518163201133.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    点,【 下载文件】的链接,下载了一个txt文件吧?好!这个文件,放到我之前说的那个static文件夹!现在的static文件夹:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518163403174.png#pic_center)
    是否疑问,我在大费周章在搞thymeleaf、txt静态资源是为了什么呢?下面细细说这个。
    ### 4)穿透内外网
    访问链接: [https://natapp.cn/login](https://natapp.cn/login).
    注册~~~购买,不不不申请免费隧道:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518164059186.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    天底下最好的东西,一定的免费的,阳光是免费的、空气是免费的,爱也是免费的。点开刚刚申请的隧道:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518164410288.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    端口用个8080;authtoken复制备用。下载客户端:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518164529118.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    自己选择吧。
    下载完了,自己创建一个文件夹,就叫natapp得了,在里面放个文件,文件名```config.ini```在里面的配置:
    ```
    #将本文件放置于natapp同级目录 程序将读取 [default] 段
    #在命令行参数模式如 natapp -authtoken=xxx 等相同参数将会覆盖掉此配置
    #命令行参数 -config= 可以指定任意config.ini文件
    [default]
    authtoken=myauthtoken                     #对应一条隧道的authtoken
    clienttoken=                    #对应客户端的clienttoken,将会忽略authtoken,若无请留空,
    log=none                        #log 日志文件,可指定本地文件, none=不做记录,stdout=直接屏幕输出 ,默认为none
    loglevel=ERROR                  #日志等级 DEBUG, INFO, WARNING, ERROR 默认为 DEBUG
    http_proxy=                     #代理设置 如 http://10.123.10.10:3128 非代理上网用户请务必留空
    ```
    刚才我说复制的authtoken,粘贴在这里。打开```natapp.exe```有木有什么?
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518165255411.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    有类似这个吗?如果是那行的意思是:现在这个域名,已经穿透到了你本地的8080端口。
    好,把我画线的部分复制到浏览器:
    是不是有这样的画面:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518165541383.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    有的话,说明穿透成功了。把```http://域名/thymeleaf/first```复制下来,编码:
    链接: [url编码](http://tool.chinaz.com/tools/urlencode.aspx).把编码后的这段复制备用。把域名(不带http://的)复制下来备用。
    ### 5)完善
    在pom.xml中引入jar包:
    ```
    		
                com.alibaba
                fastjson
                1.2.45
            
    ```
    引入这个fastjson是为了解析返回的字符串。
    
    自动注入:
    ```
    @Autowired
    WxCpProperties wxCpProperties;
    ```
    修改first方法:
    ```java
     @GetMapping(value = "/first")
    	  public String first(ServletRequest request, ServletResponse response, Model model) {
    		  
    		  HttpServletRequest servletRequest = ((HttpServletRequest) request);
    		  String userAgent = servletRequest.getHeader("user-agent");
    		  
    		  final WxCpService wxCpService = WxCpConfiguration
    					.getCpService(wxCpProperties.getAppConfigs().get(0).getAgentId());
    
    			
    			String queryString = servletRequest.getQueryString();
    			String backString = "";
    			try {
    				backString = HttpRequest.sendGet("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token="
    						+ wxCpService.getAccessToken() + "&" + queryString, null);
    			} catch (WxErrorException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			JSONObject json_test = JSONObject.parseObject(backString);  
    		  
    		model.addAttribute("Url", "thymeleaf/first");
    		model.addAttribute("Error", "0");
    		model.addAttribute("Path", "");
    		model.addAttribute("Message", "");
    		model.addAttribute("Exception", "");
    		model.addAttribute("Status", "");
    		model.addAttribute("Timestamp", System.currentTimeMillis());
    	    return "/thymeleaf/first";
    	  }
    ```
    这里用的```HttpRequest.java```是我自己写的:
    ```java
    package com.github.binarywang.demo.wx.cp.utils;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLSession;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class HttpRequest {
    	
    	public static Logger logger = LoggerFactory.getLogger(HttpRequest.class);
    	
    	/**
    	 * 向指定URL发送GET方法的请求
    	 * 
    	 * @param url
    	 *            发送请求的URL
    	 * @param param
    	 *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    	 * @return URL 所代表远程资源的响应结果
    	 */
    	public static String sendGet(String url, Map params) {
    		return sendGet(url,"", params);
    	}
    	/**
    	 * 向指定URL发送GET方法的请求
    	 * 
    	 * @param url
    	 *            发送请求的URL
    	 * @param param
    	 *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
    	 * @return URL 所代表远程资源的响应结果
    	 */
    	public static String sendGet(String url,String interfaceName, Map params) {
    		String result = "";
    		BufferedReader in = null;
    		StringBuffer strBufParamsSet = new StringBuffer();
    		
    		if(params!=null) {
    			Set paramsSet = params.keySet();
    			
    			for(String parma:paramsSet) {
    				if(strBufParamsSet.length()>0) {
    					strBufParamsSet.append("&").append(parma).append("=").append(params.get(parma));
    				}else {
    					strBufParamsSet.append("?").append(parma).append("=").append(params.get(parma));
    				}
    			}
    		}else {
    			strBufParamsSet.append("");
    		}
    		
    		
    		try {
    			String urlNameString = "";
    			if(interfaceName==null || "".contains(interfaceName.trim())) {
    				urlNameString = url + strBufParamsSet.toString();
    			}else {
    				urlNameString = url +"/"+ interfaceName + strBufParamsSet.toString();
    			}
    			urlNameString = urlNameString.replaceAll("\r\n", "");
    			trustAllHttpsCertificates();
    			logger.info("请求路径:" + urlNameString);
    			URL realUrl = new URL(urlNameString);
    			// 打开和URL之间的连接
    			URLConnection connection = realUrl.openConnection();
    			// 设置通用的请求属性
    			connection.setRequestProperty("accept", "*/*");
    			connection.setRequestProperty("connection", "Keep-Alive");
    			connection.setRequestProperty("Accept-Charset", "UTF-8");
    			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    			// 建立实际的连接
    			connection.connect();
    			// 获取所有响应头字段
    			Map> map = connection.getHeaderFields();
    //			// 遍历所有的响应头字段
    //			for (String key : map.keySet()) {
    //				System.out.println(key + "--->" + map.get(key));
    //			}
    			// 定义 BufferedReader输入流来读取URL的响应
    			in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    			String line;
    			while ((line = in.readLine()) != null) {
    				result += line;
    			}
    		} catch (Exception e) {
    			logger.debug("发送 get请求出现异常!获取文件流失败:" + e);
    			
    		}
    		// 使用finally块来关闭输入流
    		finally {
    			try {
    				if (in != null) {
    					in.close();
    				}
    			} catch (Exception e2) {
    				logger.debug("发送 get请求出现异常!获取文件流失败:" + e2);
    			}
    		}
    		return result;
    	}
    
    	
    
    	private static void trustAllHttpsCertificates() throws Exception {  
            javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];  
            javax.net.ssl.TrustManager tm = new miTM();  
            trustAllCerts[0] = tm;  
            javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext  
                    .getInstance("SSL");  
            sc.init(null, trustAllCerts, null);  
            javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc  
    				                .getSocketFactory());
    
    		HostnameVerifier hv = new HostnameVerifier() {
    			public boolean verify(String urlHostName, SSLSession session) {
    				System.out.println("Warning: URL Host: " + urlHostName + " vs. "
    								   + session.getPeerHost());
    				return true;
    			}
        	};
    		HttpsURLConnection.setDefaultHostnameVerifier(hv);
        }  
    			  
        static class miTM implements javax.net.ssl.TrustManager,
    			            javax.net.ssl.X509TrustManager {  
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {  
                return null;  
            }  
      
            public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
                return true;  
            }  
      
            public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
                return true;  
            }  
      
            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                    throws java.security.cert.CertificateException {  
                return;  
            }  
      
            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                    throws java.security.cert.CertificateException {  
                return;  
            }  
        }  
    }
    ```
    到了这一步,把
    再回企业微信应用配置的页面,复制这个:
    
    https://open.weixin.qq.com/connect/oauth2/authorize?appid=**appIdf**&redirect_uri=**编码后的域名**&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
    复制到:【工作台应用主页】里面去。
    复制**域名**到【网页授权及JS-SDK】:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518180954661.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    勾选【已上传域名归属校验文件】,【确定】!
    点:【企业微信授权登录】已启用--》Web网页--》
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518181213326.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    编辑填入**域名**。
    好了之后,debug重启:```WxCpDemoApplication.java```并且在这行打断点:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518181909512.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    
    在企业微信中打开:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518181655655.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    点进去自己的应用,如果进断点,看backString,是不是与我类似:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518182059829.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    如果看到返回值与我类似的,恭喜,已经完成了!!!如果有疑问或者需要讨论,或者报错的不好解决的话,给我留言即可。
    附上我这边最终的画面:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518182412774.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    另外,稍微看一下natapp的情况,那里有请求的情况:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200518182512992.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pYW96aGljaGVuZzE5OTA=,size_16,color_FFFFFF,t_70#pic_center)
    好了,这一篇也结束了。
    
    展开全文
  • 企业微信_Java_项目版 微信企业号星级会员。10多年软件从业经历,国家级...
  • 微信开发 Java 开发工具包(SDK),支持包括微信支付、微信开放平台、小程序、企业号/企业微信、公众号(包括服务号和订阅号)等的后端开发。 本开发工具包基于chanjarster的同名SDK,增加了不少功能和模块,并做了...
  • 微信开发 Java 开发工具包(SDK),支持包括微信支付、微信开放平台、小程序、企业号/企业微信、公众号(包括服务号和订阅号)等的后端开发。 本开发工具包基于chanjarster的同名SDK,增加了不少功能和模块,并做了...
  • 【课程内容】Java微信二次开发微信验证Java微信二次开发智能机器人java微信二次开发微信公众号平台基于java微信订阅号自动回复接口基于java微信二次开发必备要素基于java微信二次开发智能机器人基于java微信...
  • 【课程内容】 Java微信二次开发微信验证 Java微信二次开发智能机器人 java微信二次开发微信公众号平台 基于java微信订阅号自动回复接口 基于java微信二次开发必备要素 ...基于java微信二次开发...
  • 企业微信开发 2018-05-10 15:19:32
    企业微信的认识企业微信概念:企业微信2016年4月18日,腾讯正式发布全平台企业办公工具“企业微信”。与微信一致的沟通体验,为企业员工提供最基础和最实用的办公服务,并加入贴合办公场景的特色功能、轻OA工具,提供...
  • 本人比较擅长Java开发,所以本文是基于Java语言的公众号开发。话不多说,直接进入正题。 准备工作: 一、在微信公众平台申请账号。 百度搜索微信公众平台,点击注册,通过邮箱注册成功后会看到如下画面。 在...
  • 企业微信开发内部应用 2020-03-24 10:15:59
    pom添加第三方企业微信sdk <!-- 企业微信SDK --> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-cp</artifactId> <version>3.7.0...
  • 微信公众号开发-Java 2020-07-05 23:31:02
    Java微信公众平台开发基于springMVC技术和xstream,json等技术。
  • 企业微信是腾讯推出的一个新的办公协作平台,通过与微信一致的沟通体验,为企业员工提供最基础和最实用的...本文以该项目为例对在企业微信平台开发企业应用的特点进行了总结,重点分析了企业微信开发平台对应用开发...
  • 基于java微信二次开发 2020-06-05 23:30:15
    基于java微信二次开发包括微信验证,智能机器人,LBS地理位置,微人脸识别等视频
  • 在这期间也请教了一些之前做过公众号开发的同事,也与一起进行开发的同事互相讨论,使得我们的开发工作有条不紊的进行下去,在此也将开发的过程和一些心得输出出来,方便后面的同事以及微信开发爱好者借鉴,如果有...
  • 进入企业微信微信后台管理进入---应用与小程序---创建应用 设置网页授权域名:域名则是外网访问路径,设置工作台应用主页或者自定义菜单的连接地址(即要跳转的对应页面h5或者action) 需要注意点:这个是一个...
  • 微信开发框架(JAVA版) 2013-08-12 14:48:40
    这是一个基于java的简易微信开发框架,因本人水平有限,大神勿喷,多多指点。 下载地址:http://download.csdn.net/detail/qp23401/5914573 搭建环境 导入weixin.jar 以及dom4j.1.6.1.jar xstream-1.3.1.jar两个依赖...
  • 微信公众平台开发入门 2019-12-30 15:18:17
    通过本课程的学习,学员能够入门微信公众平台开发,能够胜任企业级的订阅号、服务号、企业号的应用开发工作。 通过本课程的学习,学员能够对微信公众平台有一个清晰的、系统性的认识。例如,公众号是什么,它有...
  •  基于H5开发项目,嵌入到企业微信中,并接入js-sdk 并运用企业微信接口。 开发环境:  腾讯企业微信最新版本。后端环境不做要求,能跑通即可(这里我选用的是eclipse的maven项目,之前也出了一篇搭建后台项目的...
  • failed to load the jni shared library jre bin server jvm.dll  解决:这个主要是eclipse的版本和安装的jdk...2. java.lang.SecurityException: The jurisdiction policy files are not signed by a trusted
  • 课程目录 微信二次开发基础部分.avi 01-18 Java微信二次开发微信验证.wmv 01-19 Java微信二次开发智能机器人.wmv...03-18_基于java微信二次开发必备要素.mp4 03-20基于java微信二次开发智能机器人.wmv 03-21...
  • 现在网上关于Java微信二次开发的资料少之又少,本人也是新手,做了个小的demo供大家参考,实现了智能翻译、人脸识别、歌曲点播和历史上的今天等功能。
1 2 3 4 5 ... 20
收藏数 40,068
精华内容 16,027