【SpringMVC】SpringMVC程序开发

news2024/11/18 16:48:36

SpringMVC程序开发

文章目录

  • SpringMVC程序开发
    • :one:认识SpringMVC
      • 什么是SpringMVC
      • MVC思想
    • :two:获取请求参数
      • 创建SpringMVC项目
      • 建立路由连接
      • 获取请求参数
        • 获取urlEncoded格式参数
        • 获取表单标签参数
        • 获取Json格式参数
        • 获取URL中的参数
      • 上传图片
      • 获取请求信息
        • 获取请求header
        • 获取cookie
        • 创建session
        • 获取session中存储的信息
    • :three:返回数据给前端
      • 返回页面
      • 返回Json格式数据
      • 请求转发和请求重定向

1️⃣认识SpringMVC

什么是SpringMVC

SpringMVC是基于servlet API构建的web框架,SpringMVC是spring框架的一个模块,用于快速开发web APP。SpringMVC正式名称是Spring Web MVC,一般叫作Spring MVC,也可以叫作Spring Web。

MVC思想

MVC是 model(模型) view(视图) controller(控制器)单词的缩写,是之前web开发的一种设计模式。

model,view,controller在web后端中所担任的职务:

image-20221205153032108

Model(模型):主要任务是与数据库打交道,从数据库读取数据,将数据写入到数据库,

View(视图):主要是将从数据库取出的数据构建成页面,即将原始数据构建成页面。

Controller(控制器):这是后端程序中直接与用户交互的部分,连接View,和Model的桥梁

  • 这是原始的web开发思想,并没有前后端分离。因为View也是在后端实现的,直接返回给浏览器的就是页面
  • 现在主流的开发方式是前后端分离方式,直接将原始数据返回给前端,前端拿到原始数据构建出页面

了解了MVC的思想,就能理解SpringMVC,SpringMVC就是一个web框架,采取的是MVC的思想,所以SpringMVC是MVC思想的具体实现。

2️⃣获取请求参数

创建SpringMVC项目

SpringMVC只是Spring框架中的一个模块,而SpringBoot是Spring开发的脚手架。相当于Spring和SpringBoot都是基石,SpringBoot是基石之上的一个web后端开发模块。

SpringBoot是在Spring和SpringMVC之后出现的,所以最开始创建SpringMVC项目并不是基于SpringBoot项目来创建的,是基于Spring项目来创建的。不过现在有了SpringBoot了,就都用SpringBoot来创建SpringMVC项目了,因为SpringBoot更简便。

基于SpringBoot创建SpringMVC项目,只需要在创建项目之初引入Spring Web依赖即可:

image-20221205160234664

建立路由连接

在servlet项目中,需要加@WebServlet注解,来建立路由,而在SpringMVC项目中,也是需要加注解来建立路由的:

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {
    @RequestMapping("/hi")
    public String sayHi(){
        return "Hi,SpringMVC";
    }
}

==@RequsetMapping(请求映射)注解:==建立路由,加在方法上,也可以加在类上:

  • 加在类上相当于多了一级路径,如下代码中的请求URL应该是:http://127.0.0.1:8080/web/hi
  • 不加在类上则只有一级路径,去掉@RequestMapping(“/web”)则请求的URL:http://127.0.0.1:8080/hi
  • 该注解既可以支持Get请求,也可以支持Post请求,如果要想设置只支持其中一种请求,则可以加一个参数:@RequestMapping(value = “/hi”,method = RequestMethod.GET)或者使用@GetMapping注解(只支持Get请求)效果是一样的

==@GetMapping:==和@RequestMapping注解功能类似,但是只支持Get请求

==@PostMapping:==和@RequestMapping注解功能类似,但是只支持Post请求

要想前端发来的请求能映射到代码,除了@RequestMapping,还需要@Controller注解:

==@Controller:==这个注解是Spring中的一个注解,用于将类注册到容器中,

  • 如果不将该类注册到容器中,是没法调用到sayHi()方法的,也就是Spring是感知不到WebController这个类的,当前端发来请求的时候,容器中没有这个类,找不到/web/hi这个路由,就会返回404
  • 当该类上没有加@RequsetMapping的时候,建立路由的类只能加@Controller注解将类注册到容器中,使用其他注解是没法正确访问到的,因为MVC的思想中Controller层就是和前端交互的第一站,而SpringMVC就这么设计,规定死了必须加@Controller注解
  • 但是当类上加了@RequsetMapping注解的时候,使用五大类注解都是可以的

@ReponseBody:(可以加在类上也可以加在方法上)这个注解加在类上,代表类中的所有方法返回的不是静态页面,而基本的数据。因为之前开发web app前后端不分离,后端返回的直接就是页面,那其实是可以不加这个注解的,用法如下:

image-20221205192612792

  • 先在static目录下建一个index.html文件
  • 不加@ResponseBody注解,return “/index.html”;则返回的是页面:index.html

这是之前没有前后端分离的时候的开发方式,现在都是前后端分离的方式了,返回的不再是页面,而是基本的数据,所以得加@ReponseBody注解,才能返回基本的数据。

==@RestController:==RestController注解是一个组合注解,可以代替@Controller+@ResponseBody这两个注解。

获取请求参数

最基本的连接目前已经建立好了,但是很多时候请求中有参数,该如何获取呢?

一般Get请求中,参数在URL的queryString中;一般Post请求,参数在请求的body中,body中的参数的组织格式有多种,最常用的一般有:urlencoded(也就是URL中的queryString的格式),Json格式。

获取urlEncoded格式参数

在学习servlet时,URL中的queryString中的参数可以使用req.getParameter()方法获取到,body中的数据如果和queryString的组织格式一样,也是可以使用这个方法获取到的。如果body中的数据组织格式是Json,还需要jackson将Json字符串转换为java对象来获取参数。

那在SpringMVC中,URL中的queryString中的数据或者是body中的数据(如果以urlencoded格式组织的数据)都是可以使用以下三种方式来获取到的:

1️⃣方式一:原始的servlet方式:

package com.example.demo.controller;

import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {

    @RequestMapping("/get1")
    public String get1(HttpServletRequest request, HttpServletResponse response){
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        return "name:"+name+" age:"+age;
    }
}
  • 因为SpringMVC是基于servlet的一个框架,所以它还支持servlet中获取参数的一些方法,在get1方法中加上两个参数HttpServletRequest request ,HttpServletResponse response,就可以使用原始的servlet中的方式获取请求中的参数了。
  • 需要注意的是servlet这种方式只能获取URL中queryString中的参数,以及body中的urlEncoded格式的参数,如果body中的数据组织格式是json,getParameter()方法是获取不到的。

2️⃣方式二:通过方法参数获取

上面这种原始的servlet的方式还是比较复杂,到了SpringMVC时代就有了更简单的方式:

package com.example.demo.controller;

import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {

    @RequestMapping("/get2")
    public String get2(String name,Integer age){
        return "name:"+name+" age:"+age;
    }
}
  • 前端传来的参数,直接写在方法形参中,SpringMVC会将参数获取到,然后在调用get2方法的时候,会将参数传进来,不用自己再手动获取参数了。
  • 需要注意的是方法的形参名需要和请求中参数的key保持一致,否则会获取不到参数

⭕️参数重命名:有些情况下,前端传递的参数的key不太合理,比如 :n=张三,n这个key不如使用name替换,前端参数不合理,但是我们后端又不想被前端限制住,我们不想我们方法的形参也使用n,这个时候就可以重命名:使用@RequestParam注解来重命名:

@RequestMapping("/get2")
public String get2(@RequestParam(value = "n",required = false) String name,Integer age){
    return name+":"+age;
}
  • 使用注解后形参name的就可以任意取了,有注解中的value = "n"来和前端参数对应,就不是形参名称:name和前端参数去对饮了
  • required = false代表如果获取不到这个参数就给name赋值null
  • required = true代表如果获取不到这个参数就返回状态码为400(Bad Request)的响应

3️⃣方式三:将参数封装到对象中,再通过对象获取

使用第二种方式确实简单很多,不过如果请求中的参数太多了,假如有十个参数,那还能在方法中写十个形参吗?可以倒是可以,不过不合理。更合理的方式是将前端传来的参数封装为一个对象,每个参数作为这个对象中的属性。在代码中通过调用这个对象拿到参数:

Student类:

package com.example.demo.model;

import lombok.Data;

@Data
public class Student {
    private String name;
    private Integer age;
    private String sex;
    private String classId;
}

路由类:

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {
  
    @RequestMapping("/get3")
    public String get3(Student student){
        return student.getName()+student.getAge()+student.getSex()+student.getClassId();
    }
}
  • Spring帮我们获取到参数,封装成对象,然后我们直接调用对象属性就可以
  • Student类中的属性名需要和请求参数中的名字对应,否则获取不到对应的参数,则属性的值为null

获取表单标签参数

form表单标签也可以用来构造http请求,只支持get和post请求,并且参数的组织格式依然是urlencoded格式。

  • 如果是get请求,则参数在url的queryString中;

  • 如果是post请求,则参数在请求的body中,数据的组织格式依然是urlencoded。

既然form标签提交的参数都是urlencoded格式的数据,那么就仍然可以使用上面的三种方式来获取参数。

1️⃣方式一:通过方法形参获取到前端参数

🔑前端代码:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>登录</title>
</head>
<body>
    <h1>登录</h1>
    <form action="/web/login" method="post">
        <span>名字:</span>
        <input type="text" name="name">
        <br>
        <span>密码:</span>
        <input type="password" name="password">
        <br>
        <input type="submit" value="提交">
    </form>

</body>
</html>

🔑页面:

image-20221206104914447

🔑后端代码:

package com.example.demo.controller;

import com.example.demo.model.Student;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {
    
    @RequestMapping("/login")
    public String login(String name ,String password){
        return "name:"+name+" password:"+password;
    }
}

🔑返回结果:

image-20221206105053459

2️⃣方式二:将前端参数构建成对象,再通过对象获取到参数

获取Json格式参数

对于urlencoded格式的参数,可以使用上面的三种方式来获取,那对于Json格式的参数呢,如果前端传递的参数是Json格式来组织的呢?该怎么获取到参数?

在servlet中,对于请求的body中的Json格式的数据,需要借助jackson,来实现json字符串转换为java对象,再通过对象拿到参数。

其实在SpringBoot中已经内置了jackson依赖,并且为了更方便的使用jsckson将json字符串转换为java对象,SpringMVC还提供了一个注解:@RequsetBody

🔑路由类:

package com.example.demo.controller;

import com.example.demo.model.Student;
import com.example.demo.model.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {

    @RequestMapping("/get2")
    public String get2(@RequestBody User user){
        return user.toString();
    }
}

🔑User类:

package com.example.demo.model;

import lombok.Data;

@Data
public class User {
    private String name;
    private Integer age;
    private Integer classId;
    private String sex;
}

🔑前端请求:

image-20221206134759685

  • 在参数列表中加上一个注解:@RequsetBody,就可以实现自动获取json字符串中的参数并转为User对象。json字符串中的key需要和实体类User中的属性名对应,如果名字不对应,参数是不能赋值给User对象的属性的
  • 当加上@RequsetBody后,请求中的body就必须得是json字符串,就不能是urlencoded格式的数据,否则无法正确转换为User对象
  • 当加上@RequsetBody注解后,就不能再使用name,age等变量一个参数一个参数获取了,就必须得封装成一个User类来获取参数,否则参数无法正确获取:
package com.example.demo.controller;

import com.example.demo.model.Student;
import com.example.demo.model.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {

    @RequestMapping("/get2")
    //加了@RequsetBody后,使用单个形参无法正确获取前端参数
    public String get2(@RequestBody String name,Integer age){
        return user.toString();
    }
}

获取URL中的参数

URL中的参数可以在queryString中,这是最常见的,但是其实URL中queryString前的路径也是可以传递参数的:http://127.0.0.1:8080/web/get2/zhangsan/123(这里的zhagnsan/123就不作为路径了,作为参数)

参数其实是作为路径了,这种方式比较少见,但是SpringMVC也是支持获取路径中的参数了

@RequestMapping("/get2/{name}/{password}")
//这里的形参名需要和注解中的路径名对应
public String get2( @PathVariable String name,@PathVariable String password){
    return name+":"+password;
}

image-20221207173416119

上传图片

有时候前端需要上传一个图片到服务器,比如更改用户头像,那服务器端就得有相应的代码来接收图片,并保存图片到服务器的某一个目录下。

package com.example.demo.controller;

import com.example.demo.model.Student;
import com.example.demo.model.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {

    @RequestMapping("/upload")
    public String upload(@RequestPart("myfile") MultipartFile file) throws IOException {
        //最终会将图片保存到d盘根目录下
        file.transferTo(new File("d:/img.jpg"));
        return "upload ok.";
    }
}

使用postman构造一个上传图片的请求:

image-20221206164039651

获取请求信息

获取请求header

1️⃣方式一:传统的servlet方式

package com.example.demo.controller;

import com.example.demo.model.Student;
import com.example.demo.model.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {

    @RequestMapping("/getHeader")
    public String getHeader(HttpServletRequest request,HttpServletResponse response){
        String str = request.getHeader("User-Agent");
        return str;
    }
}

2️⃣方式二:SpringMVC的方式:

@RequestMapping("/getHeader")
public String getHeader(@RequestHeader("User-Agent") String userAgent){
    return userAgent;
}
  • 使用@RequestHeader注解,参数就是要获取的Header的key

获取cookie

1️⃣方式一:传统servlet方式:

package com.example.demo.controller;

import com.example.demo.model.Student;
import com.example.demo.model.User;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

@Controller
@ResponseBody
@RequestMapping("/web")
public class WebController {
    
    @RequestMapping("/getco")
    public String getCookie(HttpServletRequest request,HttpServletResponse response){
        Cookie[] cookies = request.getCookies();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < cookies.length; i++) {
            //获取cookie的key值
            String name = cookies[i].getName();
            stringBuilder.append(name);
            stringBuilder.append(":");
            //获取cookie的value值
            String value = cookies[i].getValue();
            stringBuilder.append(value);
        }
        return stringBuilder.toString();
    }
}

2️⃣方式二:SpringMVC的方式:

@RequestMapping("/getco")
public String getCookie(@CookieValue("java") String cookieValue){
    return cookieValue;
}
  • 使用@CookieValue注解,参数是cookie的key,就可以获取到cookie的value

创建session

当用户登录时,后端检查用户名和密码都正确的之后,后端要创建sesssion,来存储用户的身份信息。

登录页面后端实现创建session,并存储用户信息方式:

@RequestMapping("/login")
    public String login(String name ,String password,HttpServletRequest request,HttpServletResponse response){
        //从数据库查询数据检查用户名和密码是否正确
        //正确无误后,创建session来保存用户身份信息
        //参数为true,服务器中有sessionId对应的session则直接返回,无则创建session
        HttpSession session = request.getSession(true);
        //在session中存储用户信息
        session.setAttribute("userName","张三");
        return "login ok";
    }

获取session中存储的信息

==方式一:==传统servlet方式:

@RequestMapping("/index")
public String index(HttpServletRequest request,HttpServletResponse response) throws IOException {
    //参数为false,从服务器查询sessionId对饮的session,有则返回,无则返回null
    HttpSession session = request.getSession(false);
    //session为null说明没有会话信息,重定向到登录页面
    if (session == null){
        response.sendRedirect("/login.html");
        return "未登录状态";
    }
    //拿到session中的用户身份信息
    String userName = (String) session.getAttribute("userName");
    return "ok";
}

==方式二:==SpringMVC使用注解的方式:

@RequestMapping("/sess")
public String getSession(@SessionAttribute(value = "userName",required = false) String userName){
    return "userName:"+userName;
}
  • 使用@SessionAttribute注解,可以自动获取到session中存储区的参数信息,并赋值给变量userName。

  • value = “userName” 代表要获取session中参数的key的名称为userName,

  • required = false代表如果从session中获取不到userName参数就给变量userName赋值为null。使用注解的方式获取session中的参数其实还是使用的原始的servlet方式一,不过代码是SpringMVC帮我们实现的,我们不用写复杂的获取HttpSession对象,再用这个对象获取session中存储的用户信息。

  • required = true代表如果从session中获取不到userName这个参数,就返回状态码为400(Bad Request)的响应

  • 获取不到userName参数有以下几种情况:

    1. 客户端发送的请求的cookie中没有sessionId(可能原因是存储sessionId的cookie过期了)
    2. 请求中的cookie中有sessionId,但是服务器重启了(服务器重启后session在内存中就没有了)
    3. 请求的cookie中的sessionId和服务器这边存储的session的sessionId对应不上
    4. 请求中的cookie中的sessionId在服务器存储的session中可以对应上,顺利获取到了HttpSession对象,但是HttpSession对象中并没有userName这个参数(可能原因是登录成功后创建session时就没有给HttpSession中设置userName这个参数)

3️⃣返回数据给前端

返回页面

在最开始前后端不分离的时候,后端直接返回的就是html页面,当不加@ReponseBody这个注解的时候,就可以返回一个页面:

@RequestMapping("/get4")
public Object get4(){
    return "/index.html";
}

image-20221207180957248

返回Json格式数据

当前后端分离开之后,后端返回的数据就不再是页面了,而是构建页面的数据,如果想在返回的响应中数据以Json格式来组织,在servlet时期,需要jackson工具,手动将java对象转换为Json字符串。

但是在SpringMVC时期,当返回的是一个HashMap的时候,就会自动实现在响应中以Json格式组织数据,这是SpringMVC帮我们做好的(其实是内置了Jackson工具):

@RequestMapping("get5")
public HashMap<String,Integer> get5(String name,Integer password){
    HashMap<String,Integer> hashMap = new HashMap<>();
    hashMap.put(name,password);
    return hashMap;
}
  • 在响应中也可以看到Content-Type:application/json。

image-20221207182905347

  • 从响应中可以看到成功返回了json格式数据,比servlet时代的方式简单了很多
  • 使用TreeMap和使用HashMap的效果是一样的。

使用HashSet也可以返回json格式数据:

@RequestMapping("get6")
public HashSet<String> get6(){
    HashSet<String> hashSet = new HashSet<>();
    hashSet.add("java");
    hashSet.add("bit");
    return hashSet;
}

image-20221207183840156

  • 使用HashSet和TreeSet的效果是一样的。

请求转发和请求重定向

请求转发和请求重定向都是用来实现跳转的,但实现方式不同。

1️⃣定义上的区别:

请求转发:发生在服务器端内部,当服务器接收到一个请求后,服务器会将请求转发给目标地址,再将目标地址返回的结果返回给客户端。

请求重定向:当服务器接收到请求后,会先返回一个响应,这个响应会告诉浏览器再给目标地址发送一个请求(目标地址在响应的header中)。然后浏览器就会向目标地址发送第二个请求,服务器再返回一个响应。

🏮举个栗子:

小明:妈妈,我想吃烤山药 妈妈:好,我去给你买(请求转发)

小明:妈妈,我想吃烤山药 妈妈:你自己去买吧(请求重定向)

2️⃣请求转发和请求重定向的过程:

image-20221207211743014

3️⃣浏览器地址栏最终显示的URL不同:

请求转发整个过程,只有一次交互,地址栏中的URL不会变

请求重定向整个过程,有两次交互,所以地址栏最终会显示第二次请求的URL,不再是第一次请求的URL。

4️⃣代码实现不同:

在SpringMVC中,

请求转发和请求重定向的代码实现略有差别:

@Controller
public class TestController {
    //请求重定向
    @RequestMapping("/hello")
    public String hello(){
        return "redirect:/index.html";
    }
    //请求转发
    @RequestMapping("/hi")
    public String hi(){
        return "forward:login.html";
    }
}

虽然后端可以实现页面跳转,但是页面跳转一般都是由前端来完成的,一般不由后端来完成。

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

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

相关文章

Linux -- 信号控制进程 Kill 命令 简引

Kill 命令 &#xff1a;给进程发送信号 &#xff1a;[rootfsw ~]# kill -l # 可以列出 当前所有的信号量 比较常用的就是 &#xff1a;1) SIGHUP 重新加载配置2) SIGINT 键盘中断^C 即 Ctrl C3) SIGQUIT 键盘退出9) SIGKILL 强制终止15) SIGTERM 终止&#xff08;正…

『OPEN3D』点云表面重建

目录 1 点云法线一致性估计 2 点云的表面重建 1 Alpha shapes reconstruction 2 Ball pivoting reconstruction 3 poisson surface reconstruction 1 点云法线一致性估计 在点云处理的章节中已经介绍使用estimate_normals来生成点云的发现信息&#xff0c;但该方法通过拟合…

业务流程测试

用例设计主要问题主要问题存在于&#xff1a;1、测试点分析&#xff1a;逻辑性不强对于整个页面功能划分不清晰&#xff1b;不同测试点归类不清晰&#xff1b;不能形成相对固定的套路&#xff0c;书写耗费大量时间...2、测试用例&#xff1a;关于&#xff0c;要细致到什么程度&…

一个供参考的计算机的学习路线

本文是介绍如何成为一个Geek&#xff0c;一个真正的计算机高手。 适合有成为IT领域技术大牛的人参考。 写给大一新生和所有向深耕IT领域的人&#xff0c;避免走一些弯路。 仅代表个人想法&#xff0c;供批判性参考。 第一门入门的必备功课-语法与算法 什么是计算机&#xff1f…

力扣sql简单篇练习(二十二)

力扣sql简单篇练习(二十二) 1 上月播放的儿童适宜电影 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # Write your MySQL query statement belowSELECT titleFROM ContentWHERE kids_contentY AND content_typeMoviesAND c…

MYSQL性能分析,Explain

文章目录一、MYSQL常见瓶颈二、ExplainExplain是什么一、MYSQL常见瓶颈 CPU&#xff1a; CPU饱和IO&#xff1a;磁盘IO速度过慢。服务器的硬件性能瓶颈。 二、Explain Explain是什么 使用explain关键字可以模拟优化器执行sql查询语句&#xff0c;从而知道mysql如何处理你的…

Python 随机漫步

目录 1. 创建 RandomWalk 类 2. 选择方向 3. 绘制随机漫步图 4. 总结 本篇博客将使用 Python 来生成随机漫步数据&#xff0c;在使用 Matplotlib 以引人注目的方式将这些数据呈现出来。 随机漫步 是这样行走得到的路径&#xff1a;每次行走都是完全随机的、没有明确…

跨域问题以及Ajax和Axios的区别

文章目录1. 同源策略2. 同源策略案例3. 什么是跨域4. 跨域解决方法4.1 Ajax的jsonp4.2 CORS方式4.3 Nginx 反向代理5. Axios 和 Ajax 的区别6. Axios 和 Ajax 的区别及优缺点6.1 Ajax&#xff1a;6.1.1 什么是Ajax6.1.2 Ajax的原理6.1.3 核心对象6.1.4 Ajax优缺点6.1.4.1 优点&…

大白话+画图 从源码角度一步步搞懂ArrayList和LinkedList的使用

1.说说ArrayList 1.基本原理 ArrayList&#xff0c;原理就是底层基于数组来实现。 01.基本原理&#xff1a; 数组的长度是固定的&#xff0c;java里面数组都是定长数组&#xff0c;比如数组大小设置为100&#xff0c;此时你不停的往ArrayList里面塞入这个数据&#xff0c;此…

Warshall算法求传递闭包及Python编程的实现

弗洛伊德算法-Floyd(Floyd-Warshall)-求多源最短路径&#xff0c;求传递闭包 Floyd算法又称为插点法&#xff0c;是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法&#xff0c; 与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大…

minikube搭建Kubernetes环境

前言 Kubernetes 一般都运行在大规模的计算集群上&#xff0c;管理很严格&#xff0c;Kubernetes 充分考虑到了这方面的需求&#xff0c;提供了一些快速搭建 Kubernetes 环境的工具。 minikube 它是一个“迷你”版本的 Kubernetes&#xff0c;自从 2016 年发布以来一直在积极地…

Lesson 8.1 决策树的核心思想与建模流程

文章目录一、借助逻辑回归构建决策树1. 决策树实例2. 决策树知识补充2.1 决策树简单构建2.2 决策树的分类过程2.3 决策树模型本质2.4 决策树的树生长过程2.5 树模型的基本结构二、决策树的分类与流派1. ID3(Iterative Dichotomiser 3) 、C4.5、C5.0 决策树2. CART 决策树3. CHA…

minio安装配置和使用(一)

minio官网https://www.minio.org.cn 从官网获得安装文件。官网提供了Binary、RPM、DEB三种方式安装minio。 Binary方式我在我的测试环境中没有测试通过&#xff0c;按官网方式下载执行会报错如下&#xff1a; 查了下这个错误提示&#xff0c;似乎跟内存有关。 改用RPM方式安…

HCIP第一个实验

实验要求与实验拓扑子网划分分析将骨干链路看成一个整体&#xff0c;路由器后的2个环回地址先看成一个&#xff0c;最后再进行拆分。计算得出&#xff0c;一共需要划分为6个子网段&#xff0c;取三位。再将每一条网段&#xff0c;按照题目要求进行划分最后完成子网划分。子网划…

进行嵌入式C语言编程调试的通用办法

总结了一下调试我们嵌入式C程序的一些基本的办法和思想&#xff0c;供大家学习参考&#xff1a; 打印日志&#xff1a;在代码中添加打印语句&#xff0c;输出变量值、函数调用等信息&#xff0c;以便在程序运行时观察程序执行情况。 断点调试&#xff1a;在代码中添加断点&…

【编程实践】用 go 语言实现 B+ 树

文章目录 用 go 语言实现 B+ 树定义 B+ 树的结构B+ 树的插入操作函数B+ 树的查找小结用 go 语言实现 B+ 树 B+ 树是一种平衡的查找树,它可以有效组织存储大量的键值对,从而支持快速的插入和查找操作。 Go 语言可以用来实现 B+ 树,实现的思路是:首先,定义 B+ 树的结构,其…

【Linux】安装Linux操作系统具体步骤

1). 选择创建新的虚拟机 2). 选择"典型"配置 3). 选择"稍后安装操作系统(S)" 4). 选择"Linux"操作系统,"CentOS7 64位"版本 5). 设置虚拟机的名称及系统文件存放路径 6). 设置磁盘容量 7). 自定义硬件信息 8). 启动上述创建的新虚拟机…

【C++初阶】list的使用

大家好我是沐曦希&#x1f495; 文章目录一、前言二、构造三、迭代器四、增删查改1.头插头删2.尾插尾删3.查找和插入4.删除五、其他成员函数1.排序和去重2.splice和remove3.resize一、前言 list本质是带头双向循环链表&#xff0c;本文只对list的一些常用接口进行说明&#xf…

Qt creator中操作QAction加入QToolBar

背景&#xff1a;个人笔记。我之前没有系统化学习过任何资料&#xff0c;使用很多工具都是按需出发&#xff0c;直接上手&#xff0c;遇到问题再研究的。所以会有一些弯路。本文言语中难免有对个人情绪的生动描述&#xff0c;希望不要影响读者心情&#xff0c;这只是我学习过程…

前端网络安全

什么是同源策略同源指的是&#xff1a;协议、端口号、域名必须一致。他是浏览器的一个用于隔离潜在恶意文件的重要安全机制。限制了从同一个源加载的文档或脚本&#xff0c;与另一个源的资源进行交互。同源策略主要限制了三个方面&#xff1a;当前域下的js脚本不能够访问其他域…