您现在的位置是:首页 >技术杂谈 >Spring MVC 的创建连接和使用网站首页技术杂谈

Spring MVC 的创建连接和使用

@糊糊涂涂 2024-10-20 00:01:03
简介Spring MVC 的创建连接和使用

目录

前言:

MVC 是什么?

1. Spring MVC 项目的创建和连接:

1.1 创建

 1.2 连接

2. @RequestMapping 注解使用详析:

2.1 指定请求类型:

2.1.1 指定 GET 请求

2.1.2 指定 POST 请求

3. 参数的获取与传递:

3.1 传递单个参数

3.2 传递对象

3.3 传递多个参数/表单传参(非对象)

3.4 后端参数重命名:

非必传参数的设置

3.5 @RequestBody 接收 JSON 对象

3.6 获取 URL 中的基础参数

3.7 上传文件

3.8 获取 Cookie/Header/Session:

3.8.1 获取 Cookie

3.8.2 获取 Header

3.8.3 Session 的存储和获取

3.9 获取静态页面

3.10 请求转发 和 请求重定向:

二者的区别



前言:

        Spring MVC 原名“Spring Web MVC”,是基于 Servlet API 构建的原始 Web 框架。

MVC 是什么?

        MVC 即 Model View Controller,是一种软件架构模式,可以把软件系统分为模型、视图、控制器三个部分;

  • Model (模型):用于处理应用程序数据逻辑的部分;
  • View(视图):应用程序中处理数据显示的部分;
  • Controller(控制器):应用程序中用于处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

        因此可以认为:Spring MVC 是实现了一个 MVC 模式,并继承了 Servlet API 的 Web 框架。同时 Spring MVC 项目就可以感知到用户在浏览器 URL 里输入的请求。

        学习 Spring MVC 要掌握其主要的三个功能:

  1. 连接的功能:将浏览器和 java 程序连接起来,通过访问一个地址就能调用到对应的 Spring 程序;
  2. 获取参数的功能:在程序中获取用户访问传递的参数;
  3. 输出数据的功能:将执行结果返回给用户;

1. Spring MVC 项目的创建和连接:

1.1 创建:

        Spring MVC 项目的创建和 Spring boot 项目创建步骤一样,只需要添加依赖时加上 “Spring Web” 即可。

 1.2 连接:

        连接既是路由映射,在 Spring MVC 中使用 @RequestMapping 注解来实现与浏览器 URL 的路由映射。访问时直接在浏览器 URL 中访问对于路径即可。

         


2. @RequestMapping 注解使用详析:

        以上只是简单了解了一下使用该注解建立连接,下面剖析该注解的具体使用规则;

        @RequestMapping 用来注册接口路由映射,当用户访问一个 URL 时,将用户的请求对应到程序中某个类的某个方法中。

  •         @RequestMapping 注解可以修饰 [类和方法] ,也可以直接修饰[方法] 。
  •         @RequestMapping 可以指定使用 GET/POST 请求;

2.1 指定请求类型:

2.1.1 指定 GET 请求:

        普通的 @RequestMapping 默认就是发送的 GET 请求;

       △ GET请求的三种写法:

    // GET 请求的三种写法:
    // 第一种:
    @RequestMapping("/request")
    // 第二种:
    @RequestMapping(value = "/request", method = RequestMethod.GET)
    // 第三种:
    @GetMapping("/request")

2.1.2 指定 POST 请求:

       △ POST 请求的两种写法:

// POST 请求两种写法:
    // 第一种:
    @RequestMapping(value = "/request", method = RequestMethod.POST)
    // 第二种:
    @PostMapping("/request")

        


3. 参数的获取与传递:

3.1 传递单个参数:

        在 Spring MVC 中可以直接使用方法中的参数进行传参;

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 传递参数
    @RequestMapping("/send")
    public Object sendParam(String username) {
        return "username: " + username;
    }
}

        在 postman 中构造请求:

3.2 传递对象:

         Spring MVC 可以自动将传递的参数赋值给对象;

@Component
@Data
public class Student {
    private int id;
    private String name;
    private int age;
}
@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 传递对象
    @RequestMapping("/send")
    public Object sendObject(Student student) {
        return "student 对象:" + student;
    }
}

        在 postman 中构造请求:

3.3 传递多个参数/表单传参(非对象):

        当有多个参数时,前后端是以参数名来进行参数匹配的,因此参数的位置不会影响后端获取参数的结果。

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/send")
    public Object sendManyParas(String name, String pwd) {
        String user = name + " " + pwd;
        return user;
    }
}

3.4 后端参数重命名:

         当前端给后端传递的参数与后端代码中设置的参数名不一样时,后端就可以通过参数重命名-参数映射来匹配。

        使用 @RequestParam 注解来重命名参数:

        这个例子中,前端传递的参数为 uid,但后端设置与之对应的重命名参数为:username;

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/send")
    // 参数重命名
    public Object resetPara(@RequestParam(value = "uid") String username) {
        return "uid : " + username;
    }
}

非必传参数的设置: 

 反过来想:既然后端的参数名为:username,那前端传一个 username 可不可以呢?

 报错 400 了,可见是不行的。因为 @RequestParam 注解重命名意为:后端规定前端必须传一个“uid”的参数,与后端的 username 匹配,进入该注解内部可以看到:

 所以这里报错就是因为我们在没有设置 required 的情况下传了个 username,不是后端规定的“uid”。那么可以通过设置 required 的值来提高前端传参的灵活性,让“uid”变成非必须传递的参数:

 注意:这样只是设置非必须传递的参数,并不代表传的参数可以被匹配到;


3.5 @RequestBody 接收 JSON 对象:

后端接收 Json 对象:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping(value = "/send", method = RequestMethod.POST)
    public Object sendJson(@RequestBody Student student) {
        return "Json 对象:" + student;
    }
}

前端构造 Json 对象:

 如果去掉 @RequestBody,可以拿到 Json 对象但无法接收到Json对象里属性的值:


3.6 获取 URL 中的基础参数:

        使用 @PathVariable 来获取 URL 里 ? 之前的参数:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 获取 URL 键值参数
    @PostMapping("/send/{name}/{password}")
    public Object getURLKV(@PathVariable String name, @PathVariable String password) {
        return "name:" + name + " password:" + password;
    }
}

 注意:

  • @RequestParam:获取 URL 里 ? 之后的参数中的参数;
  • @PathVariable:获取 URL 里 ? 之前基础部分的参数;


3.7 上传文件: 

        上传文件使用 @RequestPart 注解;

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/upload")
    public Object uploadFile(@RequestPart("myfile")MultipartFile file) {
        // 获取文件名
        String fileName = UUID.randomUUID() +
                file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        // 文件保存路径
        File savaFile = new File("D:\MVCupload\" + fileName);
        // 保存文件
        try {
            file.transferTo(savaFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

        获取文件名时借助 UUID 和 substring 保证多次上传同一个文件不会导致同名覆盖;

        如果担心上传的文件超过了限制大小,可以在配置文件中设置文件可上传最大量:


3.8 获取 Cookie/Header/Session:

3.8.1 获取 Cookie:

        使用 @CookieValue 注解来获取 cookie:

        这是用来获取单个 Cookie 的方法:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/cookie")
    public Object getCookie(@CookieValue(value = "load", required = false) String load) {
        return "load:" + load;
    }
}

         如果要获取所有的 Cookie,就可以使用传统获取方法,借助 request 对象获取:

    @RequestMapping("/cookie")
    public Object getCookies(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        return cookies;
    }

3.8.2 获取 Header:

        使用 @RequestHeader 注解获取 Header 中的信息:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/header")
    public Object getHeader(@RequestHeader("User-Agent") String userAgent) {
        return "User-Agent:" + userAgent;
    }
}

3.8.3 Session 的存储和获取:

         先按照 HttpServletRequest 存储 Session,再通过 @SessionAttribute 注解获取 Session:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 存储 Session
    @RequestMapping("/setSession")
    public void setSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.setAttribute(SESSION_KEY,"张三");
    }
    private static final String SESSION_KEY = "USER_SESSION";
    // 获取 Session
    @RequestMapping("/getSession")  
    public Object getSession(@SessionAttribute(SESSION_KEY) String name) {
        return "session_name:" + name;
    }
}

         更简洁的方式获取 session:

    @RequestMapping("/session")
    public Object getSession(@SessionAttribute(value = "session", required = false) String session) {
        return session;
    }

3.9 获取静态页面:

         首先在 static 目录下创建一个 index.html 文件:

         

        获取这个静态页面时,一定要注意是 return "/index.html",这个 / 斜杠的作用是从根目录找 index.html 这个静态页面,因为其直接被放在 static 目录下;

        如果这个文件被放在 static 目录下的 index 目录下,就要这样写:return "index.html" ,同时 URL 中路径为:http://localhost:8080/index/index.html

@RequestMapping("/test")
public class TestController {
    @RequestMapping("/index")
    public Object getIndex() {
        return "/index.html";
    }
}


3.10 请求转发 和 请求重定向:

二者的区别:

  1. 定义不同:
       请求转发(Forward):发生在服务端程序内部,当服务端收到客户端发来的请求时,会将请求转发给最终的目的地址,再将目的地址的结果返回给客户端。
       请求重定向(Redirect):服务端接收到客户端的请求之后,会给客户端换返回一个临时响应头,这个临时响应头中记录着客户端需要再次发送请求的 URL 地址,客户端再收到这个新的地址后,就重新向新的地址发送请求。
            形象举例:老大找老二借钱,老二现在没钱,但是老二去找老三借到钱后给老大,这个过程就是“请求转发”,如果老二只是让老大去找老三借钱,这个过程就是“请求重定向”。
  2. 请求方不同:
            请求转发主要是服务端在完成任务,而请求重定向主要是客户端和服务端在不断交互完成任务。
  3. 数据共享不同:
            请求转发的整个执行流程中,服务端带着同一个Request 和 Response 对象完成了所有的交互,所以请求和返回的数据是共享的;而请求重定向每次的请求和返回数据是不同意的。
  4. 最终 URL 地址不同:
    请求转发是服务端作为代理请求去找目的地址,最终将结果再带回来,所以最终的 URL 地址不变;而请求重定向在每次交互中 URL 都在发生改变。
  5. 实现代码不同,具体代码如下。
@Controller
@RequestMapping("/test")
public class TestController {
    // 请求转发
    @RequestMapping("/forward")
    public Object forward() {
        return "forward:/index.html";
    }
}

 请求转发的最终地址还是原请求的地址:

@Controller
@RequestMapping("/test")
public class TestController {
    // 请求重定向
    @RequestMapping("/redirect")
    public Object redirect() {
        return "redirect:/index.html";
    }
}

 请求重定向最终的地址是重定向的地址:

需要注意的:请求转发时,如果资源和转发的页面不在同一个目录下,会导致外部资源不可访问,但 redirect 可以访问

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