【SpringMVC】入门版

发布于:2025-03-16 ⋅ 阅读:(39) ⋅ 点赞:(0)

1.基本概念

1.1三层架构

三层架构也就是我们常说的b/s架构中的表现层,业务层和持久层,每层都各司其职,下面来分别讲解这三层的作用。

表现层:

也就是我们常说的web层。它负责接收客户端的请求,向客户端响应结果,通常客户端向web层发送HTTP请求,web层需要接收HTTP请求。表现层包含展示层和控制层,控制层负责接收前端请求,展示层负责结果的展示。表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。表现层的设计一般都使用MVC模型。

业务层:

也就是我们常说的service层。它负责业务逻辑的处理,和我们开发项目的需求息息相关。web层依赖业务层,但是业务层不依赖web层。业务层在业务处理是可能会依赖持久层。

持久层:

也就是我们常说的dao层。负责数据持久化,包括数据层即数据库和数据访问层。数据库是对数据进行持久化的载体,数据访问层是业务层和持久层的接口,业务层需要通过对数据访问层将数据持久化到数据库中,通俗的讲,持久化就是和数据库交互,对数据库进行增删改查的。

1.2MVC架构

MVC全名是Model View Controller.是模型(Model) 视图(view) 控制器 (controller)的缩写。

是一种用于创建web应用程序表现层的模式。

MVC中每个部分各司 其职:

Model(模型):

通常指的就是我们的数据模型,用来封装数据的。

View(视图):

通常指的是我们的jsp或者html。一般用来展示数据的,通常视图是依据模型数据创建的。

Controller(控制器):

是应用程序中处理用户交互的部分。用于接收前端请求。比如获取前端请求传递的参数并负责将请求交给业务层进行处理。业务层将业务结果处理完成以后,控制器接收业务 层的业务结果,并将业务数据存储在域对象,实现页面的跳转。

1.3什么是SpringMVC

SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级web框架, 属于Spring FrameWork的后续产品,已经融合在Spring Web Flow里面。Spring框 架提供了构建web应用程序的全功能MVC模块。使用Spring可插入的MVC架构,从而在使用 Spring进行web开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框 架,比如Struts2等。

他其实就是基于servelet进行封装的一个框架。                                      

SpringMVC已经成为目前最主流的MVC框架之一,并且随着Spring 3.0的发布,全 面超越Struts2,成为最优秀的web框架。它通过一套注解,让一个简单的Java类成为处理 请求的控制器,而无需事先任何接口,同时它还支持Restful编程风格

1.4SpringMVC的优势

1. 清晰的角色划分: 前端控制器(DispatcherServlet) 处理器映射器(HandlerMapping) 处理器适配器(HandlerAdpater) 视图解析器(ViewResolver) 控制器(Controller) 验证器(Validator) 命令对象(Command 请求参数绑定到的对象就叫做命令对象) 表单对象(Form Object 提供给表单展示和提交的对象就叫表单对象)

2. 分工明确,而且扩展点相当灵活,很容易进行功能扩展。

3. 由于命令对象就是一个POJO,无需继承框架特定的API,可以使用命令对象直接作为业 务对象。 4. 和Spring其他框架无缝集成,是其他web框架不具备的。

5. 可适配,通过HandlerAdapter可以支持任意的类作为处理器。

6. 可定制性,HandlerMapping ViewResolver等能够非常简单的定制。

7. 功能强大的数据验证、格式化、绑定机制。

8. 利用Spring提供的Mock对象能够非常简单的进行web层单元测试。

9. 本地化、主题的解析支持,使我们更容易进行国际化和主题的切换。

10. 强大的JSP标签库,使JSP编写更容易。 还有比如RESTFUL风格的支持,简单的文件上传、约定大于配置的契约式编程风格,基于注 解的零配置支持等。 

2.SpringMVC入门环境的搭建

首先使用maven创建一个web项目(基于骨架创建)

然后pom.xml文件中导入相关依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.xq</groupId>
        <artifactId>xq-springmvc-project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>springmvc-project-quickstart</artifactId>
    <packaging>war</packaging>
    <name>springmvc-project-quickstart Maven Webapp</name>
    <url>http://maven.apache.org</url>
<properties>
<spring.verion>5.0.2.RELEASE</spring.verion>
</properties>
<dependencies>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.verion}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.verion}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.verion}</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
</dependency>
</dependencies>
        <!--配置tomcat7插件-->
<build>
    <finalName>springmvc-project-quickstart</finalName>
<plugins>
    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <path>/</path>
            <port>8088</port>
            <uriEncoding>UTF-8</uriEncoding>
        </configuration>
    </plugin>
</plugins>
</build>
</project>

至于用什么版本倒是无所谓,可以选更高的。

接着在web.xml中配置前端控制器

​
<!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>SpringMVCDispatcherServlet</servlet-name>
 <servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
 <!-- 配置初始化参数,用于读取 SpringMVC 的配置文件 -->
 <init-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>classpath:springmvc.xml</param-value>
 </init-param>
 <!-- 配置 servlet 的对象的创建时间点:应用加载时创建。
取值只能是非 0 正整数,表示启动顺序 -->
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>SpringMVCDispatcherServlet</servlet-name>
 <url-pattern>/</url-pattern>
 </servlet-mapping>
 </web-app>

​

<servlet-name>:为 Servlet 定义一个唯一的名称,这里是 SpringMVCDispatcherServlet,后续在 <servlet-mapping> 中会使用这个名称来映射 URL。
<servlet-class>:指定 Servlet 的全限定类名,这里使用的是 Spring MVC 的核心 Servlet org.springframework.web.servlet.DispatcherServlet。DispatcherServlet 是 Spring MVC 的前端控制器,负责接收所有的 HTTP 请求,并将请求分发给相应的处理器进行处理。
<init-param>:用于配置 Servlet 的初始化参数。
<param-name>:参数名称,这里是 contextConfigLocation,表示要指定 Spring MVC 的配置文件位置。
<param-value>:参数值,classpath:springmvc.xml 表示从类路径下加载 springmvc.xml 文件作为 Spring MVC 的配置文件。
<load-on-startup>:指定 Servlet 的加载顺序。取值为非 0 正整数,数值越小,Servlet 会越早被加载。这里设置为 1,表示在 Web 应用启动时就创建并初始化这个 Servlet。 

<servlet-name>:指定要映射的 Servlet 的名称,这里要与前面 <servlet> 元素中定义的 servlet-name 一致,即 SpringMVCDispatcherServlet。
<url-pattern>:指定 Servlet 要处理的 URL 模式。/ 表示将所有的 HTTP 请求都映射到 SpringMVCDispatcherServlet 进行处理。

然后编写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"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
 <!-- 配置创建 spring 容器要扫描的包 -->
 <context:component-scan base-package="com.xq">
 </context:component-scan>
 <!-- 配置视图解析器 -->
 <bean 
class="org.springframework.web.servlet.view.InternalResourceViewR
 esolver">
 <property name="prefix" value="/pages/"></property>
 <property name="suffix" value=".jsp"></property>
 </bean>
 <!--开启springmvc注解支持-->
 <mvc:annotation-driven></mvc:annotation-driven>
 </beans>

接着在webapp的pages(自己创建)目录下,编写success.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <html>
 <head>
 <title>Title</title>
 </head>
 <body>
 <h2>欢迎你。这是一个成功页面</h2>
 </body>
 </html>

最后编写控制器代码

@Controller
 public class HelloController {
 @RequestMapping("/hello")
 public String sayHello(){
 System.out.println("hello,springmvc");
 return "success";
 }
 }

编写控制器代码,用于接收前端发送的请求,并进行页面的跳转。

整体项目结构如下

2.1入门程序分析

首先来看SpringMVC的执行流程

具体执行步骤如下

第一步:发起请求到前端控制器(DispatcherServlet)

第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配 置、注解进行查找)

第三步:处理器映射器HandlerMapping向前端控制器返回Handler, HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个 Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对 象),通过这种策略模式,很容易添加新的映射策略

第四步:前端控制器调用处理器适配器去执行Handler

第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行 Handler

第六步:Handler执行完成给适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和 view)

第八步:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解 析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更 改视图解析器即可

第九步:视图解析器向前端控制器返回View

第十步:前端控制器进行视图渲染 (视图渲染将模型数据(在 ModelAndView对象中)填充到request域)

第十一步:前端控制器向用户响应结果 

2.2SpringMVC核心组件

DispatcherServlet 前端控制器

用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求, dispatcherServlet 的存在降低了组件之间的耦合性。

HandlerMapping 处理器映射器

HandlerMapping负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口 方式,注解方式等。

Handler 处理器

它就是我们开发中要编写的具体业务控制器。由DispatcherServlet 把用户 请求转发到 Handler。由Handler对具体的用户请求进行处理。

HandlAdapter 处理器适配器

通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩 展适配器可以对更多类型的处理器进行执行。

ViewResolver 视图解析器

View Resolver负责将处理结果生成View 视图,View Resolver首先根据逻 辑视图名解析成物理视图名即具体的页面地址,再生成 View视图对象,最 后对View进行渲染将处理结果通过页面展示给用户。

View 视图

SpringMVC框架提供了很多View视图类型的支持,包括:jstlView、 freemarkerView、pdfView等。我们最常用的视图就是jsp。一般情况下需 要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程 序员根据业务需求开发具体的页面。

2.3RequestMapping注解的使用

作用:用于建立请求URL和处理请求方法之间的对应关系

它可以作用在类上(用于请求URL的第一级访问目录),也可以作用在方法上(用于请求URL的第二级访问目录).

相关属性:

value:描述的是请求资源的URL路径.它和path属性的作用是一样的.

method:用于指定请求的方法,例如GET,POST方法

params:用于指定限制请求参数的条件

如果括号里只有一个属性,如果不指定具体的属性,那么默认就是value.

使用示例

@Controller
@RequestMapping("demo1")
public class HelloController{
@requestMapping("/hello")
public String sayHello(){
System.out.println("hello")
return "success";
 }
}

那么此时我们的访问路径应该是localhost:8088/demo1/hello

这里的'/'可要可不要

不知道有人会不会有点疑惑,为什么注解既可以放在方法上,又可以放在类上,为什么都不直接放在方法上,就不用放在类上了.

就像这里,三个模块都用一样的注解,这样在进行资源定位时就不知道到底是哪个模块的,所以要在每个类上面再分别加上注解来区分 

变成这样就行了 

再具体讲一下params

当它只指定了参数名时,只需要再路径名中加上该参数并给它赋值即可成功访问该方法,例如

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class ParamController {

    @RequestMapping(value = "/test", params = "param1")
    @ResponseBody
    public String handleRequest() {
        return "Request contains param1";
    }
}

这里的访问路径就需要再在请求text 路径时包含 param1 参数,handleRequest 方法才会被调用。例如,/test?param1=value 会匹配该方法,但 /test 不会匹配。

它也可以给该参数限定范围,例如params="params=a",那么在请求时必须在写成/text?paraml=a才行

他也可以限定成params!="a",就是表示只要不等于a的值填上去就行

2.4请求参数绑定

我们都知道,用户请求参数都是基于key=value的。SpringMVC绑定请求参数的过程是通过把请求提交的参数,作为控制器中的方法参数进行绑定.

Springmvc支持的参数绑定类型:

基本类型参数: 包括基本类型和String类型

POJO类型参数:包括实体类及其关联的实体类

数组和集合类型的参数:包括List和Map结构的集合(包括数组)

SpringMVC绑定请求参数是自动实现的,但是使用必须遵循器使用要求:

如果是基本类型或者String类型: 要求我们的参数名称必须和控制器方法中 的形参名称保持一致,并严格区分大小写。

如果是POJO类型,或者其他关联对象:要求表单中的参数名称和POJO类的 属性名称一模一样,并且控制器方法的参数类型是POJO类型。

下面以基本参数类型为例

先编写一个超链接

<a href="${pageContext.request.contextPath}/demo1/getBasicParam?
 username=eric">[提交基本数据类型的参数]</a>

然后编写控制器方法

@Controller
 @RequestMapping("demo1")
 public class HelloController {
 @RequestMapping("getBasicParam")
 public String getBasicParam(String username){
 System.out.println("username: " + username);
 return "success";
 }
}

控制器会捕捉前端传过来的参数,用的是控制器下的方法来捕捉,这里的方法就是捕捉了String类型的参数。这里不仅要保持参数的类型保持一致,还要保持参数的名称保持一致才能被自动绑定,不然就要采取其他方法来实现。