【公众号开发】访问第三方接口应用于开发 · 回复图文消息

news2025/1/17 2:56:42

【公众号开发】(2)

在这里插入图片描述

文章目录

  • 【公众号开发】(2)
    • 1. 第三方接口
      • 1.1 申请免费接口
      • 1.2 解读接口文档
      • 1.3 postman测试接口
      • 1.4 公众号开发访问第三方接口原理
      • 1.5 访问第三方接口示例
        • 1.5.1 引入依赖
        • 1.5.2 获取form格式的body字符串的方法
        • 1.5.3 发送get请求
        • 1.5.4 发送post请求
        • 1.5.5 json序列化与反序列化相关方法
        • 1.5.6 获取单词方法
        • 1.5.7 测试
        • 1.5.8 TextMessage的包装方法
        • 1.5.9 修改controller层代码
        • 1.5.10 重启并给测试公众号发消息测试
    • 2. 回复图文消息
      • 2.1 封装类
        • 2.1.1 Article对象
        • 2.1.2 NewsMessage对象
      • 2.2 编写回复图文消息的方法
        • 2.2.1 封装一个NewsMessage对象并返回
        • 2.2.2 在controller约定一个分支回复图文消息
        • 2.2.3 发“图文”这个文本消息给公众号进行测试
        • 2.2.4 装杯带来的小坑

【公众号开发】(2)

natapp:NATAPP -

开发手册:开发前必读 / 首页 (qq.com)

微信测试公众号:微信公众平台 (qq.com)

重新配置哦:

在这里插入图片描述
之后不提醒了

1. 第三方接口

聚合数据 - API接口开放平台_API接口大全_免费API数据接口服务 (juhe.cn)

在这个网站中注册一个账号后登录:

在这里插入图片描述

在这里,有超级多的现成的api,可以实现对应的功能:

在这里插入图片描述

而我们要的就是里面免费的api去实现我们需要的功能(不过白嫖每天访问有次数限制)

在这里插入图片描述

而我们要学习的就是 申请免费接口,用于我们的开发,实现我们的自定义功能!

接下来,我们用一个可以免费实现的功能 “同义词接口” 为示例,其他免费接口根据实际情况举一反三即可!

1.1 申请免费接口

进入个人中心,数据中心,我的api, 申请新数据:

在这里插入图片描述

搜索一下:

在这里插入图片描述

申请:

在这里插入图片描述

我的API查看:

在这里插入图片描述

实名一下:

在这里插入图片描述

点进去查看接口文档(功能与使用):

在这里插入图片描述

错误码之后需要再说:

在这里插入图片描述

1.2 解读接口文档

接口与格式约定
在这里插入图片描述

参数约定:

  • 意味着我们请求的时候,要给定什么参数,接受响应时,可以获得什么数据

在这里插入图片描述

在这里插入图片描述

1.3 postman测试接口

key输入错误:

在这里插入图片描述

key输入要输入你的接口所描述的请求key:

  • 这个key可以说是身份标识吧

在这里插入图片描述

在这里插入图片描述

  • 补充:type不传默认为1

查看请求的统计:

在这里插入图片描述

1.4 公众号开发访问第三方接口原理

在这里插入图片描述

1.5 访问第三方接口示例

有些接口是有示例代码的,可以去看看,这里不带着大家看了

例如笑话大全接口的api页面:

在这里插入图片描述

1.5.1 引入依赖
<dependency>            
    <groupId>net.sf.json-lib</groupId>          
    <artifactId>json-lib</artifactId>         
    <version>2.2.3</version>        
    <classifier>jdk15</classifier>     
</dependency>

之后就是编写业务代码了

我们直接抄一些示例代码发送请求的工具类和方法即可:

  • 感兴趣可以去阅读一下代码~

这里我做过改良的~

public class HttpUtils {

    public static final String URL = "http://apis.juhe.cn/tyfy/query";

    //申请接口的请求key
    // TODO: 您需要改为自己的请求key
    public static final String KEY = "key";
}
1.5.2 获取form格式的body字符串的方法
public static String getFormBody(Map<String, Object> map) {
    Set<Map.Entry<String, Object>> entrySet = map.entrySet();
    StringBuilder builder = new StringBuilder();
    for(Map.Entry<String, Object> entry : entrySet) {
        builder.append(entry.toString());
        builder.append("&");
    }
    String formBody = builder.toString();
    if(StringUtils.hasLength(formBody)) {
        formBody = formBody.substring(0, formBody.length() - 1);
    }
    System.out.println(formBody);
    return formBody;
}

这个方法可以将一个哈希表的所有键值对转化为form格式:key1=val1&key2=val2

1.5.3 发送get请求
public static String doGet(String httpUrl, Map<String, Object> map) {
    // 有queryString的就加
    String formBody = HttpUtils.getFormBody(map);
    if(StringUtils.hasLength(formBody)) {
        httpUrl += "?" + formBody;
    }
    HttpURLConnection connection = null;
    InputStream inputStream = null;
    BufferedReader bufferedReader = null;
    String result = null;// 返回结果字符串
    try {
        // 创建远程url连接对象
        URL url = new URL(httpUrl);
        // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
        connection = (HttpURLConnection) url.openConnection();
        // 设置连接方式:get
        connection.setRequestMethod("GET");
        // 设置连接主机服务器的超时时间:15000毫秒
        connection.setConnectTimeout(15000);
        // 设置读取远程返回的数据时间:60000毫秒
        connection.setReadTimeout(60000);
        // 发送请求
        connection.connect();
        // 通过connection连接,获取输入流
        if (connection.getResponseCode() == 200) {
            inputStream = connection.getInputStream();
            // 封装输入流,并指定字符集
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            // 存放数据
            StringBuilder sbf = new StringBuilder();
            String temp;
            while ((temp = bufferedReader.readLine()) != null) {
                sbf.append(temp);
                sbf.append(System.getProperty("line.separator"));
            }
            result = sbf.toString();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (null != bufferedReader) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != inputStream) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            connection.disconnect();// 关闭远程连接
        }
    }
    return result;
}
1.5.4 发送post请求
public static String doPost(String httpUrl, Map<String, Object> map) {
    HttpURLConnection connection = null;
    InputStream inputStream = null;
    OutputStream outputStream = null;
    BufferedReader bufferedReader = null;
    String result = null;
    try {
        URL url = new URL(httpUrl);
        // 通过远程url连接对象打开连接
        connection = (HttpURLConnection) url.openConnection();
        // 设置连接请求方式
        connection.setRequestMethod("POST");
        // 设置连接主机服务器超时时间:15000毫秒
        connection.setConnectTimeout(15000);
        // 设置读取主机服务器返回数据超时时间:60000毫秒
        connection.setReadTimeout(60000);
        // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
        connection.setDoOutput(true);
        // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        // 通过连接对象获取一个输出流
        outputStream = connection.getOutputStream();
        // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
        outputStream.write(getFormBody(map).getBytes());
        // 通过连接对象获取一个输入流,向远程读取
        if (connection.getResponseCode() == 200) {
            inputStream = connection.getInputStream();
            // 对输入流对象进行包装:charset根据工作项目组的要求来设置
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            StringBuilder sbf = new StringBuilder();
            String temp;
            // 循环遍历一行一行读取数据
            while ((temp = bufferedReader.readLine()) != null) {
                sbf.append(temp);
                sbf.append(System.getProperty("line.separator"));
            }
            result = sbf.toString();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (null != bufferedReader) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != outputStream) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != inputStream) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            connection.disconnect();
        }
    }
    return result;
}
1.5.5 json序列化与反序列化相关方法
public class JsonUtils {
    public static ObjectMapper objectMapper = new ObjectMapper();

    public static Map<String, Object> jsonToMap(String jsonString) {
        Map map = null;
        try {
            map = objectMapper.readValue(jsonString, Map.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return map;
    }

    public static String objectToJson(Object object) {
        String jsonString = null;
        try {
            jsonString = objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return jsonString;
    }
}
1.5.6 获取单词方法
  1. 构造参数表
  2. 发起请求
  3. 处理响应
public static List<String> getWords(Integer type, String word) {
    // 构造参数表
    Map<String, Object> params = new HashMap<>();
    params.put("key", KEY);
    params.put("type", type);
    params.put("word", word);
    //发起请求接受响应
    final String response = doPost(URL, params);
    System.out.println("接口返回:" + response);
    try {
        Map<String, Object> ret = JsonUtils.jsonToMap(response);
        int error_code = (Integer) ret.get("error_code");
        String reason = (String) ret.get("reason");
        if (error_code == 0) {
            System.out.println("调用接口成功");
            Map<String, Object> result = (Map<String, Object>) ret.get("result");
            String t = (String) result.get("type");//返回的type
            List<String> words = (List<String>) result.get("words");
            System.out.println(t);
            System.out.println(words);
            return words;
        } else {
            System.out.println("调用接口失败:" + reason);
            return null;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
1.5.7 测试
public static void main(String[] args) {
    getWords(1, "开心");
}

在这里插入图片描述

1.5.8 TextMessage的包装方法
/**
 * 获取同义词
 * @param map
 * @return
 */
public static TextMessage getSynonym(Map<String, String> map) {
    TextMessage message = new TextMessage();
    message.setToUserName(map.get("FromUserName"));
    message.setFromUserName(map.get("ToUserName"));
    message.setCreateTime(System.currentTimeMillis() / 1000);
    message.setMsgType("text");
    message.setContent("回复同义词:  " + HttpUtils.getWords(1, map.get("Content")));
    return message;
}

/**
 * 获取反义词
 * @param map
 * @return
 */
public static TextMessage getAntonym(Map<String, String> map) {
    TextMessage message = new TextMessage();
    message.setToUserName(map.get("FromUserName"));
    message.setFromUserName(map.get("ToUserName"));
    message.setCreateTime(System.currentTimeMillis() / 1000);
    message.setMsgType("text");
    message.setContent("回复反义词:  " + HttpUtils.getWords(2, map.get("Content")));
    return message;
}
1.5.9 修改controller层代码

在这里插入图片描述

1.5.10 重启并给测试公众号发消息测试

在这里插入图片描述

第一次访问要加载很多东西,响应时间需要较长,这很正常哦~

到这里,相信你已经了解了访问第三方接口的大致流程,结合实际需求,业务逻辑,开始举一反三吧!

  • 无非就是申请接口,查看功能介绍,接口文档,构造请求,发送请求,处理响应~

补充:xml序列化和反序列化的方法相关方法,可能需要用到

public class XmlUtils {
    public static String objectToXml(Object o) {
        //获取序列化工具XStream对象
        XStream xStream = new XStream();
        //指定类型
        xStream.processAnnotations(o.getClass());
        //转化为xml字符串
        String xml = xStream.toXML(o);
        //返回
        return xml;
    }

    public static Map<String, String> xmlToMap(ServletInputStream inputStream) {
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        // xml字符串解析方法
        try {
            //通过请求的输入流,获取Document对象
            Document document = reader.read(inputStream);
            // 获取root节点
            Element root = document.getRootElement();
            // 获取所有子节点
            List<Element> elements = root.elements();
            // 遍历集合
            for(Element e : elements) {
                map.put(e.getName(), e.getStringValue());
            }
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }
        return map;
    }

    public static Map<String, Object> xmlToMap(String xml) {
        Map<String, Object> map = new HashMap<>();
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            org.w3c.dom.Document document = builder.parse(new InputSource(new StringReader(xml)));
            org.w3c.dom.Element root = document.getDocumentElement();
            map = parseElement(root);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
    private static Map<String, Object> parseElement(org.w3c.dom.Element element) {
        Map<String, Object> map = new HashMap<>();
        NodeList nodeList = element.getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                org.w3c.dom.Element childElement = (org.w3c.dom.Element) node;
                if (childElement.getChildNodes().getLength() > 1) {
                    map.put(childElement.getTagName(), parseElement(childElement));
                } else {
                    map.put(childElement.getTagName(), childElement.getTextContent());
                }
            }
        }
        return map;
    }
}

2. 回复图文消息

基础消息能力 / 被动回复用户消息 (qq.com)

  • 可能有时候,我不会发开发者文档的具体位置,只会发重点截图(感兴趣的可以去文档查一查,学一学)

这里以图文消息为例,其他消息按照模板返回即可,这个最具有代表性,情况覆盖面比较大~

开发者需要回复的消息模板:

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[news]]></MsgType>
  <ArticleCount>1</ArticleCount>
  <Articles>
    <item>
      <Title><![CDATA[title1]]></Title>
      <Description><![CDATA[description1]]></Description>
      <PicUrl><![CDATA[picurl]]></PicUrl>
      <Url><![CDATA[url]]></Url>
    </item>
  </Articles>
</xml>
  • item代表一个Article元素(一个文本元素)

参数描述:

在这里插入图片描述

我们回复的图文消息就差不多这种:

在这里插入图片描述

  1. 有标题
  2. 描述(简介)
  3. 图片(封面)
  4. 点击就可以跳转链接(微信站内页面、网页…)

2.1 封装类

2.1.1 Article对象
@Data
@XStreamAlias("item")
public class Article {

    @XStreamAlias("Title")
    private String title;

    @XStreamAlias ("Description")
    private String description;

    @XStreamAlias("PicUrl")
    private String picUrl;

    @XStreamAlias ("Url")
    private String url;
}

别忘了,这个图文信息被item标签包裹~

2.1.2 NewsMessage对象
@XStreamAlias("xml")
@Data
public class NewsMessage {

    @XStreamAlias("ToUserName")
    private String toUserName;

    @XStreamAlias("FromUserName")
    private String fromUserName;

    @XStreamAlias("CreateTime")
    private long createTime;

    @XStreamAlias("MsgType")
    private String msgType;

    @XStreamAlias("ArticleCount")
    private Integer articleCount;

    @XStreamAlias("Articles")
    private List<Article> articles;
}

别忘了,最外层标签xml~

List对象xml序列化规则:

  1. 这个属性的标签包裹其值
    • 这里就是Articles标签包裹
  2. 其值的序列化为集合遍历每个元素,每个元素的序列化依次排列
    • 这里就是item标签包裹的文本消息

2.2 编写回复图文消息的方法

2.2.1 封装一个NewsMessage对象并返回
public static NewsMessage getReplyNewsMessage(Map<String, Object> map) {
    NewsMessage newsMessage = new NewsMessage();
    newsMessage.setToUserName((String) map.get("FromUserName"));
    newsMessage.setFromUserName((String) map.get("ToUserName"));
    newsMessage.setCreateTime(System.currentTimeMillis() / 1000);
    newsMessage.setMsgType("news");
    newsMessage.setArticleCount(1);
    Article article = new Article();
    article.setTitle("文1");
    article.setDescription("描述1");
    article     .setPicUrl("http://mmbiz.qpic.cn/sz_mmbiz_jpg/M6lc7Lf7u4jOOQRVia3zia334d7FIXC4DoJ984J6kCqicfIaCMsXrqvjJ9ylmNOq25vHPOgv9t0lUva50iapUd5Cpg/0");
    article.setUrl("https://blog.csdn.net/Carefree_State?type=blog");
    List<Article> articleList = new ArrayList<>();
    articleList.add(article);
    newsMessage.setArticles(articleList);
    System.out.println(newsMessage);
    return newsMessage;
}

这里的PicUrl是用户发送过来,缓存在微信公众号服务器的图片链接,或者你也可以填写其他网络图片~

2.2.2 在controller约定一个分支回复图文消息

这里我的代码做出一些跳转,具体参见:wx-demo · 游离态/马拉圈2023年10月 - 码云 - 开源中国 (gitee.com)

在这里插入图片描述

调用xml转化工具后返回回去即可~

2.2.3 发“图文”这个文本消息给公众号进行测试

发图文两个字给公众号

在这里插入图片描述

点击链接可以跳转:

在这里插入图片描述

控制台查看:

在这里插入图片描述

2.2.4 装杯带来的小坑
newsMessage.setArticles(new ArrayList<Article>() {{
    this.add(new Article(){{
        this.setTitle("文1");
        this.setDescription("描述1");
        this.setUrl("https://blog.csdn.net/Carefree_State?type=blog");
        this.setPicUrl("http://mmbiz.qpic.cn/sz_mmbiz_jpg/M6lc7Lf7u4jOOQRVia3zia334d7FIXC4DoJ984J6kCqicfIaCMsXrqvjJ9ylmNOq25vHPOgv9t0lUva50iapUd5Cpg/0");
    }});
}});

如果你是通过匿名内部类的方式去构造对象并设置,xml序列化的时候会被序列化的乱七八糟,血的教训啊😫😫😫

具体为什么,我也不知道,可能是匿名内部类实例代码块的机制有关吧,有一些细节出现偏差,瑕疵导致的吧~

不要装杯!写正常易懂的代码就好了!

在这里插入图片描述

看到没有,这个List对象被序列化得乱七八糟的~

ok,就这样了,其他消息格式大家自己去研究,举一反三~


文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

代码:wx-demo · 游离态/马拉圈2023年10月 - 码云 - 开源中国 (gitee.com)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1114817.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EPLAN_005#宏边框、页宏、窗口宏/符号宏

一、宏边框 红边框不能用&#xff0c;变成了灰色 要在项目属性中更改位宏项目——才能使用宏边框功能 注意&#xff1a;创建宏边框时候要打开——显示隐藏元素 框选目标后&#xff0c;双击红边框的边——弹出红边框创建属性对话框——输入名称——更改变量ABC等 最后——自动…

10个设计人士应该关注的国内外资源网站

设计师网站1&#xff1a;即时设计 即时设计内拥有上万款来自于优秀设计师的精美设计作品&#xff0c;包括设计规范、页面、插画、图标、产品原型、作品集等等&#xff0c;这些作品往往都是由大厂团队精心总结的设计规范&#xff0c;对应着完善的设计系统与配套组件库。除此之外…

innoDB如何解决幻读

Mysql的事务隔离级别 Mysql 有四种事务隔离级别&#xff0c;这四种隔离级别代表当存在多个事务并发冲突时&#xff0c;可能出现的脏读、不可重复读、幻读的问题。其中 InnoDB 在 RR 的隔离级别下&#xff0c;解决了幻读的问题 事务隔离级别脏读不可重复读幻读未提交读&#xff…

openEuler 服务器安装 JumpServer (all-in-one 模式)

openEuler 服务器安装 JumpServer JumpServer 简介什么是 JumpServer &#xff1f;JumpServer 的各种类型资产JumpServer 产品特色或优势JumpServer 符合 4A 规范 JumpServer 系统架构应用架构组件说明 JumpServer 安装部署环境要求网络端口网络端口列表防火墙常用命令 在线脚本…

上万份订单里,读懂中国互联网企业ESG

【潮汐商业评论/原创】 “残障到底意味着什么&#xff1f;”知乎上有个高赞回答提到&#xff0c;对于大多数残障者而言&#xff0c;他们和家人鼓足了干劲、费劲了心思&#xff0c;只为过上“正常的生活”。 但我们可曾想过&#xff1a;这个世界有没有一开始就准备好接纳所有降…

记一次TheadLocal使用方式不正确导致内存泄漏问题的排查和修复过程

一、背景 一个部门其他同事的上线了很久的项目近期频繁的内存溢出——几乎每天内存溢出一次&#xff0c;而且频率越来越高。在添加了进程守护之后&#xff0c;虽然可以在内存溢出后自动重启&#xff0c;但并没有解决内存溢出的问题。不甘其扰之后&#xff0c;决定仔细排查导致内…

C++string的模拟实现

CSDN的uu们&#xff0c;大家好。这里是C入门的第十六讲。 座右铭&#xff1a;前路坎坷&#xff0c;披荆斩棘&#xff0c;扶摇直上。 博客主页&#xff1a; 姬如祎 收录专栏&#xff1a;C专题 目录 1. string类的成员变量 2. 构造函数 3. 析构函数 4. const char* c_str(…

ESP32网络开发实例-连接信号最强的热点

连接信号最强的热点 文章目录 连接信号最强的热点1、软件准备2、硬件准备3、代码实现在本文中,将向您展示如何使用 ESP32 WiFiMulti 库。 这使我们能够使用多个网络,ESP32 可以连接到列表中可用的最强 WiFi 网络。 每当它失去连接时,它都会重新连接到列表中下一个最强的网络…

数据结构-----图(Graph)论必知必会知识

目录 前言 图的基本概念 1.什么是图&#xff1f; 2 .图的相关术语 3 .有向图和无向图 4.简单图和多重图 5.连通图、强连通图、非连通图 6.权与网 7.子图和(强)连通分量 8.生成树和生成森林 前言 今天我们学习一种新的数据结构-----图&#xff0c;大家在日常生活中经常都…

KingBase用户与角色及对象访问权限(Kylin)

用户与角色 角色的概念 将一组具有相同权限的用户组织在一起&#xff0c;这一组具有相同权限的用户就称为角色&#xff08;Role&#xff09;角色在生产系统中一般被视为用户组&#xff0c;利用角色对用户进行批量授权 创建用户角色 CREATE USER name WITH [option]授予权限…

理解内存,让Android性能没有问题

内存优化一直是一个很重要但却缺乏关注的点&#xff0c;内存作为程序运行最重要的资源之一&#xff0c;需要运行过程中做到合理的资源分配与回收&#xff0c;不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏&#xff0c;重则导致用户应用程序发生 OOM&#xff08;out…

Sarscape5.6版本中导入外部控制点、写入精密轨道文件与GACOS用于大气相位

SARscape中导入外部GCP点用于轨道精炼 https://www.cnblogs.com/enviidl/p/16524645.html在SAR处理时&#xff0c;有时会加入GCP点文件&#xff0c;SAR处理中用到的控制点分为两类&#xff1a;用于校正地理位置的几何控制点&#xff08;Geometry GCP&#xff09;和用于轨道精炼…

C++类和对象(三) (this指针)

this指针 1 this指针的引出 我们先来定义一个日期类 Date class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout << _year << "-" << _month << "-" << …

【电子通识】USB接口三大类型图册

基本概念 不同时期的USB接口有不同的类型&#xff0c;USB接口分为插头和插座&#xff1a; 插头&#xff0c;plug&#xff0c;对应的也叫公口&#xff0c;即插别人的。 插座&#xff0c;receptacle&#xff0c;对应也叫做母口&#xff0c;即被插的。 USB的接口类型&#xff0…

《动手学深度学习 Pytorch版》 9.6 编码器-解码器架构

为了处理这种长度可变的输入和输出&#xff0c; 可以设计一个包含两个主要组件的编码器-解码器&#xff08;encoder-decoder&#xff09;架构&#xff1a; 编码器&#xff08;encoder&#xff09;&#xff1a;它接受一个长度可变的序列作为输入&#xff0c;并将其转换为具有固定…

模拟器-雷电-使用adb push或adb pull操作文件

一、环境 windows 10 雷电模拟器4.0.83 二、问题 有时候我们会需要往模拟器拷贝文件或者复制文件到我的电脑 三、方法 1、获取root权限 adb root adb remount 有可能遇到【daemon not running; starting now at tcp:5037】的报错 查看端口占用进程&#xff1a;netstat -…

vue2升级到vue2.7

vue2升级到vue2.7 小小的改进,大大的提升 只需要简单修改,开发体验得到大大提升. 为什么要升级Vue2.7 不能拒绝的理由: 组合式 API(解决mixins问题:命名冲突,隐式依赖)单文件组件内的 <script setup>语法模板表达式中支持 ESNext 语法(可选链:?.、空值合并:??)单文…

域渗透05-协议(NTLM)

前言&#xff1a; 首先在域内环境中主要有如下6种身份认证协议&#xff0c;最常用的还是Kerberos&#xff0c;NTLM和LDAP三种&#xff1a; Kerberos&#xff1a;Kerberos是一种网络身份验证协议&#xff0c;用于验证用户和服务之间的身份。它通过使用票据和密钥来实现认证&…

Linux 指令学习

Linux 指令学习 以此为记录&#xff0c;也方便自己日后查看回顾&#xff01; Linux命令基础格式 无论是什么命令&#xff0c;用于什么用途&#xff0c;在Linux中&#xff0c;命令有其通用的格式&#xff1a; command&#xff1a; 命令本身 options&#xff1a;[可选&#xf…

AD9371 官方例程

文章目录 前言一、HDL方面1. ZYNQ 核根据ZCU106平台修改&#xff08;**参考UG1244 ZCU106 Evaluation Board**&#xff09;&#xff0c;尤其注意**DDR**的配置&#xff08;**参考美光 MTA4ATF51264HZ**&#xff09;2.dacfifo 深度 要修改 &#xff0c;地址位宽 小于等于16&…