阶段七-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();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UnoCss(原子化css引擎) 让你的开发更轻松愉快

什么是原子化CSS&#xff0c;UnoCSS又是什么&#xff0c;对此有疑问的推荐看下antfu的这篇文章——重新构想原子化 CSS (antfu.me) 相信看完这篇文章的你也会跟我一样热衷于UnoCSS. 介绍 今天介绍一个CSS开发利器 UnoCSS , 是一个具有高性能且极具灵活性的即时原子化 CSS 引擎…

识别代理IP:保障网络安全的重要一环

在互联网的世界中&#xff0c;代理服务器被广泛用于隐藏用户真实IP地址&#xff0c;带来了一些挑战&#xff0c;特别是在网络安全和欺诈检测方面。本文将探讨如何识别代理IP&#xff0c;以确保网络的安全性和可靠性。 1. 代理IP的背景与用途 代理服务器是位于用户和目标服务器…

融合语言模型中的拓扑上下文和逻辑规则实现知识图谱补全11.18

融合语言模型中的拓扑上下文和逻辑规则实现知识图谱补全 摘要1 引言2 相关工作2.1 事实嵌入法2.2 拓扑嵌入方法2.3 规则融合方法2.4 基于LM的方法 3 准备3.1 知识图谱和拓扑上下文3.2 KG中的逻辑规则4.3 三元组嵌入 5 实验和结果5.1 数据集和评价指标 摘要 知识图补全&#xf…

【C++】——阶段性测验(帮助巩固C++前半部分知识)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

深度学习数据集—文本、数字、文字识别大合集

最近收集了一大波关于文本、数字识别相关的数据集&#xff0c;有数字识别、也有语言文字识别&#xff0c;废话不多说现在分享给大家&#xff01;&#xff01; 1、500张手写拼音数据集 500张手写拼音数据集&#xff0c;包含对应txt格式标注及图片&#xff0c;&#xff0c;并提…

STM32/N32G455国民科技芯片驱动DS1302时钟---笔记

这次来分享一下DS1302时钟IC&#xff0c;之前听说过这个IC&#xff0c;但是一直没搞过&#xff0c;用了半天时间就明白了原理和驱动&#xff0c;说明还是很简单的。 注&#xff1a;首先来区分一下DS1302和RTC时钟有什么不同&#xff0c;为什么不直接用RTC呢&#xff1f; RTC不…

asp.net心理健康管理系统VS开发sqlserver数据库web结构c#编程计算机网页项目

一、源码特点 asp.net 心理健康管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 系统视频链接 https://www.bilibili.com/video/BV19w411H7P4/ 二、功能介绍 本系统使用Microsoft Visual Studio…

【ISP图像处理】Demosaic去马赛克概念介绍以及相关方法整理

1. 基本定义 使用彩色滤光器阵列(CFA)的数码相机需要一个去马赛克程序来形成完整的RGB图像。一般的相机传感器都是采用彩色滤光片阵列(CFA)放置在光感测单元上&#xff0c;在每个像素处仅捕获三种原色成分中的一种。 去马赛克方法主要关注于复原非常规区域&#xff0c;比如边缘…

【数据结构】树与二叉树(十九):树的存储结构——左儿子右兄弟链接结构(树、森林与二叉树的转化)

文章目录 5.1 树的基本概念5.1.1 树的定义5.1.2 森林的定义5.1.3 树的术语 5.2 二叉树5.3 树5.3.1 树的存储结构1. 理论基础2. 典型实例3. Father链接结构4. 儿子链表链接结构5. 左儿子右兄弟链接结构a. 定义树节点b. 创建树节点c. 使用左儿子右兄弟链接结构将树转化为二叉树d.…

【限时免费】20天拿下华为OD笔试之 【前缀和】2023B-最大子矩阵和【欧弟算法】全网注释最详细分类最全的华为OD真题题解

文章目录 题目描述与示例题目描述输入描述输出描述示例输入输出说明 解题思路如何表示一个子矩阵暴力解法二维前缀和优化二维前缀和矩阵的构建 代码解法一&#xff1a;二维前缀和PythonJavaC时空复杂度 解法二&#xff1a;暴力解法&#xff08;不推荐&#xff09;PythonJavaC时…

解析:什么是生成式AI?与其他类型的AI有何不同?

原创 | 文 BFT机器人 快速浏览一下头条新闻&#xff0c;你会发现生成式AI似乎无处不在。事实上&#xff0c;一些新闻标题甚至可能是通过生成式AI编写的&#xff0c;例如OpenAI旗下的ChatGPT&#xff0c;这个聊天机器人已经展现出了生成看起来像人类所写文本的惊人能力。 当人们…

Ubuntu18.04安装Loam保姆级教程

系统环境&#xff1a;Ubuntu18.04.6 LTS 1.Loam的安装前要求&#xff1a; 1.1 ROS安装&#xff1a;参考我的另一篇博客 Ubuntu18.04安装ROS-melodic保姆级教程_灬杨三岁灬的博客-CSDN博客还是那句话&#xff0c;有时候加了这行也不好使&#xff0c;我是疯狂试了20次&#xf…

用script去做前端html表格分页/排序

前言: 掘弃掉与后端交互做分页和互导,有利有弊吧; 在小数据的时候,如果不停来回朝服务端发送请求,会造成堵塞.于是,放弃了之前的前后端ajax方式去请求分页表格,使用script去弄一个,降低服务器的压力; 整体思路图: 代码构造: {% extends "order_header_same.html" …

stm32入门建议跳过固件库去学习hal库吗?

stm32入门建议跳过固件库去学习hal库吗? 如果要以单片机作为以后的工作方向&#xff0c;建议还是深入了解一下单片机的原理与机制&#xff0c;比如串口收发的时候&#xff0c;内部的寄存器是怎么工作的&#xff0c;中断又是怎么工作的&#xff0c;然后我们又是怎么进行中断处…

uniapp优化h5项目-摇树优化,gzip压缩和删除console.log

1.摇树优化 勾选摇树优化,打包删除死代码 2.gzip压缩和删除console.log 安装插件webpack和compression-webpack-plugin webpack插件 npm install webpack4.46.0 --save-devcompression-webpack-plugin插件 npm install compression-webpack-plugin6.1.1 --save-devconst Com…

代码随想录算法训练营第25天|216.组合总和III 17.电话号码的字母组合

JAVA代码编写 216. 组合总和III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k …

【观察】华为:数智世界“一触即达”,应对数智化转型“千变万化”

毫无疑问&#xff0c;数智化既是这个时代前进所趋&#xff0c;也是国家战略所指&#xff0c;更是所有企业未来发展进程中达成的高度共识。 但也要看到&#xff0c;由于大量新兴技术的出现&#xff0c;技术热点不停的轮转&#xff0c;加上市场环境的快速变化&#xff0c;让数智化…

数据结构--栈与队列

目录 前言 1.栈 1.1栈的概念及结构 1.2接口函数 1.3函数实现 1.4如何使用 2.队列 2.1队列的概念及结构 2.2接口函数 2.3函数实现 2.4如何使用 前言 前面我们已经学习了顺序表和链表&#xff0c;今天我们来学习栈与队列&#xff0c;这两种结构也属于线性表&#xff0c;实…

顺序表(数据结构与算法)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

从0开始学习JavaScript--JavaScript 流程控制

JavaScript中的流程控制结构是编写结构化、可读性强的代码的关键。本文将深入研究JavaScript中的流程控制&#xff0c;包括条件语句、循环结构、跳转语句等&#xff0c;并通过丰富的示例代码来更全面地了解和运用这些概念。 条件语句 条件语句用于基于不同的条件执行不同的代…