Spring Web MVC的入门学习(一)

news2024/11/26 18:54:08

目录

一、什么是 Spring Web MVC

1、MVC 定义

二、学习Spring MVC

1、项目准备

2、建立连接

2.1 @RequestMapping 注解的学习

2.2 @RequestMapping 使用

3、请求

 3.1 传递单个参数

3.2 传递多个参数

3.3 传递对象

3.4 后端参数重命名(后端参数映射)

3.5 传递数组

3.6 传递集合

3.7 传递JSON数据

1、JSON语法

2、JSON字符串和Java对象互转

3、JSON优点

4、传递JSON对象

3.8 获取URL中参数@PathVariable

3.9 上传文件@RequestPart


 

一、什么是 Spring Web MVC

官方对于 Spring MVC 的描述是这样的:

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的 正式名称“Spring Web MVC”来自其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC".

什么是Servlet呢?

Servlet 是⼀种实现动态页面的技术. 准确来讲Servlet是⼀套 Java Web 开发的规范,或者说是⼀套 Java Web 开发的技术标准. 只有规范并不能做任何事情,必须要有人去实现它. 所谓实现 Servlet 规 范,就是真正编写代码去实现 Servlet 规范提到的各种功能,包括类、方法、属性等.
Servlet 规范是开放的,除了 Sun 公司,其它公司也可以实现 Servlet 规范,目前常见的实现了Servlet 规范的产品包括 Tomcat、Weblogic、Jetty、Jboss、WebSphere 等,它们都被称为"Servlet 容器". Servlet 容器用来管理程序员编写的 Servlet 类.

总之,我们可以知道:Spring Web MVC 是⼀个 Web 框架. 简称 “Spring MVC”。

1、MVC 定义

MVC 是 Model View Controller 的缩写,它是软件工程中的⼀种软件架构设计模式,它把软件系统分为 模型、视图和控制器 三个基本部分。

View(视图):指在应用程序中专门用来与浏览器进行交互,展示数据的资源.
Model(模型) :是应用程序的主体部分,用来处理程序中数据逻辑的部分.
Controller(控制器):可以理解为⼀个分发器,用来决定对于视图发来的请求,需要用哪⼀个模型 来处理,以及处理完后需要跳回到哪⼀个视图,即用来连接视图和模型
MVC 是⼀种架构设计模式, 也⼀种思想, 而 Spring MVC 是对 MVC 思想的具体实现 . 除此之外, Spring MVC还是⼀个Web框架.
总结来说, Spring MVC 是⼀个实现了 MVC 模式的 Web 框架 .

二、学习Spring MVC

既然 Spring MVC 是 Web 框架, 那么当用户在浏览器中输入了 url 之后,我们的 Spring MVC 项目就可以感知到用户 的请求, 并给予响应。
学习 Spring MVC,其实就是学习如何通过浏览器和用户程序进行交互
主要分以下三个方面:
  1. 建立连接:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调用到我们的 Spring 程序。
  2. 请求:用户请求的时候会带⼀些参数,在程序中要想办法获取到参数, 所以请求这块主要是 获取参数的功能.
  3. 响应:执行了业务逻辑之后,要把程序执行的结果返回给用户, 也就是响应。

1、项目准备

我们要创建一个Spring MVC 项目,和 Spring Boot 创建项目相同,在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。
创建项目时, 勾选上 Spring Web 模块即可,如下图所示:

2、建立连接

在 Spring MVC 中使用 @RequestMapping 来实现 URL 路由映射 ,也就是 浏览器连接程序的作⽤。

我们通过一个简单的代码来实现一下:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class demo {
    @RequestMapping("/hello")
    public String getHello() {
        return "Hello,Spring MVC";
    }
}

 然后来访问: http://127.0.0.1:8080/hello, 就可以看到程序返回的数据了,如图:

2.1 @RequestMapping 注解的学习

@RequestMapping 是 Spring Web MVC 应用程序中最常被用到的注解之⼀, 它是用来注册接口的路由映射的.
表示服务器收到请求时, 路径为 /hello 的请求就会调用 getHello 这个方法的代码。
路由映射: 当用户访问⼀个 URL 时, 将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射.

 那么对于程序中加的 @RestController 注解有什么作用?

 我们把 @RestController 去掉, 再来访问⼀次:

 可见,报错了404,我们找不到该页面。所以@RestController 注解也很重要,不能不加。

一个项目中, 会有很多类, 每个类可能有很多的方法, Spring程序怎么知道要执行哪个方法呢?

Spring会对所有的类进行扫描, 如果类加了注解@RestController, Spring才会去看这个类里面的方法有没有加 @RequestMapping 这个注解。

2.2 @RequestMapping 使用

@RequestMapping 既可修饰类,也可以修饰方法 ,当修饰类和方法时,访问的地址是类路径 +方法路径.
@RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息
@RequestMapping标识⼀个方法:设置映射请求的请求路径的具体信息

看如下代码:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/test")
@RestController
public class demo {
    @RequestMapping("/hello")
    public String getHello() {
        return "Hello,Spring MVC";
    }
}

访问地址:http://127.0.0.1:8080/test/hello

 

这里我们注意一下:

@RequestMapping 的URL 路径最前面加不加 / (斜杠)都可以, Spring程序启动时, 会进行判断, 如果 前面没有加 / , Spring会拼接上⼀个 /。
如:
上面代码中 @RequestMapping("/test") 我们可以写为 @RequestMapping("test")
通常情况下,我们加上 / 。
@RequestMapping 的URL路径也可以是多层路径, 最终访问时, 依然是 类路径 + 方法路径
如:
@RequestMapping("/user/m1")
@RestController
public class UserController {
   @RequestMapping("/say/hi")
   public String sayHi(){
       return "hello,Spring MVC";
   }
}
访问路径: http://127.0.0.1:8080/user/m1/say/hi

 

@RequestMapping 既支持Get请求, 又支持Post请求. 同理, 也支持其他的请 求方式.

 

3、请求

访问不同的路径, 就是发送不同的请求. 在发送请求时, 可能会带⼀些参数, 所以学习Spring的请求, 主要 学习如何传递参数到后端以及后端如何接收.

 3.1 传递单个参数

 接收单个参数, 在 Spring MVC 中直接用方法中的参数就可以,比如以下代码:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/m1")
    public String method1(String name){
        return "接收到参数name:"+ name;
    }
}
使用浏览器发送请求并传参:
http://127.0.0.1:8080/param/m1?name=spring

 由响应的结果,可以看到, 后端程序正确拿到了name参数的值.

Spring MVC 会根据方法的参数名, 找到对应的参数, 赋值给方法

如果参数名不⼀致, 是获取不到参数的.
比如请求URL: http://127.0.0.1:8080/param/m1?name1=spring
响应结果:

注意:

使用基本类型来接收参数时, 参数必须传(除boolean类型), 否则会报500错误。
类型不匹配时, 会报400错误.

我们以下面代码为例,来测试一下:

@RequestMapping("/m1/int")
public String method1GetInt(int age) {
    return "接收到参数age:"+age;
}

1、正常传递参数

http://127.0.0.1:8080/param/m1/int?age=1
浏览器响应情况:

2、不传递age参数

 http://127.0.0.1:8080/param/m1/int

浏览器响应情况:

报500 错误,可见 使用基本类型来接收参数时, 参数必须传(除boolean类型), 否则会报500错误。

3、传递参数类型不匹配

http://127.0.0.1:8080/param/m1/int?age=abc
浏览器响应情况:

报400 错误,可见 传递的参数类型不匹配时, 会报400错误.

对于包装类型, 如果不传对应参数,Spring 接收到的数据则为null。

3.2 传递多个参数

接收多个参数, 和接收单个参数⼀样, 直接使用方法的参数接收即可. 使用多个形参.

 

@RequestMapping("/m2")
public Object method2(String name, String password) {
    return "接收到参数name:" + name + ", password:" + password;
}
使用浏览器发送请求并传参:
http://127.0.0.1:8080/param/m2?name=zhangsan&password=123456

 

 可以看到, 后端程序正确拿到了name和password参数的值。

当有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的因此 参数的位置是不影响后端获取参数的结果.

3.3 传递对象

如果参数比较多时, 方法声明就需要有很多形参. 并且后续每次新增一个参数, 也需要修改方法声明。 我们可以把这些参数封装为⼀个对象。 Spring MVC 也可以自动实现对象参数的赋值
比如 Student 对象:
public class Student {
    private Integer id;
    private String name;
    private int age;

    public Student(){

    }
    public Student(Integer id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}

传递对象代码实现:

@RequestMapping("/m3")
public Object method3(Student student){
    return student.toString();
}
使用浏览器发送请求并传参:
http://127.0.0.1:8080/param/m3? id=5&name=zhangsan&age=20

 可以看到, 后端程序正确拿到了Student对象里各个属性的值。

Spring 会根据参数名称自动绑定到对象的各个属性上, 如果某个属性未传递, 则赋值为null(基本类型则赋值为默认初识值, 比如int类型的属性, 会被赋值为0)。

3.4 后端参数重命名(后端参数映射)

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,比如前端传递了⼀个 time 给后端,而后端是使用 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现 这种情况,我们就可以使用 @RequestParam 来重命名前后端的参数值.
具体示例如下,后端实现代码:
@RequestMapping("/m4")
public Object method4(@RequestParam("time") String createtime) {
    return "接收到参数createtime:" + createtime;
}
使用浏览器发送请求并传参: http://127.0.0.1:8080/param/m4?time=2023-09-12

响应:

可以看到, Spring可以正确的把浏览器传递的参数 time 绑定到了后端参数 caretetime 参数上。
那么此时, 如果浏览器使用createtime进行参数传递呢?
我们来试一下:
访问URL: http://127.0.0.1:8080/param/m4?createtime=2023-09-12
响应结果:

 

通过控制台打印的日志信息显示: 请求参数 'time' 不存在。

可以得出结论:
  1. 使用 @RequestParam 进行参数重命名时, 请求参数只能和 @RequestParam 声明的名称⼀ 致, 才能进行参数绑定和赋值.
  2. 使用 @RequestParam 进行参数重命名时, 参数就变成了必传参数.

那么如何进行非必传参数的设置呢?

非必传参数设置
先来了解下参数必传的原因, 我们查看 @RequestParam 注解的实现细节就可以发现端倪,注解
实现如下:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
可以看到 required 的默认值为true, 表示含义就是: 该注解修饰的参数默认为必传
那么, 我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错
具体实现如下:
@RequestMapping("/m4")
public Object method4(@RequestParam(value = "time", required = false) String createtime) {
    return "接收到参数createtime:" + createtime;
}
可以看到, 添加required=false之后, time前⾯也加了key, 变成了 value = "time"
注解属性赋值时, 没有指明key的话, 默认为value属性.
如果需要有多个属性进行赋值时, 需要写上key

3.5 传递数组

Spring MVC 可以自动绑定数组参数的赋值。
后端实现代码:
@RequestMapping("/m5")
public String method5(String[] array) {
    return "接收到参数:"+ Arrays.toString(array);
}
使用浏览器发送请求并传参:
数组参数:请求参数名与形参数组名称相同且请求参数为多个, 后端定义数组类型形参即可接收参数
http://127.0.0.1:8080/param/m5? array=zhangsan&array=lisi&array=wangwu
或者使用 http://127.0.0.1:8080/param/m5?array=zhangsan,lisi,wangwu

 浏览器响应结果:

可以看到后端对数组参数进行了正确的接收和响应。

3.6 传递集合

集合参数:和数组类似, 同⼀个请求参数名为多个, 且需要使用 @RequestParam 绑定参数关系。
默认情况下,请求中参数名相同的多个值,是封装到数组. 如果要封装到集合,要使用
@RequestParam 绑定参数关系。

 请求方式和数组类似:

浏览器传参:
方式⼀: http://127.0.0.1:8080/param/m6?listParam=zhangsan&listParam=lisi&listParam=wangwu
⽅式⼆: http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu
%2c 是逗号的转义编码, 解码后的url为:
http://127.0.0.1:8080/param/m6? listParam=zhangsan,lisi,wangwu

 后端接收代码:

@RequestMapping("/m6")
public String method6(@RequestParam List<String> listParam){
    return "size:"+listParam.size() + ",listParam:"+listParam;
}

3.7 传递JSON数据

JSON就是⼀种数据格式, 有自己的格式和语法, 使用文本表示一个对象或数组的信息, 因此
JSON本质是字符串,主要负责在不同的语言中数据传递和交换.
注意: JSON与Javascript的关系: 没有关系, 只是语法相似
1、JSON语法
JSON 是⼀个字符串,其格式非常类似于 JavaScript 对象字面量的格式。
我们先来看⼀段JSON数据:
{
    "squadName": "Super hero squad",
    "homeTown": "Metro City",
    "formed": 2016,
    "secretBase": "Super tower",
    "active": true,
    "members": [{
            "name": "Molecule Man",
            "age": 29,
            "secretIdentity": "Dan Jukes",
            "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"]
    }, {
            "name": "Madame Uppercut",
            "age": 39,
            "secretIdentity": "Jane Wilson",
            "powers": ["Million tonne punch", "Damage resistance", "Superhuman reflexes"]
    }, {
            "name": "Eternal Flame",
            "age": 1000000,
            "secretIdentity": "Unknown",
            "powers": ["Immortality", "Heat Immunity", "Inferno","Teleportation", "Interdimensional travel"]
    }]
}
JSON的语法:
  1. 数据在键值对(Key/Value)
  2. 数据由逗号 , 分隔
  3. 对象用 {} 表示
  4. 数组用 [] 表示
  5. 值可以为对象, 也可以为数组, 数组中可以包含多个对象
JSON的两种结构
  1. 对象: 大括号 {} 保存的对象是⼀个无序的 键值对 集合. ⼀个对象以左括号 { 开始, 右括号 } 结束。每个"键"后跟⼀个冒号 ,键值对使用逗号 , 分隔
  2. 数组: 中括号 [] 保存的数组是值(value)的有序集合. ⼀个数组以左中括号 [ 开始, 右中括 ] 结束,值之间使用逗号 , 分隔
2、JSON字符串和Java对象互转

 JSON本质上是⼀个字符串, 通过文本来存储和描述数据。

 Spring MVC框架也集成了JSON的转换工具, 我们可以直接使用, 来完成JSON字符串和Java对象的互转。

参考代码如下:

public class JSONUtils {
    private static ObjectMapper objectMapper = new ObjectMapper();
    public static void main(String[] args) throws JsonProcessingException {
        Person person = new Person();
        person.setId(5);
        person.setName("zhangsan");
        person.setPassword("123456");
        //对象转为JSON字符串
        String jsonStr = objectMapper.writeValueAsString(person);
        System.out.println("JSON字符串为:"+jsonStr);
        //JSON字符串转为对象
        Person p = objectMapper.readValue(jsonStr,Person.class);
        System.out.println("转换的对象
                id:"+p.getId()+",name:"+p.getName()+",password:"+p.getPassword());
    }
}
使用ObjectMapper 对象提供的两个方法, 可以完成对象和JSON字符串的互转
writeValueAsString: 把对象转为JSON字符串
readValue: 把字符串转为对象
3、JSON优点
  1. 简单易用: 语法简单,易于理解和编写,可以快速地进行数据交换
  2. 跨平台支持: JSON可以被多种编程语言解析和生成, 可以在不同的平台和语言之间进行数据交换和传输
  3. 轻量级: 相较于XML格式, JSON数据格式更加轻量级, 传输数据时占用带宽较小, 可以提高数据传输速度
  4. 易于扩展: JSON的数据结构灵活,支持嵌套对象和数组等复杂的数据结构,便于扩展和使用
  5. 安全性: JSON数据格式是⼀种纯文本格式,不包含可执行代码, 不会执行恶意代码,因此具有较高的安全性
4、传递JSON对象
接收JSON对象, 需要使用 @RequestBody 注解
RequestBody: 请求正文,意思是这个注解作用在请求正文的数据绑定,请求参数必须在写在请求正文中。

 后端实现:

@RequestMapping(value = "/m7")
public Object method7(@RequestBody Person person) {
    return person.toString();
}

这里我们来使用postman工具测试我们的后端程序,

使用Postman来发送json请求参数:

 可以看到, 后端正确接收了.

去除掉 @RequestBody 的结果:

可见,后端未能成功给Person对象赋值。

3.8 获取URL中参数@PathVariable

path variable: 路径变量
和字面表达的意思⼀样, 这个注解主要作用在请求URL路径上的数据绑定。 默认传递参数写在URL上,SpringMVC就可以获取到。
后端实现代码:
@RequestMapping("/m8/{id}/{name}")
public String method8(@PathVariable Integer id, @PathVariable("name") String userName){
    return "解析参数id:"+id+",name:"+userName;
}
使用浏览器发送请求或者使用Postman发送请求: http://127.0.0.1:8080/param/m8/5/zhangsan

 

可以看到, 后端正确获取到了URL中的参数.
参数对应关系如下:
如果方法参数名称和需要绑定的URL中的变量名称⼀致时, 可以简写, 不用给@PathVariable的属性赋值 , 如上述例子中的id变量;
如果方法参数名称和需要绑定的URL中的变量名称不⼀致时, 需要@PathVariable的属性value赋值, 如上述例⼦中的userName变量。

3.9 上传文件@RequestPart

后端代码实现:

@RequestMapping("/m9")
public String getfile(@RequestPart("file") MultipartFile file) throws IOException {
    //获取⽂件名称
    String fileName = file.getOriginalFilename();
    //⽂件上传到指定路径
    file.transferTo(new File("D:/temp/" + file.getOriginalFilename()));
    return "接收到⽂件名称为: "+fileName;
}

 使用Postman发送请求:

然后观察 D:/temp 路径下, 文件是否上传成功。

该篇文章就先介绍到这里了,后续内容在下篇《Spring Web Mvc的入门学习(二)》,欢迎继续收看。

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

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

相关文章

Canvas实现圆点动画

示例效果图&#xff1a; 话不多说直接上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><t…

[linux初阶][vim-gcc-gdb] TwoCharter: gcc编译器

目录 一.Linux中gcc编译器的下载与安装 二.使用gcc编译器来翻译 C语言程序 ①.编写C语言代码 ②翻译C语言代码 a.预处理 b.编译 c.汇编 d.链接 ③.执行Main 二进制可执行程序(.exe文件) 三.总结 一.Linux中gcc编译器的下载与安装 使用yum命令(相当于手机上的应用…

Flutter 开发学习笔记(2):第一个简单的Flutter项目(下)

文章目录 前言官方Flutter案例侧边栏添加代码初始化展示效果 子组件私有数据空间导航栏转为有状态WidgetsetState手动转换页面实现效果 响应式动态切换宽度添加收藏夹&#xff0c;跨Widget传数据实现效果 完整代码后续进阶效果总结 前言 接着继续上一章的内容 官方Flutter案例…

C++ 项目:使用 GSL 数学运算库 C++ 调用Python

文章目录 Part.I IntroductionChap.I CMakeListsChap.II ExportLibGSL.hChap.III test_python.cpp Part.II GSL 使用方法Part.III C 调用 Python 使用方法相关博客 Part.I Introduction 本项目是一个使用 GSL 的小项目&#xff0c;还有 C 调用 Python。项目虽简单&#xff0c;…

2024软件设计师备考讲义——(6)

信息安全与网络安全 一、信息与信息系统安全 1.信息安全含义及属性 含义是保密性、完整性、可用性其他属性如&#xff1a;真实性、可核查性、不可抵赖性、可靠性 2.安全需求 物理安全&#xff1a;物理设备和环境网络安全&#xff1a;网络攻击和入侵系统安全&#xff1a;操作…

[SWPUCTF 2021 新生赛]crypto5(小明文攻击)

题目&#xff1a; 直接暴力破解&#xff1a; from Cryptodome.Util.number import * import gmpy2 flag 251667516535309413648396638468065433877208653392633709079856557751521873194647157371165991714772070474300653458826262598807568390941796270326238953302426553…

HTTP/1.1 特性(计算机网络)

HTTP/1.1 的优点有哪些&#xff1f; 「简单、灵活和易于扩展、应用广泛和跨平台」 1. 简单 HTTP 基本的报文格式就是 header body&#xff0c;头部信息也是 key-value 简单文本的形式&#xff0c;易于理解。 2. 灵活和易于扩展 HTTP 协议里的各类请求方法、URI/URL、状态码…

Linux 常见性能分析方法论介绍(业务负载画像、下钻分析、USE方法论,检查清单)

写在前面 博文内容为 《BPF Performance Tools》 读书笔记整理内容涉及常用的性能调优方法论介绍&#xff1a;业务负载画像下钻分析USE方法论检查清单理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼…

基于百度地图实现Android定位功能实现(一)

Android集成百度地图 文章目录 Android集成百度地图前言准备工作创建工程申请密钥 在项目中集成BaiduMap SDK创建地图 前言 本案例使用百度地图实现在Android中集成地图&#xff0c;并且实现了普通地图/卫星地图&#xff0c;以及路况图和热状图功能&#xff1b; 参考技术文档&…

SRS OBS利用RTMP协议实现音视频推拉流;WebRTC 屏幕直播分享工具

一、SRS OBS利用RTMP协议实现音视频推拉流 参考&#xff1a;https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started 1&#xff09;docker直接运行SRS服务&#xff1a; docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 registry.cn-hangzhou.aliyuncs.co…

如何使用固定公网地址远程访问内网Axure RP生成的网站原型web页面

文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…

开源翻译大模型

开源翻译大模型 1 简介 在开发过程中&#xff0c;会遇到定制化翻译工具的需要&#xff0c;开源的翻译模型可以解决相应的问题。其中英语转中文的比较好的开源项目有&#xff1a; 序号组织模型地址备注1赫尔辛基大学语言技术研究小组&#xff08;Language Technology Researc…

debug: 解决typora两侧留白过大问题

问题如下图:解决办法:打开: 文件 -> 偏好设置 -> -> 外观 -> 看主题选择的是哪一个, 我选择的是GitHub * 点击打开主题设置 -> 选择你对应主题的.css文件 -> CTRL cv 备份一份, 然后打开 在文件中找到max-width : 修改对应的值 , 我改成了1920px * 改好以后…

安装即启动?探索流氓App的自启动“黑科技” (Android系统内鬼之ContentProvider篇)

前段时间发现了一个神奇的app&#xff0c;它居然可以在安装之后立即自启动&#xff1a; 看到没有&#xff0c;在提示安装成功大概1到2秒后&#xff0c;就直接弹出Toast和通知了&#xff01; 好神奇啊&#xff0c;在没有第三方app帮忙唤醒的前提下&#xff0c;它是怎么做到首次安…

谷粒商城——RabbitMQ

0. 消息中间件 1.RabbitMQ的核心概念 2. 工作流程 整体架构&#xff1a; 相关细节&#xff1a; 上述要注意的是&#xff1a; 路由键包含在message的头中&#xff0c;其作用是用于指定该消息存储与哪个消息队列中。 信道是客户端&#xff08;包括生产者和消费者&#xff09;用…

WIFI驱动移植实验:WIFI从路由器动态获取IP地址与联网

一. 简介 前面两篇文章&#xff0c;一篇文章实现了WIFI联网前要做的工作&#xff0c;另一篇文章配置了WIFI配置文件&#xff0c;进行了WIFI热点的连接。文章如下&#xff1a; WIFI驱动移植实验&#xff1a;WIFI 联网前的工作-CSDN博客 WIFI驱动移植实验&#xff1a;连接WIF…

Python字符串字母大小写变换,高级Python开发技术

寻找有志同道合的小伙伴&#xff0c;互帮互助,群里还有不错的视频学习教程和PDF电子书&#xff01; ‘’’ demo ‘tHis iS a GOod boOK.’ print(demo.casefold()) print(demo.lower()) print(demo.upper()) print(demo.capitalize()) print(demo.title()) print(dem…

什么是 SSL 证书?

SSL 证书的介绍 SSL&#xff08;Secure Sockets Layer&#xff09;证书是一种由数字证书颁发机构&#xff08;CA&#xff09;签发的加密证书&#xff0c;用于在 Web 浏览器和服务器之间建立安全连接。SSL 证书能够确保网站和应用程序的数据传输过程中不被窃听、篡改或伪造&…

springboot点餐平台网站

目 录 摘 要 1 前 言 2 第1章 概述 2 1.1 研究背景 3 1.2 研究目的 3 1.3 研究内容 4 第二章 开发技术介绍 5 2.1相关技术 5 2.2 Java技术 6 2.3 MySQL数据库 6 2.4 Tomcat介绍 7 2.5 Spring Boot框架 8 第三章 系统分析 9 3.1 可行性分析 9 3.1.1 技术可行性 9 3.1.2 经济可行…

初始《string》及手搓模拟实现《string》

目录 前言&#xff1a; 为什么学习string类&#xff1f; 标准库中的string类 1. string类对象的常见构造 ​编辑 2. string类对象的容量操作 ​编辑 3. string类对象的访问及遍历操作 4. string类对象的修改操作 5. string类非成员函数 vs和g下string结构的说明 vs下s…