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

这篇具有很好参考价值的文章主要介绍了深入探索 Spring MVC:构建优雅的Web应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

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

一、什么是 Spring MVC

1.1 什么是 MVC

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

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

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

  • 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 项目了。

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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

demo 目录下创建一个控制层的类 TestController,通过浏览器访问时,页面上输出 “Hello World” :
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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

运行启动类,通过浏览器访问 http://localhost:8080/hello 得到以下结果:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

三、@RequestMapping 注解

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

3.1 常用属性

通过查看 @RequestMapping 注解的源码可以看到里面有许多的属性:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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

属性名 说明
name 设置处理器方法的名称,用于在其他组件中进行引用。
value 指定URL路径,可以是一个字符串或字符串数组。
path value属性等价,用于指定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”。

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
通过浏览器抓包可以发现,使用的是 GET请求,那么是否支持其他请求呢?

通过 Postman 发送 POST 请求,发现也能够获取到返回的内容:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
那么,此时再次通过 Postman 发送 POST 请求:

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
则发现此时返回的状态码为 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;
    }
}

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
如果查询字符串中的参数名和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 表单数据:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

4.2 获取对象

创建一个实体类 User
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

当然,如果参数名称不匹配的话,就获取不到对应的参数了:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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
}

结果:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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

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

在 Java 代码中可以查看 @RequestParam 的源码:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
其中的 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;
    }
}

通过浏览器发送请求:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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 参数:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

那么收到的响应状态码就为 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;
    }
}

此时通过浏览器访问,就发现不会报错了:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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 中的参数了:

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
另外需要注意的是,@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 发起上传图片的请求:

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
多次上传这一张图片:
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

六、通过 @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路径上。通过浏览器访问并抓包,发现得到的内容和抓包的内容一模一样。

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

七、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:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

值得注意的是:

  • 在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"的属性,并将其值返回给用户。

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

八、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
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

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
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
最后跳转到了http://localhost:8080/index.html

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

深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc
可以发现,请求http://localhost:8080/redirect,最后出现了两次请求结果。

当请求/redirect的时候,服务器会告诉浏览器去请求/index.html
深入探索 Spring MVC:构建优雅的Web应用,Java EE,spring,mvc,spring mvc

9.3 forward 和 redirect 的区别

  1. 执行阶段:

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

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

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

选择使用请求转发还是请求重定向取决于具体的需求。请求转发适用于在服务器内部实现页面跳转、共享请求属性等情况。而请求重定向适用于需要修改浏览器地址栏、避免表单重复提交、刷新页面等情况。文章来源地址https://www.toymoban.com/news/detail-642900.html

到了这里,关于深入探索 Spring MVC:构建优雅的Web应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第三天)动态SQL

    昨天我们深入学习了 Mybatis的核心对象SqlSessionFactoryBuilder , 掌握MyBatis核心配置文件以及元素的使用 ,也掌握MyBatis映射文件及其元素的使用。那么今天我们需要掌握的是更加复杂的查询操作。 学会编写MyBatis中动态SQL 学会MyBatis的条件查询操作 学会MyBatis的更新操作 学会MyBati

    2024年02月11日
    浏览(53)
  • SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第一天)Mybatis的学习

    一、当前的主流框架介绍(这就是后期我会发出来的框架学习) Spring框架 ​ Spring是一个开源框架,是为了解决企业应用程序开发复杂性而创建的 ,其主要优势之一就是分层架构。 Spring提供了更完善的开发环境,可以为POJO(Plain Ordinary Java Object,普通Java对象 )对象提供企业级

    2024年02月12日
    浏览(58)
  • SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第五天)MyBatis的注解开发

    ​ 昨天我们深入学习了 MyBatis多表之间的关联映射,了解掌握了一对一关联映射,一对多关联映射,嵌套查询方式以及嵌套结果方式,掌握了缓存机制的一级缓存,二级缓存等概念,也使用了代码进行复现理解 。但是都是基于XML配置文件的方式来实现的,现在我们要学习一下

    2024年02月11日
    浏览(64)
  • (第十一天)初识SpringMVC SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录

    今天我们要来学习一下SSM框架的最后一个框架SpringMVC 一、初认SpringMVC 基本概念: ​ Spring MVC(Model-View-Controller)是一个用于构建Java Web应用程序的开源框架,它提供了一种基于MVC架构的方式来开发Web应用 。 ​ SpringMVC是Spring Framework的一部分,它是一种基于模型-视图-控制器(

    2024年02月07日
    浏览(72)
  • 深入探索Angular:构建现代化的Web应用

    Angular是一种流行的前端开发框架,被广泛用于构建现代化的Web应用。作为一名技术专家,我们需要深入了解Angular的核心原则和设计思想,并学会如何应用它来构建出色的Web应用。本篇博客将详细介绍Angular,包括其基本概念、关键组件以及实际案例。 Angular是一个基于TypeScr

    2024年02月12日
    浏览(73)
  • 【Java EE】关于Spring MVC 响应

    在博主前面写的博客 【Java EE】Spring请求如何传递参数详解 中我们已经设置了响应数据,Http响应结果可以是数据,也可以是静态⻚⾯,也可以针对响应设置状态码, Header信息等 首先我们像创建一个静态界面,创建位置如下: 前端代码如下: 不过这里的后端的代码和以前的代码

    2024年04月14日
    浏览(49)
  • Java EE 突击 11 - Spring MVC 程序开发 (2)

    这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架 JavaEE 进阶专栏 Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在 接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点 并且带领大家进行环境的配置 , 让大家真正用好

    2024年02月13日
    浏览(74)
  • Java EE 突击 10 - Spring MVC 程序开发 (1)

    这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架 JavaEE 进阶专栏 Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在 接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点 并且带领大家进行环境的配置 , 让大家真正用好

    2024年02月13日
    浏览(49)
  • 构建现代化的Java应用: 深入探讨Spring Boot实际应用

    Spring Boot 是一个快速构建基于 Spring 框架的应用程序的框架。它提供了自动配置、代码生成器和快速开发工具,使得创建现代化的 Java 应用程序变得非常容易。在这里,我们将深入探讨 Spring Boot 实际应用的一些关键方面。 1. 数据库访问: 2. Web 应用程序开发: 3. 安全性: 4

    2024年02月02日
    浏览(70)
  • 构建现代化的Java应用:深入探讨Spring Boot实际应用

            Spring Boot作为Spring框架的一部分,是一款用于简化Java应用开发的框架。它通过提供约定大于配置的原则,使得开发者能够更加迅速、高效地搭建和部署应用。本文将深入探讨Spring Boot的实际应用场景,以及一些最佳实践,助力开发者更好地利用这一现代化的Java开发

    2024年02月03日
    浏览(81)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包