深入探索 Spring MVC:构建优雅的Web应用

news2024/10/7 10:21:18

文章目录

  • 前言
  • 一、什么是 Spring MVC
    • 1.1 什么是 MVC
    • 1.2 什么是 Spring MVC
  • 二、Spring MVC 项目的创建
    • 2.1 项目的创建
    • 2.2 第一个 Spring MVC 程序 —— Hello World
  • 三、@RequestMapping 注解
    • 3.1 常用属性
    • 3.2 方法级别和类级别注解
    • 3.3 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping
  • 四、Spring MVC 获取参数
    • 4.1 获取简单参数
      • 4.1.1 通过 URL 查询字符串获取
      • 4.1.2 通过 form 表单获取
    • 4.2 获取对象
      • 4.2.1 通过多个参数获取
      • 4.2.2 通过 @RequestBody 接收 JSON 对象
    • 4.3 通过 @RequestParam 设置参数重命名
    • 4.4 通过 @RequestParam 设置参数必传与非必传
    • 4.5 通过 @PathVariable 获取 URL 路径中的参数
  • 五、@RequestPart 实现文件的上传
  • 六、通过 @RequestHeader 获取 HTTP 头部字段
  • 七、Session 和 Cookie 的获取
    • 7.1 Session 的储存与获取
      • 7.1.1 Session 储存
      • 7.2.2 Session 获取
    • 7.2 通过 @CookieValue 获取 Cookie
  • 八、Spring MVC 数据的返回
    • 8.1 返回数据内容
    • 8.2 返回静态页面
    • 8.3 返回 JSON 对象
  • 九、请求转发和请求重定向
    • 9.1 请求转发 forward
    • 9.2 请求重定向 redirect
    • 9.3 forward 和 redirect 的区别


前言

Spring MVC 是 Java 中最受欢迎的 Web 框架之一,它为开发人员提供的强大的工具和灵活的架构,帮助构建高效、可扩展且易于维护的 Web 应用程序。本文将深入探讨 Spring MVC 的核心概念、使用方法以及实践操作。

一、什么是 Spring MVC

1.1 什么是 MVC

在了解什么是 Spring MVC之前,我们首先有必要先了解其中的 MVC 到底是什么。

MVC 是 “Mode View Controller” 的缩写,它是一种软件设计模式,用于将应用程序划分为三个核心组件,即:Model(模型)、View(视图)和 Controller(控制器)。每个组件都有自己独特的职责,它们之间协调工作以实现应用程序的分层设计和低耦合。

  • Model(模型):负责管理应用程序的数据和业务逻辑。它独立于视图和控制器,通过提供数据接口供视图展示数据,同时也能接受来自控制器的指令来更新数据状态。

  • View(视图):负责展示数据给用户,并将用户的输入传递给控制器。它通常是用户界面的呈现,如 HTML 页面、用户界面控件等。

  • Controller(控制器):充当模型和视图之间的中介,处理用户的请求并作出响应。它接受用户输入,根据输入来更新模型状态,并选择合适的视图来展示更新后的数据。

MVC 模式的优点在于它能够是代码分离,使得应用程序更易于维护和实现。例如,当需要更改应用程序的外观时,只需更改视图层而不会影响模型和控制器的逻辑。这种解耦合的设计使得团队成员可以并行开发不同组件,从而提高开发效率。

1.2 什么是 Spring MVC

Spring MVC 是 Spring 框架中的一个 Web 框架,用于构建基于 Java 的 Web 应用程序。它是一个轻量级、灵活且功能强大的框架,采用MVC(Model-View-Controller)设计模式,将应用程序划分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)

具体来说,Spring MVC的定义如下:

  1. Web 框架:Spring MVC 专注于处理 Web 应用程序的请求和响应,提供了处理 HTTP 请求和构建 Web 页面的核心功能。

  2. 基于Servlet API:Spring MVC 构建在 Java Servlet API 之上,利用 Servlet 容器来处理 HTTP 请求和响应,因此可以与常见的 Java Web 容器无缝集成。

  3. MVC 设计模式:Spring MVC 采用了MVC 设计模式,将应用程序划分为三个主要组件,使得各组件的职责清晰分离,从而提高了代码的可维护性和可测试性。

  4. 轻量级和灵活:Spring MVC 是一个轻量级框架,不需要复杂的配置和依赖,同时具有很高的灵活性,允许开发者根据具体需求定制处理请求的流程。

  5. 与 Spring 整合:Spring MVC 是Spring 框架的一部分,因此可以与其他 Spring 组件(如 Spring Core、Spring Boot 等)无缝集成,享受 Spring 生态系统的丰富特性和便利性。

Spring MVC 通过处理器映射(Handler Mapping)将 URL 请求映射到相应的控制器方法上,控制器方法处理请求并更新模型状态,然后选择适当的视图来展示数据给用户。它还提供了视图解析器(View Resolver),用于将控制器返回的逻辑视图映射到具体的视图技术(如JSP、Thymeleaf等)。

总体而言,Spring MVC 是 Java Web 开发中最受欢迎的框架之一,它提供了丰富的功能和特性,使得开发者能够快速构建高效、可维护的Web应用程序。

二、Spring MVC 项目的创建

2.1 项目的创建

Spring MVC 项目的创建和 Spring Boot 项目的创建的方式相同,因为之前在创建 Spring Boot 项目的时候,一直都引入了一个叫做 Spring Web 的依赖。因此,当在创建 Spring Boot 项目的时候引入了这个依赖,那么我们的项目就变成了一个 Spring MVC 项目了。

2.2 第一个 Spring MVC 程序 —— Hello World

demo 目录下创建一个控制层的类 TestController,通过浏览器访问时,页面上输出 “Hello World” :

@RestController
public class TestController {
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World";
    }
}

运行启动类,通过浏览器访问 http://localhost:8080/hello 得到以下结果:

三、@RequestMapping 注解

在 Spring MVC 中,@RequestMapping 是一个非常重要的注解,用于将 HTTP 请求映射到控制器的处理方法上。通过 @RequestMapping 注解,我们可以定义 URL 路径、HTTP 请求方法、请求参数等于控制器方法的映射关系。

3.1 常用属性

通过查看 @RequestMapping 注解的源码可以看到里面有许多的属性:

下面是@RequestMapping注解的常用属性及其说明:

属性名说明
name设置处理器方法的名称,用于在其他组件中进行引用。
value指定URL路径,可以是一个字符串或字符串数组。
pathvalue属性等价,用于指定URL路径,可以是一个字符串或字符串数组。
method指定HTTP请求方法,可以是RequestMethod枚举值或RequestMethod数组。
params指定请求参数的条件,可以是一个字符串或字符串数组。
headers指定HTTP请求头部的条件,可以是一个字符串或字符串数组。
consumes指定请求的Content-Type媒体类型,可以是一个字符串或字符串数组。
produces指定响应的Content-Type媒体类型,可以是一个字符串或字符串数组。

@RequestMapping注解是一个元注解(meta-annotation),它本身也被其他注解如@GetMapping@PostMapping@PutMapping@DeleteMapping所使用。通过设置不同的属性,可以灵活地定义控制器方法的URL映射、HTTP请求方法、请求参数和请求头等条件,从而实现多样化的请求处理。

3.2 方法级别和类级别注解

@RequestMapping 注解既可以用在方法级别上,也可以用在类级别上。

方法级别:

在方法级别上,@RequestMapping注解用于指定具体的请求映射路径。例如:

@Controller
public class UserController {
    // 方法级别路径为"/profile"
    // 最终请求路径为"/profile"
    @RequestMapping("/profile")
    public String userProfile() {
        // 处理方法逻辑
        return "profile";
    }
}

类级别:

在类级别上,@RequestMapping 注解用于指定该类中所有处理方法的共同父路径。例如:

@Controller
@RequestMapping("/users")
public class UserController {
    // 类中所有方法的父路径为"/users"
    // 具体路径为"/users/profile"
    @RequestMapping("/profile")
    public String userProfile() {
        // 处理方法逻辑
        return "profile";
    }
}

3.3 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping

回到第一个 “Hello World” 程序,我们可以通过浏览器访问 http://localhost:8080/hello,然后在页面上输出 “Hello World”。

那么这个HTTP请求使用的是什么方法呢?


通过浏览器抓包可以发现,使用的是 GET请求,那么是否支持其他请求呢?

通过 Postman 发送 POST 请求,发现也能够获取到返回的内容:

另外发送 PUT 和 DELETE 方法请求,发现都能获取到结果,也就是说在默认情况下,使用@RequestMapping 注解支持所有的方法。当然,如果要想只支持某种方法,可以通过其 method 属性进行指定,例如指定 GET 方法:


那么,此时再次通过 Postman 发送 POST 请求:


则发现此时返回的状态码为 405,即不支持 POST 请求方法。

为了简化@RequestMapping注解的使用,Spring MVC 提供了更具体的缩写注解:@GetMapping@PostMapping@PutMapping@DeleteMapping。这些注解分别对应 HTTP 的 GET、POST、PUT 和 DELETE 请求方法,可以让代码更加简洁和直观。

例如,上述代码可以使用@GetMapping来替代:

@RestController
public class TestController {
    @GetMapping("/hello")
    public String hello(){
        return "Hello World";
    }
}

四、Spring MVC 获取参数

在 Web 开发中,处理用户提交的请求时,经常需要从请求中获取参数来进行后续的处理。Spring MVC提供了多种方式来获取参数,包括获取简单参数、获取对象、设置参数重命名和设置参数是否必传等。

4.1 获取简单参数

4.1.1 通过 URL 查询字符串获取

在 HTTP 请求中,查询字符串是 URL 中问号后面的参数部分,例如:http://example.com?name=zhangsan&age=25。我们可以通过在控制器方法中添加参数,使用@RequestParam注解来获取查询字符串中的参数值。

@RestController
public class TestController {
    @GetMapping("/get")
    public String  getParam(@RequestParam String name, @RequestParam Integer age){
        return "name = " + name + ", age = " + age;
    }
}


如果查询字符串中的参数名和getParam1中的参数名称一样的情况下,@RequestParam 注解可以省略,此时 Spring MVC 会自动将请求中对应的参数值绑定到方法参数上。例如:

@RestController
public class TestController {
    @GetMapping("/get")
    public String  getParam(@RequestParam String name, @RequestParam Integer age){
        return "name = " + name + ", age = " + age;
    }
}

4.1.2 通过 form 表单获取

在表单提交时,同样可以通过@RequestParam注解来获取表单中的参数值,此时和上面获取查询字符串中的参数方法基本一样,只是 HTTP 的方法变成了 POST:

表单页面:

<form action="/submit" method="post">
    <input type="text" name="name">
    <input type="number" name="age">
    <input type="submit" value="提交">
</form>

获取方法:

@RestController
public class TestController {
    @PostMapping("/submit")
    public String submitForm(@RequestParam String name, @RequestParam Integer age){
        return "name = " + name + ", age = " + age;
    }
}

通过 Postman 发送 form 表单数据:

4.2 获取对象

创建一个实体类 User

4.2.1 通过多个参数获取

此时,可以通过 URL 中的查询字符串传递nameage 参数,也可以通过form表单进行提交,只要传递的参数名称和 User 类中的参数名称能够匹配,那么 Spring MVC 就是自动将请求中的参数绑定到User对象中。

@RestController
public class TestController {
    @RequestMapping("/user")
    public String getUser(User user){
        return user.toString();
    }
}

通过浏览器访问http://localhost:8080/user?name=zhangsan&age1=25

当然,如果参数名称不匹配的话,就获取不到对应的参数了:

4.2.2 通过 @RequestBody 接收 JSON 对象

当客户端通过 JSON 格式提交数据时,可以使用 @RequestBody 注解将请求体中的 JSON 数据绑定到 Java 对象上。

@RestController
public class TestController {
    @RequestMapping("/user")
    public String getJsonUser(@RequestBody User user){
        return user.toString();
    }
}

通过 Postman 提交以下 JSON 格式的内容:

{
    "name": "zhangsan",
    "age": 25
}

结果:

4.3 通过 @RequestParam 设置参数重命名

当前后端参数不匹配的时候,如果不加处理,就不能够正确的获取到想要的参数,此时就可以通过 @RequestParam注解来设置参数的重命名。

在 Java 代码中可以查看 @RequestParam 的源码:

其中的 value 或者 name 就可以用来进行参数重命名操作,例如此时前端请求 URL 中的查询字符串是 username=zhangsan&age=25,而后端用于接收的是 nameage

@RestController
public class TestController {
    @GetMapping("/get")
    public String  getParam(@RequestParam(value = "username") String name, @RequestParam Integer age){
        return "name = " + name + ", age = " + age;
    }
}

通过浏览器发送请求:

4.4 通过 @RequestParam 设置参数必传与非必传

例如,通过下面的代码来获取 URL 中的请求参数:

@RestController
public class TestController {
    @GetMapping("/get")
    public String  getParam(@RequestParam String name, @RequestParam Integer age){
        return "name = " + name + ", age = " + age;
    }
}

此时,如果少传递一个 age 参数:

那么收到的响应状态码就为 400,即请求错误。在上文的 @RequestParam 注解中可以发现有一个参数叫做 required,其默认值为 true ,意味着参数是必传的,如果缺少的参数就会保存,那么此时,我们可以将age 参数设置为非必传的,如下面的代码:

@RestController
public class TestController {
    @GetMapping("/get")
    public String  getParam(@RequestParam String name, @RequestParam(required = false) Integer age){
        return "name = " + name + ", age = " + age;
    }
}

此时通过浏览器访问,就发现不会报错了:

4.5 通过 @PathVariable 获取 URL 路径中的参数

在 Spring MVC 中,URL 路径通常包含一些占位符,这些占位符可以用于传递参数。通过@PathVariable注解,可以将这些 URL 路径中的参数值绑定到方法的参数上,从而在控制器方法中使用这些参数进行处理。

例如,假设我们有一个URL路径为 /root/{name}/{age},其中 {name}{age} 就是占位符。我们可以通过@PathVariable注解将这个占位符对应的值绑定到方法的参数上,如下所示:

@RestController
public class TestController {
    @RequestMapping("/root/{name}/{age}")
    public String getParam(@PathVariable String name, @PathVariable String age){
        return "name = " + name + ", age = " + age;
    }
}

通过浏览器访问,就能够获取到 URL 中的参数了:


另外需要注意的是,@PathVariable 注解的参数名称需要与 URL 路径中的占位符名称一致,如果名称不一致,可以使用@PathVariable("placeholderName")指定占位符的名称。

例如,假设 URL 路径为 /root/{username}/{age},但想在方法中使用name来表示这个参数,可以这样做:

@RestController
public class TestController {
    @RequestMapping("/root/{name}/{age}")
    public String getParam(@PathVariable(name = "username") String name, @PathVariable String age){
        return "name = " + name + ", age = " + age;
    }
}

五、@RequestPart 实现文件的上传

@RequestPart 注解用于实现文件的上传。它是 Spring MVC 中处理文件上传的一种方式。

通常,在文件上传过程中,客户端将文件数据以multipart/form-data的形式提交到服务器。在 Spring MVC 中,可以使用 @RequestPart 注解将 multipart/form-data 中的文件部分绑定到控制器方法的参数上,从而实现文件的上传。

例如,现在要实现一个图片上传的功能,要求将上传的图片保存到一个文件夹中,并且每次上次的图片不能被下一次的上传操作覆盖,实现代码如下:

@RestController
public class TestController {
	private static final String SAVE_PATH = "C:\\Users\\Administrator\\Desktop\\image\\";

    @PostMapping("/upload")
    public Object uploadImg(@RequestPart("img") MultipartFile file) {
        if (file.isEmpty()) {
            return "请选择要上传的图片";
        }

        // 检查文件类型
        if (!isValidImageFile(file)) {
            return "只能上传图片文件";
        }

        // 检查文件大小
        if (!isValidFileSize(file)) {
            return "图片文件大小不能超过2MB";
        }

        String originalFileName = file.getOriginalFilename(); // 获取原始文件名称
        String extension = originalFileName.substring(originalFileName.lastIndexOf('.')); // 获取文件后缀
        String fileName = generateUniqueFileName(extension);

        File saveFile = new File(SAVE_PATH + fileName);

        try {
            file.transferTo(saveFile);
            return "上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            return "上传失败";
        }
    }

    private boolean isValidImageFile(MultipartFile file) {
        // 实现文件类型校验,根据实际需求进行判断
        // 例如可以判断文件的后缀名是否为常见的图片格式:jpg/jpeg、png、gif等
        // return file.getContentType().startsWith("image/");
        return true; // 这里简化处理,总是返回true
    }

    private boolean isValidFileSize(MultipartFile file) {
        // 实现文件大小校验,根据实际需求进行判断
        // 例如可以判断文件的大小是否小于2MB
        return file.getSize() <= 2 * 1024 * 1024; // 2MB
    }

    private String generateUniqueFileName(String extension) {
        String fileName = UUID.randomUUID().toString() + extension;
        return fileName;
    }
}

这段代码实现了一个简单的文件上传功能。下面是对代码的解析:

  1. private static final String SAVE_PATH = "C:\\Users\\Administrator\\Desktop\\image\\";

    这是一个常量,表示文件保存的路径。在这个示例中,文件将被保存到C:\Users\Administrator\Desktop\image\目录下。

  2. @PostMapping("/upload")

    这个注解表示uploadImg方法用于处理 HTTP POST 请求,并映射到路径/upload上。

  3. public Object uploadImg(@RequestPart("img") MultipartFile file)

    这个方法用于处理文件上传。@RequestPart("img")注解用于绑定请求体中名为img的部分到file参数上。MultipartFile是Spring框架提供的用于处理文件上传的接口,它表示上传的文件数据。

  4. 文件上传处理逻辑:

    • 首先,检查file是否为空,如果为空,则返回提示信息"请选择要上传的图片"。

    • 接着,调用isValidImageFile方法,检查文件类型。在示例中,这个方法被简化为总是返回true,实际使用中可以根据需要实现文件类型的检查。

    • 然后,调用isValidFileSize方法,检查文件大小。在示例中,文件大小不能超过2MB(2 * 1024 * 1024字节)。

    • 如果文件类型或文件大小校验不通过,返回相应的错误提示信息。

    • 最后,如果文件上传校验通过,生成一个唯一的文件名,通过UUID.randomUUID().toString()生成唯一的字符串,并根据原始文件的后缀名拼接成完整的文件名。然后将文件保存到SAVE_PATH指定的目录中。

  5. private boolean isValidImageFile(MultipartFile file)

    这是一个私有方法,用于实现文件类型校验。在示例中,这个方法被简化为总是返回true,实际使用中可以根据实际需求进行文件类型的检查,例如判断文件的后缀名是否为常见的图片格式:jpg/jpeg、png、gif等。

  6. private boolean isValidFileSize(MultipartFile file)

    这是一个私有方法,用于实现文件大小校验。在示例中,文件大小不能超过2MB(2 * 1024 * 1024字节)。

  7. private String generateUniqueFileName(String extension)

    这是一个私有方法,用于生成唯一的文件名。在示例中,使用UUID.randomUUID().toString()生成一个唯一的字符串,然后根据文件的后缀名拼接成完整的文件名。

通过这段代码,实现了将上传的图片保存到指定的文件夹中,并在文件名中添加唯一标识,避免了文件覆盖的问题。同时,加入了文件类型和大小校验,增强了代码的健壮性和安全性。但实际文件保存路径、文件类型校验和文件大小校验等还需要根据具体需求进行进一步调整和完善。

通过 Postman 发起上传图片的请求:


多次上传这一张图片:

六、通过 @RequestHeader 获取 HTTP 头部字段

通过@RequestHeader注解,可以获取HTTP请求头部字段的值。

在 Spring MVC 中,HTTP 请求头部包含了一些元数据信息,例如User-AgentContent-TypeAuthorization等。使用@RequestHeader注解,可以将这些 HTTP 请求头部字段的值绑定到控制器方法的参数上,从而在方法中使用这些值进行处理。

以下是一个示例代码,演示如何使用@RequestHeader获取HTTP头部字段的值:

@RestController
public class TestController {
    @GetMapping("/headers")
    public String getHeaders(@RequestHeader("User-Agent") String userAgent,
                             @RequestHeader("Accept-Language") String acceptLanguage
                             ) {
        // 在方法中使用获取到的HTTP头部字段值进行处理
        // ...
        return "User-Agent: " + userAgent + "<br>" +
                "Accept-Language: " + acceptLanguage;
    }

}

在上述示例中,我们定义了一个名为getHeaders的控制器方法,并使用@GetMapping注解将该方法映射到GET请求的/headers路径上。通过浏览器访问并抓包,发现得到的内容和抓包的内容一模一样。

七、Session 和 Cookie 的获取

7.1 Session 的储存与获取

在Web应用中,Session用于在服务器端存储用户的状态信息。在 Spring MVC 存储和获取Session中的数据的方法和Servlet中的方法一样。

7.1.1 Session 储存

在Spring MVC中,可以使用HttpSession对象来储存和获取Session中的数据。HttpSession对象代表了当前用户的Session,并可以通过HttpServletRequest对象的getSession()方法来获取。

@RestController
public class TestController {
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession(true);
        session.setAttribute("username", "zhangsan");
        return "session has set.";
    }
}

在上述示例中,在/setSession路径下定义了一个setSession方法,当用户访问该路径时,如果会话没有被创建,则会在Session中存储一个名为"username"的属性,并设置其值为 “zhangsan” 的记录。

通过 Fiddle 抓包,可以发现成功设置了 Session

值得注意的是:

  • 在Spring MVC中,当@RequestMapping注解的方法参数包含HttpServletRequestHttpServletResponse时,Spring MVC 会自动将当前的HttpServletRequestHttpServletResponse对象传递给这些方法参数。
  • 这意味着在@RequestMapping注解的方法中,可以直接声明HttpServletRequestHttpServletResponse类型的参数,而不需要额外的配置或处理,Spring MVC 会自动将请求和响应对象传递给这些参数。

7.2.2 Session 获取

要获取Session中存储的数据,可以使用HttpSession对象的getAttribute()方法来获取。

@Controller
public class TestController {

    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        String username = (String) session.getAttribute("username");
        return "Session中的username值为:" + username;
    }
}

在上述示例中,我们在/getSession路径下定义了一个getSession方法,当用户访问该路径时,会从Session中获取名为"username"的属性,并将其值返回给用户。

7.2 通过 @CookieValue 获取 Cookie

除了使用 Session 来存储用户状态信息,Web 应用还可以使用 Cookie 来存储少量的用户信息。Spring MVC 提供了@CookieValue注解来获取 Cookie 的值。

@RestController
public class TestController {

    @GetMapping("/getCookie")
    public String getCookie(@CookieValue("username") String username) {
        return "Cookie中的username值为:" + username;
    }
}

在上述示例中,我们在/getCookie路径下定义了一个getCookie方法,当用户访问该路径时,会从 Cookie 中获取名为 “username” 的值,并将其返回给用户。

请注意,在使用@CookieValue注解时,要确保指定的 Cookie 名称存在。如果不存在,可以使用defaultValue属性指定一个默认值,或者使用required 属性来设置是否必须存在。如果required属性为true,并且Cookie不存在,会抛出异常。

八、Spring MVC 数据的返回

8.1 返回数据内容

在Spring MVC中,控制器方法可以返回不同类型的数据内容。这些数据内容可以作为响应返回给客户端。

@Controller
public class DataController {

    // 返回字符串
    @GetMapping("/hello")
    @ResponseBody
    public String sayHello() {
        return "Hello, World!";
    }

    // 返回数字
    @GetMapping("/number")
    @ResponseBody
    public int getNumber() {
        return 42;
    }

    // 返回布尔值
    @GetMapping("/boolean")
    @ResponseBody
    public boolean getBoolean() {
        return true;
    }
}

在上述示例中,我们定义了一个名为DataController的控制器,并使用@GetMapping注解将三个不同的方法映射到不同的路径上。

  • sayHello方法返回一个字符串"Hello, World!"。使用@ResponseBody注解,将返回的字符串作为响应体直接返回给客户端。

  • getNumber方法返回一个整数42。同样使用@ResponseBody注解,将返回的整数作为响应体直接返回给客户端。

  • getBoolean方法返回一个布尔值true。也使用@ResponseBody注解,将返回的布尔值作为响应体直接返回给客户端。

8.2 返回静态页面

除了返回数据内容,Spring MVC还支持返回静态页面。这通常用于返回HTML页面或其他静态资源。

@Controller
public class PageController {
    @GetMapping("/index")
    public String showPage() {
        return "/index.html";
    }
}

在上述示例中,我们定义了一个名为PageController的控制器,并使用@GetMapping注解将showPage方法映射到GET请求的/index路径上。在这个示例中,返回的视图逻辑名称是"index",Spring MVC会查找名为index.html的HTML模板,并返回给客户端。

8.3 返回 JSON 对象

在Spring MVC中,还可以返回JSON格式的数据,通常用于提供API接口。

@Controller
public class JSONController {

    @GetMapping("/user")
    @ResponseBody
    public User getUser() {
        User user = new User("zhangsan", 30);
        return user;
    }
}

在上述示例中,定义了一个名为JSONController的控制器,并使用@GetMapping注解将getUser方法映射到GET请求的/user路径上。

getUser方法返回一个User对象,使用@ResponseBody注解将这个对象转换为JSON格式,并作为响应体直接返回给客户端。

在实际应用中,可能还需要引入 JSON 序列化库(例如Jackson)来将 Java 对象转换为 JSON 格式。但是Spring MVC 会自动将返回值转换为 JSON 格式,并设置正确的 Content-Type 头部,以便客户端能够正确解析返回的 JSON 数据。

九、请求转发和请求重定向

9.1 请求转发 forward

请求转发是指将请求从一个 Servlet 转发到另一个 Servlet 或 JSP 页面,转发过程在服务器端完成,客户端浏览器不感知。在 Spring MVC中,可以使用RequestDispatcher对象实现请求转发。

@Controller
public class ForwardController {

    @GetMapping("/forward")
    public String forward() {
        // 实现请求转发到 /index.html路径
        return "forward:/index.html";
    }
}

在上述示例中,定义了一个名为ForwardController的控制器,并使用@GetMapping注解将forward方法映射到 GET 请求的/forward路径上。

forward方法返回一个字符串 “forward:/index.html”,这表示将请求转发到/index.html路径。Spring MVC会在服务器端进行请求转发,将控制权交给/index.html路径对应的处理器方法。

通过浏览器访问地址http://localhost:8080/forward

9.2 请求重定向 redirect

请求重定向是指在接收到请求后,服务器端发送一个 HTTP 响应,响应头部包含了 Location 字段,客户端根据该字段内容重新发送一个新的请求。因此,请求重定向涉及两次请求和响应过程,客户端感知到的是两次请求的结果

@Controller
public class RedirectController {

    @GetMapping("/redirect")
    public String redirect() {
        // 实现请求重定向到 /index.html路径
        return "redirect:/index.html";
    }
}

在上述示例中,定义了一个名为RedirectController的控制器,并使用@GetMapping注解将redirect方法映射到GET请求的/redirect路径上。

redirect方法返回一个字符串"redirect:/index.html",这表示将请求重定向到/index.html路径。Spring MVC会在服务器端发送一个HTTP响应,响应头部包含了Location字段,告诉客户端重定向到/index.html路径。

通过浏览器访问地址http://localhost:8080/redirect

最后跳转到了http://localhost:8080/index.html

可以通过 Fiddle 抓包查看详情:


可以发现,请求http://localhost:8080/redirect,最后出现了两次请求结果。

当请求/redirect的时候,服务器会告诉浏览器去请求/index.html

9.3 forward 和 redirect 的区别

  1. 执行阶段:

    • 请求转发是 在服务器端完成的,客户端浏览器不感知 。请求从一个 Servlet 转发到另一个 Servlet 或 JSP 页面,整个过程是在服务器内部完成的。
    • 请求重定向 涉及两次请求和响应过程 。客户端接收到第一个请求的响应后,会根据响应头部的 Location 字段再发送一个新的请求。
  2. 地址栏变化:

    • 请求转发 不会改变 浏览器的地址栏内容,地址栏中仍然是原始请求的URL。
    • 请求重定向 会改变 浏览器的地址栏内容,地址栏中会显示重定向后的URL。
  3. 请求属性传递:

    • 请求转发可以在转发的过程中共享请求属性,转发前的 Servlet 可以将请求属性设置为转发后的 Servlet 或 JSP 页面所需要的值。
    • 请求重定向不能直接在两次请求之间共享请求属性,因为两次请求是独立的。

选择使用请求转发还是请求重定向取决于具体的需求。请求转发适用于在服务器内部实现页面跳转、共享请求属性等情况。而请求重定向适用于需要修改浏览器地址栏、避免表单重复提交、刷新页面等情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/851423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

贝叶斯深度学习的温和介绍

一、说明 欢迎来到令人兴奋的概率编程世界&#xff01;本文是对这个领域的温和介绍&#xff0c;你只需要对深度学习和贝叶斯统计有一个基本的了解。如果像我一样&#xff0c;你听说过贝叶斯深度学习&#xff0c;并且你猜它涉及贝叶斯统计&#xff0c;但你不知道它是如何使用的&…

SaaS化大型微服务架构智慧工地云平台源码

智慧工地云平台建设是采用先进的移动互联、物联网、云计算、大数据等新一代信息技术&#xff0c;主要由信息采集层、网络接入层、网络传输层、信息储存与处理层组成&#xff0c;主要包括云管理平台、综合管理系统、质量管理系统、安全管理系统等模块。施工管理人员可通过PC端&a…

【2.1】Java微服务: Nacos的使用

目录 Nacos介绍 Nacos安装 下载和安装 修改端口 启动 服务注册与发现 导入Nacos管理依赖 导入服务依赖 配置Nacos的服务地址 启动服务&#xff0c;查看已注册的服务 服务分级存储模型 分级存储模型介绍 具体结构 配置实例集群 同集群优先的负载均衡策略 服务权重配置…

spring-boot webservice的例子

webservice发布服务 源码下载地址 spring-boot-webservice例子资源-CSDN文库 webservice cilent调用 源码下载地址 spring-boot-clintwebservice调用服务的例子资源-CSDN文库

CSS的引入方式有哪些?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 内联样式&#xff08;Inline Styles&#xff09;⭐ 内部样式表&#xff08;Internal Stylesheet&#xff09;⭐ 外部样式表&#xff08;External Stylesheet&#xff09;⭐ 导入样式表&#xff08;Import Stylesheet&#xff09;⭐ 写在最…

Netty:ChannelHandler的两个生命周期监听事件方法:handlerAdded 和 handlerRemoved

说明 io.netty.channel.ChannelHandler有两个生命周期监听事件方法&#xff1a; handlerAdded(ChannelHandlerContext ctx)&#xff1a;当ChannelHandler被添加到实际的上下文、并且已经准备就绪等待处理事件的时候被调用。 handlerRemoved(ChannelHandlerContext ctx)&#…

光猫棒是什么?

名称&#xff1a; 光猫棒 问题描述&#xff1a; 光猫棒是什么? 回答&#xff1a; 1.PON STICK光模块也被称之为猫棒&#xff0c;可以充分满足电信级FTTB、FTTH、FTTO设备要求&#xff0c;可以热插拔到MikroTik软路由或者交换机的SFP插槽工作&#xff0c;整机就可作为ONT甚…

35岁是人生的分水岭,前后精力大不一样!

目录 【前言】 一、35岁&#xff0c;除了步入国内职场世俗意义上的尴尬期&#xff0c;也是体能下滑的断崖期 二、肥胖、疼痛、体能下滑&#xff0c;35岁的身体焦虑 三、35岁不是体能衰老的分界线 四、35岁不是年龄焦虑的节点&#xff0c;运动让人更能掌控身体 【写在最后…

笔记本电脑如何把sd卡数据恢复

在使用笔记本电脑过程中&#xff0c;如果不小心将SD卡里面的重要数据弄丢怎么办呢&#xff1f;别着急&#xff0c;本文将向您介绍SD卡数据丢失常见原因和恢复方法。 ▌一、SD卡数据丢失常见原因 - 意外删除&#xff1a;误操作或不小心将文件或文件夹删除。 - 误格式化&#…

【leetcode】394. 字符串解码

题目链接&#xff1a;力扣 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字符串中没…

SLL VPN

1. SSL工作过程是什么&#xff1f; 第一阶段&#xff1a;客户端首先发送client hello消息到服务端&#xff0c;服务端收到client hello信息后&#xff0c;再发送 server hello消息到客户端。 第二阶段&#xff1a; 第三阶段&#xff1a; 第四阶…

Spring Boot Admin 环境搭建与基本使用

Spring Boot Admin 环境搭建与基本使用 一、Spring Boot Admin是什么二、提供了那些功能三、 使用Spring Boot Admin3.1搭建Spring Boot Admin服务pom文件yml配置文件启动类启动admin服务效果 3.2 common-apipom文件feignhystrix 3.3服务消费者pom文件yml配置文件启动类control…

代码随想录算法训练营之JAVA|第二十四天| 93. 复原 IP 地址

今天是第24天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 93. 复原 IP 地址https://leetcode.cn/problems/restore-ip-addresses/ 第一想法 题目理解&#xff1a;将一串数字字符串变成正确的ip格式的字符串。 这类题目是切分字符串&#xff0c;ip一…

SpringMVC文件上传

文章目录 文件上传配置案例 文件上传配置 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 在MvcConfig配置中&#xff1a; /*** 配置文件上传解析器*/Beanpublic CommonsMultipartResolver multipartResolver() {CommonsMultipartResolver commonsMultipartR…

IDEA设置项目编码格式【修改为GBK 或 UTF-8】

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 出现问题 IDEA导入Eclipse项目、出现编码格式问题。以下过程为将编码格…

尚硅谷张天禹Vue2+Vue3笔记(待续)

简介 什么是Vue&#xff1f; 一套用于构建用户界面的渐进式JavaScript框架。将数据转变成用户可看到的界面。 什么是渐进式&#xff1f; Vue可以自底向上逐层的应用 简单应用:只需一个轻量小巧的核心库 复杂应用:可以引入各式各样的Vue插件 Vue的特点是什么&#xff1f; 1.采…

TCP/IP四层模型对比OSI七层网络模型的区别是啥?数据传输过程原来是这样的

一、TCP/IP四层模型对比OSI七层模型 它们两个定义的一些功能和协议都是差不多的。TCP/IP四层协议模型比我们的七层少了三层&#xff0c;把我们的数据链路层和物理层放在一层里面了&#xff0c;叫做数据链路层&#xff08;网络接口层&#xff09;&#xff0c;对应网络协议也没有…

在 Android 上使用机器学习套件检测人脸

须知事项 此 API 需要 Android API 级别 19 或更高级别。确保应用的 build 文件使用的 minSdkVersion 值不小于 19。 请务必在您的项目级 build.gradle 文件中的 buildscript 和 allprojects 部分添加 Google 的 Maven 代码库。 将 Android 版机器学习套件库的依赖项添加到模…

SpringMVC的架构有什么优势?——控制器(三)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

Python练习 linux系统资源监控

yum install python3 yum -y install python3-pip yum -y install epel-release yum -y install gcc python-devel pip install --trusted-host pypi.tuna.tsinghua.edu.cn psutil 初版&#xff1a; import os import sys import time import platform import subprocess …