【SpringMVC】入门版
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类型的参数。这里不仅要保持参数的类型保持一致,还要保持参数的名称保持一致才能被自动绑定,不然就要采取其他方法来实现。