您现在的位置是:首页 >学无止境 >springMVC网站首页学无止境

springMVC

1212c 2024-07-19 12:01:02
简介springMVC

什么是springMVC

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

SSM :spring + spring MVC + MyBatis / spring boot + spring web(spring MVC) + MyBatis
SM :spring boot (spring web) + MyBatis

spring:一个core框架,只有spring核心的一些源码和工具,不具备HTTP通信的能力
SpringMVC :spring整个体系中的web模块,提供了一个web框架,可以实现HTTP响应
Spring Boot:为了快速开发spring而诞生的一个脚手架

MVC定义

MVC(Model View Controller)是软件工程中的一种软件设计模式,他把软件系统分为了模型、视图、控制器。

  • model(模型):应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
  • View(视图):应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
  • Controller(控制器):应用程序中处理用户交互的部分。通常控制负责从视图读取数据,控制用户输入,并向模型发送数据。
    在这里插入图片描述
    (这套模式已经过时了,因为现在大多数用的都是前后端分离)

MVC和spring MVC的关系

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

为什么学spring MVC

现在绝大部分的 Java 项目都是基于 Spring(或 Spring Boot)的,而Spring 的核心就是 Spring MVC。也就是说 Spring MVC 是 Spring 框架的核心模块,而 Spring Boot 是 Spring 的脚手架,因此我们可以推断出,现在市面上绝大部分的 Java 项目约等于 Spring MVC 项目,这是我们要学 SpringMVC 的原因。

使用springMVC

  1. 建立连接:将用户(浏览器)和Java程序连接起来,就是访问一个地址能够调用到我们的spring程序。
  2. 获取前端给我的参数:用户访问的时候会带一些参数,我们要在程序中想办法获取到参数。
  3. 输出结果给用户:执行了业务逻辑之后,要把程序执行的结果返回给用户。

0. 创建springMVC

  1. 在2018年前,使用maven项目添加spring MVC框架的方式创建,复杂,麻烦
  2. 现在:使用spring boot创建springMVC项目【更多使用】

使用第二种spring boot创建springMVC项目:
new project
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. springMVC建立连接

@RequestMapping("/url地址")   //支持所有请求方式  (get post ..)
@PostMapping("/sayPostHi")   //只支持 post 方式
@GetMapping("/sayGetHi")   //只支持 get 类型的请求方式
@RequestMapping(value = "/user", method = RequestMethod.POST)  //设置只允许 POST 方法访问

package com.example.demo.controller;

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

@Controller
@ResponseBody
//@RestController = @Controller + @ResponseBody
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/sayHi")
    public String sayHi() {
        return "hi spring MVC";
    }
}

RequestMapping注解介绍

package com.example.demo.controller;

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


@Controller
@ResponseBody
//@RestController = @Controller + @ResponseBody
@RequestMapping(value = "/user", method = RequestMethod.POST)  //设置只允许 POST 方法访问
public class UserController {

    @RequestMapping("/sayHi")
    public String sayHi() {
        return "hi spring MVC";
    }

    @PostMapping("/sayPostHi")   //只支持 post 方式
    public String sayHello() {
        return "hello post spring MVC";
    }
    
    @GetMapping("/sayGetHi")   //只支持 get 类型的请求方式
    public String sayGet() {
        return "hello get spring MVC";
    }
    
}

2. springMVC 获取参数

传递单个参数

在 Spring MVC 中直接用方法中的参数来实现传参

@RequestMapping("/sayHi")
public String sayHi(String name) {
    return "hi spring MVC : " + name;
}
@RequestMapping("/sayHi")
public String sayHi(String name) {   // 不传递name参数,此变量就显示使用String的默认值null
    return "hi spring MVC : " + name;
}

@RequestMapping("/sayHi2")
public String sayHi2(Integer name) {  // 不传递name参数,此变量显示null,integer包装类,是包装的对象,默认值也是null
    return "hi spring MVC : " + name;
}

@RequestMapping("/sayHi3")
public String sayHi3(int name) {   // 不传递name参数,报错。int是基础的数据类型,没有值就报错,没有所谓的默认值。
                                        // 因此传递类型的时候推荐使用包装类,不推荐基本类型,基础类型会报错
    return "hi spring MVC : " + name;
}

//servlet方法获取对象
@RequestMapping("/sayHi4")
public String sayHi4(HttpServletRequest request, HttpServletResponse response) {
    return "hi servlet " + request.getParameter("name");
}

传递多个参数

顺序不重要,传参时只需要key对应上

@RequestMapping("/sayHi5")
public String sayHi5(String name, String passwd) {   // 不传递name参数,此变量就显示使用String的默认值null
    return "hi spring MVC name : " + name + "passwd : " + passwd;
}

传递对象

package com.example.demo.entity;
import lombok.Data;

@Data
public class Userinfo {
    private int id;
    private String username;
    private String passwd;
    private int age;
}
package com.example.demo.controller;

import com.example.demo.entity.Userinfo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@ResponseBody
@RequestMapping(value = "/user")
public class UserController {

    @RequestMapping("/reg")
    public Object register(Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }
}

在这里插入图片描述
框架会实现自动的参数映射,只需要保证这里的参数和程序的属性值保持一致。
在这里插入图片描述

package com.example.demo.controller;

import com.example.demo.entity.Userinfo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@ResponseBody
@RequestMapping(value = "/user")
public class UserController {

    @RequestMapping("/h1")
    public Object getH1() {
        return "<h1> 我是h1 </h1>";
    }
}

在这里插入图片描述

@RequestParam后端参数重命名(后端参数映射)

@RequestMapping("/reg2")
//@RequestParam() 中设置的是前端传来的值,用来进行参数重命名
public Object register2(@RequestParam() String name, String passwd) {
    return name + " : " + passwd;
}

在这里插入图片描述
不能用name传

@RequestMapping("/reg2")
//@RequestParam() 中设置的是前端传来的值,用来进行参数重命名
//required 设置name为非必传参数,这时用name依然穿不进去,但是不会报错,只会显示null
public Object register2(@RequestParam(value = "username",required = false) String name, String passwd) {
    return name + " : " + passwd;
}

@RequestBody 接收JSON对象


    //只能拿到对象,不是JSON格式
    @RequestMapping("/reg")
    public Object register(Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }

    //@RequestBody 拿到JSON格式的注解
    @RequestMapping("/reg3")
    public Object register3(@RequestBody Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }

在这里插入图片描述

在这里插入图片描述

获取url中的参数

两种传参方式

  • path(url) = /user/1234 基础URL
    优点:
    1. 搜索引擎抓取关键字权重更高
    2. url更简洁

  • user?uid = 1234 从URL的参数部分获取参数

从基础的URL中获取参数 @PathVariable

    //从基础的URL中获取参数
    @RequestMapping("/reg4/{name}/{passwd}")
    public Object reg4(@PathVariable String name, @PathVariable String passwd) {
        return "name = " + name + " passwd = " + passwd;
    }
    
	//不会报错,但是password的值为null
    @RequestMapping("/reg6/{name}/{password}")
    public Object reg6(@PathVariable String name, @PathVariable(required = false) String passwd) {
        return "name = " + name + " passwd = " + passwd;
    }

    @RequestMapping("/reg5/{name}/{password}")
    public Object reg5(@PathVariable String name, @PathVariable("password") String passwd) {
        return "name = " + name + " passwd = " + passwd;
    }

获取URL参数部分的参数 @RequestParm

获取上传文件@RequestPart

    @RequestMapping("/myUpload")
    public Object upload(@RequestPart("myImg")MultipartFile file) {
        File saveFile = new File("E:\java\myimg.png");
        try {
            file.transferTo(saveFile);  //问题在于,后面上传的图片会覆盖前面上传的图片
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

在这里插入图片描述

    @RequestMapping("/myUpload1")
    public Object upload1(@RequestPart("myImg")MultipartFile file) {
        String fileName = UUID.randomUUID() +   //文件名
                file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));  //后缀名

        File saveFile = new File("E:\java\" + fileName);
        try {
            file.transferTo(saveFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

获取cookie/session/header

传统获取

spring获取

获取cookie

    @RequestMapping("/getck")
    
    public Object getCk(@CookieValue(value = "java", required = false) String java) {
        return java;
    }

获取header

    //获取 header 中的某个信息
    @RequestMapping("getHeader")
    //可以写header中的任意字段
    public Object getHeader(@RequestHeader("User-Agent")String ua) {
        return "header : " + ua;
    }

在这里插入图片描述

获取session

session的存储和servlet类似,使用HttpServletRequest获取

//存储session
    private static final String SESSION_KEY = "USERINFO_SESSION_KEY";
    @RequestMapping("/setSession")
    public void doPostConstruct(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.setAttribute(SESSION_KEY, "zhang san");
    }

    //获取session
    @RequestMapping("/getSession")
    public Object getSession(@SessionAttribute(SESSION_KEY) String name) {
        return "session : " + name;
    }

3. springMVC输出结果(返回数据)

返回静态页面

@Controller
@RequestMapping("/test")
public class TestController {
    @RequestMapping("/index")
    public Object getIndex() {
        return "/index.html";   //在根目录下找 index.html
//        return "index.html";    //在当前目录 /test/index 下找 index.html 
    }
}

请求转发 vs 请求重定向

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

请求转发地址不会转变
在这里插入图片描述

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

请求重定向地址会改变
在这里插入图片描述

//response的请求重定向
@RequestMapping("/redirect2")
public void redirect2(HttpServletResponse response) throws IOException {
    response.sendRedirect("https://www.baidu.com");
}

https://www.javacn.site/net/forward.html
请求转发和请求重定向的区别
(字越少,事越多:“请求转发”的字比较少,它需要代客户端执行跳转;而“请求重定向”字比较多,它啥也不干,只是告诉客户端“去别的地儿访问”就行了)

请求转发(Forward):发生在服务端程序内部,当服务器端收到一个客户端的请求之后,会先将请求,转发给目标地址,再将目标地址返回的结果转发给客户端。 而客户端对于这一切毫无感知的。
这就好比,张三(客户端)找李四(服务器端)借钱,而李四没钱,于是李四又去王五那借钱,并把钱借给了张三,整个过程中张三只借了一次款,剩下的事情都是李四完成的,这就是请求转发。
·
请求重定向(Redirect):请求重定向指的是服务器端接收到客户端的请求之后,会给客户端返回了一个临时响应头,这个临时响应头中记录了,客户端需要再次发送请求(重定向)的 URL 地址,客户端再收到了地址之后,会将请求发送到新的地址上,这就是请求重定向。
这就好像张三(客户端)找李四(服务器端)借钱,李四没钱,于是李四就告诉张三,“我没钱,你去王五那借“,于是张三又去王五家借到了钱,这就是请求重定向。

原文链接:https://www.javacn.site/net/forward.html

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。