day05 Servlet组件(上)

1. Web资源的概念

Web资源就是运行在服务器上的资源,它一共分为两类: 静态资源以及动态资源

1.1 静态资源

静态资源就是web页面中供人们浏览的数据始终是不变,例如我们之前所学习的html、css、js、图片、音视频等等都属于静态资源

1.2 动态资源

动态资源就是web页面中供人们浏览的数据是由程序(代码)产生的,不同的用户或者不同时间点访问web页面看到的内容各不相同,例如我们后续要学习的Servlet、JSP(不学)、Thymeleaf等等都是动态资源

2. Servlet的概念

2.1 什么是Servlet

Servlet 是运行在服务端(tomcat)的Java小程序,是sun公司提供一套定义动态资源规范; 从代码层面上来讲Servlet就是一个接口

2.2 Servlet的作用

用来接收、处理客户端请求、响应给浏览器的动态资源。在整个Web应用中,Servlet主要负责接收处理请求、协同调度功能以及响应数据。我们可以把Servlet称为Web应用中的『控制器』

3. Servlet的作用的图示

现实中的例子


要实现的效果

参考去银行或者政务大厅办理业务

4. Servlet的入门案例

4.1 目标

在页面上点击超链接,由Servlet处理这个请求,并返回一个响应字符串:Hello,I am Servlet

4.2 思路

4.3 实现步骤

① 创建动态Web module


② 创建html页面
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>index</title>
</head>
<body><h1>index首页</h1>
<a href="hello">HelloServlet</a>
</body>
</html>
③ 创建HelloServlet类 需先添加依赖 看④
package com.atguigu.servlet;import javax.servlet.*;
import java.io.IOException;/*** 包名:com.atguigu.servlet* * 编写Servlet的步骤:* 1. 编写一个类实现Servlet接口,并且重写里面的方法: 主要是要重写service方法* 2. 重写service方法,service方法中就是接收、处理请求,并且将信息响应给客户端* 3. 配置Servlet的映射路径(供客户端访问的路径):在web/WEB-INF/web.xml中配置*/
public class HelloServlet implements Servlet {@Overridepublic void init(ServletConfig config) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("---------------------HelloServlet service1------------------");// 不要使用中文servletResponse.getWriter().println("HelloServlet Success");}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}
④添加依赖

④ 在web.xml中配置HelloServlet

配置文件位置:WEB-INF/web.xml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R50PvL5D-1666236914681)(images/img008.png)]

<!--配置HelloServlet的映射路径 -->
<servlet><!--相当于给该Servlet取个名,我们可以就使用Servlet的类名/类名首字母改小写--><servlet-name>helloServlet</servlet-name><!--你要配置的那个Servlet的全限定名--><servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
</servlet><servlet-mapping><!--和servlet标签中的servlet-name保持一致 --><servlet-name>helloServlet</servlet-name><!--这就是要给HelloServlet配置的映射路径,以/开头--><url-pattern>/hello</url-pattern>
</servlet-mapping>

『映射路径』:Servlet并不是文件系统中实际存在的目录或文件,所以为了方便浏览器访问,我们创建了映射路径来访问它。

4.4 小结

需求:在浏览器上点超链接能够访问Java程序

5. 概念梳理

5.1 原生Tomcat

安装在电脑上的实实在在的Tomcat软件

5.2 IDEA中的Tomcat实例

通过idea的配置在idea上集成的Tomcat实例,其实还是使用的原生的Tomcat软件

5.3 IDEA中的Web工程

程序员使用IDEA编写的动态Web工程,该工程只是用于程序员编码,实际上部署运行在Tomcat服务器中的并不是这个工程

5.4 根据Web工程生成的war包

根据程序员创建的动态Web工程,IDEA会将其打包成一个war包,而真正部署运行在Tomcat服务器中的其实是war包

5.5 访问资源的地址

5.5.1 访问静态资源

/Web应用名称/静态资源本身的路径(就是静态资源在web文件夹中的路径)

5.5.2 访问动态资源

/Web应用名称/映射路径

5.6 Web应用名称(项目名)

注意Web应用名不是你工程或者Module的名字,而是你在部署时候的ApplicationContext的内容

5.7 总体的逻辑结构

6. Servlet的注解方式配置(了解即可)

注意: 一个Servlet要么使用配置文件方式配置,要么使用注解方式配置,不能两者都使用

使用注解方式配置的优势: 代码更加简单

使用注解方式配置的劣势: 耦合度高

我们一般更推荐使用配置文件方式配置Servlet,尤其是配置第三方框架中的Servlet:例如SpringMVC中的DispatcherServlet,我们只能够使用配置文件方式进行配置

6.1 使用注解方式配置的代码实现

在要进行配置的Servlet类上添加注解@WebServlet("/映射路径")

7. Servlet的生命周期

7.1 Servlet生命周期概述

  • 应用程序中的对象不仅在空间上有层次结构的关系,在时间上也会因为处于程序运行过程中的不同阶段而表现出不同状态和不同行为——这就是对象的生命周期。
  • 简单的叙述生命周期,就是对象在容器中从开始创建到销毁的过程。

7.2 Servlet容器

Servlet对象是Servlet容器创建的,生命周期方法都是由容器调用的。这一点和我们之前所编写的代码有很大不同。在今后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开发人员要尽可能多的将精力放在业务逻辑的实现上。

7.3 Servlet生命周期的主要过程

① Servlet对象的创建:构造器
  • 默认情况下,Servlet容器第一次收到HTTP请求时创建对应Servlet对象。
  • 容器之所以能做到这一点是由于我们在注册Servlet时提供了全类名,容器使用反射技术创建了Servlet的对象。
② Servlet对象初始化:init()
  • Servlet容器**创建Servlet对象之后,会调用init(ServletConfig config)**方法。
  • 作用:是在Servlet对象创建后,执行一些初始化操作。例如,读取一些资源文件、配置文件,或建立某种连接(比如:数据库连接)
  • init()方法只在创建对象时执行一次,以后再接到请求时,就不执行了
  • 在javax.servlet.Servlet接口中,public void init(ServletConfig config)方法要求容器将ServletConfig的实例对象传入,这也是我们获取ServletConfig的实例对象的根本方法。
③ 处理请求:service()
  • 在javax.servlet.Servlet接口中,定义了**service(ServletRequest req, ServletResponse res)**方法处理HTTP请求。
  • 在每次接到请求后都会执行。
  • 上一节提到的Servlet的作用,主要在此方法中体现。
  • 同时要求容器将ServletRequest对象和ServletResponse对象传入。
④ Servlet对象销毁:destroy()
  • 服务器重启、服务器停止执行或Web应用卸载时会销毁Servlet对象,会调用public void destroy()方法。
  • 此方法用于销毁之前执行一些诸如释放缓存、关闭连接、保存内存数据持久化等操作。

7.4 配置Servlet提前创建

有时候我们需要在Servlet创建的时候做一些资源加载等等耗时操作,所以如果Servlet在第一次接收请求的时候才创建的话必然会影响用户的访问速度,所以此时我们需要让Servlet提前创建,将Servlet的创建提前到服务器启动的时候。

通过修改web.xml中Servlet的配置可以实现:

<!-- 配置Servlet本身 -->
<servlet><!-- 全类名太长,给Servlet设置一个简短名称 --><servlet-name>HelloServlet</servlet-name><!-- 配置Servlet的全类名 --><servlet-class>com.atguigu.servlet.HelloServlet</servlet-class><!-- 配置Servlet启动顺序 --><load-on-startup>1</load-on-startup>
</servlet>

8. ServletConfig的介绍(了解)

8.1 接口概览

8.2 接口方法介绍

方法名 作用
getServletName() 获取<servlet-name>HelloServlet</servlet-name>定义的Servlet名称
getServletContext() 获取ServletContext对象
getInitParameter() 获取配置Servlet时设置的『初始化参数』,根据名字获取值
getInitParameterNames() 获取所有初始化参数名组成的Enumeration对象

8.3 获取Servlet的初始化参数

我们可以在web.xml中对Servlet配置初始化参数,接下来可以在Servlet的init方法中获取配置的初始化参数的值

web.xml代码

    <servlet><servlet-name>ConfigServlet</servlet-name><servlet-class>com.atguigu.servlet.ConfigServlet</servlet-class><init-param><param-name>username</param-name><param-value>anqila</param-value></init-param><init-param><param-name>pwd</param-name><param-value>123</param-value></init-param></servlet>

ConfigServlet代码

package com.atguigu.servlet;import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;public class ConfigServlet implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("-----------getServletName()-----------");String servletName = servletConfig.getServletName();System.out.println("servletName = " + servletName);  // servletName = ConfigServletSystem.out.println("-----------getInitParameter()----------");String unameValue = servletConfig.getInitParameter("username");System.out.println("unameValue = " + unameValue);  // unameValue = anqilaString pwdValue = servletConfig.getInitParameter("pwd");System.out.println("pwdValue = " + pwdValue);  // pwdValue = 123System.out.println("-----------getInitParameterNames() 获取所有的初始化参数的名字---------");Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();while (initParameterNames.hasMoreElements()){String name = initParameterNames.nextElement();String value = servletConfig.getInitParameter(name);System.out.println("name = " + name + ", value = " + value);/*-----------getInitParameterNames() 获取所有的初始化参数的名字---------name = pwd, value = 123name = username, value = anqila*/}}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}

9. ServletContext的概念

服务器为其部署的每一个应用(项目)都创建了一个ServletContext对象。ServletContext属于整个项目的,该项目中的所有Servlet都可以共享同一个ServletContext对象

9.1 获取ServletContext的API

9.1.1 调用Servlet自身的getServletContext方法获取
ServletContext ServletContext = getServletContext()
9.1.2 调用ServletConfig接口的getServletContext方法
ServletContext ServletContext = servletConfig.getServletContext();
//HttpServletRequest对象也实现了ServletConfig接口,所以也有getServletContext()方法
ServletContext ServletContext = request.getServletContext();

9.2 ServletContext获取全局的初始化参数

9.2.1 在web.xml中配置Web应用级别的初始化参数
<context-param><param-name>username</param-name><param-value>atguigu</param-value>
</context-param>
9.2.2 在Servlet的doGet方法中获取全局参数
String username = servletContext.getInitParameter("username");
System.out.println("在ServletDemo04中获取全局的初始化参数username=" + username);

9.3 ServletContext作为全局的域对象

9.3.1 什么是域对象

域对象就是在一定的作用域范围内进行数据共享的对象,ServletContext作为全局域对象可以在整个项目的所有动态资源(包含所有Servlet)中进行数据共享

9.3.2 ServletContext作为域对象的API
① 往全局域对象中存入数据
servletContext.setAttribute("key",value)
② 从全局域对象中取出数据
Object value = ServletContext.getAttribute("key");

9.4 案例

9.4.1 目标

在ServletDemo01中往全局域对象中存入"key"为"value"的键值对,然后在ServletDemo02中从全局域对象中根据"key"获取对应的值

9.4.2 代码

ServletDemo01中的代码

//1. 获取ServletContext对象
ServletContext ServletContext = getServletContext();
//2. 存入数据
String str = "atguigu";
//将str设置到servletContext里面
servletContext.setAttribute("str",str);

ServletDemo02中的代码

//1. 获取ServletContext对象
ServletContext ServletContext = getServletContext();
//2. 取出数据
String str = (String) servletContext.getAttribute("str");
System.out.println("在ServletDemo02中获取ServletContext域对象中的str = " + str);

9.5 获取资源的真实路径

9.5.1 为什么需要用代码获取资源的真实路径

例如我们的目标是需要获取项目中某个静态资源的路径,不是工程目录中的路径,而是部署目录中的路径;我们如果直接拷贝其在我们电脑中的完整路径的话其实是有问题的,因为如果该项目以后部署到公司服务器上的话,路径肯定是会发生改变的,所以我们需要使用代码动态获取资源的真实路径

9.5.2 获取资源真实路径的API
String realPath = servletContext.getRealPath("资源在web目录中的路径");
9.5.3 动态获取真实路径的优势

只要使用了servletContext动态获取资源的真实路径,那么无论项目的部署路径发生什么变化,都会动态获取项目运行时候的实际路径,所以就不会发生由于写死真实路径而导致项目部署位置改变引发的路径错误问题

10. Servlet的体系结构

10.1 类型关系

Servlet接口有一个实现类是GenericServlet,而GenericServlet有一个子类是HttpServlet,我们创建Servlet的时候会选择继承HttpServlet,因为它里面相当于也实现了Servlet接口,并且对一些方法做了默认实现;而且子类的功能会比父类的更加强大

10.2 方法关系

我们编写Servlet类继承HttpServlet的时候,只需要重写doGet()和doPost()方法就行了,因为HttpServlet重写了service()方法,在service()方法中判断请求方式,根据不同的请求方式执行doXXX()方法

10.3 使用Idea直接创建Servlet

10.3.1 创建步骤

10.3.2 创建后的代码

web.xml代码

<!-- IDEA会自动生成servlet标签 -->
<servlet><servlet-name>QuickServlet</servlet-name><servlet-class>com.atguigu.servlet.QuickServlet</servlet-class>
</servlet><!-- 我们自己补充servlet-mapping标签 -->
<servlet-mapping><servlet-name>QuickServlet</servlet-name><url-pattern>/QuickServlet</url-pattern>
</servlet-mapping>

Servlet代码

public class QuickServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//在doPost()方法中调用doGet(),这样的话就只需要重写doGet()方法就能处理post和get请求doGet(request,response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}

10.4 Servlet的三种映射路径的配置

10.4.1 映射路径的作用

Servlet的映射路径是提供一个让别人能够访问该Servlet的路径,例如Servlet的映射路径是"/hello",那么在浏览器上访问该Servlet的路径是http://localhost:8080/项目部署名/hello

注意:一个Servlet可以配置多个映射路径,但是多个Servlet不能配置相同的映射路径

10.4.2 映射路径的分类
① 完全路径匹配

访问当前Servlet的路径需要和配置的映射路径完全一致,例如Servlet的配置是/demo01,那么访问该Servlet的时候的路径也必须是http://localhost:8080/项目部署名/demo01才可以访问到

<servlet-mapping><servlet-name>LiBaiServlet</servlet-name><url-pattern>/libai</url-pattern><url-pattern>/libaibai</url-pattern>
</servlet-mapping>
<h5>精确匹配</h5>
<a href="libai"> 李白</a>
<a href="libaibai"> 李白白</a> <br>
② 目录匹配

/ 开始需要以 * 结束,: Servlet里面用的不多, 但是过滤器里面通常就使用目录匹配

例如:  配置/* 访问的路径可写成/任意字符串,比方: /aa, /aaa; 配置 /aa/*  访问的路径可写成/aa/任意字符串,比方: /aa/b , /aa/cc
<servlet-mapping><servlet-name>AnQiLaServlet</servlet-name><url-pattern>/aa/*</url-pattern>
</servlet-mapping>
<h5>目录匹配</h5>
<a href="aa/bb"> 安琪拉1</a>
<a href="aa"> 安琪拉2</a>
<a href="aa/bb/cc/dd"> 安琪拉3</a>
③ 扩展名匹配

*开头,以.扩展名结束,能够匹配所有以.相同扩展名结尾的请求路径

    <servlet-mapping><servlet-name>DaJiServlet</servlet-name><url-pattern>*.action</url-pattern><url-pattern>*.do</url-pattern></servlet-mapping>
<h5>后缀名匹配</h5>
<a href="cc.do">妲己1</a>
<a href="mm.action">妲己2</a>
<a href="abc/def/mm.action">妲己3</a>
<a href="abc/def/nn.do">妲己4</a>

11. 动态Web工程内编写路径(非常重要)

11.1 为什么要写路径

  • 整个系统要根据功能拆分成许许多多独立的资源
  • 资源之间既要完成自身的功能又要和其他资源配合
  • 写路径就是为了从一个资源访问下一个资源

11.2 工程目录和部署目录的结构对比

11.2.1 工程目录

我们写代码的地方,但是在服务器上运行的不是这个

11.2.2 部署目录

经过Java源文件编译和目录重组后,IDEA就替我们准备好了可以在服务器上运行的部署目录

11.2.3 编写路径的基准

用户通过浏览器访问服务器,而服务器上运行的是部署目录,所以写路径的时候参考部署目录而不是工程目录

11.2.4 工程目录和部署目录的对应关系

工程目录下的web目录对应部署目录的根目录,同时部署目录的根目录也是路径中的Web应用根目录

11.3 url的介绍

11.3.1 url的概念

url是uniform Resource Locater的简写,中文翻译为统一资源定位符,它是某个互联网资源的唯一访问地址,客户端可以通过url访问到具体的互联网资源

11.3.2 url的组成

11.3.3 url的使用场景

客户端访问服务器的资源,或者一台服务器中要访问另外一台服务器的资源都是通过url访问

11.4 uri的介绍

11.4.1 uri的概念

uri是Uniform Resource Identifier的缩写,中文翻译为统一资源标识符, 它是服务器中某个资源的唯一标识,通过uri可以实现同一项目中的某个资源中访问另一个资源

11.4.2 uri的组成

uri的写法是/项目部署名/资源路径

11.4.3 uri的使用场景

在同一个项目的某个资源中访问该项目中的另一个资源

11.5 相对路径的使用(不建议使用)

11.5.1 目标

目标: 在A资源中访问B资源

A资源的uri路径: /app/pages/a.html

B资源的uri路径:/app/static/vue.js

11.5.2 相对路径的概念

相对路径是不以/开头的路径写法,编写相对路径的原则是以目标资源的uri路径相对当前资源的uri路径

11.5.3 相对路径实例

那么要实现在A资源中访问B资源的相对路径写法是../static/vue.js,其中../static表示找到当前资源的上一级目录下的static目录

11.6 绝对路径的使用(建议使用)

11.6.1 目标

目标: 在A资源中访问B资源

A资源的uri路径: /app/pages/a.html

B资源的uri路径:/app/static/vue.js

11.6.2 绝对路径的概念

绝对路径是以/开头的路径写法,编写绝对路径的原则是通过目标资源的uri访问目标资源,但是特殊情况是请求转发,如果是请求转发访问目标资源的话,那么绝对路径是在uri的基础之上省略/项目部署名

11.6.3 绝对路径实例

那么要实现在A资源中访问B资源的绝对路径写法是/app/static/vue.js

11.6.4 在请求转发的时候使用绝对路径

请求转发在后续内容中会讲解,现在我们只需要搞懂在请求转发的时候绝对路径的写法是/资源名,其实就是在uri的基础上省略/项目部署名

11.7 动态获取上下文路径(部署的项目名)

11.7.1 上下文路径的概念

上下文路径(context path)=/Web应用名称

11.7.2 为什么要动态获取上下文路径

因为我们使用绝对路径的时候需要用到资源的uri路径,而uri路径中是包含上下文路径的,所以如果采用静态方式写绝对路径,那么就会将上下文路径写死在绝对路径中;而我们在部署项目的时候,上下文路径是可变的,所以这样就会因为部署时设置的上下文路径不同从而导致绝对路径出错的问题

11.7.3 动态获取上下文路径的API
package com.atguigu.servlet3;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/a")
public class AServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("--------- AServlet -----------");// <a href='/day33/success.html'>AServlet</a>// 动态获取应用名String contextPath = req.getContextPath();System.out.println("contextPath = " + contextPath);  // contextPath = /day33//        resp.getWriter().println("<a href='/day33/success.html'>AServlet</a>");resp.getWriter().println("<a href='" + contextPath + "/success.html'>AServlet</a>");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

使用上述API可以动态获取项目的上下文路径,每一次获取的都是当前环境下实际的上下文路径的值

day05 Servlet组件(上)相关推荐

  1. javaweb上传文件_javaWeb中,如何通过CommonsFileUpload组件上传文件

    大家好,欢迎来到雄雄的小课堂,今天给大家分享的是<javaWeb中,如何通过Commons-FileUpload组件上传文件> 前言:文件上传大家都不陌生,在这个互联网飞速发展的时代,共享 ...

  2. servlet文件上传下载_Servlet上传文件和下载文件示例

    servlet文件上传下载 Java Web应用程序中的文件上载和下载以及常见任务. 由于最近我写了很多有关Java servlet的文章 ,因此我想提供一个使用servlet上传和下载文件的示例示例 ...

  3. 使用SmartUpload组件上传文件,自己踩过的坑

    昨天使用SmartUpload组件上传文件,代码很简单: smartupload_demo01.html <html> <head><title>smartuplo ...

  4. 使用Fileupload组件上传文本和文件

    使用fileupload组件上传文本和文件 绪论 使用fileupload组件可以很方便的向服务器上传数据,包括表单数据以及二进制文件,比如pdf.图片视频等等.下面演示如何上传form表单数据以及二 ...

  5. Struts2之Servlet文件上传详解

    声明:此次讲解文件上传使用的FileUpload组件和IO组件,都是Apache官网最新版,FileUpload版本号:commons-fileupload-1.3.1-bin.zip,IO版本号:c ...

  6. Asp无组件上传进度条解决方案

    http://webuc.net/dotey/archive/2004/07/22/1334.aspx 我还是一点一点用一个实例来说明的吧,客户端HTML如下.要浏览上传附件,我们通过<inpu ...

  7. Servlet文件上传

    1 文件上传的作用 例如网络硬盘!就是用来上传下载文件的. 在智联招聘上填写一个完整的简历还需要上传照片呢. 2 文件上传对页面的要求 上传文件的要求比较多,需要记一下: 必须使用表单,而不能是超链接 ...

  8. 使用commons-fileupload组件上传文件(随笔)

    1.第三方控件又被称为是第三方组件,使用第三方组件,可以避免大量编码,减少开发工作量及由于逻辑或算法造成的程序异常,从而降低开发成本,提高开发效率.由于第三方组件是第三方组织或者个人提供的,在开发时提 ...

  9. 关于ASP无组件上传在2003下出错

    关于ASP无组件上传在2003下出错.. 问题描述: asp无组件上传程序无法上传较大的文件"Request 对象 错误 ASP 0104 : 80004005",(大概大于100 ...

  10. 最快的ASP无组件上传类(4M只需10秒)0.96版

    <% '---------------------------------------------------------------------- '转发时请保留此声明信息,这段声明不并会影响 ...

最新文章

  1. python绘制简单直方图-python plotly绘制直方图实例详解
  2. JSP完全自学手册图文教程
  3. docker容器中安装vim 、telnet、ifconfig, ping命令
  4. java 方法 示例_Java集合syncedSortedSet()方法与示例
  5. linux防火墙开启某端口命令行,linux上防火墙 开启某个端口
  6. php hmacsha1计算,PHP HMAC_SHA1 算法 生成算法签名
  7. npm 安装axios和使用增删改查
  8. 阿里巴巴惠普_2019全球供应链25强榜单,中国仅一席,阿里巴巴首次上榜
  9. 持有数字货币的手机丢了,数字货币还能找回来吗?该注意些什么?
  10. paip.c++ qt __gxx_personality_sj0 __gxx_personality_v0问题的解决
  11. Miro Video Converter针对FFMPEG转换参数
  12. doc转docx文件会乱吗_我电脑里所有Word的doc格式都变成了docx格式.传Word文件给别人都打不开.请问为什么?...
  13. threejs包围盒的应用
  14. Codeforces1436 A. Reorder
  15. 串口发送+RAM+VGA传图
  16. 安卓日志系统初探(带你了解Android日志系统的概貌)
  17. ROS2教程(入门级):记录和回播数据
  18. 小程序为什么要办理ICP增值电信业务经营许可证
  19. 【023】Springboot+vue+mysql员工考勤管理系统(多角色登录、请假、打卡)(含源码、数据库、运行教程)
  20. 替代A4988的微型打印机驱动TMI8421国产电机驱动芯片

热门文章

  1. 云社区博客博客详情火瞳智慧通行助力疫情防控及安全出行
  2. 贪心算法 | 神秘电报密码——哈夫曼编码
  3. NL2SQL深度学习方法总结
  4. 转!!以太网方案设计
  5. 金融科技发展布局之服务渠道建设
  6. Mysql replace/insert into 插入修改数据
  7. mysql的配置文件(my.ini或者 my.cnf)所在位置
  8. shell编程——select语句东子破解
  9. c语言三角形的周长和面积公式,计算三角形的周长和面积
  10. LA 4670 Dominating Patterns