当前位置: 首页 > news >正文

搭建Tomcat(三)---重写service方法

目录

引入

一、在Java中创建一个新的空项目(初步搭建)

问题:

要求在tomcat软件包下的MyTomcat类中编写main文件,实现在MyTomcat中扫描myweb软件包中的所有Java文件,并返回“@WebServlet(url="myFirst")”中url内填写的值:

①main函数解析:

首先,main函数用try-catch做了异常处理:

指定包名:

 获取包下所有类的类对象:

扫描遍历:

二、搭建服务器端

在socket软件包的Server文件中编写:当存在客户端连接后,获取:

分析一下获取路径和请求方法的过程:

三、搭建

重写service方法:


引入

前面已经提到了,TomCat就是项目运行的环境,之前用到的Servlet文件都是通过eclipse中的tomcat容器来运行的,那么接下来在Java文件中去模拟这个过程。

在tomcat项目中创建Servlet项目。

一、在Java中创建一个新的空项目(初步搭建)

创建新项目后再去在目录下创建如下软件包Java类。

@WebServlet接口中代码:

package com.qcby.tomcat.webservlet;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(value= RetentionPolicy.RUNTIME)
@Target(value={ElementType.TYPE})
public @interface WebServlet {String url() default "";String className() default "";
}

myweb里面的MyFirstServlet等三个文件内调用@WebServlet接口,如下代码:
(以MyFirstServlet为例:)

package com.qcby.tomcat.myweb;import com.qcby.tomcat.HttpServlet.HttpServlet;
import com.qcby.tomcat.webservlet.WebServlet;@WebServlet(url="myFirst")
public class MyFirstServlet extends HttpServlet {}

问题:

要求在tomcat软件包下的MyTomcat类中编写main文件,实现在MyTomcat中扫描myweb软件包中的所有Java文件,并返回“@WebServlet(url="myFirst")”中url内填写的值:

MyTomcat内:

package com.qcby.tomcat;import com.qcby.tomcat.webservlet.WebServlet;import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;public class MyTomcat {public static void main(String[] args) {//扫描myweb这个包下的所有文件,并获取到它的@WebServlet中的url的值// get current dirtry {// 1. 扫描包路径 (com.wzh.tomcat.myweb)String packageName = "com.qcby.tomcat.myweb";List<Class<?>> classes = getClasses(packageName);   //通过getClasses()方法获取到了myweb这个包下面的所有类的类对象,并将其放到了类对象中// 2. 遍历所有类,检查是否有@WebServlet注解for (Class<?> clazz : classes) {if (clazz.isAnnotationPresent(WebServlet.class)) {// 3. 获取@WebServlet注解的值WebServlet webServlet = clazz.getAnnotation(WebServlet.class);System.out.println("类名: " + clazz.getName() + " | URL路径: " + webServlet.url());}}} catch (Exception e) {e.printStackTrace();//打印异常}}/*** 获取指定包下的所有类** @param packageName 包名,例如 "com.qcby.tomcat.myweb"* @return 类对象列表* @throws Exception*/private static List<Class<?>> getClasses(String packageName) throws Exception {List<Class<?>> classes = new ArrayList<>(); //将类文件封装进List中String path = packageName.replace('.', '/'); // 将包名转换为文件路径// 通过类加载器获取包的资源路径ClassLoader classLoader = Thread.currentThread().getContextClassLoader();Enumeration<URL> resources = classLoader.getResources(path);while (resources.hasMoreElements()) {URL resource = resources.nextElement();File directory = new File(resource.toURI());// 扫描文件夹下的所有类文件if (directory.exists()) {for (File file : directory.listFiles()) {if (file.getName().endsWith(".class")) {    //获得.class文件(.java->.class)此处获取的就是经过编译后的.class文件// 获取类的完整类名String className = packageName + "." + file.getName().replace(".class", "");classes.add(Class.forName(className));}}}}return classes;}
}

解析:

①main函数解析:
首先,main函数用try-catch做了异常处理:
  • try-catch块用于捕获并处理在扫描包和读取注解时可能发生的异常。
指定包名
  • String packageName = "com.qcby.tomcat.myweb";:定义了一个字符串变量packageName,它存储了要扫描的包名。
 获取包下所有类的类对象
  • List<Class<?>> classes = getClasses(packageName);
  • 这行代码调用了一个名为getClasses的方法(后面分析getClasses就知道这是一个获取类对象的方法),将这些获取的类对象写入到一个泛型中,方便后续遍历。
  • 调用getClasses方法,传入包名,获取该包下所有类的Class对象列表,并存储在classes变量中。
扫描遍历:

对获得并写入List中的每个文件进行isAnnotationPresent判断是否有@WebServlet注解:

注释:isAnnotationPresent是Java语言中的一种方法,它主要用于判断某个类、方法、变量等元素上是否存在指定类型的注解。】

  • 调用clazz.getAnnotation(WebServlet.class);时,Java虚拟机(JVM)会做以下几件事情:
  1. 检查clazz对象所代表的类上是否存在WebServlet注解的实例。
  2. 如果存在,返回这个注解的实例。
  3. 如果不存在,返回null

扫描获得后打印输出。 

那么分析完成main函数后,接着来分析一下getClases方法具体是怎么实现获取包中类信息的:

(详细参见注释:)

// 定义一个静态方法,用于获取指定包名下的所有类对象列表
private static List<Class<?>> getClasses(String packageName) throws Exception {List<Class<?>> classes = new ArrayList<>(); // 初始化一个ArrayList,用于存储找到的类对象// 将包名中的点(.)替换为文件路径中的斜杠(/),以构造资源路径String path = packageName.replace('.', '/');// 获取当前线程的类加载器,用于加载资源ClassLoader classLoader = Thread.currentThread().getContextClassLoader();// 通过类加载器获取指定路径下的所有资源(可能是目录或JAR文件中的条目)Enumeration<URL> resources = classLoader.getResources(path);// 遍历所有找到的资源while (resources.hasMoreElements()) {URL resource = resources.nextElement(); // 获取下一个资源URL// 注意:这里假设资源是一个文件系统上的目录,但这不是总是正确的,特别是当资源在JAR中时File directory = new File(resource.toURI()); // 将资源URL转换为File对象(这里存在潜在问题,对于JAR文件不适用)// 检查目录是否存在(对于文件系统上的资源有效)if (directory.exists()) {// 遍历目录下的所有文件和子目录for (File file : directory.listFiles()) {// 检查文件是否以".class"结尾,即是否是类文件(.java文件经过编译后的.class文件)if (file.getName().endsWith(".class")) {// 构造类的完整名称(包括包名)String className = packageName + "." + file.getName().replace(".class", "");// 使用反射加载类,并添加到类列表中// 注意:这里可能会抛出ClassNotFoundException,但在这个方法内部没有捕获处理classes.add(Class.forName(className));}}}}// 返回找到的类对象列表return classes;
}

二、搭建服务器端

在socket软件包的Server文件中编写:
当存在客户端连接后,获取:

package com.qcby.tomcat.socket;import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public static void main(String[] args) throws  Exception {// 1.打开通信端口   tomcat:8080   3306  ---------》进行网络通信ServerSocket serverSocket = new ServerSocket(8080);System.out.println("****************server start.....");//2.接受请求数据while (true){Socket socket = serverSocket.accept();  //--------------------->注意:此时监听网卡的是:主线程System.out.println("有客户进行了链接");new Thread(()->{//处理数据---------》数据的处理在于读和写try {handler(socket);} catch (Exception e) {e.printStackTrace();}}).start();}}public static void handler(Socket socket) throws Exception {//读取请求的数据InputStream inputStream = socket.getInputStream();requestContext(inputStream);}public static void requestContext(InputStream inputStream) throws IOException { //获取全部信息//将bit流转为文字信息int count = 0;while (count == 0){count = inputStream.available();}byte[] bytes = new byte[count];inputStream.read(bytes);String Context = new String(bytes);System.out.println(Context);//解析数据if(Context.equals("")){System.out.println("你输入了一个空请求");}else {String firstLine=Context.split("\\n")[0];String path=firstLine.split("\\s")[1];String method=firstLine.split("\\s")[0];System.out.println(path+" "+method);}}//获取第一个词和第二个词
//    public static void requestContext(InputStream inputStream) throws IOException {
//        StringBuilder sb = new StringBuilder();
//        int ch;
//        // 读取输入流直到遇到换行符或文件结束
//        while ((ch = inputStream.read()) != -1) {
//            if (ch == '\n') {
//                break; // 遇到换行符,停止读取
//            }
//            sb.append((char) ch); // 将读取的字符添加到StringBuilder中
//        }
//
//        String firstLine = sb.toString().trim(); // 获取第一行并去除首尾空格
//        if (firstLine.isEmpty()) {
//            System.out.println("你输入了一个空请求");
//        } else {
//            String[] words = firstLine.split("\\s+"); // 使用正则表达式按空格分割单词
//            if (words.length >= 2) {
//                System.out.println("第一个词是:" + words[0]);
//                System.out.println("第二个词是:" + words[1].substring(1));
//            } else {
//                System.out.println("第一行没有足够的词");
//            }
//        }
//    }}

分析一下获取路径和请求方法的过程:

  1. String firstLine = Context.split("\\n")[0];
    • 这行代码将 Context 字符串按照换行符(\n)进行分割,并取出分割后的第一个元素(即第一行)赋值给 firstLine
  2. String path = firstLine.split("\\s")[1];
    • 接着,这行代码将 firstLine 按照空白字符(包括空格、制表符等,\s 是一个正则表达式,用于匹配任何空白字符)进行分割,并取出分割后的第二个元素(索引为1)赋值给 path。这里假设路径是 firstLine 中方法名后面的第一个元素。
  3. String method = firstLine.split("\\s")[0];
    • 这行代码再次对 firstLine 按照空白字符进行分割,并取出分割后的第一个元素(索引为0)赋值给 method。这里假设方法名是 firstLine 中的第一个元素。
  4. System.out.println(path + " " + method);
    • 最后,这行代码打印出 path 和 method 的值,但顺序是先打印 path,后打印 method,中间用空格分隔。

三、搭建

【注:接口--接口就是用来定义方法的;实现接口类就必须实现接口中的方法;

抽象类中可以有抽象方法,也可以有具体方法;抽象类实现了接口,那么抽象类可以有选择性的实现接口中的方法】

重写service方法:

HTTP请求:

请求方法--Get,Post....等(主要是Get\Post方式)

而上述实现service方法,就是为了获取请求方法并且判断是Get还是Post请求(然后将请求送到doGet()/doPost()方法中)

在HttpServlet包中的方法HttpServlet抽象类中重写service方法:

首先创建request:

public class Request {private String path;private String method;public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}
}

并且修改Server来得到path和method:

import com.qcby.tomcat.Request.Request;import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server {//实例化Requestprivate static Request request = new Request();public static void main(String[] args) throws Exception {// 1.打开通信端口   tomcat:8080   3306  ---------》进行网络通信ServerSocket serverSocket = new ServerSocket(8080);System.out.println("****************server start.....");//2.接受请求数据while (true) {Socket socket = serverSocket.accept();  //--------------------->注意:此时监听网卡的是:主线程System.out.println("有客户进行了链接");new Thread(() -> {//处理数据---------》数据的处理在于读和写try {handler(socket);} catch (Exception e) {e.printStackTrace();}}).start();}}public static void handler(Socket socket) throws Exception {//读取请求的数据InputStream inputStream = socket.getInputStream();requestContext(inputStream);}public static void requestContext(InputStream inputStream) throws IOException { //获取全部信息//将bit流转为文字信息int count = 0;while (count == 0) {count = inputStream.available();}byte[] bytes = new byte[count];inputStream.read(bytes);String Context = new String(bytes);System.out.println(Context);//解析数据if (Context.equals("")) {System.out.println("你输入了一个空请求");} else {String firstLine = Context.split("\\n")[0];String method = firstLine.split("\\s")[0];String path = firstLine.split("\\s")[1];System.out.println(method + " " + path);//任何请求都会被打到这个类中,随后就会被解析//将解析后的数据(method和path放进申请的static的Request实例中--再被运输给其他需要的地方)request.setMethod(method);request.setPath(path);}}

即可通过这种方式让HttpServlet中的service方法得到Http请求的key和请求方法:

import com.qcby.tomcat.Request.Request;
import com.qcby.tomcat.socket.Server;public abstract class HttpServlet {/** 一定不能是抽象方法因为HttpServlet是要被实现的* 根据用户的请求,来调用不用的方法去处理*       GET请求   doGet()请求*       POST请求  doPost()请求** *///重写service()方法public  void service(Request request){//一定不能是抽象方法因为HttpServlet是要被实现的if(request.getMethod().equals("GET")){doGet(request);}else if(request.getMethod().equals("POST")){doPost(request);}}//去实现doGet--意味着所有继承HttpServlet抽象类的对象,都要去实现这两个方法public abstract void doGet(Request request);//去实现doPostpublic abstract void doPost(Request request);}

那么就意味着(继承抽象类的实例必须实现抽象类中的方法):

那么到这里,一个基础的、连贯的tomcat雏形就存在了:

四、Tomcat雏形

1.tomcat的server接收到一个请求:

发送请求:

2.被tomcat的server接收到:

 3.此时server内部创建了一个static的Request实例,并被HttpServlet里面的service接收:

通过if-else if判断后,被送到对应的doGet或doPost方法:

由于HttpServlet是抽象类,所以所有继承这个抽象类的实例都要实现抽象类中的所有方法: 

类似:

同时,由于doGet()和doPost()方法都是抽象方法,所以HttpServlet想要实现这些方法,就要去到各自的实例中,而这个实例究竟是哪一个,则就对应path中存的路径了。 

以上就是一个基础的雏形(关于tomcat是如何接收并初步处理一个请求的)

相关文章:

搭建Tomcat(三)---重写service方法

目录 引入 一、在Java中创建一个新的空项目&#xff08;初步搭建&#xff09; 问题&#xff1a; 要求在tomcat软件包下的MyTomcat类中编写main文件&#xff0c;实现在MyTomcat中扫描myweb软件包中的所有Java文件&#xff0c;并返回“WebServlet(url"myFirst")”中…...

跟着AI 学AI开发二,本地部署自己的Chat GPT

这里要安装的是Open Web UI &#xff0c;用一张架构图说明AI 前端与后端的关系。 之前的Python 的方法已经做过多次介绍&#xff0c;这里不做赘述。 顺序&#xff1a;1&#xff0c;Ollama。 2&#xff0c;Docker。 3&#xff0c;Open WebUI。 Ollama 安装下载地址&#xff1…...

XXE靶机漏洞复现通关

1.扫描XXE靶机的ip地址 将kali虚拟机和XXE靶机部署在同一局域网中&#xff0c;都采用NAT网络模式 搭建好后在kali终端中进行扫描XXE靶机的ip arp-scan -l 根据常识我们可以推断192.168.27.153为靶机的ip地址 2.访问靶机页面并扫描附录 进入页面后我们可以打开御剑扫描网页中…...

XS9922B 同轴RX芯片 四通道 多合一模拟高清解码器

XS9922B 是一款 4 通道模拟复合视频解码芯片&#xff0c;支持 HDCCTV 高清协议和 CVBS 标 清协议&#xff0c;视频制式支持 720P/1080P 高清制式和 960H/D1 标清制式。芯片将接收到的高清 模拟复合视频信号经过模数转化&#xff0c;视频解码以及 2D 图像处理之后&#xff0c;转…...

如何在谷歌浏览器中设置电子邮件通知

在现代互联网生活中&#xff0c;电子邮件已成为我们日常沟通的重要工具。为了更高效地管理邮件&#xff0c;您可以在谷歌浏览器中设置电子邮件通知。本文将详细介绍如何实现这一功能&#xff0c;并附带一些相关的Chrome使用技巧。&#xff08;本文由https://chrome.google64.cn…...

利用Java获取淘宝商品详情API接口的深入指南引言

引言 在电商领域&#xff0c;数据的价值日益凸显&#xff0c;尤其是在淘宝这样的大型电商平台上。淘宝商品详情API接口允许开发者通过编程方式获取商品的详细信息&#xff0c;这对于市场分析、竞争对手研究等方面至关重要。本文将详细介绍如何使用Java编写爬虫程序&#xff0c…...

3D工具显微镜的测量范围

一、测量尺寸范围 样品尺寸&#xff1a; 3D工具显微镜通常能够测量各种尺寸和形状的样品&#xff0c;从小至微米级别的微小结构到大至几厘米甚至更大的物体。具体的测量尺寸范围取决于显微镜的载物台大小、镜头焦距以及软件处理能力。测量精度&#xff1a; 3D工具显微镜的测量…...

WPF DataTemplate 数据模板

DataTemplate 顾名思义&#xff0c;数据模板&#xff0c;在 wpf 中使用非常频繁。 它一般用在带有 DataTemplate 依赖属性的控件中&#xff0c;如 ContentControl、集合控件 ListBox、ItemsControl 、TabControls 等。 1. 非集合控件中使用 <UserControl.Resources>&l…...

知道一个服务器IP地址,如何attack对方美国

CSDN提醒&#xff1a;亲爱的用户&#xff1a;你好&#xff01; 你的账号于2024-12-17 19:04:04在美国美国登录&#xff0c;登录IP为&#xff1a;47.238.159.124。若非本人登录&#xff0c;请及时修改密码。 莫名其妙显示美国登录了我的CSDN博客 卧槽 简介 服务器的IP地址是一…...

lettuce 默认情况下连接池参数不生效,源码分析

先说结论&#xff1a; 1.LettuceConnectionFactory 属性 shareNativeConnection 默认为true&#xff0c;要想连接池生效&#xff0c;该参数设置为false; 2.使用redisTemplate模版封装的pipeline没有意义&#xff0c;autoFlashCommands 默认为true;spring2.0开始默认使用lettuc…...

《宇宙机器人》提示错误弹窗“找不到d3dx9_43.dll”是什么原因?“d3dx9_43.dll缺失”怎么解决?

电脑游戏运行时常见问题解析&#xff1a;《宇宙机器人》提示“找不到d3dx9_43.dll”的解决之道 TGA2024落幕&#xff0c;年度最佳游戏——《宇宙机器人》&#xff0c;作为一名在软件开发领域深耕多年的从业者&#xff0c;我深知电脑游戏在运行过程中可能会遇到的各种挑战&…...

应用于项目的 C++单例基类的设计、实现与应用

文章目录 应用于项目的 C单例基类的设计、实现与应用一、引言二、单例基类的设计2.1 线程安全的单例基类2.2 局部静态变量的单例基类 三、单例基类的实现3.1 配置管理单例类 四、单例基类的应用4.1 多线程环境下的配置管理 五、深入探讨5.1 单例的线程安全问题5.2 单例的延迟初…...

Mongodb 启用认证

MongoDB 启用认证的完整指南 启用 MongoDB 的认证功能需要按照以下步骤进行设置&#xff1a; 检查 MongoDB 配置文件 在 MongoDB 配置文件中&#xff08;通常为 mongod.conf&#xff09;&#xff0c;需要启用认证功能。 修改配置文件 打开 mongod.conf 文件&#xff0c;找…...

QT:vlc出错处理及重新播放

这个问题一直想解决&#xff0c;昨天认真研究了一下。 要点 视频用的Widget不能重复使用&#xff0c;每次出错后&#xff0c;都要新建。 回调函数的处理。 代码1 关键在于libvlc_event_attach void VideoWidget::play() {libvlc_media_t* media;if (strstr(video_path, &…...

密钥管理系统在数据安全解决方案中的重要性

密钥管理系统在数据安全解决方案中占据着举足轻重的地位&#xff0c;其重要性体现在以下几个方面&#xff1a; 一、保障数据机密性 密钥管理系统通过生成、存储和管理加密密钥&#xff0c;确保了数据的机密性。这些密钥用于加密和解密数据&#xff0c;只有授权用户才能访问和…...

Docker的容器编排

目录 1. 什么是容器编排&#xff08;Docker Compose&#xff09;2. 容器编排的功能3. 容器编排文件&#xff08;docker-compose.yml&#xff09;的介绍3.1 文件语法版本3.2 文件基本结构及常见指令 4. Docker Compose命令详解4.1 Docker Compose命令清单4.2 命令格式和常见选项…...

Java Web项目部署教程简单实用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…...

推送本地仓库到远程git仓库

目录 推送本地仓库到远程git仓库1.1修改本地仓库用户名1.2 push 命令1.3远程分支查看 推送本地仓库到远程git仓库 删除之前的仓库中的所有内容&#xff0c;从新建库&#xff0c;同时创建一个 A.txt 文件 清空原有的远程仓库内容&#xff0c;重新创建一个新的仓库&#xff0c;…...

线性池学习

一、什么是进程&#xff1f;什么是线程&#xff1f; 1. 进程的定义 从操作系统的角度解释&#xff1a; 进程是操作系统分配资源和调度执行的基本单位。每个进程都是操作系统中一个独立的实体&#xff0c;拥有自己的内存空间、文件描述符、代码、数据等资源。进程是程序在执行…...

微积分复习笔记 Calculus Volume 2 - 4.3 Separable Equations

4.3 Separable Equations - Calculus Volume 2 | OpenStax...

前端项目部署方法

ngnix服务器部署 下载nignx&#xff0c;我下的是windows版本的 下载链接&#xff1a;[https://nginx.org/en/download.html](https://nginx.org/en/download.html) 解压文件 如果原本的80端口号被占用了&#xff0c;可以改为其他的端口号 可以点击nginx.exe文件启动nginx,它可能…...

Docker创建一个mongodb实例,并用springboot连接 mongodb进行读写文件

一、通过Docker 进行运行一个 mongodb实例 1、拉取镜像 docker pull mongo:5.0.5 2、创建 mongodb容器实例 docker run -d --name mongodb2 \-e MONGO_INITDB_ROOT_USERNAMEsalaryMongo \-e MONGO_INITDB_ROOT_PASSWORD123456 \-p 27017:27017 \mongo:5.0.5 3、进入容器&am…...

Android app反编译 攻与防

大概是2020年的时候&#xff0c;有一次&#xff0c;我们的竞争同行有另外一家公司要用我们的安卓软件app,拉了个群&#xff0c;告知他用一个软件多少钱&#xff0c;然后在群里发了一个我打包的apk包。结果就没有下文了。又过了一个月。我同事在那个要买我们apk的人的朋友圈&…...

ElasticSearch 简介

一、什么是 ElastcSearch&#xff1f; ElasticSearch 是基于 Lucene 的 Restful 的分布式实时全文搜索引擎。 1.1 ElasticSearh 的基本术语概念 index 索引 索引类似与 mysql 中的数据库&#xff0c;ES 中的索引是存储数据的地方&#xff0c;包含了一堆有相似结构的文档数据…...

Kerberos实验

kdc&#xff1a;192.168.72.163 客户端&#xff08;机器账户win10&#xff09;&#xff1a;192.168.72.159 用户&#xff1a;administrator 抓包&#xff1a;开机登录win10&#xff0c;使用administrator域用户凭据登录。 生成 Kerberos 解密文件 抓取 krbtgt 用户和 win1…...

Android之RecyclerView显示数据列表和网格

一、RecyclerView的优势 RecyclerView 的最大优势在于&#xff0c;它对大型列表来说非常高效&#xff1a; 默认情况下&#xff0c;RecyclerView 仅会处理或绘制当前显示在屏幕上的项。例如&#xff0c;如果您的列表包含一千个元素&#xff0c;但只有 10 个元素可见&#xff0…...

docker mysql挂载

在提供的 docker run 命令中&#xff0c;已经挂载了三个卷到 MySQL 容器中&#xff1a;日志目录、数据目录和配置目录。然而&#xff0c;还没有挂载一个包含 cube_admin.sql 文件的目录。要将 SQL 文件放入容器中并在 MySQL 中执行它&#xff0c;可以按照以下步骤操作&#xff…...

顺序表-递增有序表合并

两个递增有序表合并操作 题目&#xff1a; 将两个递增有序的顺序表 A 和 B 合并成一个新的递增有序顺序表 C。 思路&#xff1a; 使用三个索引 i, j, k 分别遍历顺序表 A, B 和合并后的顺序表 C。比较 A 和 B 当前索引指向的元素&#xff0c;将较小的元素放入 C 中&#xf…...

【Qt】qt安装

在工作一年之后&#xff0c;还是想做一个Qt的教程&#xff0c;遥想研一刚刚接触Qt&#xff0c;从0到1学习&#xff0c;没有什么参考书籍&#xff0c;网上的资料也不多&#xff0c;幸好Qt官方文档写得好&#xff0c;加上自己肯研究&#xff0c;才堪堪入门。 现在我想自己写一个…...

CXF WebService SpringBoot 添加拦截器,处理响应报文格式

描述 XFIRE升级CXF框架&#xff0c;但是对接的系统不做调整&#xff0c;这时候就要保证参数报文和响应报文和以前是一致的。但是不同的框架有不同的规则&#xff0c;想要将报文调整的一致&#xff0c;就需要用到拦截器拦截报文&#xff0c;自定义解析处理。 CXF框架本身就是支…...