目录
4.修改Maven配置(具体查看博主之前发布的Maven配置)
5.确保该文件中有thymeleaf相关配置内容 (2023版idea中配置后会自动生成)
1.为了节省时间把application.properties中的端口号8080改为80
3.在controller包中创建hellocontroller.java文件
(2)运行Demo2Application文件,并打开浏览器,输入localhost/hello
(1)在templates包下新建一个index.html页面
(4)运行Demo2Application文件,在浏览器中输入localhost/或localhost/index
(1)在controller包下新建studentcontroller.java和teachercontroller.java
(2)在studentcontroller.java中输入以下代码
(3)在teachercontroller.java中输入以下代码
(3)在studentcontroller.java中修改代码
(4)运行Demo2Application文件,在浏览器中输入localhost/student/add
(2)在entity包下新建一个student.java文件
(5)运行Demo2Application文件,在浏览器中输入localhost/getstu
(7)运行Demo2Application文件,在浏览器中输入localhost/getbymv
(6)使用 @RequestHeader 注解来获取请求头中的信息
(7)使用 @CookieValue 注解来获取请求中的 Cookie 值
(8)直接在方法参数中声明 HttpServletRequest 对象来获取完整的请求信息
一.idea部分
(一)配置部分
1.新建项目
2.配置文件
3.解决乱码问题
4.修改Maven配置(具体查看博主之前发布的Maven配置)
5.确保该文件中有thymeleaf相关配置内容 (2023版idea中配置后会自动生成)
若是旧版需要下载Lombok
(二)代码部分
1.为了节省时间把application.properties中的端口号8080改为80
(这样在网页中输入的时候不需要输入端口号,直接输入即可)
2.如图,建立MVC的四个包
3.在controller包中创建hellocontroller.java文件
(1)输入以下代码
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
public class hellocontroller {
@RequestMapping("/hello")
@ResponseBody//将return的值直接返回给前端页面。这个注解必须写否则前端页面找不到
public String hello(){
return "hello SpringBoot";
}
}
(2)运行Demo2Application文件,并打开浏览器,输入localhost/hello
结果应如图所示
若不写@ResponseBody注解,则运行时会出现下图的情况
4.在resources包下新建一个templates包
(1)在templates包下新建一个index.html页面
thymeleaf依赖只能识别templates包下的页面(原因见下面第二个图)
(2)在hellocontroller.java中修改代码
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
public class hellocontroller {
//@RequestMapping("/hello")
@RequestMapping({"/index","/"})//当网页中输入localhost/或localhost/index都会返回index页面
//@ResponseBody
public String hello(){
//return "hello SpringBoot";
return "index";//这里不用写后缀.html。因为默认后缀就是.html
}
}
注意:这里不能写@ResponseBody注解,因为该注解会直接将retrun的值返回给前端页面,会导致index不能重定向到index.html页面
(3)在index.html页面中随意书写一段代码
(4)运行Demo2Application文件,在浏览器中输入localhost/或localhost/index
结果如图所示
5.进一步了解@RequestMapping注解的用途
(1)在controller包下新建studentcontroller.java和teachercontroller.java
(2)在studentcontroller.java中输入以下代码
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/student")
public class studentcontroller {
}
(3)在teachercontroller.java中输入以下代码
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/teacher")
public class teachercontroller {
}
会发现要想前端运行该代码需要输入localhost/ + @RequestMapping("")里面输入的内容
6. 继续了解@RequestMapping注解
(1)在templates包下新建一个add.html页面
(2)在add.html中输入代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>this is a add page</h1>
</body>
</html>
(3)在studentcontroller.java中修改代码
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
//所以网页中要转到add页面,需要输入localost/student/add
@RequestMapping("/student")//在类上面
public class studentcontroller {
@RequestMapping(value ="/add",method = RequestMethod.GET)//在方法上面
/*
当@RequestMapping或其他注解中有默认值的话,value就是一个默认值,
或者说括号内只有一个参数的话,默认值可以不写
但增加第二个参数(method)时,value必须显示出来
*/
public String hello(){
return "add";
}
}
(4)运行Demo2Application文件,在浏览器中输入localhost/student/add
结果如图所示
当@RequestMapping或其他注解中有默认值的话,value就是一个默认值,或者说括号内只有一个参数的话,默认值可以不写,但增加第二个参数(method)时,value必须显示出来
7.应用lombok
(1)在pom.xml中添加依赖
依赖为:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
刷新后出现如图所示即正确
(2)在entity包下新建一个student.java文件
输入代码:
package nuc.edu.mvctest.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data//能生成所有类当中的set/get方法和toString方法、
@NoArgsConstructor//能生成无参构造函数
@AllArgsConstructor//能生成全部参数的构造函数
public class Student {
private Integer stu_id;
private String stu_name;
}
(3)在hellocontroller.java中修改代码
package com.example.demo.controller;
import com.example.demo.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class hellocontroller {
//@RequestMapping("/hello")
@RequestMapping({"/index","/"})//当网页中输入localhost/或localhost/index都会返回index页面
//@ResponseBody
public String hello(){
//return "hello SpringBoot";
return "index";//这里不用写后缀.html。因为默认后缀就是.html
}
@RequestMapping("/getstu")
public String getStu(Model model){//Model当中装载的是返回的数据
model.addAttribute("name","dalao");
return "index";
}
}
(4)修改index.html页面的代码
添加 xmlns:th="http://www.thymeleaf.org"
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--<h1>hello SpringBoot</h1>-->
<h1 th:text="${name}"></h1>
</body>
</html>
(5)运行Demo2Application文件,在浏览器中输入localhost/getstu
如图所示
(6)在hellocontroller.java中修改代码
package com.example.demo.controller;
import com.example.demo.entity.Student;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class hellocontroller {
//@RequestMapping("/hello")
@RequestMapping({"/index","/"})//当网页中输入localhost/或localhost/index都会返回index页面
//@ResponseBody
public String hello(){
//return "hello SpringBoot";
return "index";//这里不用写后缀.html。因为默认后缀就是.html
}
@RequestMapping("/getstu")
public String getStu(Model model){//Model当中装载的是返回的数据
model.addAttribute("name","dalao");
return "index";
}
@RequestMapping("/getbymv")
public ModelAndView getStu(ModelAndView modelAndView){
modelAndView.setViewName("index");
modelAndView.addObject("name","dalaodedalao");
return modelAndView;
}
}
(7)运行Demo2Application文件,在浏览器中输入localhost/getbymv
如图所示
二.MVC
(一)概念
MVC全称Model View Controller,是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分:模型(Model)、视图(View)和控制器(Controller)
Model(模型):业务模型,负责在数据库中存取数据,对应项目只读service和dao
View(视图):渲染数据,生成页面,是应用程序中处理数据显示的部分。对应项目中的Jsp
Controller(控制器):控制MVC流程,接收用户在View层的输入,调用Model层获取数据,填充给View层。对应项目中的Servlet
通常控制器负责从视图读取用户输入的数据,然后从模型中请求数据,并将其交给视图
(二)MVC注解
@Controller: 标记一个类为控制器,处理用户请求并返回视图或数据。用于标识处理请求的控制器类。
@RequestMapping: 映射请求 URL 到处理方法,用于指定请求路径和 HTTP 方法。用于将请求映射到具体的处理方法,可以用于类级别和方法级别。
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping: 分别映射 GET、POST、PUT、DELETE 请求。用于更明确地指定请求方法。
@RequestParam: 从请求参数中获取值,可设置默认值和是否必需。获取请求参数,用于处理方法参数。
@PathVariable: 从 URL 路径中获取值,用于动态路径参数。从 URL 中提取参数值,用于处理方法参数。
@RequestBody: 将请求体中的数据反序列化为对象,用于处理 JSON 或 XML 数据。将请求体数据映射到方法参数。
@ResponseBody: 将方法返回值序列化为响应体,常用于返回 JSON 或 XML 数据。将方法返回值直接作为响应体返回给客户端。
@ModelAttribute: 用于绑定请求参数到模型对象。将请求参数绑定到模型对象,通常用于表单数据绑定。
@Valid: 用于数据校验,配合 JSR-303 校验注解使用。用于在处理方法中进行数据校验。
@InitBinder: 用于初始化数据绑定,自定义数据转换和验证规则。自定义数据绑定和验证规则。
@SessionAttributes: 用于将模型属性暂存到会话中,多用于表单数据的临时存储。将模型属性存储在会话中,以供多个请求使用。
@ModelAttribute: 在方法参数上使用,表示将会话中的属性绑定到方法参数上。在方法参数中获取会话中的属性。
@ExceptionHandler: 用于处理控制器中的异常,定义全局或局部的异常处理方法。处理控制器中的异常情况。
@RequestMapping、@GetMapping 等的 "produces" 和 "consumes" 属性: 用于指定请求的媒体类型(Content-Type)和响应的媒体类型(Accept)。更精确地控制请求和响应的媒体类型。
@RequestMapping 的 "params" 和 "headers" 属性: 用于基于请求参数和头部信息进行请求映射。基于请求参数和头部信息进行请求映射。
(三)SpringMVC执行流程
(四)SpringMVC的组件
DispatcherServlet:前端控制器,接受所有请求,调用其他组件。
HandlerMapping:处理器映射器,根据配置找到方法的执行链。
HandlerAdapter:处理器适配器,根据方法类型找到对应的处理器。
ViewResolver:视图解析器,找到指定视图。
(五)组件的工作流程
客户端将请求发送给前端控制器。
前端控制器将请求发送给处理器映射器,处理器映射器根据路径找到方法的执行链,返回给前端控制器。
前端控制器将方法的执行链发送给处理器适配器,处理器适配器根据方法类型找到对应的处理器。
处理器执行方法,将结果返回给前端控制器。
前端控制器将结果发送给视图解析器,视图解析器找到视图文件位置。
视图渲染数据并将结果显示到客户端。
(六)SpringMVC的请求和响应
1. 请求参数获取方式
(1)通过方法参数直接接收
@RequestMapping("/test1")
public String test1(String name){
System.out.println(name);
return "test";
}
(2)使用 @RequestParam
注解来获取请求参数
// 使用@RequestParam注解,其中value表示指定接收的参数名称;required表示是否可以为空,默认true;defaultValue表示为空时的默认值
@RequestMapping("/test2")
public String test2(@RequestParam(value = "name",required = false,defaultValue = "张三") String name){
System.out.println(name);
return "test";
}
(3)使用@PathVariable注解获取参数
// 使用@PathVariable注解,传输参数时可以不通过url?aa=aa&bb=bb的方式,而是通过url/aa/bb的方式进行参数传输
@RequestMapping("/test3/{name}")
public String test3(@PathVariable String name){
System.out.println(name);
return "test";
}
(4)使用一个pojo对象封装请求参数
// 当请求是以表单参数或URL参数的方式传递数据,而不是将数据包含在请求体中的JSON或XML格式,
// SpringMVC会根据参数名称和请求参数名称的匹配自动将请求参数映射到对象的属性上。
@RequestMapping("/test4")
public String test4(Student student){
System.out.println(student);
return "test";
}
(5)使用RequestBody注解获取自定义对象
// 使用@RequestBody注解,可以将请求体中的数据反序列化成您指定的对象类型,适用于传输数据为一个自定义的对象
@RequestMapping("/test5")
public String test5(@RequestBody Map<String,String> map){
System.out.println(map);
return "test";
}
(6)使用 @RequestHeader
注解来获取请求头中的信息
// 使用@RequestHeader,可以将请求中的指定头部信息
@RequestMapping("/test6")
public String test6(@RequestHeader("User-Agent") String userAgent){
System.out.println(userAgent);
return "test";
}
(7)使用 @CookieValue
注解来获取请求中的 Cookie 值
// 使用@CookieValue获取cookie中的值
@RequestMapping("/test7")
public String test7(@CookieValue("name") String name) {
System.out.println(name);
// 使用 username 处理业务逻辑
return "test";
}
(8)直接在方法参数中声明 HttpServletRequest
对象来获取完整的请求信息
// 直接在方法参数中声明HttpServletRequest,再通过request获取其中的其他值
@RequestMapping("/test8")
public String test8(HttpServletRequest request) {
System.out.println(request.getParameter("name"));
// 使用 username 处理业务逻辑
return "test";
}
2. 响应
(1)返回视图名称字符串
// 返回视图名称字符串
@RequestMapping("/res1")
public String res1(){
// 因为视图解析器进行类配置,所以最终会走/template/test.jsp这个页面
return "test";
}
(2)返回视图对象(View Object)
// 返回视图对象
// 跳过视图解析器的过程,这在需要更精确的控制视图的情况下很有用。
@RequestMapping("/res2")
public View res2(){
return new InternalResourceView("/template/test.jsp"); // 返回视图对象
}
(3)返回ModelAndView对象
// 返回ModelAndView对象
// 返回一个ModelAndView对象,除了View的视图以外还可以添加数据
@RequestMapping("/res3")
public ModelAndView res3(){
// 创建一个ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
// 添加一个值,类似于Map的添加方式,在前端可以通过el表达式进行获取
modelAndView.addObject("name","小米");
// 设置跳转的视图名称,这将走视图解析器,因此类似于第一种只需要视图的名称就行
modelAndView.setViewName("test");
return modelAndView;
}
(4)重定向
// 重定向,可以跳过视图解析器
@RequestMapping("/res4")
public String res4(){
return "redirect:/template/test.jsp";
}
(5)请求转发
// 请求转发,可以跳过视图解析器
@RequestMapping("/res5")
public String res5(){
return "forward:/template/test.jsp";
}
(6)无返回值
// 无返回值
// 在没有返回值时,需要加上@ResponseBody,否则会默认将请求路径当做视图,最终会返回一个页面/template/res6.jsp
@ResponseBody
@RequestMapping("/res6")
public void res6(){
System.out.println("你好");
}
(7)返回一个任意的对象
// 返回一个任意的对象
// 返回一个对象时,需要加上@ResponseBody注解,否则同上
// 当返回类型为String类型时,如果有一个@ResponseBody注解,那么只是单纯将字符串进行了返回,是一个text/html的格式
// 当返回类型为其他对象时,一般是以JSON格式进行返回,需要加上jackson-databind依赖
// 如果上述两种返回类型出现中文乱码的情况,需要配置消息转换器,去处理返回类型的编码格式
@ResponseBody
@RequestMapping("/res7")
public List<Map<String,String>> res7(){
HashMap<String, String> map = new HashMap<>();
map.put("id","1");
map.put("name","张三");
map.put("age","15");
HashMap<String, String> map1 = new HashMap<>();
map1.put("id","2");
map1.put("name","王五");
map1.put("age","18");
ArrayList<Map<String, String>> maps = new ArrayList<>();
maps.add(map);
maps.add(map1);
return maps;
}
(8)返回响应状态码和消息
// 返回响应状态码和消息
// @ResponseStatus中可以设置当前请求最终响应回去的状态码以及其对应的消息
@ResponseBody
@ResponseStatus(HttpStatus.NOT_EXTENDED)
@RequestMapping("/res8")
public String res8(){
return "这是一个测试方法";
}