Spring Web MVC入门(中)

news2024/9/19 12:18:08

1. 请求

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

        传递参数, 咱们主要是使⽤浏览器和Postman来模拟;

1.1 传递单个参数

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

package com.example.zxslzw2014_8_11;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
    @RequestMapping("/test01")
    public String test(String name) {
        return "接收到的参数name:" + name;
    }
}

         使用postman发起请求:

        收到响应:

        可以看到, 后端程序正确拿到了name参数的值. Spring MVC 会根据⽅法的参数名, 找到对应的参数, 赋值给⽅法 ;如果参数不⼀致, 是获取不到参数的;

1.1.1 基础类型

        基础类型参数正常传递,代码如下:

package com.example.zxslzw2014_8_11;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
    @RequestMapping("/test01")
    public String test(int age) {
        return "接收到的参数age:" + age;
    }
}

        postman返回参数如下:

1、基础类型不传递参数;

        状态码是500,由此可见是服务器代码出现了问题,观察日志查看问题:

        错误显示int类型的参数age,虽然为可选的,但由于被声明为基本类型,而不能转换为空值,考虑将其声明为对应基本类型的包装类型。

2、传字符串 

        post请求如下:

        状态码为400,说明在客户端出现问题,同时错误显示是错误请求,我们同时查看服务器的错误日志:

        错误显示说明基本类型int不能转换为字符串;

1.1.2 包装类型

         包装类参数传递的代码如下:

package com.example.zxslzw2014_8_11;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
    @RequestMapping("/test01")
    public String test(Integer age) {
        return "接收到的参数age:" + age;
    }
}

1、正常传递数字类型参数,结果如下:

2、传递参数为空时:

          和基本类型不同,并没有报错,而是显示出null;对于包装类型,如果不传对应参数,Spring接收到的数据则为null,所以企业开发中,对于参数可能为空的数据,建议使用包装类型

 3、传递字符串

        报错结果如上面类似:

        综上所述:

        对于方法里参数可能为null的数据,建议使用包装类型;而对于传递对象时(后面会讲到),对象(类)里面可以不使用包装类型,如果无法进行区分,那就都使用包装类型好了。 

1.2 传递多个参数

         代码逻辑和接收单个参数一样。代码如下所示:

package com.example.zxslzw2014_8_11;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
    @RequestMapping("/test01")
    public String test(String name,Integer age) {
        return "接收到的参数name:" + name + "  接收到的参数age:" + age;
    }
}

         Postman观察结果如下:

        传参的时候,填入query string 的参数位置顺序可以任意的,结果不受这个顺序影响。 但是如果要传很多个,3个,4个,5个.....,这样进行传参代码就会显得很丑,所以,就可以引入对象,下面的内容介绍传对象。

1.3 传递对象

        现在有Student类,代码如下:

public class Student {
    private String name;
    private int age;
    private int id;
 
    public String getName() {return name;}
    public int getAge() {return age;}
    public int getId() {return id;}
    public void setName(String name) {this.name = name;}
    public void setAge(int age) {this.age = age;}
    public void setId(int id) {this.id = id;}
 
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}

         传递对象的代码:

@RequestMapping("test02")
    public Object test3(Student student) {
        return student.toString();
    }

        Postman发送请求,结果如下:

1、传递正常的对象参数

2、不传递任何参数

 

        由此可知,不会报错,原因就是在对象(类)中,成员属性会自动初始化,使用基础类型,也会进行初始化,如果没有传递这个参数,不会报错;但如果直接在接口方法中声明,使用int类型,没传参就会报错,就像上面介绍基础类型报错的例子。

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

        某些特殊的情况下,前端传递的参数key和我们后端接收的key可以不一致,比如前端传递了一个time给后端,但后端是使用createtime字段来接收的,这样就会出现参数接收不到的情况,如果我们想前端传过来的参数,后端接收的参数是重命名后的,就可以使用@RequestParam来重命名后端等待参数值。

        代码如下:

@RequestMapping("test03")
    public String getTime(@RequestParam(value = "time") String newTime) {
        return "接收到的参数newTime:" + newTime;
    }

        收到请求结果如下: 

         可以看到,Spring可以正确的把浏览器传递的参数time绑定到后端参数newTime上 

        接下俩试试前端传参的参数改成newTime,看看有没有问题,postman页面如下:

 

         错误码400,说明客户端这边的请求有问题,看看报错日志如下:

        错误信息显示:请求参数“time”不存在,说明访问这个方法,必须要有参数,而我们传的newtTime参数,在这里没有,所以就报错了;

        我们也可以设置该参数不是必须的,代码如下:

 @RequestMapping("test03")
    public String getTime(@RequestParam(value = "time" ,required = false) String newTime) {
        return "接收到的参数newTime:" + newTime;
    }

        post请求返回的结果:

结论如下:

1、注解:@RequestParam 进行参数重命名时,请求参数只有和@RequestParam声明的名称一致,才能进行参数绑定和赋值。

2、注解:@RequestParam 默认访问此方法是必须要带参数的,也可以设置不再参数。

1.5 传递数组

        传递数组时,Spring MVC可以自动绑定数组参数的赋值,代码如下: 

 @RequestMapping("test04")
    public String method(String[] str) {
        return Arrays.toString(str);
    }

         postman请求的返回结果:

1.5 传递集合

        集合参数,和数组类似,同一个请求参数名有多个,且需要使用@RequestParam注解绑定参数关系。

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

1.5.1 不加注解@RequestParam

        代码如下:

 @RequestMapping("test05")
    public String method3(List<String> list) {
        return "size:" + list.size() + ",list:" + list;
    }


      可以看到,服务器这边报错了,看看日志:

        错误显示,说明传参的时候,出问题了,因为没有加注解@RequestParam,所以默认传的参数是数组,但接收的确实集合List,所以服务器这边代码就会报错。 

1.5.2 加注解@RequestParam

        代码如下:

@RequestMapping("test05")
    public String method3(@RequestParam List<String> list) {
        return "size:" + list.size() + ",list:" + list;
    }

        返回结果如下所示:

        因为加了注解@RequestParam后,客户端这边传的参数就不会是默认的数组了,而是List。

1.6 传递JSON数据 

1.6.1 JSON概念

        JSON:JavaScript Object Notation【JavaScript 对象表示法】

        简单来说:JSON就是一种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,因此JSON本质是字符串。主要负责在不同的语言中进行数据传递和交换。

        JSON于JavaScript的关系:
        二者没有关系,只是语法相似,js开发者能更快的上手而已;

1.6.2 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",
                "Radiationblast"
            ]
        },
        {
            "name": "Madame Uppercut",
            "age": 39,
            "secretIdentity": "Jane Wilson",
            "powers": [
                "Million tonne punch",
                "Damage resistance",
                "Superhumanreflexes"
            ]
        }      
    ]
}

         也可以压缩表⽰;

1、JSON的语法

1、数据在键值对(Key / Value)中。

2、数据由逗号 " , " 分割。

3、对象用 " { } " 表示。

4、数组用 " [ ] " 表示。

5、值可以为对象,也可以为数组,数组中可以包含多个对象。

2、JSON的两种结构:

1、对象:大括号 " { } " 保存的对象是一个无序的 键值对 集合。一个对象以左括号 " { " 开始,右括号 " } " 结束。每个 "键" 后跟一个冒号 " : ",键值对使用逗号 " , " 分隔。

2、数组:中括号 " [ ] " 保存的数组是值(Value)的有序集合。一个数组以左中括号 " [ " 开始,右中括号 " ] ",值之间使用逗号 " , " 分隔。

         可以使用在线JSON格式化工具来进行校验和书写:在线JSON校验格式化工具(Be JSON)

 1.6.3 JSON字符串和Java对象互转

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

        Spring MVC框架也集成了JSON的转换工具,我们可以直接使用来完成JSON字符串和Java对象的互转,其本质上是 Jackson-databind 提供的功能,Spring MVC框架中已经把该工具包引入了进来,咱们直接使用即可,如果脱离SPring MVC使用,需要引入相关依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.5</version>
</dependency>

        当前定义person类如下:

package com.example.zxslzw2014_8_11;

public class Person {
    private int id;
    private String name;
    private String password;
    public Person(){ };
    public Person(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    };
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
    public int getId() {return id;}
    public String getName() {return name;}
    public String getPassword() {return password;}
    public void setId(int id) {this.id = id;}
    public void setName(String name) {this.name = name;}
    public void setPassword(String password) {this.password = password;}
}

         互转的代码如下:

        

package com.example.zxslzw2014_8_11;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JSONUtils {
    private static ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws JsonProcessingException {
        Person person = new Person(10, "shengmengyao", "123456");
        //对象转为JSON字符串
        String jsonStr = objectMapper.writeValueAsString(person);
        System.out.println("JSON字符串为:" + jsonStr);
        //JSON字符串转为对象
        Person p = objectMapper.readValue(jsonStr, Person.class);
        System.out.println("转换的对象为:" + person.toString());
    }
}

        运行结果如下:

1.6.4 JSON优点

 1、简单易用:语法简单,易于理解和编写,可以快速地进行数据转换。

2、跨平台支持:JSON可以被多种编程语言解析和生成,可以在不同的平台和语言之间进行数据交换和传输。

3、轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占用的带宽较小,可以提高传输速度。

4、易于扩展:JSON的数据结构灵活,支持嵌套对象和数组等复杂的数据结构,便于扩展和使用。

5、安全性:JSON数据格式是一种纯文本格式,不包含可执行代码,不会执行恶意代码,因此具有较高的安全性。

        基于以上特点,JSON在Web应用程序中被广泛使用,如前后端数据交互、API接口数据传输等。

 1.6.5 传递JSON对象

        接收JSON对象,需要使用@RequestBody注解。

RequestBody:请求正文,意思是这个注解作用在请求正文的数据绑定,请求参数必须写在请求正文中。

        后端代码如下:

@RequestMapping("/test06")
    public Object method1(@RequestBody Person person) {
        return person.toString();
    }

结果如下:

         如果后端代码去掉注解@RequestBody,代码如下:

 @RequestMapping("/test06")
    public Object method1(Person person) {
        return person.toString();

        结果如下:

        可以看到没有给person赋值成功;

1.7 获取URL中参数@PathVariable

        path variable:路径变量,和字面表达的意思一样,这个注解主要作用在请求URL路径上的数据绑定(默认传递参数写在URL上,Spring MVC就可以获取到)。

        后端代码如下所示:

        由上图所示,后端接受了url上的参数,并且返回;

        如果方法参数名称和需要绑定的URL的变量名称一致时,可以简写,不用给@PathVariable的属性赋值,例如上述例子中的id变量。

        如果方法参数名称和需要绑定的URL的变量名称不一致时,需要给@PathVariable的属性赋值,如上述例子中的userName变量。

1.8 上传文件@RequestPart

        使用注解RequestPart,后端代码如下:

 @RequestMapping("test08")
    public String getFile(@RequestPart("file") MultipartFile file) throws IOException {
        //获取文件名称
        String fileName = file.getOriginalFilename();
        //文件上传到指定路径
        file.transferTo(new File("C:\\Users\\缘客扫\\Desktop\\图集\\图集\\tmp" + file.getOriginalFilename()));
        return "接收到的文件名称为: " + fileName;
    }

postman观察结果如下:

2. 获取Cookie / Session 

        HTTP协议自身是属于 “无状态” 协议。“无状态” :默认情况下,HTTP协议的客户端和服务器的这次通信,和下次通信之间没有直接的联系(也可以理解成 “无记忆”);在计算机领域,我们认为 “无状态” 是好的,相反,“有状态” 就不好。

        但是实际开发中,很多时候是需要知道请求之间有关联的关系,例如我登录第三方网站,第一次登录成功后,后续的访问就不用继续输入账户密码,可以直接登录成功,所以这时候服务器就需要知道我之前是登录过了的。

2.1 初识Cookie

        Cookie本质是浏览器这边,本地化永久存储数据的机制,是一个身份标识,相当于令牌。客户端和服务器之间的登录请求交互,大概流程图如下:

        客户端这边有了Cookie这个 “令牌”,那服务器这边也就需要记录 这个 “令牌” 的信息;因为一个网站,会有很多客户,大型网站无时无刻都有很多请求访问过来,那么就会带有非常多的Cookie,这也就意味着,服务器这边也要对 这些 “令牌” 进行管理,这些工作也就是下面要介绍的 Session 来负责了。

2.2 了解Session

        了解Session之前,我们先谈谈会话(会话:对话的意思),现实中的会话如下图:

        

        在计算机领域中,会话是一个客户端与服务器的不中断的请求响应。对于服务器来说,客户端发来的请求,服务器能识别出请求来自同一个客户端。当一个未知的客户端向Web应用程序发送第一个请求,此时就开始了一个会话。当客户明确结束会话或者服务器在一个时限(时间阈值,Session默认的超时时间是30min,但这也是可以进行设置)没有接收到客户端发来的任何请求,此时会话就结束了

        服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个用户, 也就是属于 哪个会话, 就需要在服务器这边记录每个会话以及与用户的信息的对应关系. Session是服务器为了保存⽤⼾信息⽽创建的⼀个特殊的对象,其运行逻辑如下:

        Session的本质就是一个 “哈希表”,存储了一些键值对结构。Key就是SessionID,Value就是用户信息(用户信息可以根据需求灵活设计)。结构大概如下图:

         SessionId 是由服务器生成的一个 “唯一性字符串”,从Session机制的角度来看,这个唯一性字符串称为 “SessionId”。但是站在整个登录流程中看待,也可以把这个唯一性字符串称为:“token”。

        上述例子中的令牌ID,就可以看做是SessionId,只不过令牌除了 ID 之外,还会带一些其他信息,比如时间、签名等,sessionid的使用如下所示:

 1、当用户登录的时候,服务器在Session会新增一个新记录,并把SessionID,返回给客户端(通过HTTP响应中是Set-Cookie字段返回)。

2、客户端后续再给服务器发送请求的时候,需要在请求中带上SessionId(通过HTTP请求中的Cookie字段带上)。

3、服务器接收到请求后,根据请求中的SessionId,找到对应的Session中,获取到对应的用户信息,再进行后续的操作。如果找不到,就重新创建Session,再把SessionId返回给客户端。

        Session默认是保存在内存中的,如果重启服务器,Session数据就像消失

Cookie和Session的工作流程流程如下:

2.3 Cookie 和 Session 的区别 

1、Cookie是客户端保存用户信息的一种机制,Session是服务器保存用户信息的一种机制。

2、Cookie和Session之间是通过SessionId关联起来的(并没有什么直接关系),SessionId是Cookie和Session之间的桥梁。

3、Cookie和Session经常会搭配在一起使用,但不是必须搭配的。

        1)、完全可以用Cookie保存一些数据在客户端;这些数据并不一定是用户身份信息(SessionId)。

        2)、Session的SessionId也不是非得通过Cookie / Set-Cookie传递,也有其他方式,比如通过URL传递。

2.4 获取Cookie

2.4.1 传统获取Cookie

        代码如下:

@RequestMapping("/get")
    public String getCookie(HttpServletRequest request, HttpServletResponse response) {
        //获取参数
        //String name = request.getParameter("name");
        //获取所有参数
        Cookie[] cookies = request.getCookies();

        //1、不使用lambda表达式
//        StringBuilder stringBuilder = new StringBuilder();
//        if (cookies != null) {
//            for (Cookie ck : cookies) {
//                stringBuilder.append(ck.getName() + ":" + ck.getValue());
//            }
//        }
        //return "获取Cookie信息:" + stringBuilder;

        //2、使用lambda表达式
        if (cookies != null) {
            Arrays.stream(cookies).forEach(ck -> System.out.println(ck.getName() + ":" + ck.getValue()));
        }
        return "获取Cookie";
    }

        结果如下:

 因为没有设置Cookie,现在Cookie是null,控制台也不会打印Cookie;

        在应用程序里面手动添加cookie:

再次运行程序,如下图所示:

        从这个例⼦中, 也可以看出Cookie是可以伪造的, 也就是不安全的, 所以使⽤Cookie时, 后端需要进⾏ Cookie校验

        也可以使用Postman设置Cookie,如图:

        运行程序结果如下:

1、Spring MVC是基于Servlet API构建的原始Web框架,也是在Servlet的基础上实现的,HttpServletRequest、HttpServletResponse 是Servlet提供的两个类,是Spring MVC方法的内置对象。需要时直接在方法中添加声明即可(例如注解@CookieValue,下面会介绍)。

2、HttpServletRequest 对象代表客户端的请求。当客户端通过HTTP协议访问服务器时,HTTP请求头的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获取到客户端请求的所有信息。

3、HttpServletResponse 对象代表服务器的响应。HTTP响应的信息都在这个对象中,比如向客户端发送的数据、响应头、状态码等等。通过这个对象提供的方法,可以获得服务器响应的所有内容。

        Spring MVC在这两个对象的基础上进行了封装,给我们提供了更简单的使用方法(使用注解)。下面介绍简洁获取Cookie的使用方法。 

2.4.2 简洁获取Cookie

        后端代码如下:

@RequestMapping("/get2")
    public String getCookie2(@CookieValue("name") String newName) {
        return "从Cookie中获取值,name:" + newName;

结果如下:

2.5 获取session 

2.5.1 Session 存储

        因为Session是服务器这边存储的信息,所以要获取到到Session前要先有它。Session也是基于HttpServletRequest来存储和获取的,下面是存储Session的后端代码:

@RequestMapping("/set")
    public String setSess(HttpServletRequest request) {
        //从Cookie中获取到SessionId,根据SessionId获取Session对象,如果没有,就会创建一个
        HttpSession session = request.getSession();
        session.setAttribute("name", "yuanyiqi");
        return "设置Session成功";
    }

         这个代码中虽然看不到SessionId这样的概念,但是getSession操作内部会提取到请求中的Cookie的SessionId,然后根据SessionId获取到对应的Session对象,Session对象用HttpSession来描述。如图: 

 运行代码后浏览器页面如下:

        可以看到我们的cookie多了一个;

下面来看我们的postman界面:

 

        也是多了一个,和浏览器一样的Cookie。

2.5.2 传统获取Session

        获取Session有两种方式,getSession的不同参数有两种情况,如下两种:

HttpSession getSession(boolean create);
HttpSession getSession();

        HttpSession getSession(boolean create),参数如果为true,则当不存在会话是,会新建会话;参数如果不为false,则当不存在会话时,返回null,不新建会话。

        后端代码如下:

 @RequestMapping("getses1")
    public String getsSess(HttpServletRequest request) {
        //从cookie中获取到了sessionID, 根据sessionID获取Session对象取Session对象,如果session不存在,不会自动创建
        HttpSession session = request.getSession(false);
        String userName = (String) session.getAttribute("name");
        return "name: " + userName;
    }

         Object getAttribute(String name):返回该session会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。前面我们已经存储了Session:session.setAttribute("name", "yuanyiqi");   

        现在获取一下session,浏览器访问:http:127.0.0.1:8080/user/getses1 ,页面如下:

        注意:因为session是存储在内存中的,一般来说重启一次程序就会刷新,所以我们在进行查找session之前尽量在设置一次session;

         可以看到,客户端发送HTTP请求时,SessionId通过Cookie传递给了服务器。这里如果我们修改一下Cookie的值,就会拿不到了,如图:

        因为修改了Cookie,也就是伪造的,Cookie里的SessionId也就会改变,但服务器这边没有这个对应的SessionId,就拿不到Session了。

2.5.3 简洁获取 Session(1)

        后端代码如下:

@RequestMapping("getses2")
    public String getSess2(HttpSession session) {
        String name = (String)session.getAttribute("name");
        return "从Session中获取name: " + name;
    }

        结果如下:

2.5.4 简洁获取 Session(2) 

        代码如下:

@RequestMapping("getses3")
    public String getSess3(@SessionAttribute("name") String name) {
        return "从Session中获取name: " + name;
    }

        结果与之前一样;

        上面三个代码,分别进行一步步地简化,特别是第三个代码使用注解,大大的减少了代码的行数,提高了使用效率;

3. 获取Header

3.1 传统获取Header

        后端代码如下:

 @RequestMapping("getHeader1")
    public String getHeader1(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        return "从Header获取信息,userAgent:" + userAgent;
    }

        浏览器页面如下:

 3.2 简洁获取Header

        后端代码如下:

@RequestMapping("getHeader2")
    public String getHeader2(@RequestHeader("User-Agent") String userAgent) {
        return "从Header获取信息,userAgent:" + userAgent;
    }

        浏览器页面如下:

ps:本次的内容就到这里了,如果对你有所帮助的话,就请一键三连哦!!!

本文的封面来自:bilibili苏杉杉的pv,侵权删 url:https://www.bilibili.com/video/BV1vo4y167eh/?spm_id_from=333.999.0.0&vd_source=866da5be2ef0ddd213b053523da53138
————————————————

电子签名:上嘉路

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

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

相关文章

七段S型加减速算法原理及其多种形状仿真

1、基本7段S型&#xff1a; 七段S型加减速的位置、速度、加速度、加加速度曲线如下图所示。 加加速度&#xff1a; 加速度&#xff1a; 速度&#xff1a; 位置&#xff1a; 以上是7段S型加减速的最基本公式&#xff0c;在实际应用中还需要考虑到起始和终止速度大于匀速速度的情…

【JavaSE】解读Java中的toString方法

前言&#xff1a; 在Java中&#xff0c;toString方法来自java.lang.Object 类&#xff0c;然后所有对象都继承该Object 类。默认情况下&#xff0c;它的作用是返回对象的字符串表示形式。在实际开发中&#xff0c;重写 toString() 方法可以帮助我们以更易读的形式输出对象信息&…

Verilog基础:模块端口(port)定义的语法(2001标准)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 Verilog中的端口定义有两种风格&#xff0c;一种是Verilog Standard 1995风格&#xff0c;一种是Verilog Standard 2001风格&#xff0c;本文将对Verilog Standar…

C语言基础11指针

指针的引入 为函数修改实参提供支持。 为动态内存管理提供支持。 为动态数据结构提供支持。 为内存访问提供另一种途径。 指针概述 内存地址&#xff1a; 系统为了内存管理的方便&#xff0c;将内存划分为一个个的内存单元&#xff08; 1 个内存单元占 1 个字节&#xff09…

自动控制——状态观测器

自动控制——状态观测器 引言 在自动控制系统中&#xff0c;准确地了解系统的状态对实现高性能控制至关重要。然而&#xff0c;在许多实际应用中&#xff0c;我们无法直接测量系统的所有状态变量。这时&#xff0c;状态观测器&#xff08;State Observer&#xff09;就发挥了…

【LeetCode面试150】——209长度最小的子数组

博客昵称&#xff1a;沈小农学编程 作者简介&#xff1a;一名在读硕士&#xff0c;定期更新相关算法面试题&#xff0c;欢迎关注小弟&#xff01; PS&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟沈小农&#xff0c;希望我的文章能帮助到你。欢迎大家在…

轻松上手MYSQL:精通正则表达式,数据匹配不再难!

&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索MYSQL正则表达式函数之旅✨ &#x1f44b; 大家好&#xff01;文本学习…

【Cesium】Cesium图层请求完成的回调

有一个业务需要用到cesium图层请求完成的回调&#xff0c;翻了好久的文档终于给我找到&#x1f336;️。 是Cesium.ImageryProvider类的一个属性readyPromise 效果如下&#xff1a; Cesium图层请求完成的回调 完整代码如下&#xff1a; <html lang"en"><h…

PCDN业务推荐

神鸟云&蘑菇云最新业务推荐 &#x1f525;短Z业务-- 支持nat0~nat4 省内调度&#xff0c;晚高峰 跑量9成 配置要求: 线路&#xff1a;单条上行30M 硬件&#xff1a;32线程 64内存条 240G系统盘 1G:2T固态盘 单价&#xff1a;移动1900 电联2500 http://oss.download.…

Mysql(四)---增删查改(进阶)

文章目录 前言1.查询操作1.1.全列查询1.2.指定列查询1.3.列名为表达式查询1.4.查询中使用别名1.5.去重查询1.6.排序1.6.2.NULL 1.7.条件查询1.8.分页查询 2.修改3.删除 前言 上一篇博客&#xff0c;我们学习了一些主键的概念&#xff0c;并且分别创造了一些示例表&#xff0c;…

通过相机来获取图片

文章目录 1. 概念介绍2. 方法与细节2.1 实现方法2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何混合选择多个图片和视频文件"相关的内容&#xff0c;本章回中将介绍如何通过相机获取图片文件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. …

Codeforces Round 966 (Div. 3)(A,B,C,D,E,F)

A. Primary Task 签到 void solve() {string s;cin>>s;bool bltrue;if(s.size()<2)blfalse;else{if(s.substr(0,2)"10"){if(s[2]0)blfalse;else if(s[2]1&&s.size()<3)blfalse; }else blfalse;}if(bl)cout<<"YES\n";else cout…

数据结构第二天

分文件编程实现&#xff1a; main.c #include <stdio.h> #include <stdlib.h> #include "seqlist.h"int main(int argc, char const *argv[]) {seqlist_p p CreateEpSeqlist();InsertIntoSeqlist(p, 0, 10);InsertIntoSeqlist(p, 1, 20);InsertIntoSeql…

打卡第四十五天:不同的子序列、两个字符串的删除操作、编辑距离

一、不同的子序列&#xff08;困难&#xff09; 题目 文章 视频 这道题目如果不是子序列&#xff0c;而是要求连续序列的&#xff0c;那就可以考虑用KMP。相对于72. 编辑距离简单了不少&#xff0c;因为本题相当于只有删除操作&#xff0c;不用考虑替换增加之类的。但相对于…

Mapreduce_Distinct数据去重

MapReduce中数据去重 输入如下的数据&#xff0c;统计其中的地址信息&#xff0c;并对输出的地址信息进行去重 实现方法&#xff1a;Map阶段输出的信息K2为想要去重的内容&#xff0c;利用Reduce阶段的聚合特点&#xff0c;对K2进行聚合&#xff0c;去重。在两阶段中&#xff…

【数据结构篇】~顺序表

顺序表前言 想要学好数据结构的三大基本功&#xff1a;1.结构体2.指针3.动态内存开辟,这三样将是贯彻整个数据结构的工具。&#xff08;可以去这里了解这三大基本功&#xff09; 顺序表也是线性表的一种&#xff0c;那线性表又是什么呢&#xff1f; 线性表&#xff08;linear …

系列:水果甜度个人手持设备检测-无损检测常用技术和方式汇总

系列:水果甜度个人手持设备检测 -- 无损检测常用技术和方式汇总 概述 无损检测以不损坏被检测对象的使用性能为前提&#xff0c;以物理或化学方法为手段&#xff0c;借助相应的设备器材&#xff0c;按照规定的技术要求&#xff0c;对材料、零部件、结构件进行有效的检验和测…

软件测试第1章 软件测试是什么

目录​​​​​​​ 内容说明 一、软件测试与质量概览需要熟悉什么 二、如何理解质量保证 三、软件测试的误区-程序员和测试的关系 四、软件测试是什么&#xff1f; 五、软件测试的目的 六、软件测试与软件质量保证 七、软件测试的必要性 八、软件测试的基本概念分析 …

HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现(十一)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

智碳云/高能耗企业 水-电-气-热-油-空压机等能源数据采集系统【源码】

智碳云/高能耗企业 水-电-气-热-油-空压机等能源数据采集系统【源码】 介绍基于SpringCloud的能源管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管管理系统源码-能管系统软件架构