阶段七-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。
小提示:
-
因为一个请求只有一个请求体。控制单元参数中绝对不允许出现两个@RequestBody注解。
-
因为@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:表现层状态转移)是一种软件架构风格,其核心是面向资源的一种设计。何为面向资源,意思是网络上的所有事物都可以抽象为资源,而每个资源都有唯一的资源标识&…...
YOLOv5独家原创改进:最新原创WIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能精度
💡该教程为属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 💡本篇文章为YOLOv5独家原创改进:独家首发最新原创WIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能精度。 💡对自己数据集改进有效…...
【深度学习】pytorch快速得到mobilenet_v2 pth 和onnx
在linux执行这个程序: 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安全防护系统在业务方面的应用
在当今数字化的时代,网络安全问题日益严峻,保护网站和数据免受攻击变得至关重要。CDN安全防护系统作为一种有效的解决方案,受到了广泛关注。小德将向您介绍CDN安全防护系统的原理、应用场景以及使用方法,助您更好地保障网络安全。…...
opencv(3):控制鼠标,创建 tackbar控件
文章目录 控制鼠标相关APIsetMouseCallbackcallback TrackBar 控件cv2.createTrackbarcv2.getTrackbarPos: 控制鼠标相关API setMouseCallback(winname, callback, userdata)callback(event, x, y, flags, userdata) setMouseCallback 在 OpenCV 中,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生命周期管理实务
前言: kubernetes的管理维护的复杂性体现在了方方面面,例如,pod的管理,服务的管理,用户的管理(RBAC)…...
【总结】坐标变换和过渡矩阵(易忘记)
xCy,此为x到y的坐标变换。 [β1,β2,…,βn] [α1,α2,…αn]C,此为基α到基β的过渡矩阵。 这个概念经常忘记。。。alpha到beta看来就是alpha后面加一个过渡矩阵了,很直观。坐标变换就是根据过渡矩阵和基本形式推一推得到吧,记…...
第十一周任务总结
本周任务总结 本周物联网方面主要继续进行网关的二次开发与规则引擎实现设备联动的实现 非物联网方面主要复习了docker的使用与算法的学习 1.网关的二次开发,本周将实现debug调试输出的文件下载到了网关,但网关出了问题无法连接,最终跟客服…...
Java Web——JavaScript基础
1. 引入方式 JavaScript程序不能独立运行,它需要被嵌入HTML中,然后浏览器才能执行 JavaScript 代码。 通过 script 标签将 JavaScript 代码引入到 HTML 中,有3种方式: 1.1. 内嵌式(嵌入式) 直接写在html文件里,用s…...
Vue3 toRaw 和 markRaw
一、toRaw 我们可以使用ref 和 reactive 将普通对象类型的数据变为响应式的数据。 我们可以使用toRaw 将reactive 对象的数据变为一般对象类型的数据。 使用toRaw 需要先进行引入: import { toRaw } from vue; 语法格式: const xxx toRaw(数据) set…...
麒麟信安助力长沙市就业与社保数据服务中心政务系统向自主创新演进
应用场景 长沙市就业与社保数据服务中心依托长沙市“政务云”的公共基础资源和相应的支撑能力,围绕社保、就业、人事人才、劳动关系等人社全量业务服务,力求建立以“智慧服务、智慧监管、智慧决策”为核心的“智慧人社”综合服务平台,实现人…...
【LeetCode刷题-双指针】--16.最接近的三数之和
16.最接近的三数之和 方法:排序双指针 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 错误提示:zsh: command not found: brew解决方法 解决方法:mac 安装homebrew, 用以下命令安装,序列号选择中科大(1)或 阿里云 /bin/zsh -c "$(curl…...
MongoDB入门级别教程全(Windows版,保姆级教程)
下载mongodb 进入官网: Download MongoDB Community Server | MongoDB 选择msi,Windows版本 下载完后直接双击: 选择complete 这里建议改地方: 我这里直接改成d盘:work目录下面: 点击next: 因…...
基于机器学习的居民消费影响因子分析预测
项目视频讲解: 基于机器学习的居民消费影响因子分析预测_哔哩哔哩_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 拉取代码: git clone https://github.com/ossrs/srs.gitcd ./configure make ./objs/srs -c conf/https.rtc.confsrs在公网上,由于srs是lite-ice端,导致他不会主动到srs获取自己的公网i…...
【Flutter】设计原则(2)深入解析 SOLID 原则的应用
【Flutter】设计原则(2)深入解析 SOLID 原则的应用 文章目录 一、前言二、SOLID原则三、在 Flutter 中应用单一职责原则1. 专注单一功能的 Widget2. 提高代码可维护性四、在 Flutter 中应用开闭原则1. 利用多态和基类实现可扩展的 Widget2. 增强应用的可扩展性和灵活性五、在…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
