Spring MVC - Controller的创建与使用

控制器Controller是处理器,是真正处理请求的组件

1 创建Controller

一般在src/main/java/com/qdu下建立一个controller包用来存放所有控制器。当创建一个控制器时,首先要记得使用@Controller标记将该类注册成为一个控制器类。

然后在SpringMVCConfig类中开启对com.qdu.controller包的扫描,并使用@EnableWebMvc注解,这样controller待会要用到的@RequestMapping等的配置会生效。

@Configuration
@ComponentScan(basePackages = {"com.qdu.controller"})
@EnableWebMvc
public class SpringMVCConfig implements WebMvcConfigurer{
    
    @Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/static/**").addResourceLocations("/static/");
	}

	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		registry.jsp("/WEB-INF/jsp/", ".jsp");
	}

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/").setViewName("index");
		registry.addViewController("/toIndex").setViewName("index");
		registry.addViewController("/toPage1").setViewName("page1");
		registry.addViewController("/toPage2").setViewName("page2");
		registry.addViewController("/toPage3").setViewName("page3");
		registry.addViewController("/toNext").setViewName("next");
		registry.addViewController("/toAddStudent").setViewName("add_student");
		registry.addViewController("/toFindStudentPage").setViewName("find_student");
	}

}

可以发现在Spring MVC的配置类中我们也配置了许多视图控制器,用于跳转到对应的JSP页面,如这里的toIndex是跳转到index.jsp,在前端页面的引用方法为:

<div class="text-center">
    <a href="toIndex" class="btn btn-sm btn-danger">返回首页</a>
</div>

2 关于Get请求和Post请求的映射

在controller中可以使用@RequestMapping注解,它默认可以映射所有请求,包括get和post。也可以通过method属性指定当前方法处理的请求的类型,这样方法只能处理对应类型请求。

假设现在有一个控制器TestController1,要在该控制器中处理两数相加的get请求与post请求,方法名分别是cal1与cal2

@Controller
@RequestMapping("/test1")
public class TestController1 {

    public String cal1(int num1, int num2, Model model) { }

    public String cal2(int num1, int num2, Model model) { }

}

首先对两种方法使用@RequestMapping注解,内容应填入对应的url,也可以用method属性指定请求对应的类型。

@RequestMapping(value = "/test1/cal1", method = RequestMethod.GET)
public String cal1(int num1, int num2, Model model) { }

@RequestMapping(value = "/test1/cal2", method = RequestMethod.POST)
public String cal2(int num1, int num2, Model model) { }

接下来继续写方法内容,大致过程就是获取请求参数(这里就是要相加的两个数),然后进行加和操作后再返回结果页面。

我们可以从前端的表单看到输入进来的两个数:

<form action="test1/cal1" class="form-inline text-center bg-danger" id="form1" method="get">
	<h3 class="text-danger">表单1-使用Get提交表单</h3>
	<hr />
	数字1: <input type="text" name="num1" value="100" class="form-control">
	<br><br> 
	数字2: <input type="text" name="num2" value="200" class="form-control"> 
	<br><br> 
	<button class="btn btn-sm btn-danger">计算</button>
</form>

注意观察两个数字的name属性的值即可。 

@RequestMapping(value = "/test1/cal1", method = RequestMethod.GET)
public String cal1(int num1, int num2, Model model) {
    model.addAttribute("jieguo", num1 + num2);
    return "result";
}

这里给前端展示结果的变量取名为“jieguo”,故引用时应为${jieguo},代码应如下:

<h4 class="text-primary">
    计算结果: <span class="text-danger padding5">${jieguo}</span>
</h4>

同时还可以在前端展示请求的url,在cal1方法中加上:

model.addAttribute("requestUrl", "/test1/cal1");

前端展示的代码应为:

<h4 class="text-primary">
    请求url: <span class="text-danger padding5">${requestUrl}</span> 
</h4>

最后展示的结果应该为:

请求url:/test1/cal1

计算结果:300

cal2方法的代码大同小异,只需要将method属性的值改为:RequsetMethod.POST

如果觉得使用@RequestMapping注解书写较多,也可使用@GetMapping、@PostMapping简化书写。

最后,完整的的TestController1代码如下:

package com.qdu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/test1")
public class TestController1 {
	
	@GetMapping("/cal1")
	public String cal1(int num1, int num2, Model model) {
		model.addAttribute("requestUrl", "/test1/cal1");
		model.addAttribute("jieguo", num1 + num2);
		return "result";
	}

	@PostMapping("/cal2")
	public String cal2(int num1, int num2, Model model) {
		model.addAttribute("requestUrl", "/test1/cal2");
		model.addAttribute("jieguo", num1 + num2); 
		return "result"; 
	}

}

一定要注意,这里的

return "result"

是指跳转到result.jsp页面,原理在创建和配置Spring MVC框架构建Web应用这篇文章中提到过

因为WEB-INF/jsp目录下的页面是不能直接访问,需要经过控制器跳转,而且最一开始的Spirng MVC配置类中,我并没有给result.jsp配置对应的视图控制器,而是应该在得出计算结果之后,由对应的控制器控制跳转到结果界面。

最后有一个小区别,我们观察浏览器的url栏,发现get请求和post请求的url并不一样:
get请求会显示出请求参数及其值:

而post请求则不会:

3 控制器类方法的接受参数

3.1 参数名与请求参数同名

控制方法参数可以是任何类型,可以保持参数名和请求参数名同名来接收对应的参数,常规类型转换会自动完成。

请看接下来的例子,前端请求两个数num1、num2,返回二者相加的结果,控制器类方法的参数也为num1、num2

前端:

<a href="test2/req1?num1=11&num2=12">1.  任意类型-方法参数名和请求参数名同名</a>

在这一章节中使用的TestController2的代码初始化如下:

@Controller
@RequestMapping("/test2")
public class TestController2 {

    @Autowired
    private ExamService examService;

}

控制器类方法req1:(注意,req1的参数应该与前端的一样,为num1、num2)

@GetMapping("/req1")
public String req1(int num1, int num2, Model model) {
    model.addAttribute("jieguo", num1 + num2);
    return "result";
}

3.2 请求参数名和方法参数名不同名

若前端发来的请求参数名与控制器类的方法参数不同名,则应使用@RequestParam注解指定请求参数的信息。

假如在前端,传请求参数的代码为:

<a href="test2/req2?number1=21&number2=22">2.  使用@RequestParam注解</a>

可以看到前端的请求参数名为number1、number2,但是在控制器类方法中,我仍然想用num1、num2当方法参数,可以这样写:

@GetMapping("/req2")
public String req2(
        @RequestParam(value = "number1", defaultValue = "0") int num1, 
        @RequestParam(value = "number2", defaultValue = "0") int num2,
        Model model) {
    model.addAttribute("jieguo", num1 + num2);
    return "result";
}

value或name属性: 指定请求参数的名称

defaultValue属性: 指定当该请求参数没有提供的时候,使用什么默认值

requird属性: 指定该请求参数是否必须要提供,默认是true,不提供会抛出异常,对于可选的参数可设置为false

3.3 接收一个请求参数的多个值

有时候一个参数会有多个值,比如我们使用复选框来提交的数据。

假设我们前端让用户选取自己的爱好有哪些,可以多选,前端会传来多个请求参数hobbies的值。对于这多个hobbies的值,我们可以用一个String[]数组来接受。

@GetMapping("/req3")
public String req3(String[] hobbies, Model model) {
    model.addAttribute("hobbies", hobbies);
    return "hobby_page";
}

在前端hobby_page展示爱好,使用<c:forEach>遍历hobbies数组:

<h4 class="text-primary">
    结果:
    <span class="text-danger padding5">
        <c:forEach items=${hobbies} var="hobby">
            ${hobby}
        </c:forEach>
    </span>
</h4>

3.4 获取请求对象与响应对象

有的时候除了获取请求参数,还可能需要操作请求,可以直接获取请求对象

可以使用HttpServletRequest或ServletRequest类型来获取请求对象
可以使用HttpServletResponse或ServletResponse类型来获取响应对象

前端的请求参数为:

<a href="test2/req4?num1=41&num2=42">4.  请求对象(HttpServletRequest)和响应对象(HttpServletResponse)</a>

在控制器方法中,使用HttpServletRequest类型的req获取请求对象,进而得到请求参数num1、num2

@GetMapping("/req4")
public String req4(Model model, HttpServletRequest req, HttpServletResponse resp) {
    int num1 = Integer.parseInt(req.getParameter("num1"));
    int num2 = Integer.parseInt(req.getParameter("num2"));
    model.addAttribute("jieguo", num1 + num2);
    return "result";
}

3.5 包含所有请求参数的Map集合

有的时候可能需要获取所有的请求参数(请求参数比较多的时候,而且个数不定的时候),可以直接使用一个Map<String, String>集合获取所有的请求参数。但是该参数前面必须添加@RequestParam注解说明这个Map集合用于封装所有的请求参数

@GetMapping("/req5")
public String req5(@RequestParam Map<String, String> map, Model model) {
    int num1 = Integer.parseInt(map.get("num1"));
    int num2 = Integer.parseInt(map.get("num2"));
    model.addAttribute("jieguo", num1 + num2);
    return "result";
}

3.6 会话对象HttpSession

3.6.1 介绍会话对象

可以发现,我们之前的控制器类方法中都有一个参数Model对象,放入Model对象的数据是请求范围的数据,默认跳转页面是以请求转发的形式跳转页面。

可以直接加一个HttpSession类型的参数,用于获取当前会话对象,以操作当前会话对象

@GetMapping("/req6_1")
public String req6_1(int number, HttpSession session) {
    session.setAttribute("jieguo", number * number);
    return "result";
}

3.6.2 HttpSession对象获取会话对象中属性 

如果希望获取会话范围的属性或操作会话,可以直接获取会话对象,进而操作会话

@GetMapping("/req6_2")
public String req6_2(HttpSession s) {
    System.out.println("~~~~~~~~~~~~~~~jieguo:" + s.getAttribute("jieguo"));
    return "hint";
}

 在这里,我们会在控制台输出6_1中number * number的结果:

3.6.3 @SessionAttribute注解获取会话对象中属性 

如果希望获取会话范围的属性,也可使用@SessionAttribute注解修饰的方法参数来获取一个会话范围的属性,可以直接使用对应类型接收会话属性。
需要指定获取的属性的名称,如这里的jieguo 

@GetMapping("/req6_3")
public String req6_3(@SessionAttribute("jieguo") int result) {
    System.out.println("***************jieguo:" + result);
    return "hint";
}

3.7 Model、ModelMap、Map

如果控制器方法中需要返回一些数据显示到页面上,可以使用Model或ModelMap或Map对象,作用一样,但是每个类型提供的方法不同
可以根据选择,通常使用Model即可,这三个对象中的数据都是请求范围的数据

@GetMapping("/req7")
public String req7(Model model, ModelMap mm, Map map) {
    model.addAttribute("msg1", "这是使用Model对象添加的属性");
    mm.addAttribute("msg2", "这是使用ModelMap对象添加的属性");
    map.put("msg3", "这是使用Map对象添加的属性");
    return "message";
}

3.8 路径变量@PathVariable

3.8.1 单个参数

对于REST风格的路径req8/8 ,如果某一级表示的是参数值,则使用{变量名}来表示这是一个路径变量/路径参数

前端我们设定的url为test2/req8/8,我们要将最后这个8设定为路径变量

<a href="test2/req8/8">8.  使用@PathVariable(路径变量)-单个参数</a>

我们在控制器方法添加了一个参数number(使用对应类型即可),用于接收路径变量num的值:

@GetMapping("/req8/{num}")
public String req8(Model model, @PathVariable("num") int number) {
    model.addAttribute("jieguo", number * number);
    return "result";
}

3.8.2 单个参数 - url写法

对于url:/req9/9/square

//如果方法参数名和路径变量名同名,则使用@PathVariable注解的时候就不需要指定路径变量的名称了
@GetMapping("/req9/{num}/square")
public String req9(@PathVariable int num, Model model) {
    model.addAttribute("jieguo", num * num);
    return "result";
}

3.8.3 多个路径变量/参数

对于url:/req10/10/add/100,我想将10与100分别设为路径变量,分别命名为num1、num2,直接在方法声明多个参数即可

@GetMapping("/req10/{num1}/add/{num2}")
public String req10(@PathVariable int num1, @PathVariable int num2, Model model) {
    model.addAttribute("jieguo", num1 + num2);
    return "result";
}

3.8.4  *通配符

使用 * 通配符匹配一级路径

诸如此路径:/req11/*/square/111,这个路径可以匹配/req11/user/square/111,也可以匹配/req11/admin/square/111

假设在前端有这两个请求:

<a href="test2/req11/user/square/111">11.1.  使用@PathVariable(路径变量)-通配符*</a></li>
<a href="test2/req11/admin/square/112">11.2.  使用@PathVariable(路径变量)-通配符*</a>

在这里,路径最后的数为路径变量num,要在控制器方法中得到num*num,除此之外只有第三级user与admin不同,可以用一个*通配符来匹配这一级路径。

@GetMapping("/req11/*/square/{num}")
public String req11(Model model, @PathVariable int num) {
    model.addAttribute("jieguo", num * num);
    return "result";
}

3.8.5 **通配符

使用 ** 通配符匹配任意多级路径

诸如这两个路径:

/req12/aaa/bbb/ccc/ddd/121/square

/req12/ddd/122/square

我们可以发现,路径中的数字为路径变量num,在控制器方法中得到num*num,其余部分只在/req12与/{num}之间的路径不同,但是这之间并不只是单级路径,而是多级路径,要使用 ** 通配符来匹配:

@GetMapping("/req12/**/{num}/square")
public String req12(Model model, @PathVariable int num) {
    model.addAttribute("jieguo", num * num);
    return "result";
}

3.9 对象类型

控制器类方法参数支持对象类型,在有以下类似的情形可以使用对象类型参数:
要提交多个数据,每个请求参数与实体类的参数一一对应,诸如我们前端有一个表单,用来收集学生的个人信息:

<form action="test2/req13" class="form-inline" method="post">
    <span>学号:</span><input type="text" name="sid" value="2019208888" class="form-control" placeholder="在此输入学号">
    <br><br>
    <span>姓名:</span><input type="text" name="sname" value="anna" class="form-control" placeholder="在此输入姓名">
    <br><br>
    <span>密码:</span><input type="text" name="spassword" value="123456" class="form-control" placeholder="在此输入密码">
    <br><br>
    <span>性别:</span>
    <select name="sgender" class="form-control fixedWidth">
        <option value="男">男</option>
        <option value="女">女</option>
    </select>
    <br><br>
    <span>班级:</span>
    <select name="sbatch" class="form-control fixedWidth">
        <option value="19软件J01">19软件J01</option>
        <option value="19软件BD01">19软件BD01</option>
        <option value="19软件BD02">19软件BD02</option>
        <option value="19软件BD03">19软件BD03</option>
    </select>  
    <br><br>
    <span>生日:</span>
    <input type="date" name="sdob" class="form-control" value="2001-12-03">
    <br><br>
    <input type="submit" value="添 加" class="btn btn-sm btn-primary">
</form>

在这里我们还有一个实体类Student,Student类中的每一个参数与表单中的每一请求参数一一对应:

public class Student {

	private String sid;
	private String sname; 
	private String spassword;
	private String sgender;
	private String sbatch;
	
	//所有的请求参数都是以字符串的形式提交,字符串转成double、int等类型会自动转换
	//但是不能自动转换成Date类型
	//使用@DateTimeFormat注解后,字符串类型的请求参数就可以转换成Date类型 
	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date sdob;

	public Student() {
	}

	public Student(String sid, String sname, String spassword, String sgender, String sbatch, Date sdob) {
		this.sid = sid;
		this.sname = sname;
		this.spassword = spassword;
		this.sgender = sgender;
		this.sbatch = sbatch;
		this.sdob = sdob;
	}

	public String getSid() {
		return sid;
	}

	public void setSid(String sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public String getSpassword() {
		return spassword;
	}

	public void setSpassword(String spassword) {
		this.spassword = spassword;
	}

	public String getSgender() {
		return sgender;
	}

	public void setSgender(String sgender) {
		this.sgender = sgender;
	}

	public String getSbatch() {
		return sbatch;
	}

	public void setSbatch(String sbatch) {
		this.sbatch = sbatch;
	}

	//对于java对象,如果有日期类型的属性,转换成json的时候,默认是以毫秒的形式显示时间
	//对于日期时间类型的数据,可以添加@JsonFormat来指定转成json的时候
	//日期时间是什么格式,还可以指定时区
	@JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")
	public Date getSdob() {
		return sdob;
	}

	public void setSdob(Date sdob) {
		this.sdob = sdob;
	}

	@Override
	public String toString() {
		return "Student [sid=" + sid + ", sname=" + sname + ", spassword=" + spassword + ", sgender=" + sgender
				+ ", sbatch=" + sbatch + ", sdob=" + sdob + "]";
	}
}

我们要将前端获得的学生信息进行展示:

@GetMapping("/req13")
public String req13(Student s) {
    System.out.println("学生信息:"+s);
    return "hint";
}

3.10 获取Cookie值

在这里为了简化,不再自行创建cookie,每个web程序都会放置一个名为JSESSIONID的cookie到客户端
为了获取某个Cookie的值,可以给控制器方法添加参数,用于获取Cookie的值
用于获取Cookie值的参数需要使用@CookieValue注解修饰,并指定Cookie的名称

@GetMapping("/req14")
public String req14(@CookieValue("JSESSIONID") String sessionId) {
	System.out.println("*******************sessionId:"+sessionId);
	return "hint"; 
}

4 控制器类方法的返回参数

4.1 String

从前端接受一个数并返回这个数的平方,控制器类的方法为String类型

前端发送请求的代码为:

<a href="test3/req3_1?number=31">3.1. String</a>

控制器类方法代码: 

@GetMapping("/req3_1")
public String req3_1(int number, Model model) {
    model.addAttribute("jieguo", number * number);
    return "result";
}

在默认情况下,最后的return "result"是指要跳转的视图的名称。

但有些情况下,我们希望控制器方法返回的内容为响应正文的内容,而不是跳转的视图名称,此时可以使用@ResponseBody注解修饰该方法。

// produces属性用于指定返回的响应内容的MIME类型和字符集编码
@GetMapping("/req4_1", produces = "text/html;charset=utf-8")
@ResponseBody
public String req4_1(String name) {
    return "<h1>Hello, " + name + "</h1>";
}

4.2 ModelAndView

这里控制器类的方法为ModelAndView类型,返回ModelAndView类型的mv。将结果和要跳转的视图都封装到ModelAndView中,最后返回这个ModelAndView。

@GetMapping("/req3_2")
public ModelAndView req3_2(int number) {
    ModelAndView mv = new ModelAndView();
    mv.setViewName("result");
    mv.addObject("jieguo", number * number);
    return mv;
}

 4.3 Integer、int、Double、double、Float、float、Boolean、boolean等

@GetMapping("/req4_2")
@ResponseBody
public Integer req4_2(int number) { return number * number; }

4.4 单个对象:如Student、Dog、Product、Course等

Spring MVC默认使用Jackson作为json处理器,来转换java对象和json数据。只要添加jackson的依赖,java对象就会被自动转换为json对象。

如果返回一个对象(封装器类型和String等除外),则数据默认会被转换成json格式

@GetMapping("/req4_3")
@ResponseBody
public Student req4_3() {
    return new Student(
        return new Student(
            "2019209999","张三","123456","男","19软件J03",Date.valueOf("2001-12-03")
    );
}

 再举一个例子,发送ajax请求,返回单个对象。

假设前端有一个表单收集学生的学号,填写学号后能显示该学生的学生信息:

<form class="form-inline">
                  学号:<input type="text" id="sid" value="2019209991"class="form-control"> 
    &nbsp;&nbsp;
    <input type="button" id="btn" value="查询" class="btn btn-sm btn-danger">
</form>

显示查到的学生信息的前端代码如下:

<div id="studentInfo">
    <p>学号:<span id="idSpan"></span> </p>
    <p>姓名:<span id="nameSpan"></span> </p>
    <p>密码:<span id="passwordSpan"></span> </p>
    <p>姓名:<span id="genderSpan"></span> </p>
    <p>班级:<span id="batchSpan"></span> </p>
    <p>生日:<span id="dobSpan"></span> </p>
</div>

 我们有一个控制器类TestController4,调用StudentService中的方法根据学号查询学生,返回一个Student对象:

//@RestController是@Controller+@ResponseBody注解的组合
//@RestController说明当前类是个控制器类,并且相当于每个方法前添加@ResonseBody注解
@RestController
@RequestMapping("/test4")
public class TestController4 {
    
    @Autowired 
    StudentService studentService;

    @GetMapping("/req4_7")
    public Student req4_7(String id) {
        return studentService.getOne(id);
    }
}

此时我们回到前端来写ajax部分的代码,根据后端Controller的方法可以得知,请求的url应为/test4/req4_7,请求类型为Get请求

<script>
    $(document).ready(function () {
    
        $("#btn").click(function() {

            //ajax()函数用于发送一个ajax请求
            $.ajax({
                url: "/test4/req4_7",
                type: "GET",
                data: {id : $("#sid").val()},
                success: function (s){
                    //success对应的函数可以添加一个参数,用于接收控制器返回的数据
                    //参数名可以随意命名,但是尽量有意义,这里s用于接收返回的学生数据,是一个json对象
                    $("#idSpan").html(s.sid); //html()函数可用于修改选中元素的内容为指定内容
                    $("#nameSpan").html(s.sname);
                    $("#passwordSpan").html(s.spassword);
                    $("#genderSpan").html(s.sgender);
                    $("#batchSpan").html(s.sbatch);
                    $("#dobSpan").html(s.sdob);
                },
                error: function (req, status, error) {
                    alert("请求失败:" + error);
                }
            });
        });
    });
</script>

 

4.5 列表:List<Student>、List<Product>等

如果返回的是列表,列表会被转换成json数组

@GetMapping("/req4_4")
public List<Student> req4_4() {
	List<Student> list=new ArrayList();
	list.add(new Student("2019209991","小胖","123456","男","19软件J01",Date.valueOf("2001-12-03")));
	list.add(new Student("2019209992","小强","123456","男","19软件J01",Date.valueOf("2002-02-09")));
	list.add(new Student("2019209993","小兰","123456","女","19软件J02",Date.valueOf("2003-11-10")));
	list.add(new Student("2019209994","小明","123456","男","19软件J02",Date.valueOf("2000-09-01")));
	list.add(new Student("2019209995","小奇","123456","男","19软件J03",Date.valueOf("2001-07-08")));
	list.add(new Student("2019209996","小红","123456","女","19软件J03",Date.valueOf("2002-11-19")));
	return list;
}

4.6 Map集合:Map<String,String>,Map<String,Student>等

如果返回的是一个Map集合,则该Map对象会被转换成一个json对象

@GetMapping("/req4_5")
public Map req4_5() {
	Map map=new HashMap();
	map.put("error_code", 101);
	map.put("error_message", "发送的请求参数有错");
	return map;
}

4.7 void类型

返回类型为void,说明返回的响应内容为空

@GetMapping("/req4_6")
public void req4_6() {
	System.out.println("...................我没返回任何值!!!");
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PostgreSQL数据库的json操作

1.操作符 select json字段::json->key值 from order -- 对象域 select json字段::json->>key值 from order -- 文本 select json字段::json#>{key值} from order -- 对象域 select json字段::json#>>{key值} from order -- 文本对象域表示还能继续操作&#…

《MySQL系列-InnoDB引擎02》InnoDB存储引擎介绍

文章目录 第二章 InnoDB存储引擎1 InnoDB存储引擎概述2 InnoDB存储引擎的版本3 InnoDB体系架构3.1 后台线程3.2 内存 4 Checkpoint技术5 Master Thread 工作方式5.1 InnoDB 1.0.x版本之前的Master Thread5.2 InnoDB 1.2.x版本之前的Master Thread5.3 InnoDB 1.2.x版本的Master …

Windows下使用wireshark抓取usb数据

参考&#xff1a;使用Wireshark获取USB数据&#xff08;https://blog.csdn.net/2301_76293276/article/details/133791136&#xff09; 文章目录 安装wireshark运行wireshark筛选所需连接设备数据 安装wireshark 直接官网下载wireshark&#xff08;https://www.wireshark.org…

关于“Python”的核心知识点整理大全57

目录 3. 模板edit_entry edit_entry.html 4. 链接到页面edit_entry topic.html 19.2 创建用户账户 19.2.1 应用程序 users 1. 将应用程序users添加到settings.py中 settings.py 2. 包含应用程序users的URL urls.py 19.2.2 登录页面 urls.py 1. 模板login.html log…

Git原理与使用(二):分支管理

Git原理与使用[二]:分支管理 一.分支的基本操作1.理解分支2.创建分支3.切换分支4.删除分支5.补充:创建并切换分支 二.合并分支1.合并分支的基础操作2.分支冲突 三.分支管理策略1.Fast-forward模式2.--no--ff(即:禁用Fast-forward模式)3.分支策略 四.创建临时分支修复bug1.git s…

NSSCTF 1zjs

开启环境: 搞就完事了,别玩魔法! 源码打开 点击访问:./dist/index.umd.js" 搜索php,找到23条相关的,注意到有一个特别的信息: PERFORMANCE OF THIS SOFTWARE.Your gift just take it : /fk3f1ag.php 访问: node4.anna.nssctf.cn:28325/fk3f1ag.php 得到这样: ([![]…

【Java 21 新特性】顺序集合(Sequenced Collections)

1 摘要 引入新的接口表示具有定义的遇到顺序的集合。每个这样的集合都有一个明确定义的第一个元素、第二个元素&#xff0c;依此类推&#xff0c;直到最后一个元素。提供统一的API来访问它的第一个和最后一个元素&#xff0c;并以相反的顺序处理它的元素。 "生活只能向后…

【算法与数据结构】968、LeetCode监控二叉树

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题的一共有两个难点&#xff0c;一个在于如何遍历二叉树&#xff08;前中后遍历&#xff0c;选择什么…

MySQL 时间日期函数,流程控制函数,加密解密函数以及聚合查询函数

注:本文仅作为查找函数和部分理解使用,希望能给大家带来帮助 以下函数均可以使用 SELECT NOW()等函数 FROM DUAL;来测试 //其中dual是一个准们用来测试的测试表 1.时间日期函数 1.1 获取时间的函数 重点记忆前三个红色标注的函数, 第一个函数返回值如2024-01-02的形式 第二个如…

如何使用curl在PHP中同时上传文件和其他数据?

问CHAT&#xff1a;举个例子说明如何使用curl在PHP中同时上传文件和其他数据&#xff1f; CHAT回复&#xff1a;以下例子为&#xff1a; php <?php $url http://www.example.com/path/; $filename path/to/your/file.png; $fields array( fieldParam1 > someValue, …

C++摸版(初阶)----函数模版与类模版

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…

Mac环境下反编译apk

Mac环境下反编译apk 安装反编译工具dex2jar&#xff1a;[官网下载](https://sourceforge.net/projects/dex2jar/)JD-GUI&#xff1a;[官网下载](https://jd-gui.apponic.com/) 实操1. 将需要反编译的 .apk 文件放在下载的 dex2jar 文件夹目录下2. 使用 cd /xxx/dex2jar-2.0 命令…

深度生成模型之GAN的评估 ->(个人学习记录笔记)

文章目录 深度生成模型之GAN的评估图像翻译的应用1. 风格迁移2. 数据增强3. 经典图像任务4. 内容创作5. 人脸图像编辑6. 人体图像编辑 图像翻译模型1. 有监督图像翻译模型2. 无监督图像翻译模型3. 多域图像翻译模型 深度生成模型之GAN的评估 图像翻译的应用 1. 风格迁移 各类…

120基于matlab的LMS自适应滤波算法

基于matlab的LMS自适应滤波算法&#xff0c;如、解相关LMS算法&#xff0c;滤波型LMS算法&#xff0c;变换域LMS算法&#xff0c;输出滤波前后及学习曲线图。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 120自适应滤波算法变换域LMS算法 (xiaohongshu.com…

k8s的陈述式管理

k8s的陈述式管理&#xff1a; 所谓的陈述式管离也就是命令行工具 优点&#xff1a;90%以上都可以满足 对资源的增删查比较方便&#xff0c;对改不是很友好 缺点&#xff1a;命令比较冗长&#xff0c;复杂&#xff0c;难记 声明式&#xff1a; k8s当中的YAML文件来实现资源管…

测试要不要写测试用例(多方面剖析)

前言 最近在网上看到关于这样的一个话题“测试需要写测试用例吗&#xff1f;”&#xff0c;引起了很多同学的讨论。这段话是这样的&#xff1a; 测试用例主要作用&#xff1a;有效地评估软件的质量&#xff0c;测试用例质量体现了测试的质量。 下面摘取一部分同学的观点&…

对比开源大语言模型的自然语言生成SQL能力

背景 NL-to-SQL&#xff08;自然语言到结构化查询语言&#xff09;任务是自然语言处理&#xff08;NLP&#xff09;领域的一个难题。 它涉及将自然语言问题转换为 SQL 查询&#xff0c;然后可以针对关系数据库执行该查询来回答问题。 该任务是 NLP 中的一个专门子领域&#xf…

Java企业电子招投标系统源代码,支持二次开发,采用Spring cloud框架

在数字化采购领域&#xff0c;企业需要一个高效、透明和规范的管理系统。通过采用Spring Cloud、Spring Boot2、Mybatis等先进技术&#xff0c;我们打造了全过程数字化采购管理平台。该平台具备内外协同的能力&#xff0c;通过待办消息、招标公告、中标公告和信息发布等功能模块…

SQL 在已有表中修改列名的方法

文章目录 1. MySQL2. SQL Server3. Oracle / PostgreSQL Question&#xff1a; 假设有一张表 StudentInfo&#xff0c;表中有一个列名是 Student_Name &#xff0c;想要把这个列名改成 StudentName 应该如何操作&#xff1f; 建表语句如下&#xff1a; --建表 if object_id(S…

Java-网络爬虫(一)

文章目录 前言一、网络爬虫1. 介绍2. 爬虫协议3. 法律法规 二、相关知识1. HttpClient2. Jsoup 三、综合案例1. 案例一2. 案例二 四、总结 前言 在大数据时代&#xff0c;信息采集是一项重要的工作&#xff0c;而互联网中的数据是海量的&#xff0c;如果单纯靠人力进行信息获取…