SpringMVC

文章目录

  • 一、什么是SpringMVC?
    • 1.什么是MVC?
    • 2.SpringMVC和MVC的关系
    • 3.为什么要学 Spring MVC?
    • 4.怎么学 Spring MVC (Spring Boot) 学习目标
  • 二、SpringMVC的创建和连接
    • 1.连接用户和程序
      • @RequestMapping
      • @ResponseBody
      • @RequestMapping 注解参数设置
      • 路由拓展 (@PostMapping + @GetMapping)
      • 总结
    • 2.得到用户参数
      • 获取单个参数
      • 获取多个参数
      • 获取对象
      • @RequestParam 重命名前端参数
      • @RequestBody 接收JSON对象
      • @PathVariable 从URL中获得参数
      • @RequestPart 上传文件
      • 获取Cookie/Session/header
      • 总结
    • 3. 返回结果给前端
      • 返回text/html
      • 返回JSON格式的数据
      • 返回前端页面
    • 4. 请求转发和重定向
      • 请求转发和重定向的区别


一、什么是SpringMVC?

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它
的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为“Spring
MVC”

从上述定义我们可以得出两个关键信息:

  1. Spring MVC 是⼀个 Web 框架。
  2. Spring MVC 是基于 Servlet API 构建的。
    然⽽要真正的理解什么是 Spring MVC?我们⾸先要搞清楚什么是 MVC

1.什么是MVC?

MVC是 Model View Controller 的缩写,它是软件工程中的一种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。
下图是比较早期的MVC图,前后端未分离时期的。

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

2.SpringMVC和MVC的关系

MVC 是⼀种思想,⽽ Spring MVC 是对 MVC 思想的具体实现。
总结来说,Spring MVC 是⼀个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web 框
架,那么当⽤户在浏览器中输⼊了 url 之后,我们的 Spring MVC 项⽬就可以感知到⽤户的请求。

3.为什么要学 Spring MVC?

现在绝⼤部分的 Java 项⽬都是基于 Spring(或 Spring Boot)的,⽽ Spring 的核⼼就是 Spring
MVC。也就是说 Spring MVC 是 Spring 框架的核⼼模块,⽽ Spring Boot 是 Spring 的脚⼿架,因此我
们可以推断出,现在市⾯上绝⼤部分的 Java 项⽬约等于 Spring MVC 项⽬,这是我们要学 Spring
MVC 的原因。
在创建 Spring Boot 项⽬时,我们勾选的 Spring Web 框架其实就是 Spring MVC 框架,如下图所示:

SpringMVC_第2张图片

简单来说,咱们之所以要学习 Spring MVC 是因为它是⼀切项⽬的基础,我们以后创建的所有 Spring、
Spring Boot 项⽬基本都是基于 Spring MVC 的

4.怎么学 Spring MVC (Spring Boot) 学习目标

  1. 连接用户和咱们的程序:将⽤户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring 程序
  2. 得到前端用户的参数:⽤户访问的时候会带⼀些参数,在程序中要想办法获取到参数
  3. 组装数据能够成功的把结果返回给前端:执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤户。
    对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC

二、SpringMVC的创建和连接

Spring MVC 项⽬创建和 Spring Boot 创建项⽬相同(Spring MVC 使⽤ Spring Boot 的⽅式创建),
在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。

1.连接用户和程序

@RequestMapping

@Controller
@RequestMapping("/demo")
public class UserController {
    @RequestMapping("/hello")
    @ResponseBody//返回非页面数据
    public String hello(String name) {
        return "hello "+name;
    }
}

URL的路径要和注解的路由名称对应
SpringMVC_第3张图片
@RequestMapping 的作用就是用来注册一个 url 路由,通过这个路由,前端的请求就可以实现和后端程序的交互了,而 @RequestMapping 这个注解既能修饰方法,又能修饰类

@ResponseBody

默认情况下使用@RequestMapping 会返回一个 html 页面,当加上 @ResponseBody注解之后就能返回非页面的数据了
当使用 @ResponseBody 修饰一个类的时候,它表示此类中的所有方法都会返回一个非页面的数据

@Controller
@RequestMapping("/demo")
@ResponseBody// 使用 @ResponseBody 修饰一个类的时候,它表示此类中的所有方法都会返回一个非页面的数据
public class UserController {
    @RequestMapping("/hello")
    
    public String hello(String name) {
        return "hello "+name;
    }
}

@RequestMapping 注解参数设置

1. @RequestMapping在只设置路由地址的情况下,那么此方法是 既支持 GET 请求 又支持 POST请求类型的
2. 当给 @RequestMapping 设置了 method 属性之后,那么它只能支持设置的请求类型,其它类型会报 405错误

RequestMethod 是一个枚举类型

@RequestMapping(value = "get", method = RequestMethod.GET)
    public String demo(String str) {
        return "测试Get请求";
    }

路由拓展 (@PostMapping + @GetMapping)

等同于上面的那种写法,但这两个注解只能修饰方法

 @PostMapping("/testPost")
    public String postType() {
        return "test post";
    }
    @GetMapping("/getType")
    public String getType() {
        return "test get";
    }

总结

  1. @RequestMapping:支持任意一种请求类型(get/post …)(既能修饰方法又能修饰类)
  2. @GetMapping:只支持 get 方式的请求(只能修饰方法)
  3. @PostMapping:支持post 方式的请求(只能修饰方法)

2.得到用户参数

获取单个参数

前端传递的参数 key 必须要和方法的参数名一致,否则不能正常的获取前端参数
比如前端必须传过来的 名为 name 的 key 才能获取值

@RequestMapping("/hello")
    public String hello(String name) {
        return "hello "+name;
    }

获取多个参数

@PostMapping("/all")
    public Object getAll(Integer id,String name) {
        return "学号:"+id+",姓名:"+name;
    }

注意: 当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置
是不影响后端获取参数的结果

SpringMVC_第4张图片

获取对象

User对象

@Data//使用lombok的组合注解添加Get、Set、toString等方法
public class User {
    private  int id;
    private String name;
    private int age;
    private String sex;
}

获取对象方法

@GetMapping("/getUser")
    public User getUser(User user) {
        return user;
    }

测试结果

SpringMVC_第5张图片

@RequestParam 重命名前端参数

在某些特殊情况下,前端传递的参数 key 和我们后端接收的key可以不一致,比如前端传递了一个 time给后端,而后端是用 newTime接收的,而此时我们有大量代码都用到了 newTime不好修改,前端也下班了,出现这种情况就可以用 @RequestParam 来重命名前后端的参数值

代码

@GetMapping("/getTime")
    public String getTime(@RequestParam("time") String myTime) {
        return "当前时间"+myTime+":"+System.currentTimeMillis();
    }

SpringMVC_第6张图片

@RequestParam 既能重命名请求参数,又能保证此参数为必传参数
如果 required 设置为 true ,前端如果不传此参数就会报错(默认为true)

@GetMapping("/getTime")
    public String getTime(@RequestParam(value = "time",required = false) String myTime) {
        return "当前时间"+myTime+":"+System.currentTimeMillis();
    }

SpringMVC_第7张图片
当我们想设置此参数可传可不传就通过 @RequestParam 注解设置 required 为false

@RequestBody 接收JSON对象

在参数的前面加上 @RequestBody才能接收 JSON格式的数据

@GetMapping("/getUser")
    public User getUser(@RequestBody User user) {
        return user;
    }

SpringMVC_第8张图片

@PathVariable 从URL中获得参数

@GetMapping("/path/{name}/{password}")//这里要和下方变量名对应
public String getUrlParameter(@PathVariable String name, @PathVariable String password) {
    return "username: "+name+",密码:"+password;
}

SpringMVC_第9张图片

注意事项:@GetMapping("/path/{name}/{password}") 中的 {password} 参数不能省略 ,且名字要和方法的参数名对应

@RequestPart 上传文件

通过@RequestPart注解和MultipartFile 类型可以实现文件上传

代码示例

// 获取配置文件中的文件保存路径
    @Value("${uploadPath}")
    private String path;

    @RequestMapping("/upload")
    public String uploadFile(@RequestPart("myFile") MultipartFile file) throws IOException {
        // 1.通过uuid生成动态的文件名
        String fileName = UUID.randomUUID()+
                file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));

        // 2.保存文件
        file.transferTo(new File(path+fileName));

        return "文件上传成功!"+fileName;
    }

SpringMVC_第10张图片

获取Cookie/Session/header

获取Cookie

@RequestMapping("/cookie")
public Cookie[] getCookie(HttpServletRequest request, HttpServletResponse response) {
    // 1.获取所有cookie
    Cookie[] cookies = request.getCookies();

    return cookies;
}

浏览器伪造cookie

SpringMVC_第11张图片
更简洁获取 Cookie

// required如果为false说明Cookie可以为空
@RequestMapping("/getCookie")
    public String getCookie(@CookieValue(value = "name",required = false) String userName) {
        return "userName:"+userName;
    }

SpringMVC_第12张图片

获取 Header

@RequestMapping("/getHead")
    public String getHead(HttpServletRequest request) {
        String head = request.getHeader("User-Agent");

        return head;
    }

更简洁的获取 Header

@RequestMapping("/getHead2")
public String getHead2(@RequestHeader("User-Agent") String head) {
    return "User-Agent: "+head;
}

Session 存储和获取
Session 存储和 Servlet 类似,是使⽤ HttpServletRequest 中获取的,如下代码所示:

存储和获取Session

@RequestMapping("/getSession")
    public String getSession(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        String status = "未登录";
        if (session != null) {
            status = (String) session.getAttribute("userName");
        }

        return status;
    }

    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request) {
        // 设置为true如果不存在就会创建一个 session会话
        HttpSession session = request.getSession(true);
        if (session != null) {
            session.setAttribute("userName","admin");
        }

        return "登录成功";
    }

SpringMVC_第13张图片

SpringMVC_第14张图片
获取 Session 更简洁的⽅式
required表示可以不存在不会报错

@RequestMapping("/getSession2")
    public String getSession2(@SessionAttribute(value = "userName", required = false) String userName) {
        return userName;
    }
    

总结

  1. 获取单个参数(结果参数):再方法中写相应的参数就可以实现
  2. 获取对象:在方法中直接写对象就可以实现
  3. 获取 JSON 对象:@RequestBody 加到方法中的参数的前面
  4. 获取文件:@RequestPart
  5. 获取用户 Cookie/Session/Header:@CookieValue/@SessionAttribute/@RequestHeader

3. 返回结果给前端

Spring MVC 会根据返回类型自动对你返回回的类型进行适配,设置 Content-Type
注意:text/html 和JSON都是一个非页面的数据

返回text/html

@ResponseBody // 返回一份非页面的数据
    @RequestMapping("/getText")
    public String getText(String name) {
        return "

hello "+name+"

"
; }

SpringMVC_第15张图片

返回JSON格式的数据

@ResponseBody
    @RequestMapping("/getJson")
    public Object getJson() {
        Map<String,String> map = new HashMap<>();
        map.put("id","001");
        map.put("userName","张三");
        map.put("password","654321");

        return map;
    }

SpringMVC_第16张图片
SpringMVC_第17张图片

返回前端页面

当返回的是一个前端页面时,就不能用 @ResponseBody 注解修饰了

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

在这里插入图片描述

4. 请求转发和重定向

return不但可以放回一个视图,还可以实现跳转,跳转的方式有两种

  • forward:请求转发
  • redirect:请求重定向
@Controller
@RequestMapping("/demo")
public class UserController {

    @RequestMapping("/index")
    public Object index() {
        return "forward:/index.html";
    }
    @RequestMapping("/getIndex")
    public Object  getIndex() {
        return "redirect:/index.html";
    }
}

使用请求转发

SpringMVC_第18张图片

使用请求重定向
访问前的URL
SpringMVC_第19张图片
访问后的URL

SpringMVC_第20张图片
通过上面请求转发的访问资源路径,并不是在根路径,所以会出现资源访问不到的情况
如果是在类上没有加 @RequestMapping 注解,就不会出现资源访问不到的情况

@Controller
public class UserController {

    @RequestMapping("/index")
    public Object index() {
        return "forward:/index.html";
    }
    @RequestMapping("/getIndex")
    public Object  getIndex() {
        return "redirect:/index.html";
    }
}

SpringMVC_第21张图片

请求转发和重定向的区别

页面转发

  1. 请求转发 forward :服务器帮客户端进行请求转发并将结果响应给客户端,URL 地址是不变的
  2. 请求重定向 redirect:服务器端将请求重新定义到要访问的地址上,URL地址会发生改变
  3. 转发是服务器帮转的,⽽重定向是让浏览器重新请求另⼀个地址

请求转发和重定向的区别
1.请求转发 URL地址不变,因为是服务器端进行转发和响应的;请求重定向 URL 地址会发生改变,因为服务器端直接将请求重定向到具体的地址上
2.使用请求转发有可能外部资源是会丢失,访问不到的;而请求重定向是直接重定向到 URL 地址了,所以请求重定向和直接访问目标地址的效果是一模一样的,所以不会存在外部资源丢失的情况


你可能感兴趣的:(web后端,spring,java,mvc)