Java 微信公众号开发_学习笔记
一、课程介绍
- 本套课程的学习内容,开发语言
- 微信公众号介绍,申请以及后台设置详解
- 编辑模式下的消息回复,菜单建立,素材管理等
- 开发前的环境搭建以及工具准备
- 开发者模式的切换、以及消息的接收与响应
- 百度BAE服务器的搭建,代码上传
二、公众号与微信的区别
- 微信定位于聊天、朋友圈等个人娱乐
- 公众号定位于商业用途,达到个人品牌的推广、企业品牌宣传等
三、公众号类型介绍
账号类型一旦成功建立账号,类型不可更改(企业号、服务号与订阅号)
企业号与服务号、订阅号的区别:
企业号 | 服务号 | 订阅号 | |
面向人群 | 面向企业、政府、事业单位和非政府组织,实现生产管理、协作运营的移动化 | 面向企业、政府或组织,用以对用户进行服务 | 面向媒体和个人提供一种信息传播方式 |
消息显示方式 | 出现在好友会话列表首层 | 出现在好友会话列表首层 | 折叠在订阅号目录中 |
消息次数限制 | 最高每分钟可群发200次 | 每月主动发送消息不超过4条 | 每天群发一条 |
验证关注身份 | 通讯录成员可关注 | 微信用户扫码即可关注 | 微信用户扫码即可关注 |
消息保密 | 消息可转发、分享。支持保密消息,防止成员转发 | 消息可转发、分享 | 消息可转发、分享 |
高级接口权限 | 支持 | 支持 | 不支持(微信支付、推广等) |
定制应用 | 可根据需要定制应用,多个应用聚合成一个企业号 | 不支持,新增服务号需要重新关注 | 不支持,新增服务号需要重新关注 |
四、公众号申请
a.公众号申请需要在微信公众号平台进行操作:https://mp.weixin.qq.com/
b.申请流程
登陆微信公众平台->点击立即注册->选择订阅号->按流程注册->类型选择(订阅号)->主体类型(个人)->继续填写注册信息->进入公众号信息填写
c.公众号信息填写
账号名称:微信公众账号的昵称而并非微信号(微信号是在审核通过以后后台进行设置的)
功能介绍:内容介绍
五、微信公众平台介绍
微信公众平台是腾讯为了让用户申请和管理微信公众账号而推出的一个WEB平台。微信公众账号的操作和管理都要在这个平台进行。
a.功能模块
群发功能:主要是微信公众账号把所需要的信息推送给所有的关注用户,其中的信息有文字,图片,语音,图文五大类型。文字消息
自动回复:被添加自动回复、消息自动回复、关键词自动回复
自定义菜单:总共可添加15个菜单
投票管理:功能
b.管理模块
消息管理:查看用户发送的消息
用户管理:可对用户进行分组
素材管理:--
六、自动回复
编辑模式介绍:在编辑模式下实现消息自动回复、菜单创建;以及在微信公众平台推送消息给关注用户
a.设置被关注回复:
b.关键词自动回复
七、Java公众号开发环境准备
1.一个微信公众号
2.外网映射工具(开发调试)
与微信对接的url要具备以下条件
- 在公网上能够访问
- 端口只支持80端口
结论:需要借助映射工具将本机地址映射到公网上。(花生壳、ngrok等工具)
3.ngrok可以将内网映射到公网上去,这样就可以在公网访问你的本地网络服务
用法:
ngrok 8080
ngrok -config ngrok.cfg -subdomain dzj0712 8080
帮助文档:http://www.tunnel.mobi/
4.ngrok的使用
youName是你想要设置的域名,如 wswx
Port是你想映射的本地端口,如8080
最后,访问http://wswx.tunnel.echomod.cn/ 即可在外网访问你的本地服务器
a.在dos中进入所在盘符执行ngrok -config ngrok.cfg -subdomain dzj0712 8080得到以下结果
b.存在问题
ngrok是国外的工具,服务器也是在国外,在国内访问较慢,甚至无法访问
映射的公网地址是随机的,会造成不便
c.以上的a步骤直接使用了在国内部署的tunnel网络服务,它支持了ngrok的绝大多数功能,同时解决了ngrok在美国造成的访问缓慢等问题
八、数据交互原理
1.开发模式
开发模式与编辑模式是两者互斥的关系,也就是当打开开发模式之后编辑模式的自动回复与自定义菜单等功能就会跟着失效,同样的开发模式也会在编辑模式中失效
2.数据交互原理
当用户发送请求之后,用户会进行解析公众号的地址,并根据该地址将请求转发至微信公众号服务器。服务器处理完成后会将处理的结果返回给微信后台,之后微信后台再将结果转发给客户端。
开发人员主要进行的工作就是红字显示的服务器开发
九、开发模式接入
1.登陆微信公众平台
打开开发文档填写服务器配置
2.校验signature对请求进行加密
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
将token、timestamp、nonce三个参数进行字典序排序 2)将三个参数字符串拼接成一个字符串进行sha1加密 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
3.检验signature的Java示例代码:
a.微信服务器入口代码
1 package com.imooc.servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 import com.imooc.util.CheckUtil; 12 13 public class WeixinServlet extends HttpServlet{ 14 15 @Override 16 /** 17 * 使用doget方法进行验证 18 */ 19 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 20 // 获取微信公众号服务器发送的参数 21 String signature = req.getParameter("signature"); 22 String timestamp = req.getParameter("timestamp"); 23 String nonce = req.getParameter("nonce"); 24 String echostr = req.getParameter("echostr"); 25 26 PrintWriter out = resp.getWriter(); 27 //校验成功将随机字符串返回 28 if(CheckUtil.checkSignature(signature, timestamp, nonce)) { 29 out.print(echostr); 30 } 31 } 32 }
View Code
b.校验的工具类
1 package com.imooc.util; 2 3 import java.security.MessageDigest; 4 import java.util.Arrays; 5 6 /** 7 * 校验工具类 8 */ 9 public class CheckUtil { 10 private static final String token = "imooc"; 11 /** 12 * 13 * @param signature 加密签名 14 * @param timestamp 时间戳 15 * @param nonce 随机数字 16 * @return 17 */ 18 public static boolean checkSignature(String signature, String timestamp, String nonce) { 19 20 String[] arr = new String[] { token, timestamp, nonce }; 21 // 排序 22 Arrays.sort(arr); 23 // 生成字符串 24 StringBuffer content = new StringBuffer(); 25 for (int i = 0; i < arr.length; i++) { 26 content.append(arr[i]); 27 } 28 // sha1加密 29 String temp = getSha1(content.toString()); 30 // 与微信传过来的加密签名进行比较 31 return temp.equals(signature); 32 } 33 34 public static String getSha1(String str) { 35 if (str == null || str.length() == 0) { 36 return null; 37 } 38 char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 39 try { 40 MessageDigest mdTemp = MessageDigest.getInstance("SHA1"); 41 mdTemp.update(str.getBytes("UTF-8")); 42 43 byte[] md = mdTemp.digest(); 44 int j = md.length; 45 char buf[] = new char[j * 2]; 46 int k = 0; 47 for (int i = 0; i < j; i++) { 48 byte byte0 = md[i]; 49 buf[k++] = hexDigits[byte0 >>> 4 & 0xf]; 50 buf[k++] = hexDigits[byte0 & 0xf]; 51 } 52 return new String(buf); 53 } catch (Exception e) { 54 // TODO: handle exception 55 return null; 56 } 57 } 58 }
View Code
c.在xml中对servlet进行配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"><display-name>Weixin</display-name><servlet><servlet-name>weixinServlet</servlet-name><servlet-class>com.imooc.servlet.WeixinServlet</servlet-class></servlet><servlet-mapping><servlet-name>weixinServlet</servlet-name><url-pattern>/wx.do</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list> </web-app>
View Code
十、消息的接收与响应
1.将本地地址映射到公网上,在公网上面访问本地的servlet
2.在浏览器中进行访问
3.成功访问后:将该地址配置到微信的后台服务器
点击提交之后,就会执行servlet中的doget方法进行接入的校验
4.提交之后启用开发模式(编辑模式I失效)
5.开发者模式下实现消息的接收与响应
之前的接入是通过get方法,而现在的消息响应微信服务器将post请求,并以xml的形式返回数据,因为微信后台发回的数据是一个xml格式,因此需要将其转换为集合类型,并提供对象类型转换为xml类型的方法
1 package com.imooc.util; 2 3 import java.awt.font.TextMeasurer; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.util.HashMap; 7 import java.util.List; 8 import java.util.Map; 9 10 import javax.servlet.http.HttpServletRequest; 11 12 import org.dom4j.Document; 13 import org.dom4j.DocumentException; 14 import org.dom4j.Element; 15 import org.dom4j.io.SAXReader; 16 17 import com.imooc.po.TextMessage; 18 import com.thoughtworks.xstream.XStream; 19 20 /** 21 * 消息的格式转换 22 * 23 * @author Administrator 24 * 25 */ 26 public class MessageUtil { 27 /** 28 * xml转为map集合 29 * 30 * @param request 31 * @return 32 * @throws IOException 33 * @throws DocumentException 34 */ 35 public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException { 36 Map<String, String> map = new HashMap<String, String>(); 37 SAXReader reader = new SAXReader(); 38 // 从Request中获取输入流 39 InputStream ins = request.getInputStream(); 40 Document doc = reader.read(ins); 41 Element root = doc.getRootElement(); 42 43 List<Element> list = root.elements(); 44 45 for (Element e : list) { 46 map.put(e.getName(), e.getText()); 47 } 48 ins.close(); 49 50 return map; 51 } 52 53 /** 54 * 将文本消息对象类型转为xml类型 55 * 56 * @param textMessage 57 * @return 58 */ 59 public static String textMessageToXml(TextMessage textMessage) { 60 61 XStream xstream = new XStream(); 62 //将xml的根节点替换为xml 63 xstream.alias("xml", textMessage.getClass()); 64 return xstream.toXML(textMessage); 65 } 66 67 }
View Code
文本对象类
1 package com.imooc.po; 2 3 public class TextMessage { 4 private String ToUserName; 5 private String FromUserName; 6 private String CreateTime; 7 private String MsgType; 8 private String Content; 9 private String MsgId; 10 public String getToUserName() { 11 return ToUserName; 12 } 13 public void setToUserName(String toUserName) { 14 ToUserName = toUserName; 15 } 16 public String getFromUserName() { 17 return FromUserName; 18 } 19 public void setFromUserName(String fromUserName) { 20 FromUserName = fromUserName; 21 } 22 public String getCreateTime() { 23 return CreateTime; 24 } 25 public void setCreateTime(String createTime) { 26 CreateTime = createTime; 27 } 28 public String getMsgType() { 29 return MsgType; 30 } 31 public void setMsgType(String msgType) { 32 MsgType = msgType; 33 } 34 public String getContent() { 35 return Content; 36 } 37 public void setContent(String content) { 38 Content = content; 39 } 40 public String getMsgId() { 41 return MsgId; 42 } 43 public void setMsgId(String msgId) { 44 MsgId = msgId; 45 } 46 47 48 }
View Code
6.写完消息格式的转换之后,我们现在通过post方法实现消息的接收与响应
1 package com.imooc.servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.util.Date; 6 import java.util.Map; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import org.dom4j.DocumentException; 14 15 import com.imooc.po.TextMessage; 16 import com.imooc.util.CheckUtil; 17 import com.imooc.util.MessageUtil; 18 19 public class WeixinServlet extends HttpServlet{ 20 21 @Override 22 /** 23 * 使用doget方法进行验证 24 */ 25 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 26 // 获取微信公众号服务器发送的参数 27 String signature = req.getParameter("signature"); 28 String timestamp = req.getParameter("timestamp"); 29 String nonce = req.getParameter("nonce"); 30 String echostr = req.getParameter("echostr"); 31 32 PrintWriter out = resp.getWriter(); 33 //校验成功将随机字符串返回 34 if(CheckUtil.checkSignature(signature, timestamp, nonce)) { 35 out.print(echostr); 36 } 37 } 38 /** 39 * 接收消息 40 */ 41 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 42 req.setCharacterEncoding("UTF-8"); 43 resp.setCharacterEncoding("UTF-8"); 44 //通过PrintWriter将消息返回给微信后台 45 PrintWriter out = resp.getWriter(); 46 try { 47 //通过集合去接收 48 Map<String,String> map = MessageUtil.xmlToMap(req); 49 //获取对应的属性 50 String fromUserName = map.get("FromUserName"); 51 String toUserName = map.get("ToUserName"); 52 String msgType = map.get("MsgType"); 53 String content = map.get("Content"); 54 55 String message = null; 56 //判断是否为文本消息 57 if("text".equals(msgType)) { 58 //创建文本消息对象 59 TextMessage text = new TextMessage(); 60 //返回给发送者 61 text.setFromUserName(toUserName); 62 text.setToUserName(fromUserName); 63 text.setMsgType("text"); 64 text.setCreateTime(new Date().getTime()); 65 text.setContent("您发送的消息是:" + content); 66 message = MessageUtil.textMessageToXml(text); 67 68 System.out.println(message); 69 } 70 out.print(message); 71 } catch (DocumentException e) { 72 e.printStackTrace(); 73 } finally { 74 out.close(); 75 } 76 } 77 }
View Code
十一、欢迎消息回复和关键字消息回复
添加关注后的消息回复和按照关键字进行消息回复的功能。
1.消息类型有哪些
文本消息-text
图片消息-image
语音消息-voice
视频消息-video
链接消息-link
地理位置消息-location
事件推送-event
--关注-subscribe
--取消关注-unsubscribe
--菜单点击-CLICK、VIEW
2.servlet类的完善
package com.imooc.servlet;import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import java.util.Map;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.dom4j.DocumentException;import com.imooc.po.TextMessage; import com.imooc.util.CheckUtil; import com.imooc.util.MessageUtil;public class WeixinServlet extends HttpServlet{@Override/*** 使用doget方法进行验证*/protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取微信公众号服务器发送的参数String signature = req.getParameter("signature");String timestamp = req.getParameter("timestamp");String nonce = req.getParameter("nonce");String echostr = req.getParameter("echostr");PrintWriter out = resp.getWriter();//校验成功将随机字符串返回if(CheckUtil.checkSignature(signature, timestamp, nonce)) {out.print(echostr);}}/*** 接收消息*/protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");//通过PrintWriter将消息返回给微信后台PrintWriter out = resp.getWriter();try {//通过集合去接收Map<String,String> map = MessageUtil.xmlToMap(req);//获取对应的属性String fromUserName = map.get("FromUserName");String toUserName = map.get("ToUserName");String msgType = map.get("MsgType");String content = map.get("Content");String message = null;//判断是否为文本消息if(MessageUtil.MESSAGE_TEXT.equals(msgType)) {if("1".equals(content)) {message = MessageUtil.initText(toUserName, fromUserName, MessageUtil.firstMenu());}else if("2".equals(content)) {message = MessageUtil.initText(toUserName, fromUserName, MessageUtil.secondtMenu());}else if("?".equals(content)||"?".equals(content)) {message = MessageUtil.initText(toUserName, fromUserName, MessageUtil.menuText());}//事件推送的逻辑}else if(MessageUtil.MESSAGE_EVENT.equals(msgType)) {String eventType = map.get("Event");if(MessageUtil.MESSAGE_SUBSCRIBE.equals(eventType)) {message = MessageUtil.initText(toUserName, fromUserName, MessageUtil.menuText());}}out.print(message);} catch (DocumentException e) {e.printStackTrace();} finally {out.close();}} }
View Code
3.MessageUtil类的完善
package com.imooc.util;import java.awt.font.TextMeasurer; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader;import com.imooc.po.TextMessage; import com.thoughtworks.xstream.XStream;/*** 消息的格式转换* * @author Administrator**/ public class MessageUtil {/*** 消息类型常量*/public static final String MESSAGE_TEXT = "text";public static final String MESSAGE_IMAGE = "image";public static final String MESSAGE_VOICE = "voice";public static final String MESSAGE_VIDEO = "video";public static final String MESSAGE_LINK = "link";public static final String MESSAGE_LOCATION = "location";public static final String MESSAGE_EVENT = "event";public static final String MESSAGE_SUBSCRIBE = "subscribe";public static final String MESSAGE_UNSUBSCRIBE = "unsubscribe";public static final String MESSAGE_CLICK = "CLICK";public static final String MESSAGE_VIEW = "VIEW";/*** xml转为map集合* * @param request* @return* @throws IOException* @throws DocumentException*/public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException {Map<String, String> map = new HashMap<String, String>();SAXReader reader = new SAXReader();// 从Request中获取输入流InputStream ins = request.getInputStream();Document doc = reader.read(ins);Element root = doc.getRootElement();List<Element> list = root.elements();for (Element e : list) {map.put(e.getName(), e.getText());}ins.close();return map;}/*** 将文本消息对象类型转为xml类型* * @param textMessage* @return*/public static String textMessageToXml(TextMessage textMessage) {XStream xstream = new XStream();//将xml的根节点替换为xmlxstream.alias("xml", textMessage.getClass());return xstream.toXML(textMessage);}public static String initText(String toUserName,String fromUserName,String content) {TextMessage text = new TextMessage();text.setFromUserName(toUserName);text.setToUserName(fromUserName);text.setMsgType(MessageUtil.MESSAGE_TEXT);text.setCreateTime(new Date().getTime());text.setContent("您发送的消息是:" + content);return MessageUtil.textMessageToXml(text);}/*** 主菜单* @return*/public static String menuText() {StringBuffer sb = new StringBuffer();sb.append("欢迎您的关注,请按照菜单提示进行操作: \n\n");sb.append("1、地区介绍");sb.append("2、城区介绍");sb.append("回复?调出此菜单");return sb.toString();}public static String firstMenu() {StringBuffer sb = new StringBuffer();sb.append("主要介绍了本区域的气候环境,农产品分布及产量以及水利建设等方面");return sb.toString();}public static String secondtMenu() {StringBuffer sb = new StringBuffer();sb.append("主要介绍了城区的历史及居民生活习惯等方面");return sb.toString();} }
View Code
http://dzj0712.tunnel.echomod.cn
转载于:https://www.cnblogs.com/dzj0712/p/8934247.html
Java 微信公众号开发_学习笔记相关推荐
- 慕课网_《Java微信公众号开发进阶》学习总结
时间:2017年08月12日星期六 说明:本文部分内容均来自慕课网.@慕课网:http://www.imooc.com 教学源码:http://img.mukewang.com/down/... 学习 ...
- java微信公众号开发token验证失败的问题及解决办法
java微信公众号开发token验证失败的问题及解决办法 参考文章: (1)java微信公众号开发token验证失败的问题及解决办法 (2)https://www.cnblogs.com/beardu ...
- Java微信公众号开发梳理
Java微信公众号开发梳理 现在微信公众平台的开发已经越来越普遍,这次开发需要用到微信公众平台.因此做一个简单的记录,也算是给那些没踩过坑的童鞋一些启示吧.我将分几块来简单的描述一下,之后会做详细的说 ...
- Java微信公众号开发微信网页授权之前端传递code方式获取用户信息
本片博客讲解的网页授权分为两步,前端先传递backUrl(回调地址)到后台网页授权接口,该接口拿到回调地址后组装授权连接,重定向到前端页面,前端页面截取Code,传入后端获取用户信息方法,获取用户信息 ...
- Java微信公众号开发(一:接入平台,验证token)
Java微信公众号开发(一:接入平台,验证token) 开发环境: 环境:JDK1.8 框架:springBoot 首先,在我们接入微信公众平台之前,我们需要注册微信公众号的开发者账号,获取开发者ID ...
- JAVA微信公众号开发第8篇JSSDK图片上传预览
简介 博主微信JSSDK&图片上传预览基于微信分享做拓展,所以一些配置操作请点击查阅JAVA微信公众号开发第7篇JSSDK&微信分享博文 页面 <html><head ...
- Java+微信公众号开发学习总结(一)
这两天自己想学习微信公众号开发,于是在网上搜索并上手练习,在这个过程中因为各种问题,(描述不完整,有的文章不知道怎么就蹦出个新的常量,也没说在哪定义的,还有jar包版本的问题坑了我一天的时间)所以特此 ...
- Java微信公众号开发(附源码!!!)
笔者最近在为一个艺考服务团队开发手机端的服务,由于开发app需要的时间较长,所以选择开发微信公众号.本人比较擅长Java开发,所以本文是基于Java语言的公众号开发.话不多说,直接进入正题. 准备工作 ...
- 该微信用户未开启“公众号安全助手”的消息接收功能,请先开启后再绑定,Java微信公众号开发消息推送公众号用户绑定问题 的解决办法
问题概述 在进行微信公众号开发的时候遇到的这个问题,通过Web开发公众号的模板消息推送,在调试的过程中,需要进行开发者接口联调&调试,在调试之前需要将当前的公众号与用户的微信号进行绑定, 绑定 ...
最新文章
- Java面向对象:覆写与重载
- 人工神经网络中为什么ReLu要好过于tanh和sigmoid function?
- 关于如何用100行如何实现docker
- python numpy库安装-Python Numpy库安装与基本操作示例
- C++words search单词搜索的算法实现(附完整源码)
- 一起学习C语言:结构体(二)
- OC基础15:内存管理和自动引用计数
- 若依集成redisson实现redis分布式锁
- SWUST OJ Coin Changing
- JVM内存与垃圾回收篇
- python求100以内的质数
- 系列学习 Gateway 之第 5 篇 —— 搭建高可用网关(完结)
- 【Matlab】MATLAB编辑器主题颜色更改(MATLAB Schemer)
- 计算机edp测试是什么测试,五、信息工具--(一)EDP:电子数据处理
- 逍遥模拟器微信提示无法连接服务器,逍遥模拟器无法连接网络怎么办?
- [Win10] [C# Desktop] 两种方法发送原生Toast通知
- Springboot上传视频到阿里云(视频点播)和aliyun-java-sdk-vod依赖报红问题
- 搭建无线监控云存储服务器,mac 篇二:自建docker视频录像机NVR存储-家用摄像头云存储服务zoneminder...
- 电商云仓储到底是什么?
- 卸载和安装番茄小助手
热门文章
- 华为手环4有哪些变化
- 会长得了绝症(转自NGA)
- 千兆路由器与1200M路由器区别?
- 如何去掉打印时左上角的STSM@EJL 1284.4@EJL
- Serverlet具体解释
- DDD(Domain Driven Design) 领域驱动设计从理论到实践 四
- Nonlinear isotropic diffusion filtering
- 广州品向:开发一个类似斗鱼的视频直播app的成本
- 苹果电脑html为什么显示不出来,苹果自带的天气为什么显示不出来
- 梦幻跨服购买需要登录服务器未响应,梦幻西游8月4日定期维护公告:跨服购买限制放宽...