Spring MVC

Sprig MVC简介

Spring MVC 是 Spring 框架中的一个模块,用于构建基于 Java 的 Web 应用程序。它提供了一种基于 MVC(Model-View-Controller)设计模式的方式来开发 Web 应用,使开发人员能够更好地组织和管理项目代码。下面是关于 Spring MVC 的简要介绍:

特点和优势

  1. MVC 架构:
  • Spring MVC 遵循经典的 MVC 设计模式,将应用程序分为模型(Model)、视图(View)和控制器(Controller),有助于代码的分层和模块化。
  1. 灵活性:
  • Spring MVC 提供了灵活的配置选项,允许开发人员根据需求自定义和配置各个组件,如处理器映射、视图解析器等。
  1. 强大的处理器映射:
  • Spring MVC 使用处理器映射来将请求路由到相应的处理器方法,支持基于 URL、参数、HTTP 方法等多种映射方式。
  1. 视图解析:
  • 支持多种视图技术,如 JSP、Thymeleaf、FreeMarker 等,开发人员可以根据需求选择合适的视图解析器。
  1. 拦截器:
  • Spring MVC 提供拦截器机制,允许开发人员在请求处理的不同阶段执行预处理和后处理操作,实现横切关注点的功能。
  1. 数据绑定和验证:
  • 支持数据绑定和验证,简化表单数据的处理和校验过程,提高开发效率。
  1. RESTful 支持:
  • Spring MVC 提供对 RESTful 风格的支持,可以轻松构建符合 REST 原则的 Web 服务。

Spring MVC 的工作流程

  1. 客户端发送请求:客户端(浏览器、移动应用等)发送 HTTP 请求到服务器。

  2. 前端控制器:DispatcherServlet 充当前端控制器,负责接收所有请求并将其分发给相应的处理器。

  3. 处理器映射:处理器映射器根据请求映射到对应的处理器(Controller)。

  4. 处理器处理请求:处理器执行业务逻辑,可能会调用服务层或数据访问层进行处理。

  5. 处理器返回模型数据:处理器将处理结果封装成模型数据,并返回视图名。

  6. 视图解析:视图解析器解析视图名,将模型数据填充到视图中生成最终的响应。

  7. 响应返回客户端:最终生成的响应返回给客户端。

Spring MVC 的核心组件

1. DispatcherServlet(前端控制器):

  • DispatcherServlet 是 Spring MVC 的核心,负责接收所有请求并将其分发到相应的处理器(Controller)进行处理。

  • 它是一个 Servlet,通常在 web.xml 中进行配置,并拦截所有请求。

2. HandlerMapping(处理器映射器):

  • HandlerMapping 用于确定请求应该由哪个处理器来处理。

  • Spring 提供了多种 HandlerMapping 实现,如 BeanNameUrlHandlerMapping、RequestMappingHandlerMapping 等。

3. Controller(处理器):

  • Controller 是 Spring MVC 中的处理请求的组件**,负责处理用户请求、执行业务逻辑,并返回适当的响应**。

  • 可以是一个类,通常使用 `@Controller` 或 `@RestController` 注解标记。

4. HandlerAdapter(处理器适配器):

  • HandlerAdapter 用于将请求分派给实际的处理器方法。

  • 根据处理器的类型,选择合适的 HandlerAdapter 来调用处理器的方法。

5. ViewResolver(视图解析器):

  • ViewResolver 用于解析视图名称并将其解析为实际的视图对象。

  • Spring MVC 提供了多种 ViewResolver 实现,如 InternalResourceViewResolver、ThymeleafViewResolver 等。

6.View(视图):

  • View 负责渲染模型数据,并生成最终的响应内容。

  • 可以是 JSP、Thymeleaf、FreeMarker 等不同类型的视图技术。

7. HandlerInterceptor(处理器拦截器):

  • HandlerInterceptor 允许在请求处理的不同阶段执行预处理和后处理操作。

  • 可以用于实现日志记录、权限检查、性能监控等功能。

8. ModelAndView(模型和视图):

  • ModelAndView 用于封装模型数据和视图信息,将处理器方法的处理结果传递给 View 进行渲染。

9. DataBinder(数据绑定器):

  • DataBinder 负责将请求参数绑定到处理器方法的参数中,简化数据绑定和类型转换操作。

这些核心组件共同协作,构成了 Spring MVC 框架的基本架构,使开发人员能够以一种清晰、模块化的方式构建灵活和可扩展的 Web 应用程序。通过合理配置和使用这些组件,可以实现高效的请求处理、模型数据操作和视图渲染,提供优秀的用户体验。

Spring MVC 中各组件的工作流程:

  1. 客户端发送请求:
  • 客户端(浏览器、移动应用等)发送 HTTP 请求到服务器。
  1. DispatcherServlet 接收请求:
  • DispatcherServlet 充当前端控制器,接收所有请求,并根据配置找到对应的处理器。
  1. HandlerMapping 确定处理器:
  • HandlerMapping 根据请求信息确定应该由哪个处理器(Controller)来处理请求。
  1. HandlerAdapter 调用处理器方法:
  • HandlerAdapter 负责调用处理器的方法,并处理方法的返回结果。
  1. Controller 处理请求:
  • Controller 接收请求,执行业务逻辑,可能会调用服务层或数据访问层进行处理。

  • Controller 将处理结果封装到 ModelAndView 对象中,包括模型数据和视图名称。

  1. HandlerInterceptor 执行拦截器:
  • 如果配置了拦截器,HandlerInterceptor 将在处理器执行前后执行预处理和后处理操作。
  1. ViewResolver 解析视图:
  • ViewResolver 解析视图名称,找到对应的视图对象。
  1. View 渲染视图:
  • View 负责渲染模型数据,生成最终的响应内容。

  • 可以是 JSP、Thymeleaf、FreeMarker 等不同类型的视图技术。

  1. ModelAndView 返回响应:
  • ModelAndView 包含了模型数据和视图信息,最终将生成的响应返回给客户端。
  1. 响应返回客户端:
  • 最终生成的响应返回给客户端,完成请求-响应周期。

通过以上工作流程,Spring MVC 实现了请求的分发、处理、渲染和响应的过程。每个组件在流程中扮演重要角色,协同工作以确保请求得到正确处理并生成符合预期的响应。这种基于 MVC 设计模式的架构使得开发人员能够更好地组织和管理项目代码,实现高效、灵活和可维护的 Web 应用程序。

IDEA 中搭建 Spring MVC 项目

步骤一:创建新项目

  1. 打开 IntelliJ IDEA,选择 "Create New Project"。

  2. 在左侧选择 "Spring Initializr"。

  3. 配置项目信息,包括 Group、Artifact、Type、Language 等。

  4. 确保勾选 "Spring Web" 依赖,这将包括 Spring MVC 在内的必要依赖。

  5. 点击 "Next",选择项目位置和名称,然后点击 "Finish" 创建项目。

步骤二:编写 Spring MVC Controller

  1. 在项目中创建一个新的 Java 类,作为 Spring MVC 的 Controller。

  2. 在类上添加 `@Controller` 或 `@RestController` 注解,以标识这是一个处理请求的 Controller。

  3. 在方法上添加 `@RequestMapping` 或 `@GetMapping`、`@PostMapping` 等注解,定义处理不同请求的方法。

@Controller

public class MyController {

@RequestMapping("/hello")

public String hello() {

return "hello";

}

}

步骤三:创建视图

  1. 在项目中创建一个 `webapp/WEB-INF/views` 目录,用于存放 JSP 视图文件。

  2. 在该目录下创建一个名为 `hello.jsp` 的 JSP 文件,用于展示处理结果。

<!DOCTYPE html>

<html>

<head>

<title>Hello Page</title>

</head>

<body>

<h1>Hello, Spring MVC!</h1>

</body>

</html>

步骤四:配置 Spring MVC

  1. 在web.xml 配置Spring MVC的DispatcherServlet。

  2. 在配置文件中配置 Spring MVC 相关的组件,包括 HandlerMapping、ViewResolver 等。

<!DOCTYPE web-app PUBLIC

"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>

<display-name>Archetype Created Web Application</display-name>

<!-- 配置核心控制器 -->

<servlet>

<servlet-name>dispatcherServlet</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<!-- springmvc配置文件加载路径

1)默认情况下,读取WEB-INF下面的文件

2)可以改为加载类路径下(resources目录),加上classpath:

-->

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:springmvc.xml</param-value>

</init-param>

<!--

DispatcherServlet对象创建时间问题

1)默认情况下,第一次访问该Servlet的创建对象,意味着在这个时间才去加载springMVC.xml

2)可以改变为在项目启动时候就创建该Servlet,提高用户访问体验。

<load-on-startup>1</load-on-startup>

数值越大,对象创建优先级越低! (数值越低,越先创建)

-->

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>dispatcherServlet</servlet-name>

<!--/ 匹配所有的请求;(不包括.jsp)-->

<!--/* 匹配所有的请求;(包括.jsp)-->

<!--*.do拦截以do结尾的请求-->

<url-pattern>/</url-pattern>

</servlet-mapping>

</web-app>

springmvc.xml进行配置

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!-- 配置自动扫包 -->

<context:component-scan base-package="com.zyh.controller"></context:component-scan>

<!-- 视图解析器 -->

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<!--给逻辑视图加上前缀和后缀 -->

<!--前缀-->

<property name="prefix" value="/"></property>

<!--后缀-->

<property name="suffix" value=".jsp"></property>

</bean>

</beans>

步骤五:运行项目

  1. 点击 IntelliJ IDEA 中的运行按钮,启动项目。

  2. 在浏览器中访问 `http://localhost:8080/hello\`,应该能看到显示 "Hello, Spring MVC!" 的页面。

Cookie和Session

Cookie是一种在客户端(通常是浏览器)和服务器之间传输的小型文本文件,用于存储特定网站的用户信息。在Web开发中,Cookie常用于跟踪用户会话、记录用户偏好设置等。

Spring MVC中设置和读取Cookie

在Spring MVC中,你可以使用`javax.servlet.http.Cookie`类来操作Cookie。以下是一个简单的示例,演示如何在Spring MVC中设置和读取Cookie:

设置Cookie

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServletResponse;

@RestController

public class CookieController {

@RequestMapping("/setCookie")

public String setCookie(HttpServletResponse response) {

Cookie cookie = new Cookie("username", "john_doe");

cookie.setMaxAge(3600); // 设置Cookie的有效期为1小时

response.addCookie(cookie);

return "Cookie set successfully!";

}

}

读取Cookie

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServletRequest;

@RestController

public class CookieController {

@RequestMapping("/getCookie")

public String getCookie(HttpServletRequest request) {

Cookie[] cookies = request.getCookies();

if (cookies != null) {

for (Cookie cookie : cookies) {

if ("username".equals(cookie.getName())) {

return "Username: " + cookie.getValue();

}

}

}

return "Cookie not found!";

}

}

在上面的示例中,`setCookie`方法用于设置名为`username`的Cookie,有效期为1小时。`getCookie`方法用于读取名为`username`的Cookie并返回其值。这些操作都是基于Servlet API提供的功能来实现的。

请注意,Spring MVC并没有提供专门的Cookie管理功能,因此在处理Cookie时,你需要直接使用Servlet API中的Cookie类。当然,你也可以编写自定义的拦截器或过滤器来处理Cookie,以更好地与Spring MVC集成。

Cookie的安全性

Cookie属于客户端(通常是浏览器),因为它们是存储在用户计算机上的文本文件,用于跟踪用户会话、记录用户偏好设置等。服务器端通过在HTTP响应中发送Set-Cookie头来设置Cookie,客户端会在后续的请求中将这些Cookie发送回服务器端。

关于Cookie的安全性,有一些方面需要考虑:

  1. **明文传输**:Cookie在客户端和服务器之间是以明文形式传输的,因此在网络传输过程中可能会被拦截和窃取。为了增加安全性,可以通过HTTPS来加密通信,以保护Cookie的传输过程。

  2. **敏感信息**:一些敏感信息(如用户身份验证信息)可能会存储在Cookie中。为了防止这些信息被窃取,应该避免在Cookie中存储敏感数据,或者对存储的数据进行加密处理。

  3. **跨站点脚本攻击(XSS)**:恶意脚本可能会通过注入恶意代码来访问和窃取Cookie,从而冒充用户身份。为了防止XSS攻击,应该对用户输入进行适当的验证和过滤,以及在设置Cookie时使用HttpOnly标志来限制JavaScript访问。

  4. **跨站点请求伪造(CSRF)**:攻击者可能利用用户的Cookie来发起伪造的跨站点请求。为了防止CSRF攻击,可以使用CSRF令牌等机制来验证请求的来源和完整性。

总的来说,虽然Cookie在Web开发中是常用的会话管理工具,但在使用过程中需要注意保护用户隐私和数据安全。合理设置Cookie的属性、避免存储敏感信息、加强通信安全等措施可以帮助提升Cookie的安全性。

浏览器不会将与其他域(域名)关联的Cookie发送给服务器端

客户端浏览器会在发起HTTP请求时将与特定域相关的Cookie一起发送给服务器端。这意味着当用户访问某个网站时,浏览器会将与该网站相关的Cookie包含在请求头中发送给服务器。但是,浏览器不会将与其他域(域名)关联的Cookie发送给服务器端。

这是因为浏览器遵循同源策略(Same Origin Policy),该策略限制了来自一个源(协议 + 域名 + 端口)的页面对另一个源的内容进行访问。因此,浏览器只会将与当前访问的域相关的Cookie发送给服务器,而不会将与其他域生成的Cookie发送过去。

这种行为有助于保护用户的隐私和安全,防止跨站点请求伪造(CSRF)等攻击。服务器端可以依赖浏览器的这种行为来确保只收到与自己域相关的Cookie,从而有效地管理用户会话和数据。

Session(会话)

Session(会话)是一种在服务器端存储用户信息的机制,用于跟踪用户在网站上的状态和活动。每个用户访问网站时都会被分配一个唯一的会话标识符(Session ID),该标识符通常存储在Cookie中,但也可以通过URL重写等方式传递。会话数据通常存储在服务器端的内存或数据库中。

Session 的特点:

  • 存储位置:会话数据存储在服务器端,相对于Cookie中的数据更安全,因为用户无法直接修改或查看服务器端的会话数据。

  • 安全性:相对于Cookie来说,会话数据更安全,因为用户无法直接篡改会话数据。

  • 生命周期:会话数据的生命周期与用户会话相关联,通常随着用户关闭浏览器或超时而失效。

Session 与 Cookie 的区别:

  • 存储位置:Cookie存储在客户端(浏览器),而Session数据存储在服务器端。

  • 安全性:Session比Cookie更安全,因为会话数据存储在服务器端,用户无法直接访问或修改。

  • 容量:Cookie的存储容量有限(通常为4KB),而Session可以存储更多数据。

  • 生命周期:Cookie可以设置持久性,而Session通常在用户关闭浏览器或超时后失效。

总的来说,Session相对于Cookie更安全,因为敏感数据存储在服务器端,并且用户无法直接访问或修改会话数据。然而,开发人员需要注意会话劫持等安全问题,确保会话标识符的安全传输和存储,以防止会话被恶意攻击者劫持。

转发(Forwarding)和重定向(Redirecting)

转发(Forwarding)和重定向(Redirecting)是Web开发中常用的两种跳转机制,它们在实现页面跳转和请求处理时有着不同的作用和方式。

转发(Forwarding):

  • 定义:转发是在服务器端内部进行的跳转,一般是在同一个Web应用程序内部进行的页面跳转。

  • 工作原理:当服务器接收到一个请求后,可以在服务器内部将请求转发到另一个资源(如另一个Servlet或JSP),并由该资源处理请求。

  • 特点:转发是服务器端行为,客户端浏览器并不知道发生了转发,地址栏中显示的仍然是原始请求的URL。

  • 示例:在Servlet中处理请求后,可以使用`request.getRequestDispatcher("newPage.jsp").forward(request, response);`来实现转发到另一个JSP页面。

重定向(Redirecting):

  • 定义:重定向是在客户端浏览器进行的跳转,通常用于指示浏览器去请求另一个URL。

  • 工作原理:当服务器接收到一个请求后,会返回一个特殊的HTTP响应码(如302 Found),告知浏览器要重定向到另一个URL。

  • 特点:重定向是客户端行为,浏览器会向新的URL发起新的请求,地址栏中显示的是新的URL。

  • 示例:在Servlet中可以使用`response.sendRedirect("newPage.jsp");`来实现重定向到另一个JSP页面。

区别:

  1. 位置:转发是在服务器端内部进行的跳转,重定向是在客户端浏览器进行的跳转。

  2. 行为:转发是在同一个Web应用内部实现的页面跳转,重定向是告知浏览器去请求新的URL。

  3. 地址栏显示:转发时地址栏不会改变,重定向会显示新的URL。

  4. 效率:转发效率高,因为是在服务器内部进行的跳转,重定向效率较低,因为需要浏览器再次发起请求。

在实际应用中,开发人员需要根据具体需求选择合适的跳转方式,转发适合在同一个应用内部进行页面跳转,而重定向适合在不同应用或不同服务器之间进行跳转。

springmvc数据绑定

spring MVC 的数据绑定是指将 HTTP 请求参数绑定到控制器方法的参数或对象上。Spring MVC 提供了多种方式来实现数据绑定,包括基本数据类型、对象类型、集合类型等。

Spring MVC 中实现文件上传和下载

在 Spring MVC 中实现文件上传和下载是常见的需求。下面将分别介绍如何在 Spring MVC 中实现文件上传和文件下载:

文件上传(File Upload):

1. 配置文件上传解析器:

在 Spring MVC 的配置文件中配置 `CommonsMultipartResolver` 或 `StandardServletMultipartResolver` 来处理文件上传。

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<property name="maxUploadSize" value="10485760"/> <!-- 设置最大上传文件大小 -->

</bean>

2. 编写处理文件上传的控制器方法:

复制代码
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String handleFileUpload(@RequestParam("file") MultipartFile file) {
    // 处理上传的文件
    return "uploadSuccess";
}

文件下载(File Download):

  1. 设置响应头信息:

在控制器方法中设置响应头信息,告诉浏览器要下载文件。

@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)

public void downloadFile(HttpServletResponse response) {

// 设置响应头信息

response.setContentType("application/octet-stream");

response.setHeader("Content-Disposition", "attachment; filename=\"example.txt\"");

// 读取文件内容并写入响应流

try (InputStream is = new FileInputStream("path/to/file/example.txt");

OutputStream os = response.getOutputStream()) {

IOUtils.copy(is, os);

os.flush();

} catch (IOException e) {

e.printStackTrace();

}

}

通过以上步骤,你可以在 Spring MVC 中实现文件上传和下载功能。确保配置正确的文件上传解析器,编写处理文件上传和下载的控制器方法,以及设置合适的响应头信息来实现文件下载。同时,编写对应的页面来提供文件上传和下载的交互界面。

相关推荐
菜鸡且互啄6917 分钟前
在线教育平台,easyexcel使用案例
java·开发语言
八月林城17 分钟前
JAVA导出数据库字典到Excel
java·数据库·excel
浅念同学2 小时前
算法-常见数据结构设计
java·数据结构·算法
杰哥在此4 小时前
Java面试题:讨论持续集成/持续部署的重要性,并描述如何在项目中实施CI/CD流程
java·开发语言·python·面试·编程
咖啡煮码5 小时前
深入剖析Tomcat(十五、十六) 关闭钩子,保证Tomcat的正常关闭
java·tomcat
C.C5 小时前
java IO流(1)
java·开发语言
黑头!6 小时前
Tomcat注册为服务之后 运行时提示JVM异常
java·jvm·tomcat
袁震7 小时前
Java---Mybatis详解二
java·开发语言·mybatis
《黑巧克力》7 小时前
【JavaEE】多线程进阶
java·spring·java-ee·maven·dubbo·idea
idealzouhu7 小时前
函数式接口的定义及常见类型
java