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

阶段七-Day02-SpringMVC

一、Restful请求格式

1. 介绍

Rest(Representational State Transfer:表现层状态转移)是一种软件架构风格,其核心是面向资源的一种设计。何为面向资源,意思是网络上的所有事物都可以抽象为资源,而每个资源都有唯一的资源标识,对资源的操作不应该改变这些标识。

通俗讲就是每个资源都有一个url地址,而不是不同的操作有不同的url地址,比如我们对用户信息的增删改查,用户就是资源,增删改查是操作,以前我们是一个操作一个url地址,现在按照Restful的说法,url地址只能有一个。

Restful的出现同时也解决了客户端的种类多种多样造成请求的格式比较混乱的问题,Restful提供了一种统一的前后端交互的接口规范,可以更好的实现数据的交互。

2. 正常使用

以前我们来实现对用户的增删该查的时候是以操作为基础来声明URL地址的:

新增用户: http://localhost:8080/userAdd?uid=1&uname=zhangsan&age=12

修改用户: http://localhost:8080/userUpdate?uid=1&uname=zhangsan

删除用户: http://localhost:8080/userDelete?uid=1

查询用户:http://localhost:8080/userSel?uid=1

而按照Restful的格式对用户的操作应当只有一个url地址:

操作用户: http://localhost:8080/user

Restful要求在当前的url地址中直接嵌套请求数据。

新增用户: http://localhost:8080/user/1/zhangsan/12

修改用户: http://localhost:8080/user/1/zhangsan/28

删除用户: http://localhost:8080/user/1

查询用户: http://localhost:8080/user/1

但请求数据被嵌套在了请求地址中如何获取呢?不能在像以前直接在单元方法上声明形参来接收了,需要结合@PathVariable注解来获取。

/*** @RequestMapping注解可以接收任意请求方式的请求* @GetMapping("地址"):接收GET请求,一般用在查询方法上* @DeleteMapping("地址"):接收DELETE请求,一般用在删除方法上* @PostMapping("地址"):接收POST请求,一般用户在新增上* @PutMapping("地址"):接收PUT请求,一般用在修改上*/
//查询用户信息
@GetMapping("/user/{id}")
public String selUser(@PathVariable Integer id){System.out.println("用户ID为:"+id);return "success.jsp";
}
//删除用户信息
@DeleteMapping("/user/{id}")
public String delUser(@PathVariable Integer id){System.out.println("用户ID为:"+id);return "success.jsp";
}
//新增用户信息
@PostMapping("/user/{id}/{name}/{age}")
public String addUser(@PathVariable Integer id,@PathVariable String name,@PathVariable Integer age){System.out.println("id = " + id + ", name = " + name + ", age = " + age);return "success.jsp";
}
//修改用户信息
@PutMapping("/user/{id}/{name}")
public String updateUser(@PathVariable Integer id,@PathVariable String name){System.out.println("id = " + id + ", name = " + name);return "success.jsp";
}

3. 使用Restful显示页面

我们知道,为了提高安全性,可以把页面放入到WEB-INF中。但是放入到WEB-INF中之后,访问页面之前必须先执行控制器,可以使用Restful方式显示页面,这样可以大大减少显示页面的控制器数量。

@Controller
@RequestMapping("page")
public class PageController {@GetMapping("{pageName}")public String showPage(@PathVariable String pageName){return "/WEB-INF/" + pageName + ".jsp";}
}

二、@ResponseBody注解

1. @ResponseBody介绍

@ResponseBody注解是类或方法级注解。

当方法上添加@ResponseBody注解后,控制单元方法返回值将不再被视图解析器进行解析|不会使用转发。而是把返回值放入到响应流中进行响应。

2. 最简单使用

直接在方法上添加上@ResponseBody,Spring MVC会把返回值设置到响应流中。

package com.sh.controller;import com.sh.pojo.Emp;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
/*
*   @ResponseBody : 控制单元添加了该注解 , 不会执行视图解析器, 将控制单元的返回值直接响应会到客户端
*           要求:
*               默认:
*                   1.控制单元只能返回String类型的数据.返回其他数据类型出现406状态码
*                   2.配合@RequestMapping(produces = "text/plain;charset=utf-8")设置响应内容类型及编码格式。
*
* */
//交给SpringMVC
@Controller
public class EmpController {/* 走视图解析器 */@RequestMapping("a1")public void a1(HttpServletResponse response, HttpServletRequest req){//什么都不做}@RequestMapping("a2")public String a2(HttpServletResponse response, HttpServletRequest req){return "index";}@RequestMapping("a3")public String a3(HttpServletResponse response, HttpServletRequest req) throws IOException {response.getWriter().print("ok");return "index";}@RequestMapping("a4")public void a4(HttpServletResponse response, HttpServletRequest req) throws IOException {response.setContentType("text/plain;charset=utf-8");Emp emp = new Emp(1, "zs", "bj", new Date());//自动调用了toString()方法response.getWriter().print(emp);}/* 添加@ResponseBody 默认只能返回String类型,其他类型返回406状态码 */@RequestMapping("a5")@ResponseBodypublic Emp a5(HttpServletResponse response, HttpServletRequest req) throws IOException {Emp emp = new Emp(1, "zs", "bj", new Date());return emp;}@RequestMapping("a6")@ResponseBodypublic String a6(HttpServletResponse response, HttpServletRequest req) throws IOException {Emp emp = new Emp(1, "zs", "bj", new Date());String s = emp.toString();return s;}@RequestMapping(value = "a7",produces = "text/plain;charset=utf-8")@ResponseBodypublic String a7(HttpServletResponse response, HttpServletRequest req) throws IOException {//返回字符串中文时会出现乱码,需要配合@RequestMapping(produces = "text/plain;charset=utf-8")设置响应内容类型及编码格式return "你好";}}

3. 自动转换为JSON字符串

@ResponseBody注解可以把控制单元返回值自动转换为JSON字符串。主要完成下面几个事情:

(1)判断返回值是否为JavaBean、JavaBean数组、List<JavaBean类型>、Map等满足键值对的类型。

(2)如果满足键值对类型,会使用Jackson把对象转换为JSON字符串,设置到响应流中。

同时会设置响应内容类型(Content-Type)为application/json;charset=utf-8

因为Spring MVC默认使用Jackson作为JSON转换工具,所以必须保证项目中存在Jackson的依赖。

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.10.8</version>
</dependency>
@ResponseBody : 控制单元添加了该注解 , 不会执行视图解析器, 将控制单元的返回值直接响应会到客户端要求:默认:1.控制单元只能返回String类型的数据.返回其他数据类型出现406状态码2.配合@RequestMapping(produces = "text/plain;charset=utf-8")设置响应内容类型及编码格式。导入json依赖之后:1.控制单元可以返回,JavaBean,数据[元素为JavaBean],集合{元素为JavaBean},Map2.SpringMVC默认使用jack将控制单元的返回值变为json格式的字符串,设置响应内容类型为application/json;charset=utf-8@RequestBody:将客户端请求参数为 json ,xml 转换为 javabean。需要引入相关依赖。
//交给SpringMVC
@Controller
public class EmpController {/* 走视图解析器 */@RequestMapping("a1")public void a1(HttpServletResponse response, HttpServletRequest req){//什么都不做}@RequestMapping("a2")public String a2(HttpServletResponse response, HttpServletRequest req){return "index";}@RequestMapping("a3")public String a3(HttpServletResponse response, HttpServletRequest req) throws IOException {response.getWriter().print("ok");return "index";}@RequestMapping("a4")public void a4(HttpServletResponse response, HttpServletRequest req) throws IOException {response.setContentType("text/plain;charset=utf-8");Emp emp = new Emp(1, "zs", "bj", new Date());//自动调用了toString()方法response.getWriter().print(emp);}/* 添加@ResponseBody 默认只能返回String类型,其他类型返回406状态码 */@RequestMapping("a5")@ResponseBodypublic Emp a5(HttpServletResponse response, HttpServletRequest req) throws IOException {Emp emp = new Emp(1, "zs", "bj", new Date());return emp;}@RequestMapping("a6")@ResponseBodypublic String a6(HttpServletResponse response, HttpServletRequest req) throws IOException {Emp emp = new Emp(1, "zs", "bj", new Date());String s = emp.toString();return s;}@RequestMapping(value = "a7",produces = "text/plain;charset=utf-8")@ResponseBodypublic String a7(HttpServletResponse response, HttpServletRequest req) throws IOException {//返回字符串中文时会出现乱码,需要配合@RequestMapping(produces = "text/plain;charset=utf-8")设置响应内容类型及编码格式return "你好";}@RequestMapping("a8")@ResponseBodypublic Emp a8(HttpServletResponse response, HttpServletRequest req) throws IOException {Emp emp = new Emp(1, "zs", "bj", new Date());return emp;//{"id":1,"uname":"zs","addr":"bj","bir":1698236241717}}@RequestMapping(value = "a11")@ResponseBody //将符合要求的内容转换为json,必须引入json工具类。public List<Emp> a11() throws IOException {Emp people = new Emp(1, "张三", "北京", new Date());Emp people1 = new Emp(2, "张三1", "北京", new Date());Emp people2 = new Emp(3, "张三2", "北京", new Date());ArrayList<Emp> list = new ArrayList<>();Collections.addAll(list, people, people1, people2);return list;}@RequestMapping(value = "a12")@ResponseBody //将符合要求的内容转换为json,必须引入json工具类。public Emp[] a12() throws IOException {Emp people = new Emp(1, "张三", "北京", new Date());Emp people1 = new Emp(2, "张三1", "北京", new Date());Emp people2 = new Emp(3, "张三2", "北京", new Date());Emp[] people3 = {people, people1, people2};return people3;}@RequestMapping(value = "a13")@ResponseBody //将符合要求的内容转换为json,必须引入json工具类。public Map<String, Object> a13() throws IOException {Map<String, Object> map = new HashMap<>();//使用map集合代替实体类map.put("id", 1);map.put("name", "张三");map.put("addr", "北京");map.put("bir", new Date());return map;}}

5. 转换为XML文件

XML格式在一些开放平台上用的比较多。例如:微信里面很多接口都是XML格式。

在Spring MVC中支持把返回值转换为XML文件。如果还是使用jackson-databind依赖,默认只能转换返回值为类类型的控制单元,返回值为List是无法转换为XML的,同时还要求实体类上必须有@XmlRootElement,才能转换。

如果项目中所有控制单元返回值结果都希望是XML格式,可以按照下面步骤完成。

5.1 导入依赖

导入依赖时注意:

(1)不要导入jackson-databind,只导入jackson-dataformat-xml。

(2)jackson-dataformat-xml版本不要太高,和Tomcat8插件不兼容。2.9.9和Spring 5.3.x可以正确兼容。

(3)因为上面练习导入的是jackson-databind,所以需要点击Maven面板 -> Lifecycle -> Clean 清空下缓存。

<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.9.9</version>
</dependency>
5.2 编写控制单元

控制单元方法和转换为JSON时写法完全相同。

6. @RestController注解

对于页面中使用前端框架时的项目。例如页面时通过:EasyUI、BootStrap、Vue等前端框架进行编写时,客户端向服务端发送的请求都是异步Ajax(或类似Ajax的异步请求)。对于这样的项目,控制器中所有的方法都包含@ResponseBody注解

补充知识

实际开发中一般响应结果会创建一个类来接收 
例如创建一个Result类 
package com.sh.pojo;import java.io.Serializable;public class Result<T> implements Serializable {private String msg; //消息private int code;   //自定义的状态码 200 成功   500 失败private T data;        //数据public Result() {}public Result(String msg, int code, T data) {this.msg = msg;this.code = code;this.data = data;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public T getData() {return data;}public void setData(T data) {this.data = data;}@Overridepublic String toString() {return "Result{" +"msg='" + msg + '\'' +", code=" + code +", data=" + data +'}';}
}

三、@RequestBody注解

1. 介绍

@RequestBody注解底层依赖的依然是Jackson工具包,其作用是把客户端传递过来的请求体中JSON或XML数据转换为Map、类、List<类>、List<Map>等类型。

既然是转换为请求体数据,所以不能是GET类型请求(GET没有请求体),多用在POST类型的请求中。

@RequestBody注解在单体架构项目使用的不是特别多。主要用在分布式项目中多个项目之间传递数据或一些开发平台中(例如微信开发平台接口返回XML数据)

如果希望在单体架构项目中使用@RequestBody注解,需要在客户端中使用Ajax请求,刻意设置请求的内容类型(Content-Type)为JSON或XML。

2. 请求内容类型详解

在客户端中无论使用的是<form>表单,还是Ajax请求,post请求内容类型都是application/x-www-form-urlencoded,表示普通表单参数。普通表单参数接收方式和上次课讲解的参数接收方式是相同的。因为是默认请求内容类型,所以在谷歌浏览器开发者工具中有时不会特意的显示,有时会显示。

2.1 表单参数接收

普通表单写法:

<form action="/testContentType" method="post">编号:<input type="text" name="id"/><br/>姓名:<input type="text" name="name"/><br/><input type="submit" value="提交"/>
</form>

谷歌开发者工具中可以看到Content-Type为application/x-www-form-urlencoded。

对于普通表单参数,使用同名参数或JavaBean接收都可以。

@Controller
public class Demo2Controller {// 使用多个简单数据类型接收请求参数@RequestMapping("/testContentType")public String testContentType(int id, String name) {System.out.println(id + "," + name);return "/index.jsp";}
//    使用JavaBean接收请求参数@RequestMapping("/testContentType")public String testContentType2(People peo){System.out.println(peo);return "/index.jsp";}
}
2.2 Ajax请求参数

使用Ajax请求时,默认的参数类型也是普通表单参数(Form Data)。

$.ajax({url:"/testContentTypeAjax",data:{"id":1,"name":"张三"},type:"post",success:function (data) {console.log(data);},dataType:"json"
});

3. 修改请求内容类型

如果希望修改请求内容类型,可以使用HTML的<form>中enctype属性或使用Ajax中contentType属性进行设置。

注意:<form>的enctype属性一般只有在文件上传时才会修改,所以希望传递特定类型请求参数内容时,都是通过Ajax进行请求。

下面演示下,请求参数内容为JSON字符串的写法。

在下面代码中有三次需要重点注意的地方:

(1)contentType:必须设置。常见取值“application/json”或"application/xml"。如果没有设置这个属性,取值默认是application/x-www-form-urlencoded,表示普通表单参数。当设置为"application/json"时,会把data取值设置到请求体中,所以服务端接收参数时就不能按照普通表单参数进行接收。

(2)data:请求参数。必须是JSON字符串类型,不能是JSON格式的对象。因为在JSON中key两次必须有双引号,所以data取值两侧用单引号包含。因为在JavaScript中字符串string类型可以使用单引号包含,也可以使用双引号包含。

(3)type:请求类型不能是get类型,因为get类型没有请求体。常用就是post类型。

$.ajax({url:"testContentType",contentType:"application/json",// 修改请求内容类型为JSONdata:'{"id":1,"name":"张三"}',// 取值两次必须有单引号,没有单引号无效type:"post",// 不能是GET类型请求success:function (data) {console.log(data);},dataType:"json"
});

服务端接收请求体中包含JSON字符串的请求时,需要在参数前面添加@RequestBody。表示使用Jackson把请求体中JSON/XML格式数据转换为JavaBean或Map。

小提示:

  1. 因为一个请求只有一个请求体。控制单元参数中绝对不允许出现两个@RequestBody注解。

  2. 因为@RequestBody底层使用Jackson,所以只适用于把请求体数据转换为JavaBean或Map。绝对不能在@RequestBody后面使用String等类型接收请求体内容。也就是说,客户端把JSON或XML设置到请求体,服务端使用JavaBean或Map接收请求体数据时,才能在控制单元参数前面添加@RequestBody注解。

四、Spring MVC文件上传

1. 文件上传介绍

文件上传就是把客户端的文件上传到服务端进行保存。在文件上传时文件和其他请求参数是在请求体中进行传递。所以不支持GET类型请求。

默认的表单内容类型application/x-www-form-urlencoded不支持传递文件流。所以需要在<form>的enctype中设置enctype="multipart/form-data"才表示把文件和其他表单参数设置到请求体中。

Spring MVC的文件上传是通过MultipartResovler组件实现的。提供了两个具体的实现类

必须在Spring MVC的配置文件中配置CommonsMultipartResovler组件的Bean,同时也得在项目中导入Commons-Fileupload的依赖。

(1)客户端:

   请求方式必须是POST

   enctype必须为multipart/form-data

(2)服务端:

   必须配置MultipartResovler。否则无法解析上传文件的流数据。(<bean>的id值必须叫做multipartResovler)如果没有配置MultipartResovler不仅仅是文件流数据无法解析,连带着其他表单域数据也无法解析。因为文件流数据和表单数据都在请求体中,不解析的话,文件流数据和表单数据都接收不到。

   注意文件域的name取值,文件域必须MultipartFile类型接收。且name的取值必须和MultipartFile对象名相同。

2. 文件上传实现流程

2.1 导入依赖
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>
2.2 在页面中编写文件上传代码

要设置method="post" enctype="multipart/form-data"

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><form action="/upload" method="post" enctype="multipart/form-data">姓名:<input type="text" name="name"/><br/>头像:<input type="file" name="photo"/><br/>地址:<input type="text" name="address"/><br/><input type="submit" value="提交"/><br/></form>
</body>
</html>
2.3 配置上传解析器bean
<!-- 文件上传时,必须配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
2.4 编写单元方法处理上传请求

我们直接在单元方法上声明形参来接收请求数据即可,普通表单数据还是直接使用键名获取即可,上传的时候解析后会被存储到MultipartFile对象中,我们声明MultipartFile类型的形参接即可,但是形参名必须和file标签的name属性值一致。然后我们在单元方法中将接收到的上传资源通过流存储到服务器的硬盘中即可。

小提示:

如果客户端就一个文件域使用一个MultipartFile对象接收就可以了。

如果客户端是多个同名的文件域使用MultipartFile 数组接收。

如果客户端是多个不同名的文件域使用多个MultipartFile对象接收就可以了。

@Controller
public class PeopleController {/*** 文件上传控制单元方法实现** @param name    也可以使用JavaBean接收name的值* @param address 也可以使用JavaBean接收address的值* @param photo   名字必须和表单中文件域的name属性值相同* @return* @throws IOException transferTo抛出的异常,可以使用try...catch处理异常。示例中为了让代码看起来简洁直接抛出了。*/@RequestMapping("/upload")public String upload(String name, String address, MultipartFile photo) throws IOException {photo.transferTo(new File("D:/images", photo.getOriginalFilename()));return "/upload.jsp";}
}

3. 生成唯一文件名

在上面代码中,保存文件名称时是使用文件上传时的名称进行保存。这样做存在一个问题:如果存在同名文件,后上传文件会覆盖之前文件内容。

所以在文件上传时都会生成一个全局唯一的文件名。常见有两种方式:

(1)时间戳+随机数

(2)UUID

//时间戳long l = System.currentTimeMillis();System.out.println(l);//UUIDUUID uuid = UUID.randomUUID();String s = uuid.toString().replace("-","");System.out.println(s);

文件名是全局唯一的,但是保存时文件扩展名要和上传文件的扩展名保持一致。

  @RequestMapping("/upload")public String upload(String name, String address, MultipartFile photo) throws IOException {// 判断上传文件流是否为空。如果不为空继续执行if(!photo.isEmpty()) {// 使用UUID生成文件名称// String fileName = UUID.randomUUID().toString();// 使用时间戳+随机数生成文件名long timeMillis = System.currentTimeMillis();Random random = new Random();String fileName = timeMillis + "" + random.nextInt(1000);// 获取上传时文件名String oldName = photo.getOriginalFilename();// 获取上传时文件的扩展名String suffix = oldName.substring(oldName.lastIndexOf("."));// 获取到当前项目images目录,发布到Tomcat后的绝对路径。String realPath = request.getServletContext().getRealPath("/images");System.out.println(realPath);// 保存到当前项目的images目录中。photo.transferTo(new File(realPath,fileName + suffix));}return "/upload.jsp";}

5. 限制上传文件大小

在很多项目中是对上传文件做严格大小限制的。当文件太大会占用服务器存储空间。当文件太小(尤其是图片)可能显示不清晰。

在CommonsMultipartResolver中提供了setmaxUploadSize(long)方法,表示设置上传文件的大小。单位是字节byte。默认值为-1,表示无限制。

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="1024"></property>
</bean>

五、Spring MVC文件下载

1. 文件下载介绍

文件下载就是把服务器中的资源下载到本地。

但是需要注意的是浏览器本身作为一款软件,能够打开的文件格式比较多。

例如:.html文件、图片文件、.txt文件、.xml文件、.json文件等。当超链接访问的是浏览器本身能打开的资源。浏览器直接打开。这个特点就是响应头参数Content-Disposition控制的,其默认值为inline,表示能打开就打开,不能打开就下载。

Content-Disposition可取值有两个:

(1)inline。直接在浏览器中打开(能打开就打开,不能打开就下载)。

(2)attachment。以附件形式下载。

2. 测试inline效果

因为Content-Disposition默认值就是inline。所以不需要特殊设置。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><a href="/images/a.png">a.png</a><a href="/images/b.json">b.json</a><a href="/images/c.rar">c.rar</a>
</body>
</html>

3. 测试attachment效果

如果希望所有的文件都是下载,而不是能打开则打开。可以在响应头中设置Content-Disposition参数为attachment。attachment结合filename可以设置下载文件的名称。

@RequestMapping("/download")
public void download(HttpServletRequest req, HttpServletResponse response, String filename) {try {// filename=的值就是客户端看到的下载文件名称response.setHeader("Content-Disposition", "attachment;filename=" + filename);File file = new File(req.getServletContext().getRealPath("/images"), filename);FileInputStream fis = new FileInputStream(file);ServletOutputStream os = response.getOutputStream();IOUtils.copy(fis, os);} catch (IOException e) {e.printStackTrace();}
}

4. 文件下载中包含中文名称解决办法

如果文件下载时包含中文名称,需要保证filename=后面的内容是ISO-8859-1编码。如果filename=后面是UTF-8编码且包含中文会乱码。

改写控制器代码,需要反复进行编码转换

@RequestMapping("/download")
public void download(HttpServletRequest req, HttpServletResponse response, String filename) {try {// 因为是GET请求,所以要解决请求参数中文乱码问题String fileNameUtf8 = new String(filename.getBytes("iso-8859-1"), "utf-8");// 图片名称满足固定格式String newFilenameUtf8 = "来自尚学堂的"+fileNameUtf8;String newFilenameISO = new String(newFilenameUtf8.getBytes("utf-8"),"iso-8859-1");// 此处是ISO-8859-1编码的内容response.setHeader("Content-Disposition", "attachment;filename=" + newFilenameISO);// 此处必须是UTF-8解决参数乱码问题的名称File file = new File(req.getServletContext().getRealPath("/images"), fileNameUtf8);FileInputStream fis = new FileInputStream(file);ServletOutputStream os = response.getOutputStream();IOUtils.copy(fis, os);} catch (IOException e) {e.printStackTrace();}
}

相关文章:

阶段七-Day02-SpringMVC

一、Restful请求格式 1. 介绍 Rest(Representational State Transfer&#xff1a;表现层状态转移)是一种软件架构风格&#xff0c;其核心是面向资源的一种设计。何为面向资源&#xff0c;意思是网络上的所有事物都可以抽象为资源&#xff0c;而每个资源都有唯一的资源标识&…...

YOLOv5独家原创改进:最新原创WIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能精度

💡该教程为属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 💡本篇文章为YOLOv5独家原创改进:独家首发最新原创WIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能精度。 💡对自己数据集改进有效…...

【深度学习】pytorch快速得到mobilenet_v2 pth 和onnx

在linux执行这个程序&#xff1a; import torch import torch.onnx from torchvision import transforms, models from PIL import Image import os# Load MobileNetV2 model model models.mobilenet_v2(pretrainedTrue) model.eval()# Download an example image from the P…...

高防CDN安全防护系统在业务方面的应用

在当今数字化的时代&#xff0c;网络安全问题日益严峻&#xff0c;保护网站和数据免受攻击变得至关重要。CDN安全防护系统作为一种有效的解决方案&#xff0c;受到了广泛关注。小德将向您介绍CDN安全防护系统的原理、应用场景以及使用方法&#xff0c;助您更好地保障网络安全。…...

opencv(3):控制鼠标,创建 tackbar控件

文章目录 控制鼠标相关APIsetMouseCallbackcallback TrackBar 控件cv2.createTrackbarcv2.getTrackbarPos&#xff1a; 控制鼠标相关API setMouseCallback(winname, callback, userdata)callback(event, x, y, flags, userdata) setMouseCallback 在 OpenCV 中&#xff0c;s…...

UE4动作游戏实例RPG Action解析二:GAS系统播放武器绑定的技能,以及GE效果

一、GAS系统播放武器技能 官方实例激活技能通过装备系统数据激活,我先用武器数据资产直接激活 官方实例蒙太奇播放是自定义的AbilityTask,我先用更简单的方法实现效果 1.1、技能系统必要步骤: 1.1.1 插件启用AbilitySystem 1.1.2 PlayerCharacter绑定技能组件AbilitySy…...

做完这些_成为机器学习方面的专家

简单记个帖子, 用来记录学习机器学习的路线图 1. 数学分析, 高等代数, 概率论这三大件不多说, 基础中的基础. 2. 对于编程工具, b站上500集的python教程---python面向对象编程五部曲(从零到就业). 3. 对于机器学习的理论板块, 推荐b站up主---啥都会一点的研究生, 里面有一个吴恩…...

kubernetes|云原生| 如何优雅的重启和更新pod---pod生命周期管理实务

前言&#xff1a; kubernetes的管理维护的复杂性体现在了方方面面&#xff0c;例如&#xff0c;&#xff50;&#xff4f;&#xff44;的管理&#xff0c;服务的管理&#xff0c;用户的管理&#xff08;&#xff32;&#xff22;&#xff21;&#xff23;&#xff09;&#xf…...

【总结】坐标变换和过渡矩阵(易忘记)

xCy&#xff0c;此为x到y的坐标变换。 [β1,β2,…,βn] [α1,α2,…αn]C&#xff0c;此为基α到基β的过渡矩阵。 这个概念经常忘记。。。alpha到beta看来就是alpha后面加一个过渡矩阵了&#xff0c;很直观。坐标变换就是根据过渡矩阵和基本形式推一推得到吧&#xff0c;记…...

第十一周任务总结

本周任务总结 本周物联网方面主要继续进行网关的二次开发与规则引擎实现设备联动的实现 非物联网方面主要复习了docker的使用与算法的学习 1.网关的二次开发&#xff0c;本周将实现debug调试输出的文件下载到了网关&#xff0c;但网关出了问题无法连接&#xff0c;最终跟客服…...

Java Web——JavaScript基础

1. 引入方式 JavaScript程序不能独立运行&#xff0c;它需要被嵌入HTML中&#xff0c;然后浏览器才能执行 JavaScript 代码。 通过 script 标签将 JavaScript 代码引入到 HTML 中&#xff0c;有3种方式&#xff1a; 1.1. 内嵌式(嵌入式) 直接写在html文件里&#xff0c;用s…...

Vue3 toRaw 和 markRaw

一、toRaw 我们可以使用ref 和 reactive 将普通对象类型的数据变为响应式的数据。 我们可以使用toRaw 将reactive 对象的数据变为一般对象类型的数据。 使用toRaw 需要先进行引入&#xff1a; import { toRaw } from vue; 语法格式&#xff1a; const xxx toRaw(数据) set…...

麒麟信安助力长沙市就业与社保数据服务中心政务系统向自主创新演进

应用场景 长沙市就业与社保数据服务中心依托长沙市“政务云”的公共基础资源和相应的支撑能力&#xff0c;围绕社保、就业、人事人才、劳动关系等人社全量业务服务&#xff0c;力求建立以“智慧服务、智慧监管、智慧决策”为核心的“智慧人社”综合服务平台&#xff0c;实现人…...

【LeetCode刷题-双指针】--16.最接近的三数之和

16.最接近的三数之和 方法&#xff1a;排序双指针 class Solution {public int threeSumClosest(int[] nums, int target) {Arrays.sort(nums);int ans nums[0] nums[1] nums[2];for(int i 0;i<nums.length;i){int start i1,end nums.length - 1;while(start < en…...

Mac 安装 protobuf 和Android Studio 使用

1. 安装,执行命令 brew install protoc 2. Mac 错误提示&#xff1a;zsh: command not found: brew解决方法 解决方法&#xff1a;mac 安装homebrew&#xff0c; 用以下命令安装&#xff0c;序列号选择中科大&#xff08;1&#xff09;或 阿里云 /bin/zsh -c "$(curl…...

MongoDB入门级别教程全(Windows版,保姆级教程)

下载mongodb 进入官网&#xff1a; Download MongoDB Community Server | MongoDB 选择msi&#xff0c;Windows版本 下载完后直接双击&#xff1a; 选择complete 这里建议改地方&#xff1a; 我这里直接改成d盘&#xff1a;work目录下面&#xff1a; 点击next&#xff1a; 因…...

基于机器学习的居民消费影响因子分析预测

项目视频讲解: 基于机器学习的居民消费影响因子分析预测_哔哩哔哩_bilibili 主要工作内容: 完整代码: import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import missingno as msno import warnings warnings.filterwarnin…...

Qt HTTP 摘要认证(海康球机摄像机ISAPI开发)

接到一个需求是开发下海康的球机,控制云台,给到我的是一个开发手册,当然了是海康的私有协议 ISAPI开发手册https://download.csdn.net/download/qq_37059136/88547425关于开发这块读文档就可以理解了,海康使用的是摘要认证,当然了海康已经给出使用范例 通过libcurl就可以直接连…...

srs webrtc推拉流环境搭建(公网)

本地环境搭建 官方代码https://github.com/ossrs/srs 拉取代码&#xff1a; git clone https://github.com/ossrs/srs.gitcd ./configure make ./objs/srs -c conf/https.rtc.confsrs在公网上&#xff0c;由于srs是lite-ice端&#xff0c;导致他不会主动到srs获取自己的公网i…...

【Flutter】设计原则(2)深入解析 SOLID 原则的应用

【Flutter】设计原则(2)深入解析 SOLID 原则的应用 文章目录 一、前言二、SOLID原则三、在 Flutter 中应用单一职责原则1. 专注单一功能的 Widget2. 提高代码可维护性四、在 Flutter 中应用开闭原则1. 利用多态和基类实现可扩展的 Widget2. 增强应用的可扩展性和灵活性五、在…...

python爬虫概述及简单实践:获取豆瓣电影排行榜

目录 前言 Python爬虫概述 简单实践 - 获取豆瓣电影排行榜 1. 分析目标网页 2. 获取页面内容 3. 解析页面 4. 数据存储 5. 使用代理IP 总结 前言 Python爬虫是指通过程序自动化地对互联网上的信息进行抓取和分析的一种技术。Python作为一门易于学习且强大的编程语言&…...

ts视频文件转为mp4(FFmpeg)

有些视频资源下载下来之后发现是.ts的文件&#xff0c;除了用下载它时用的工具或是浏览器才能看&#xff0c;那有没有将ts文件转换成更加通用视频格式的方法。 几乎万能的音视频工具--ffmpeg登场 安装和环境配置可看这篇博客&#xff1a;FFmpeg指令行打开usb摄像头&#xff0…...

2023年咸阳市《网络建设与运维》赛题解析------四、安全配置

安全配置 说明:IP地址按照题目给定的顺序用“ip/mask”表示,IPv4 any地址用0.0.0.0/0,IPv6 any地址用::/0,禁止用地址条目,否则按零分处理。 1.FW1配置IPv4 nat,实现集团产品1段IPv4访问Internet IPv4,转换ip/mask为200.200.200.16/28,保证每一个源IP产生的所有会话将…...

什么是java枚举?为什么要用java枚举?

什么是java枚举&#xff1f; 原始的接口定义常量 public interface IConstants {String MON "Mon";String TUE "Tue";String WED "Wed";String THU "Thu";String FRI "Fri";String SAT "Sat";String SUN …...

USB复合设备构建CDC+HID鼠标键盘套装

最近需要做一个小工具&#xff0c;要用到USB CDCHID设备。又重新研究了一下USB协议和STM32的USB驱动库&#xff0c;也踩了不少坑&#xff0c;因此把代码修改过程记录一下。 开发环境&#xff1a; ST-LINK v2 STM32H743开发板 PC windows 11 cubeMX v6.9.2 cubeIDE v1.13.2 cub…...

准备篇(四)HTTP 基本原理

URI 和 URLURIURLURI vs URLHTTP 和 HTTPS超文本HTTPHTTP 请求与响应HTTPS你是否想过,在浏览器中敲入 URL 到 获取网页内容 之间发生了什么? 了解这些,有助于进一步了解爬虫的基本原理。 URI 和 URL URI(Uniform Resource Identifier),即统一资源标识符;URL(Universa…...

模板初阶笔记分享

有道云笔记...

使用Spring Boot实现大文件断点续传及文件校验

一、简介 随着互联网的快速发展&#xff0c;大文件的传输成为了互联网应用的重要组成部分。然而&#xff0c;由于网络不稳定等因素的影响&#xff0c;大文件的传输经常会出现中断的情况&#xff0c;这时需要重新传输&#xff0c;导致传输效率低下。 为了解决这个问题&#xff…...

读取PDF中指定数据写入EXCEL文件

使用Java读取文件夹中的PDF文件,再读取文件中的指定的字体内容,然后将内容写入到Excel文件中,其中包含一些正则判断,可以忽略,字体以Corbel字体为例。 所需要的maven依赖为: <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel…...

[黑马程序员SpringBoot2]——开发实用篇1

目录&#xff1a; 手工启动热部署自动启动热部署热部署范围配置关闭热部署功能第三方bean属性绑定松散绑定常用计量单位应用bean属性校验进制数据转换规则加载测试专用属性加载测试专用配置测试类中启动web环境发送虚拟请求匹配响应执行状态匹配响应体匹配响应体(json)匹配响应…...

Python------列表 集合 字典 推导式(本文以 集合为主)

推导式&#xff1a; 推导式comprehensions&#xff08;又称解析式&#xff09;&#xff0c;是Python的一种独有特性。推导式是可以从一个数据序列 构建 另一个 新的数据序列&#xff08;一个有规律的列表或控制一个有规律列表&#xff09;的结构体。 共有三种推导&#xff…...

网工内推 | Linux运维,六险二金,最高30K,IE认证优先

01 上海域起 招聘岗位&#xff1a;Linux运维工程师 职责描述&#xff1a; 1.负责游戏产品运维相关的工作&#xff0c;流程文档、技术文档、功能脚本的编写整理 2.负责分析并排除系统、数据库、网络、应用等游戏产品运维中出现的故障及错误 3.负责对游戏产品项目进行线上部署、…...

服务器集群配置LDAP统一认证高可用集群(配置tsl安全链接)-centos9stream-openldap2.6.2

写在前面 因之前集群为centos6&#xff0c;已经很久没升级了&#xff0c;所以这次配置统一用户认证也是伴随系统升级到centos9时一起做的配套升级。新版的openldap配置大致与老版本比较相似&#xff0c;但有些地方配置还是有变化&#xff0c;另外&#xff0c;铺天盖地的帮助文…...

12-1- GAN -简单网络-线性网络

功能 随机噪声→生成器→MINIST图像。 训练方法 0 损失函数:gan的优化目标是一个对抗损失,是二分类问题,用BCELoss 1 判别器的训练,首先固定生成器参数不变,其次判别器应当将真实图像判别为1,生成图像判别为0 loss=loss(real_out, 1)+loss(fake_out, 0) 2 生成器的…...

Antv/G2 分组柱状图+折线图双轴图表

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width,heightdevice-height"><title>分组柱状图折线图双轴图表</title><styl…...

springboot323基于Java的美妆购物网站的设计与实现

交流学习&#xff1a; 更多项目&#xff1a; 全网最全的Java成品项目列表 https://docs.qq.com/doc/DUXdsVlhIdVlsemdX 演示 项目功能演示&#xff1a; ————————————————...

vue项目本地开发完成后部署到服务器后报404

vue项目本地开发完成后部署到服务器后报404是什么原因呢&#xff1f; 一、如何部署 前后端分离开发模式下&#xff0c;前后端是独立布署的&#xff0c;前端只需要将最后的构建物上传至目标服务器的web容器指定的静态目录下即可 我们知道vue项目在构建后&#xff0c;是生成一系…...

Android设计模式--状态模式

真知即所以为行&#xff0c;不行不足谓之知 一&#xff0c;定义 当一个对象的内在状态改变时&#xff0c;允许改变其行为&#xff0c;这个对象看起来像是改变了其类。 这么说可能很难理解&#xff0c;通俗来讲就是当一个对象它有多种状态的时候&#xff0c;把每一种状态的行为…...

C++关系运算符重载

#include<iostream> using namespace std;class Person { public:string name;int age;Person(string n, int a){name n;age a;}//friend bool operator(Person& p1, Person& p2); 使用友元//成员函数实现函数关系符重载bool operator(Person& p) {if (na…...

HLS基础issue

hls 是一个用C/c 来开发PL &#xff0c;产生rtl的工具 hls是按照rtl code来运行的 &#xff0c; 但是rtl会在不同器件调用不同的源语&#xff1b; 可能产生的ip使用在vivado另外一个器件的话 会存在问题&#xff1b; Hls &#xff1a; vivado ip &#xff0c; vitis kernel 是…...

C#特性(Attribute)

C#特性&#xff08;Attribute&#xff09;是一种在程序中添加元数据的机制&#xff0c;它可以为代码提供额外的信息和指示。通过使用特性&#xff0c;我们可以为类、方法、属性等元素添加标记&#xff0c;以便在运行时进行更多的操作和决策。 C#特性是一种声明式编程的工具&…...

【设计模式】七大设计原则

七大设计原则 文章目录 七大设计原则一、概述二、单一职责原则三、接口隔离原则四、依赖倒转原则五、里氏替换原则六、开闭原则七、迪米特法则八、合成复用原则 一、概述 设计模式是为了让程序(软件)&#xff0c;具有更好代码重用性&#xff0c;可读性&#xff0c;可扩展性&am…...

思维导图软件 Xmind mac中文版特点介绍

XMind 2022 mac是一款思维导图软件&#xff0c;可以帮助用户创建各种类型的思维导图和概念图。 XMind mac软件特点 - 多样化的导图类型&#xff1a;XMind提供了多种类型的导图&#xff0c;如鱼骨图、树形图、机构图等&#xff0c;可以满足不同用户的需求。 - 强大的功能和工具&…...

Day32力扣打卡

打卡记录 买卖股票的最佳时机 IV&#xff08;状态机DP&#xff09; 链接 class Solution:def maxProfit(self, k: int, prices: List[int]) -> int:n len(prices)max lambda x, y: x if x > y else yf [[-0x3f3f3f3f] * 2 for _ in range(k 2)]for i in range(k 2…...

抗击.Elbie勒索病毒:如何应对.Elbie病毒威胁,保卫您的数据

导言&#xff1a; .Elbie勒索病毒如今成为网络世界中的一大威胁&#xff0c;其狡猾性让用户防不胜防。本文将深入介绍.Elbie病毒的特点、对数据的威胁&#xff0c;提供被感染文件的恢复方法&#xff0c;并详述一系列强化网络安全的预防措施&#xff0c;让您远离.Elbie勒索病毒…...

Vue3 函数式弹窗

运行环境 vue3vitetselement-plus 开发与测试 1. 使用h、render函数创建Dialog 建议可在plugins目录下创建dialog文件夹&#xff0c;创建index.ts文件&#xff0c;代码如下 import { h, render } from "vue";/*** 函数式弹窗* param component 组件* param opti…...

如何解决 Critical dependency: the request of a dependency is an expression ?

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; ruoyi-nbcio: nbcio-boot的若依版本,基于ruoyi-flowable-plus和flowable6.7.2&#xff0c;目前处于开发功能完善阶段&#xff0c;目标是打造一个最好的若依平台上flowable流程管理系统开源版本&…...

挑战视觉边界,探索图形验证码背后的黑科技

在日常生活中&#xff0c;我们登录网站或者其他平台时&#xff0c;在填写完账号密码之后&#xff0c;还会让我们填写4或6位的数字或者英文字母等&#xff0c;填写正确才能请求登录。这个其实是防止某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试&#xff0c;如下…...

【网络奇缘】- 计算机网络|网络类型|性能指标

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 计算机网络分类 1.根据范围分类 ​编辑 2.按使用者分​编辑 3.按交换技术分 ​编辑4.按拓扑结构分 ​…...

Leetcode—剑指Offer LCR 140.训练计划II【简单】

2023每日刷题&#xff08;三十三&#xff09; Leetcode—LCR 140.训练计划II 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* trainingPlan(struct ListNode* head, int cnt) {str…...