Spring MVC程序开发

  • Post author:
  • Post category:其他


一. 什么是 Spring MVC

1) Spring MVC 是一个 Web 框架

2) Spring MVC 是基于 Servlet API 构建的

1.1 MVC 定义


MVC 是


Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构模式,它把软件系统分

为模型、视图和控制器三个基本部分


Model (模型)


是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存   取数据。



View(视图)

是应⽤程序中处理数据显示的部分。通常视图是依据模型数据创建的。



Controller(控制器)

是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据,控制⽤户输⼊,并向模型发送数据。


1.2 MVC 和 Spring MVC 的关系



MVC 是⼀种思想,而Spring MVC 是对 MVC 思想的具体实现


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



二. Spring MVC



1)

连接功能

:将⽤户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的v      Spring 程序。


2)

获取参数的功能

:⽤户访问的时候会带⼀些参数,在程序中要想办法获取到参数。


3)



输出数据的功能

:执⾏了业务逻辑之后,要把程序执行的结果返回给⽤户


2.1 Spring MVC 创建和连接


2.1.1 创建 Spring MVC 项目


1)Spring MVC 可以基于 Spring Boot 创建,也就是创建⼀个 Spring Boot 项⽬,勾选上 Spring Web模块即可

2)

创建⼀个 UserController 类,实现⽤户到 Spring 程序的互联互通:

@RequestMapping("/test") // 路由注册
//@Controller // 把类注册到框架中
//@ResponseBody // 告诉程序返回的是数据而非页面
@RestController //和上面两个效果相同

public class TestController {
    @PostMapping("/hi")
    public String sayHi(){
        return "Hi,Spring boot~";
    }
}

3)运行程序,

访问地址:


http://localhost:8080/test/hi


,就能打印“Hi,Spring boot”了


2.1.2 @RequestMapping 注解介绍



@RequestMapping 是用


来注册接口的路由映射的


路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射

@RequestMapping 基础使⽤:

1)


@RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类 + ⽅


法。

2)

@RequestMapping 也可以直接修饰⽅法



2.1.3 指定 @RequestMapping 接收 post 或 get 请求




get :

// 写法1
@RequestMapping("/index")

// 写法2
@RequestMapping(value = "/index",method = RequestMethod.GET)

// 写法3
@GetMapping("/index")


post:

// 写法1
@RequestMapping(value = "/index",method = RequestMethod.POST)

// 写法2
@PostMapping("/index")

2.2 获取参数

2.2.1 传递单个参数


在 Spring MVC 中可以直接⽤⽅法中的参数来实现传参:

@RequestMapping("/m1")
public Object method_1(String name){
 System.out.println("参数 name:"+name);
 return "/index.html";
}

2.2.2 传递对象



Spring MVC 可以⾃动实现参数对象的赋值


1)Person 对象

import lombok.Data;
@Data
public class Person {
 private int id;
 private String name;
 private String password;
}

2)传递对象

@RequestMapping("/m2")
public Object method_2(Person p){
 System.out.println("对象中的 name:"+p.getName());
 System.out.println("对象中的 password:"+p.getPassword());
 return "/index.html";
}

2.2.3

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

@RequestMapping("/m3")
public Object method_3(String name, String pwd) {
 System.out.println("name 参数:" + name);
 System.out.println("pwd 参数:" + pwd);
 return "/index.html";
}

2.2.4 后端参数重命名


当前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个time 给后端,⽽后端⼜是有 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值

@RequestMapping("/m4")
public Object method_4(@RequestParam("time") String createtime) {
 System.out.println("时间:" + createtime);
 return "/index.html";
}

2.2.5 设置参数必传@RequestParam


上⾯的列⼦,如果我们是前端传递⼀个⾮ time 的参数,就会出现程序报错的情况

这是因为后端已经声明了前端必须传递⼀个 time 的参数,但是前端没有给后端传递


非必传参数设置


如果我们的实际业务前端的参数是⼀个⾮必传的参数,我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错:

@RequestMapping("/m4")
public Object method_4(@RequestParam(value = "time", required = false) String createtime) {
 System.out.println("时间:" + createtime);
 return "/index.html";
}

2.2.6 @RequestParam 接受JOSN对象

在 postman 中访问方法

后端接收代码

@RequestMapping(value = "/m5", method = RequestMethod.POST)
public Object method_5(@RequestBody Person person) {
 System.out.println("Person:" + person);
 return "redirect:/index.html";
}

2.2.7 获取URL中参数@PathVariable

后端实现:

@PostMapping("/m6/{name}/{password}")
public Object method_6(@PathVariable String name, @PathVariable String password) {
 System.out.println("name:" + name);
 System.out.println("password:" + password);
 return "redirect:/index.html";
}

前端方法地址:

2.2.8 上传文件@RequestPart

@RequestMapping("/param10")
    public String param10(@RequestPart("myfile") MultipartFile file) throws IOException {
        // 根目录
        String path = "D:\\text3\\";
        // 根目录 + 唯一文件名
        path += UUID.randomUUID().toString().replace("-","");
        // 根目录 + 唯一文件名 + 文件后缀
        path += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        // 保存文件
        file.transferTo(new File(path));
        return path;
    }


获取项目目录的几种方式:

ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX).getPath();
new ClassPathResource("").getFile().getAbsolutePath();
ClassUtils.getDefaultClassLoader().getResource("").getPath();
ResourceUtils.getFile("classpath:static/").getPath();

2.2.9 获取Cookie/Session/header


获取 Request 和 Response 对象

@RequestMapping("/param11")
public String param11(HttpServletResponse response, HttpServletRequest requ
est) {
 String name = request.getParameter("name");
 // 获取所有 cookie 信息
 Cookie[] cookies = request.getCookies();
 return name + " 你好.";
}


获取 Cookie——@CookieValue

@RequestMapping("/cookie")
@ResponseBody
public String cookie(@CookieValue("bite") String bite) {
 return "cookie:" + bite;
}


获取 Header——@RequestHeader

@RequestMapping("/header")
@ResponseBody
public String header(@RequestHeader("User-Agent") String userAgent) {
 return "userAgent:"+userAgent;
}


Session 存储和获取


存储:

@RequestMapping("/setsess")
@ResponseBody
public String setsess(HttpServletRequest request) {
 // 获取 HttpSession 对象,参数设置为 true 表示如果没有 session 对象就创建⼀个session
 HttpSession session = request.getSession(true);
 if(session!=null){
 session.setAttribute("username","java");
 }
 return "session 存储成功";
}


获取:

@RequestMapping("/sess")
@ResponseBody
public String sess(HttpServletRequest request) {
 // 如果 session 不存在,不会⾃动创建
 HttpSession session = request.getSession(false);
 String username = "暂⽆";
 if(session!=null && session.getAttribute("username")!=null){
 username = (String) session.getAttribute("username");
 }
 return "username:"+username;
}


更简单的获取:

@RequestMapping("/sess2")
@ResponseBody
public String sess2(@SessionAttribute(value = "username",required = false)
String username) {
 return "username:"+username;
}

2.3 返回数据


默认请求下⽆论是 Spring MVC 或者是 Spring Boot 返回的是视图 (xxx.html),⽽现在都是前后端分离的,后端只需要返给给前端数据即可,这个时候我们就需要使⽤

@ResponseBody

注解了

2.3.1 返回静态页面

创建前端页面 index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>hello,spring mvc</title>
    <script src="index.js"></script>
</head>
<body>
<h1>Hello,Spring MVC.</h1>
</body>
</html>

创建控制器 controller:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/p")
public class PersonController {
    @RequestMapping("/index")
    public Object index(){
        // 执⾏业务...
        // 返回view -> index.html
        return "/index.html";
    }
}

2.3.2 返回 text/html

@RequestMapping("/m7")
@ResponseBody
public String method_7() {
 return "<h1>Hello,HTML~</h1>";
}

2.3.3 返回 JSON 对象

@RequestMapping("/m8")
@ResponseBody
public HashMap<String, String> method_8() {
 HashMap<String, String> map = new HashMap<>();
 map.put("Java", "Java Value");
 map.put("MySQL", "MySQL Value");
 map.put("Redis", "Redis Value");
 return map;
}

2.3.4 请求转发或请求重定向



1)forward 请求转发;



2)redirect 请求重定向。

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

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


转发和重定向的区别:转发是服务器帮转的,而重定向是让浏览器重新请求另⼀个地址。



forward 和 redirect 具体区别:


1.


请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。

2.


请求重定向地址发⽣变化,请求转发地址不发⽣变化。

3.


请求重定向与直接访问新地址效果⼀致,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。


请求转发 forward 导致问题演示


请求转发如果资源和转发的⻚⾯不在⼀个⽬录下,会导致外部资源不可访问

controller 示例代码:

@Controller
@RequestMapping("/user")
public class UserController {
 @RequestMapping(value = "/index")
 public String sayHi(){
 return "forward:/index.html";
 }
}

程序的⽬录如下:
执行结果:


尝试将转发 foward 换成重定向 redirect:

@Controller
@RequestMapping("/user")
public class UserController {
 @RequestMapping(value = "/index")
 public String sayHi(){
 return "redirect:/index.html";
 }
}

页面就可以正常获取到外部资源 js 了

2.3.5 @ResponseBody 说明


@ResponseBody 返回的值如果是字符会转换成 text/html,如果返回的是对象会转换成application/json 返回给前端。

@ResponseBody 可以⽤来修饰⽅法或者是修饰类,修饰类表示类中的所有⽅法都会返回 html 或者 json,而不是视图。


2.3

.6 组合注解:@RestController


@RestController = @Controller + @ResponseBody



版权声明:本文为qq_68875683原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。