Servlet【最复杂的hello world】

news2024/11/24 11:44:50

目录

一、Hello World

1.创建项目

2.引入依赖

3.创建目录

4.编写代码

4.1 继承 HttpServlet 父类,重写 doGet 方法

4.2 在 doGet 中编写代码,打印 hello world

4.3 给 HelloServlet 加上注解

4.4 完整代码

5.打包代码

6.部署

7.验证程序

二、简化部署方式

1.安装 Smart Tomcat 插件

2.配置 Smart Tomcat 插件

3.常见错误

4.简化的本质区别

三、servlet 中常见的问题

1. 404

2.405

3.500

4.出现“空白页面”

5.出现“无法访问此网站” 

四、Servlet API 详解

1. HttpServlet 

1.1 HttpServlet 方法

1.2 Servlet 的生命周期(面试题)


Tomcat 的基本使用是比较容易的:

1️⃣启动2️⃣把内容拷贝到 webapps3️⃣通过浏览器访问4️⃣使用 netstat 查看端口

我们要学习的重点是基于 Tomcat 进行编程!!

现在要写网站后端(HTTP 服务器),虽然可以重头写一个 HTTP 服务器,但是比较麻烦,Tomcat 已经完成这部分工作,并且 Tomcat 给我们提供了一系列 API,可以让我们在程序中直接调用;此时就可以省去一部分工作(HTTP 服务器肯定要根据 HTTP 协议解析请求报文,还要根据 HTTP 协议,构造响应报文,Tomcat 已经弄好了),更专注于业务逻辑了(写的程序要解决什么问题,是怎么解决的)

接下来我们将学习Tomcat 给提供了一系列 API 也叫 Servlet


一、Hello World

 在 java 中使用 Servlet,先从一个 hello world 着手❗❗注意,接下来见到的是咱们整个学习生涯中,最复杂的 hello world;需要经历七个步骤(对初学者非常不友好),但是这些步骤都是一个固定套路

1.创建项目

此处需要创建一个 maven 项目:maven 是一个构建工具,能帮助我们去构建、测试、打包一个项目;

 首次使用 maven 项目,IDEA 会从互联网上加载很多的依赖,需要花一定的时间,同时需要保证网络通畅

一个 maven 项目,首先会有一个 pom.xml 配置文件;这个文件描述了maven 项目的各个方面的内容;

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>servlet</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

一个 maven 创建好之后,IDEA 会帮助我们自动创建出一些目录:

2.引入依赖

Servlet 是 tomcat 提供的 api(不是标准库);标准库例如:String、Thread、List/Map、Scanner...只要装了 jdk,这些都是内置的;因此 servlet 是需要额外下载安装的(Tomcat 安装好了,是 Tomcat 运行时使用的,现在阶段是开发阶段,需要额外安装 Servlet 的 jar 包)

从中央仓库下载安装:Maven Repository: Search/Browse/Explore (mvnrepository.com)

在 pom.xlm 中添加 dependenceies 标签,把上边代码复制粘贴到这个标签中

<dependencies>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

 此时依赖就下载成功了;jar 包是被下载到本地的一个隐藏目录了,c 盘的用户里 .m2 文件中,找到 resposity打开,再找到 javax 寻找 servlet,里边有我们下载的 3.1.0 版本,只要下载好以后,后续使用就不必重新下载

3.创建目录

1️⃣创建 webapp 目录在 main 目录下, java 目录并列, 创建一个 webapp 目录 (注意, 不是 webapps).

2️⃣创建 WEB-INF 目录:然后在 webapp 目录内部创建一个 WEB-INF 目录

3️⃣创建一个 web.xml 文件

这里的目录结构、目录位置、目录名字务必保证一字不差❗❗

web.xml 是给 tomcat 看的:tomcat 从 webapps 目录中加载 webapp,就是以 web.xml 为依据的

4️⃣编写 web.xml

web.xml 中拷贝以下代码. 具体细节内容我们暂时不关注.

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
</web-app>

4.编写代码

在 java 项目下创建一个类 HelloServlet:

import javax.servlet.http.HttpServlet;
public class HelloServlet extends HttpServlet {
}

创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确,尝试刷新

4.1 继承 HttpServlet 父类,重写 doGet 方法

public class HelloServlet extends HttpServlet {

    //继承 HttpServlet 父类,重写 doGet 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

  • HttpServletRequest 表示 HTTP 请求:Tomcat 收到请求把这个请求按照 HTTP 协议的格式,解析成了对象(这个对象里的属性就是 HTTP 中的各个信息)也就是说 Tomcat 按照 HTTP 请求的格式把 字符串 格式的请求转成了一个 HttpServletRequest 对象. 后续想获取请求中的信息(方法, url, header, body ) 都是通过这个对象来获取.
  • HttpServletResponse 表示 HTTP 响应:此处响应对象是一个空的对象,需要在 doGet 中设置响应的一些数据(例如响应的 body、header和状态码等...,只要把属性设置到这个 resp 对象中,Tomcat 就会自动根据响应对象,构造一个 HTTP 响应字符串,通过 socket 返回给客户端
  • 重写 doGet 方法:这个方法不是手动调用,而是 Tocmat 在合适的时机自动调用的

这种代码的编写方式,就算“框架”(framework) 

1️⃣注释掉 super.doGet(req, resp);

点进父类的 doGet 可以看到这里直接返回一个错误页面,如果步干掉就返回了一个 405

4.2 在 doGet 中编写代码,打印 hello world

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {

    //继承 HttpServlet 父类,重写 doGet 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);//调用父类的doGet,需要注释掉这个代码

        //这里在服务器的控制台中,打印了字符串(服务器看到了,客户端没看到)
        System.out.println("hello world");
        //这个是给 resp 的 body 写入 hello world 字符串,这个内容就会被 HTTP 响应返回给浏览器,显示到浏览器页面上
        resp.getWriter().write("hello wprld");
    }
}
  • resp.getWriter() :得到了 resp 内部持有的 Writer 对象(字符流),既然是字符流就可以使用 write 来写,此处写的数据就是写到 http 响应的body中 Tomcat 会把整个响应转成字符串, 通过 socket 写回给浏览

4.3 给 HelloServlet 加上注解

@WebServlet("/hello")

4.4 完整代码

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("/hello")
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {

    //继承 HttpServlet 父类,重写 doGet 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);//调用父类的doGet,需要注释掉这个代码

        //这里在服务器的控制台中,打印了字符串(服务器看到了,客户端没看到)
        System.out.println("hello world");
        //这个是给 resp 的 body 写入 hello world 字符串,这个内容就会被 HTTP 响应返回给浏览器,显示到浏览器页面上
        resp.getWriter().write("hello world");
    }
}

上述代码就已经写完了,不需要 main 方法;上述代码并非独立运行,而是把这个代码插入到 Tomcat 中,由 Tomcat去调用的

5.打包代码

我们的程序不能独立运行,而是必须放到 Tomcat 上运行(部署),部署的前提是打包

  • 对于一个规模比较大的项目,里边就会包含很多的 .java 文件,进一步就会产生很多的 .class,所以把这些 .class 答案宝成一个压缩包再进行拷贝,是比较科学的
  • 在 java 中使用的压缩包为 jar(普通的 java 程序)、war(部署给 tomcat 的程序)
  • war 和 jar 本质上没有区别,都是把一堆 .class 文件给打包进去,但是 war 包是属于 tomcat 的专属格式,里边会有一些特定的目录结构和文件,比如 web.xml,后续 tomcat 就要识别这些内容来加载 webapp

如何使用 maven 进行打包操作❓❓打开 maven 窗口 (般在 IDEA 右侧就可以看到 Maven 窗口, 如果看不到的话可以通过 菜单 -> View -> Tool Window -> Maven 打开),然后展开 Lifecycle , 双击 package 即可进行打包

 打包的操作:

  1. 检查代码中是否存在一些依赖,依赖是否下载好(这个事情都是 maven 负责的,之前引入了 serlvet 的依赖)
  2. 把代码进行编译,生成一堆 .class 文件
  3. 把这些 .class 文件,以及 web.xml 按照一定的格式进行打包

为了打出来的是 war 包,需要调整 pom.xml,描述打包生成的包格式:pom.xml 中,在 project 顶级标签下方,写一个 <packing> 标签,描述打包的类型是 war;此处也可以修改打包的文件名

 此时重新打包,就看到了一个 war 包

 打好的 war 包,就是一个普通的压缩包,收可以使用解压工具(WINRAR)打开,看到里边的内容,但是并不需要手动解压缩,直接把整个 war 交给 tomcat,tomcat能够自动的解压缩

6.部署

把打好的 war 包 ,拷贝到 tomcat 的 webapps 目录中;重新打开 tomcat 的 bin 文件 的 startup.bat ,此时就已经部署完成

这个乱码表示 hello_servlet.war 已经部署完成,只不过日志乱码;乱码是因为拜尼马方式不一样,tomcat 使用的编码是 utf8,而 windows 的 cmd 编码是 gdk 

7.验证程序

doGet : 遇到 GET 请求,就可以执行 doGet,前提是 请求的 URL 的路径要匹配

浏览器 url 中输入(hello_servlet表示一级路径、hello表示二级路径):127.0.0.1/8080/hello_servlet/hello

此处的路径是分两级:

  1. hello_servlet:称为 Context Path / Application Path,标识了一个 webapp(也就是 webapp 的目录名 / war 包名)一个 Tomcat 上可以多个webapp
  2. hello:称为 Servlet Path,标识当前请求要调用哪个 Servlet 类的 doGet(一个 webapp 中可以有多个 Servlet,自然就有多个 doGet),此处的 hello 是根据注解来的

二、简化部署方式

上述 hello word 的程序也可以简化:把 5(打包代码) 和 6(部署) 简化成一键式完成,我们使用 IDEA 中的 Smart Tomcat 插件来完成这个过程

IDEA 功能非常多,非常强大,凡是及时如此,IDEA也无法做到“面面俱到”,为了支持这些特定的、小众的功能就引入了“插件体系”,插件可以视为对IDEA原有功能的扩充,程序猿可以按需使用;同理很多这样的程序都引入了插件体系,例如 VSCode

1.安装 Smart Tomcat 插件

1️⃣打开 file,继续打开 Settings

2️⃣选择 Plugins, 选择 Marketplace, 搜索 "tomcat", 点击 "Install"

使用 Smart Tomcat 插件,可以简化打包部署工作(社区版使用的方法);IDEA 专业版来说,内置了 Tomcat Server(这个东西用起来更复杂,还是建议使用 smart tomcat)

2.配置 Smart Tomcat 插件

首次使用,需要配置插件:

1️⃣点击右上角的 "Add Configuration";选择左侧的 "Smart Tomcat"

2️⃣在这里 Name 可以改也可以不改,我改为了 hello servlet;并且把 Tomcat server 的路径改为 原本 Tomcat 安装的路径

3️⃣修改 Content path:访问程序的两级路径中的第一级 (我的第一级目录是 hello_servlet)

  • 特殊规则:
  • 如果我们的程序是拷贝 war 包到 webapps 中运行,此时 Context Path 是 war 包名字
  • 如果我们的程序是使用 Smart Tomcat 运行,Context Path 是在上述配置中,手动设置的,默认是项目名字 

4️⃣运行代码

此时右上角的 "Add Configuration"旁边有个三角形,点击即可运行

此时 Tomcat 的日志就在 IDEA 中就显示了,不会再单独弹出 cmd,因此乱码问题就解决了

3.常见错误

初学者可能出现以下错误问题:

 端口被占用:Tomcat 启动需要绑定两个端口,8080(业务端口)、8005(管理端口);一个端口号只能呗一个进程绑定;此时我们直接把 bin 文件打开的 startup.bat 关闭即可

 此时就运行成功了

以上地址是提示 Tomcat 如何访问(localhost == 127.0.0.1),不要点,点了就是 404 ;因为这个路径只有 Context Path,没有 Servlet Path

4.简化的本质区别

smart tomcat 的运行方式和之前拷贝到 webapps 中,是存在本质的

  • smart tomcat 使用了 Tomcat 另外一种运行方式;在运行 Tomcat 的时候,通过特定的参数来指定 Tomcat 加载某个特定目录中的 webapp

因此,上述过程既不会打包也不会拷贝;这是开发和调试阶段使用的方式,如果是部署到生产环境,还的是打 war 包拷贝 

三、servlet 中常见的问题

1. 404

404 表示浏览器访问的资源在服务器上不存在

1️⃣请求的路径写错了

例如刚刚上述的地址( Tomcat 如何访问):路径只有 Context Path,没有 Servlet Path 或者路径只有 Servlet Path,没有 Context Path

 再例如:Servlet Path 写的和 URL 不匹配,也会出现 404

2️⃣路径写对了,但是 war 包没有被正确加载

web.xml 写错了 或者 如果有两个 Servlet 的 Servlet Path 相同,会导致 war 包不能被正确加载(如果没正确加载,会在日志中有提示)

2.405

405 表示 对应 HTTP 请求方法没有实现

1️⃣发送请求的方法和代码不匹配:比如代码写的是 doPost,而发送的请求是 GET 请求

2️⃣ 方法和代码匹配,但是忘记消掉 super.doXXX

3.500

500 往往是 Servlet 代码中抛出的异常导致:需要观察异常调用栈

修改 HelloServlet 代码:

@WebServlet("/hello")
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {

    //继承 HttpServlet 父类,重写 doGet 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);//调用父类的doGet,需要注释掉这个代码

        String s = null;
        System.out.println(s.length());
        //这里在服务器的控制台中,打印了字符串(服务器看到了,客户端没看到)
        System.out.println("hello world");
        //这个是给 resp 的 body 写入 hello world 字符串,这个内容就会被 HTTP 响应返回给浏览器,显示到浏览器页面上
        resp.getWriter().write("hello world");
    }
}

4.出现“空白页面”

修改代码:去掉 resp.getWritter().write() 操作

@WebServlet("/hello")
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {

    //继承 HttpServlet 父类,重写 doGet 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);//调用父类的doGet,需要注释掉这个代码

        //这里在服务器的控制台中,打印了字符串(服务器看到了,客户端没看到)
        System.out.println("hello world");
        //这个是给 resp 的 body 写入 hello world 字符串,这个内容就会被 HTTP 响应返回给浏览器,显示到浏览器页面上
        //resp.getWriter().write("hello world");
    }
}

重启服务器,访问服务器可以看到一个空白页面

5.出现“无法访问此网站” 

停止 Tomcat,然后访问服务器就可以看到“无法访问此网站”

四、Servlet API 详解

虽然 Servlet API 有很多,重点掌握三个类即可

  1. HttpServlet
  2. HttpServletRequest
  3. HttpServletResponse

1. HttpServlet 

Servlet 程序都是要继承一个 HttpServlet 类

 因此我们就需要知道哪些方法是能够被重写的,也就是 HttpServlet 中有什么方法,都是做什么的

1.1 HttpServlet 方法

方法名称调用时机
doGet收到 GET 请求的时候调用(由 service 方法调用)
doPost收到 POST 请求的时候调用(由 service 方法调用)
doPut/doDelete/doOptions/...
收到其他请求的时候调用 ( service 方法调用 )
init
HttpServlet 实例化之后被调用一次
destroy
HttpServlet 实例不再使用的时候调用一次
service
收到 HTTP 请求的时候调用

1️⃣init 方法

HttpServlet 被实例化之后会调用一次(只调用一次)(首次匹配请求的时候,会被调用),使用这个方法来做一些初始化相关的工作

@WebServlet("/hello")
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("打印 init");
    }

    //继承 HttpServlet 父类,重写 doGet 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);//调用父类的doGet,需要注释掉这个代码

        //这里在服务器的控制台中,打印了字符串(服务器看到了,客户端没看到)
        System.out.println("hello world");
        //这个是给 resp 的 body 写入 hello world 字符串,这个内容就会被 HTTP 响应返回给浏览器,显示到浏览器页面上
         resp.getWriter().write("hello world");
    }
}

启动服务器,此时并没有实例化对象,并没有执行到“打印 init”:

 而是服务器收到一个匹配的请求的时候会被调用(能够调用 doGet 的请求):

 此时就执行了 “打印 init”;上述 127.0.0.1:8080/hello_servlet/hello 这个请求会触发 HelloServlet 类的 doGet 的执行,就会调用 doGet 之前,先调用 init;❗❗注意,只会调用一次

 因此这个方法来做一些初始化相关的工作

2️⃣destroy 方法

这个方法是 webapp 被卸载(被销毁之前)执行一次;用来做一些收尾工作

destroy 是否能被执行,是不靠谱的❓❓❓


  1. 如果是通过 8005 管理端口来停止服务器,此时 destroy 能执行
  2. 如果是直接杀死进程的方式停止服务器,此时 destroy 执行不了

所以不建议使用 destroy

 ❓❓8005 管理端口是什么

Tomcat 启动会使用两个端口:8080业务端口(工作)、8005管理端口(生活)

3️⃣service 方法

每次收到路径匹配的请求都会执行;doGet 和 doPost 其实是在 service 中被调用的,一般不会重写 service,只是重写 doXXX 就行了

@WebServlet("/hello")
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        //HttpServlet 被实例化之后会调用一次(只调用一次)(首次匹配请求的时候,会被调用),使用这个方法来做一些初始化相关的工作
        System.out.println("打印 init");
    }
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("执行 service");
    }

    //继承 HttpServlet 父类,重写 doGet 方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doGet(req, resp);//调用父类的doGet,需要注释掉这个代码

        //这里在服务器的控制台中,打印了字符串(服务器看到了,客户端没看到)
        System.out.println("hello world");
        //这个是给 resp 的 body 写入 hello world 字符串,这个内容就会被 HTTP 响应返回给浏览器,显示到浏览器页面上
         resp.getWriter().write("hello world");
    }
}

4️⃣doGet、doPost、doPut...方法:

@WebServlet("/hello")
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("doPost");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("doPut");
    }
}

启动服务器,使用 Postman 构造请求:

❗❗注意:

@WebServlet("/hello")
//创建一个类 HelloServlet , 继承自 HttpServlet(来自于从 maven 中央仓库下载的 jar 包);如果提示不出来说明 jar 包没有加载正确

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("这是一个 doGet 请求");
    }
}

 ???说明是乱码了


  • 数据返回的时候,自身是一种编码方式(IDEA 里边写一个字符串,默认都是 UTF8)
  • 浏览器在展示的时候,也有一种编码方式(根据系统的默认编码——windows 10 简体中文版,默认编码是 gdk)

如果上述两个方式对不上,就会乱码

解决方法:加入 resp.setContentType("text/html; charset=utf8"); 代码代表:告诉浏览器返回的数据是 utf8

1.2 Servlet 的生命周期(面试题)

生命周期:什么阶段在做什么事

  1. init 是初始情况下调用一次
  2. destroy 是结束之前调用一次
  3. service 是每次收到路径匹配的请求都调用一次

🌈这节课我们讲解了 Servlet 的使用,写了有史以来最复杂的 Hello World,并且解决了写代码出现的问题,而且介绍了三种重要的 Servlet API 中的 HttpServlet,下节课我们将介绍 HttpServletRequest 、 HttpServletResponse以及代码示例

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

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

相关文章

分享一个403界面给大家

先看效果图&#xff08;说明&#xff1a;小鬼影会飘来飘去&#xff0c;长时间停留会有小惊喜&#xff0c;具体大家跑一下就知道&#xff09;&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UT…

depends_on 解决 docker 容器依赖问题

如果你经常使用docker-compose启动服务的话&#xff0c;可能会遇到下面的问题&#xff1a;服务 B 依赖服务 A&#xff0c;需要服务 A 先启动&#xff0c;再启动服务 B 举个例子&#xff0c;在部署 kafka 集群的时候&#xff0c;需要启动两个kafka&#xff0c;并使用zookeeper做…

基于云计算和物联网技术开发的智慧校园云平台源码

智慧校园系统是利用物联网和云计算&#xff0c;强调对教学、科研、校园生活和管理的数据采集、智能处理、为管理者和各个角色按需提供智能化的数据分析、教学、学习的智能化服务环境。它包含“智慧环境、智慧学习、智慧服务、智慧管理”等层面的内容。 文末获取联系 它描绘的是…

准备搞个大动作!

目前我们的会员群的同学越来越多&#xff0c;然后我们提供的内容已经从起步篇&#xff0c;趣味篇&#xff0c;工具篇到高级篇了。但是到了高级篇很多内容都跟编程相关&#xff0c;有一点门槛&#xff0c;如果单单看文字是肯定无法满足大家的需求。为了更好的服务大家&#xff0…

跃升数字生产力,九州云受邀出席闵行国际人才月

5月22日&#xff0c;由闵行人才工作领导小组办公室指导、中共闵行区马桥镇委员会及闵行区马桥镇人民政府主办、上海人工智能研究院协办的首届“大零号湾”国际人才月马桥人工智能周成功召开。 本届大会以“AI才共赢 智敬未来”为主题&#xff0c;探讨科技创新的最新动态和趋势&…

如何使用Linux Top命令

Linux中的top命令允许您监视当前正在运行的进程及其使用的系统资源。作为系统管理员&#xff0c;它可能是工具箱中最有用的工具&#xff0c;特别是如果您知道如何使用它的话。所有Linux发行版都预装了top实用程序。通过这个交互式命令&#xff0c;您可以自定义如何浏览进程列表…

电脑蓝屏该如何给电脑重装系统

电脑蓝屏问题是让人头疼的常见故障之一&#xff0c;而重装系统是解决蓝屏问题的有效方法。本文将为您详细介绍如何在电脑蓝屏的情况下进行系统重装&#xff0c;轻松摆脱蓝屏困扰。 工具/原料&#xff1a; 系统版本&#xff1a;windows10系统 品牌型号&#xff1a;华为MateBoo…

常见的黄金期货交易风险包含哪些内容?

黄金期货交易作为受市场欢迎的投资理财方式&#xff0c;兼具高风险和高收益并存的特性。黄金期货交易风险也同样存在&#xff0c;那常见的黄金期货交易风险包含哪些内容&#xff1f; 黄金期货交易风险一、市场风险 投资者在黄金期货交易中&#xff0c;主要的风险来源于市场价格…

快来试试!免费用上GPT-4 !!!

GPT-4 简介 GPT-4是OpenAI上个月推出的最新人工智能语言模型&#xff0c;它可以根据给定的文本或关键词生成各种类似于人类语言甚至超越人类语言的文本&#xff0c;例如文章、故事、诗歌、代码、对话等。 GPT-4拥有1750亿个参数&#xff0c;是目前最大的语言模型之一&#xf…

红米8a,刷机到安卓调用之路

什么是BL锁&#xff1f; https://baijiahao.baidu.com/s?id1614459630284912892&wfrspider&forpc bl锁简单来说&#xff0c;就是厂商为了自己的目的&#xff0c;为了避免刷机&#xff0c;而人为设置的一道障碍&#xff0c;我的第一步就需要等待168小时&#xff0c;经…

随想011:关于编程

1945 年时&#xff0c;刚开始有计算机&#xff0c;那时候使用二进制数编程到了40年代末期&#xff0c;出现了汇编器&#xff0c;可以自动将汇编程序转换为二进制数序列1951 年 Grace Hopper 发明了编译器1957 年&#xff0c;Fortran&#xff0c;第一个高级语言&#xff0c;首次…

npm 无法下载 win32-x64-72_binding.node

使用npm安装node-sass时&#xff0c;其依赖了win32-x64-72_binding.node&#xff0c;但是一直提示“cannot download http://xxx/win32-x64-72_binding.node”&#xff0c;有两种方案可以解决&#xff0c;一种是在有私服的情况下&#xff0c;可以通过设置 SASS_BINARY_SITE 环境…

百度云原生数据库GaiaDB的HTAP与多地多活技术实践

​摘要&#xff1a;云原生数据库在使用存算分离技术后&#xff0c;可以在完全兼容MYSQL协议和语法的情况下&#xff0c;极大提升单实例所能承载的数据规模与吞吐能力上限。但除了对客户端兼容外&#xff0c;对整个数据生态&#xff08;地域容灾&#xff0c;数据分析&#xff0c…

javaWebssh旅游论坛系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh旅游论坛系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Mye…

机器学习中四类进化算法的详解(遗传算法、差分进化算法、协同进化算法、分布估计算法)

1、遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09; GA算法原理 首先我们来介绍进化算法的先驱遗传算法&#xff0c;遗传算法&#xff08;Genetic Algorithm&#xff0c;简称GA&#xff09;是一种最基本的进化算法&#xff0c;它是模拟达尔文生物进化理论的…

牛牛截图控件与利洽远程控制产品升级-支持证书自动升级

今天我们来聊一聊浏览器控件的一个痛点&#xff01;看看我们是如何解决他的。 背景信息 目前市面上存在多种浏览器&#xff0c;IE、Chrome、Firefox、Edge以及一众国产浏览器&#xff0c;这些浏览器中&#xff0c;IE支持ActiveX&#xff0c;部分国产浏览器支持npapi&#xff…

vscode开发小程序项目并在微信开发者工具运行

需求&#xff1a;vscode开发uniapp之后在微信开发者工具运行&#xff0c;更改的时候微信开发者也同步更改 1.创建小程序命令 这里的uniapp-vue是项目名称&#xff0c;不能大写 vue create -p dcloudio/uni-preset-vue uniapp-vue 2.选择uni-app模版 有几种模版选择&#x…

Ubuntu TDengine 集成 EMQX 通过规则引擎实现设备数据直接入库

背景 曾使用过 IoTDB 自带的 MQTT Broker 实现了设备数据入库&#xff0c;那么使用 TDengine 时&#xff0c;我们可以借助 EMQX &#xff08;一款优秀的国产开源 MQTT Broker &#xff09;的规则引擎结合 TDengine 的 RESTful API 完成设备数据的路由与入库。 用到的工具 TD…

PAI-Diffusion中文模型全面升级,海量高清艺术大图一键生成

作者&#xff1a;段忠杰&#xff08;终劫&#xff09;、刘冰雁&#xff08;伍拾&#xff09;、汪诚愚&#xff08;熊兮&#xff09;、黄俊&#xff08;临在&#xff09; 背景 以Stable Diffusion模型为代表&#xff0c;AI生成内容&#xff08;AI Generated Content&#xff…

鸿蒙Hi3861问题解决-[OHOS ERROR] clang not found, install it please

一、简介 在使用DevEco进行编译时出现[OHOS ERROR] clang not found, install it please问题&#xff0c;导致编译失败&#xff0c;这里做个问题记录。 二、解决 这种问题其实还是工具链安装不全造成的。 安装gn 这里用的是VSCode DevEco组件&#xff0c;里边包含了gn组件的安…