Spring MVC

Spring MVC

  • 什么是 Spring MVC
    • MVC
    • 对比 MVC 与 Spring MVC
  • Spring MVC—连接
    • @RequestMapping 默认情况下支持的请求类型
    • @RequestMapping 指定请求类型
  • Spring MVC—获取参数
    • 获取单个参数
    • 获取两个参数
    • 参数重命名
    • 传递对象
    • 传递 JSON 对象
    • 获取 URL 中的参数
    • 上传文件
    • 获取 Cookie / header / Session
      • 传统方式获取 Cookie
      • 利用注解获取 Cookie
      • 传统方式获取 header
      • 利用注解获取 header
      • Session 的存储与获取
        • 存储 Session
        • 获取 Session
          • 通过 Servlet 获取
          • 通过 @SessionAttribute 获取
  • Spring MVC—返回数据
    • @ResponseBody
    • 返回 JSON 对象
    • 请求转发与请求重定向
      • 理解 forward(请求转发) 与 redirect(请求重定向)
  • 总结

什么是 Spring MVC


Spring Web MVC 是基于 Servlet 构建的原始 Web 框架, 包含在 Spring 框架中.
Spring Web MVC 来自其源模块的名称(Spring-webmvc), 但通常称作 Spring MVC

  • Spring MVC 构建在 Servlet 之上
  • Spring MVC 是一个 Web 框架
  • Spring MVC 基于 Spring-webmvc 模块

MVC


MVC(Model View Controller)—模型视图控制器

  • Model(模型), 应用程序中用于处理应用程序数据逻辑的部分. 通常模型对象负责在数据库中存取数据
  • View(视图), 应用程序中用于处理数据显示的部分. 通常视图是依据模型数据创建的
  • Controller(控制器), 应用程序中用于处理用户交互的部分. 通常控制器负责从视图读取数据, 控制用户输入, 并向模型发送数据

Spring MVC_第1张图片

对比 MVC 与 Spring MVC


MVC 与 Spring MVC 之间的关系类似于 IOC(思想) 与 DI(思想的具体实现) 之间的关系

MVC 是一种思想
Spring MVC 是对 MVC 思想的具体实现

Spring MVC—连接


利用 Spring MVC 输出 hello world

在 demo 包下创建一个 controller 包
在 controller 包下创建一个 TestController 类

demo(package) → controller(package) → TestController(.class)

Spring MVC_第2张图片

  • @Controller, 存储 TestController 至 Spring 容器
  • @ResponseBody, 返回数据而非页面
  • @RequestMapping(), 设置请求路径

注意

  1. @Controller可与@ResponseBody合并为@RestController
  2. @RequestMapping()既可以修饰类也可以修饰方法

完整代码

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

// @Controller
// @ResponseBody
@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/hello")
    public String sayHello() {
        return "hello world";
    }

}

运行结果

Spring MVC_第3张图片

@RequestMapping 默认情况下支持的请求类型


@RequestMapping 默认情况下支持多种 HTTP 请求
包括 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS…

可通过 Postman 工具进行查看

Spring MVC_第4张图片

@RequestMapping 指定请求类型


通过 method 属性指定请求的类型

Spring MVC_第5张图片

可指定的请求类型

Spring MVC_第6张图片

举个栗子

指定 GET 请求method = RequestMethod.GET

完整代码

@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String sayHello() {
        return "hello world";
    }

}

另一种指定 GET 请求的方式
(其他类型同理)

@GetMapping("/hello")

效果与@RequestMapping(value = "/hello", method = RequestMethod.GET)相同

此时通过其他请求进行访问就会报错

405(Method Not Allowed)—方法不被允许

Spring MVC_第7张图片

Spring MVC—获取参数


获取单个参数


@RestController
@RequestMapping("/test")
public class TestController {

    // 获取单个参数
    @GetMapping("/hello")
    public String sayHello(String name) {
        return "hello " + name;
    }
    
}

注意

URL 中的 key 必须与所传参数一致

Spring MVC_第8张图片

错误示范

Spring MVC_第9张图片

获取两个参数


@RestController
@RequestMapping("/test")
public class TestController {

    // 获取两个参数
    @GetMapping("/hello")
    public String sayHello(String name, Integer age) {
        return "hello name: " + name + " | age: " + age;
    }
    
}

注意

建议传参的类型为包装类型, 而非基础类型

Spring MVC_第10张图片

错误示范

当传参的类型为基础类型时

// 获取两个参数
@GetMapping("/hello")
public String sayHello(String name, int age) {

    return "hello name: " + name + " | age: " + age;
    
}

Spring MVC_第11张图片

当传参的类型为包装类型时

// 获取两个参数
@GetMapping("/hello")
public String sayHello(String name, Integer age) {

    return "hello name: " + name + " | age: " + age;
    
}

Spring MVC_第12张图片

参数重命名


利用注解@RequestParam为参数重命名

举个栗子

有两个参数 String t1(起始时间), String t2(结束时间)

滑稽老哥觉得 t1, t2 这两个名字不太好, 想要改成 startTime, endTime

于是利用注解@RequestParam为参数重命名

将 t1 重命名为 startTime
将 t2 重命名为 endTime

@GetMapping("time")
public String showTime(
		@RequestParam(value = "t1", required = false) String startTime, 
		@RequestParam(value = "t2", required = false) String endTime) {

    return "开始时间: " + startTime + " | 结束时间: " + endTime;
    
}

对于 required 的解释

分析@RequestParam()源码发现, required默认为 true

即忘记填写对应的 key 时就会报错

Spring MVC_第13张图片

Spring MVC_第14张图片

设置required为 false

Spring MVC_第15张图片

传递对象


当所需获取的参数较多时, 可通过传递对象的方式进行传参

设置对象属性

@Data
public class User {
    private int id;
    private String name;
    private int age;
}

传递对象

@RestController
@RequestMapping("/test")
public class TestController {

	// 传递对象
    @GetMapping("/user")
    public String showUser(User user) {
        return user.toString();
    }	

}

注意

URL 中的 key 必须与所传对象的属性一致

Spring MVC_第16张图片

错误示范

Spring MVC_第17张图片

传递 JSON 对象


利用注解@RequestBody传递 JSON 对象

@RestController
@RequestMapping("/test")
public class TestController {

	// 传递 JSON 对象
	@PostMapping("/json-user") // 推荐使用 @PostMapping
	public String showJsonUser(@RequestBody(required = false) User user) {
    	return user.toString();
	}

}

Spring MVC_第18张图片

注意

此处不建议使用@GetMapping传递 JSON 对象 , @GetMapping默认使用 URL 传递参数

获取 URL 中的参数


http://127.0.0.1:8080/test/login?username=bibubibu

http://127.0.0.1:8080/test/login/bibubibu

此处所指获取 URL 中的参数是后者的形式

/后面就是参数, 而不是?username=bibubibu

利用注解@PathVariable获取 URL 中的参数

举个栗子

需要传递的参数用 { } 包裹

{username}
{password}

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/login/{username}/{password}")
    public String login(
            @PathVariable(value = "username", required = false) String username,
            @PathVariable(value = "password", required = false) String password) {

        return "username: " + username + " | password: " + password;
    }
    
}

Spring MVC_第19张图片

上传文件


利用注解@RequestPart上传文件

@RestController
@RequestMapping("/test")
public class TestController {

	// 上传文件
    @RequestMapping("/upfile")
    public String upFile(@RequestPart("files") MultipartFile file) throws IOException {
        // 1. 根目录
        String path = "D:\\Java\\documents\\png_file\\";
        // 2. 根目录 + 唯一文件名
        path += UUID.randomUUID().toString().replace("-", "");
        // 3. 根目录 + 唯一文件名 + 文件后缀
        path += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        // 4. 保存文件
        file.transferTo(new File(path));
        
        return path;
    }	
    
}

Spring MVC_第20张图片

Spring MVC_第21张图片

获取 Cookie / header / Session


Spring MVC 内置了 HttpServletRequest, HttpServletResponse

传统方式获取 Cookie


传统方式获取 Cookie—通过 Servlet 获取(获取全部 Cookie)

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

	@RequestMapping("/getCookies")
    public String getCookies(HttpServletRequest req) {
        Cookie[] cookies = req.getCookies();

        for(Cookie item : cookies) {
            log.error(item.getName() + " | " + item.getValue());
        }

        return "getCookies~~";
    }
    
}    

校验

添加 Cookie

Spring MVC_第22张图片

运行查看结果

Spring MVC_第23张图片

Spring MVC_第24张图片

利用注解获取 Cookie


利用注解获取 Cookie—通过@CookieValue获取(获取指定 Cookie)

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

	@RequestMapping("/getCookie")
    public String getCookie(@CookieValue("Homo") String val) {

        log.error("Homo | " + val);
        return "getCookie~~";

    }
    
}    

运行查看结果

Spring MVC_第25张图片

传统方式获取 header


传统方式获取 header—通过 Servlet 获取

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/getUser-Agent")
	public String getHeader(HttpServletRequest req) {
    	String userAgent = req.getHeader("User-Agent");
    	return "tradition | UserAgent : " + userAgent;
	}
    
} 

运行查看结果

Spring MVC_第26张图片

利用注解获取 header


利用注解获取 header—通过@RequestHeader获取

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/getUser-Agent")
    public String getUA(@RequestHeader("User-Agent") String userAgent) {
        return "Annotation | UserAgent : " + userAgent;
    }
    
} 

运行查看结果

Spring MVC_第27张图片

Session 的存储与获取


存储 Session


利用 Servlet 存储 Session

对于getSession(), getSession(true), getSession(false)的解释

  • getSession(true), 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 Session
  • getSession(false), 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 返回 Null
  • getSession(), 等同于getSession(true)
@RestController
@RequestMapping("/test")
public class TestController {

	// 通过 Servlet 存储 Session
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest req) {
        // 如果当前含有 HttpSession, 使用当前 HttpSession, 如果没有, 新创建 Session
        HttpSession session = req.getSession(true);
        // 设置 key, value
        session.setAttribute("userInfo", "userInfo");
        return "Set Session Success";
    }
    
}

获取 Session


获取 Session 有 2 种方式

  1. 通过 Servlet 获取
  2. 通过 @SessionAttribute 获取
通过 Servlet 获取

@RestController
@RequestMapping("/test")
public class TestController {

	// 通过 Servlet 获取 Session
    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest req) {
        HttpSession session = req.getSession(false);
        
        if(session != null && session.getAttribute("userInfo") != null) {
            return (String) session.getAttribute("userInfo");
        } else {
            return "session 信息不存在";
        }
    }
    
}
通过 @SessionAttribute 获取

@RestController
@RequestMapping("/test")
public class TestController {

	// 通过 @SessionAttribute 获取 Session
    @RequestMapping("/getSession")
    public String getSession(
            @SessionAttribute(value = "userInfo", required = false) String userInfo) {

        return userInfo;

    }	
    
}

Spring MVC—返回数据


@ResponseBody


  • 未添加@ResponseBody, 返回页面
  • 添加@ResponseBody, 返回数据

返回页面

(未添加@ResponseBody)

@RequestMapping("/resp")
@Controller
public class RespController {

    @RequestMapping("/page")
    public String retPage() {
        return "/hello.html";
    }

}

Spring MVC_第28张图片
Spring MVC_第29张图片

返回数据

(添加@ResponseBody)

@RequestMapping("/resp")
@Controller
@ResponseBody
public class RespController {

    @RequestMapping("/page")
    public String retPage() {
        return "/hello.html";
    }

}

Spring MVC_第30张图片

返回 JSON 对象


返回 对象(Object) / HashMap 都是 JSON 格式

JSON 格式是键值对结构, 对象(Object) / HashMap 也是键值对结构

以 HashMap 为例

@RestController
@RequestMapping("/test")
public class TestController {

	@RequestMapping("/response")
    public HashMap<String, String> respJson() {
        HashMap<String, String> map = new HashMap<>();
        map.put("Tom", "Tom_Val");
        map.put("Homo", "Homo_Val");
        map.put("Jack", "Jack_Val");
        return map;
    }
    
}    

抓包查看结果

Spring MVC_第31张图片

请求转发与请求重定向


  • 请求转发 → forward
  • 请求重定向 → redirect

请求转发

// 请求转发
@RequestMapping("/bibubibu-forward")
public String reqForward() {
    return "forward:/hello.html";
}

请求重定向

// 请求重定向
@RequestMapping("/bibubibu-redirect")
public String reqRedirect() {
    return "redirect:/hello.html";
}

Spring MVC_第32张图片

理解 forward(请求转发) 与 redirect(请求重定向)


举个栗子

滑稽老哥对他女朋友说想吃羊肉串

女朋友帮他买羊肉串(请求转发)
滑稽老哥自己去买羊肉串(请求重定向)

具体区别

  1. 请求转发 → 由服务器端负责转发, 请求重定向 → 将请求重定位到资源
  2. 请求转发 → 地址不会发生改变, 请求重定向 → 地址会发生改变
  3. 请求转发 → 服务器端负责转发, 地址不发生改变(可能造成原外部资源不能访问)
    请求重定向 → 地址发生改变, 等同于直接访问新地址(原外部资源能够访问)

类似于滑稽老哥自己去买羊肉串他就能买到口感最好的羊肉串(自己平时光顾较多的烧烤店) → 原外部资源能够访问
而委托女朋友去买虽然告诉了具体的地址仍然有可能买错 → 原外部资源不能访问

总结


  • Spring MVC—连接
    • @RestController@Controller + @ResponseBody
    • @RequestMapping默认支持多种 HTTP 请求(GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS…)
    • @RequestMapping指定请求类型 → @RequestMapping(value = "", method = RequestMethod.指定请求的类型)
    • @RequestMapping指定请求类型 == 指定请求类型Mapping
      (例如@RequestMapping(value = "", method = RequestMethod.GET) == @GETMapping(value = ""))
  • Spring MVC—获取参数
    • 获取参数时 URL 中的 key 必须与所传参数一致
    • 建议传参的类型为包装类型, 而非基础类型
    • 参数重命名 → @RequestParam
    • 传递对象 → 当所需获取的参数较多时, 可通过传递对象的方式进行传参(URL 中的 key 必须与所传对象的属性一致)
    • 传递 JSON 对象 → @RequestBody
    • 获取 URL 中的参数 → @PathVariable
    • 上传文件 → @RequestPart
    • 获取 Cookie
      • 传统方式获取 Cookie—通过 Servlet 获取(获取全部 Cookie)
      • 利用注解获取 Cookie—通过@CookieValue获取(获取指定 Cookie)
    • 获取 header
      • 传统方式获取 header—通过 Servlet 获取
      • 利用注解获取 Cookie—通过@RequestHeader获取
    • Session 的存储与获取
      • 存储 Session—通过 Servlet 存储 Session
      • 获取 Session—通过 Servlet 获取 Session
      • 获取 Session—通过 @SessionAttribute 获取
  • Spring MVC—返回数据
    • @ResponseBody → 未添加@ResponseBody, 返回页面 / 添加@ResponseBody, 返回数据
    • 请求转发(地址不会发生改变) → forward / 请求重定向(地址会发生改变) → redirect

Spring MVC_第33张图片

完结撒花

你可能感兴趣的:(JavaEE,spring,mvc,java)