SpringMVC框架学习笔记01()

01,三层结构和MVC

1.1,三层架构

  • 先来看一张图
    在这里插入图片描述
  • 我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,
    另一种是 B/S 架构,也就是浏览器服务器。
    在 JavaEE 开发中,几乎全都是基于 B/S 架构的开发。那么在 B/S 架构中,系统标准的三层架构包括:表现层、业务层、持久层

表现层:
也就是我们常说的web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求web 层, web 需要接收 http 请求,完成 http 响应。

  • 表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。
  • 表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。
  • 表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)

业务层:
也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。

  • web 层依赖业务层,但是业务层不依赖 web 层。
  • 业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的,事务应该放到业务层来控制)

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

1.2,MVC模型

  • MVC 是表现层的设计模型,和其他层没有关系
  • MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种用于设计创建 Web 应用程序表现层的模式。
  • MVC 中每个部分各司其职:
    Model(模型) :
    通常指的就是我们的数据模型。作用一般情况下用于封装数据。(JavaBean)
    View(视图) :
    通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。通常视图是依据模型数据创建的。
    Controller(控制器) :
    是应用程序中处理用户交互的部分。 作用一般就是处理程序逻辑的。它相对于前两个不是很好理解,这里举个例子:
    例如:
    我们要保存一个用户的信息,该用户信息中包含了姓名,性别,年龄等等。这时候表单输入要求年龄必须是 1~100 之间的整数。姓名和性别不能为空。并且把数据填充到模型之中(使用JavaBean接收数据并封装起来),此时除了 js 的校验之外,服务器端也应该有数据准确性的校验,那么校验就是控制器的该做的。当校验失败后,由控制器负责把错误页面展示给使用者。如果校验成功,也是控制器负责把数据填充到模型,并且调用业务层实现完整的业务需求。
  • 常见的MVC框架包括:SpringMVC和Struts2等。

02,SpringMVC

  • 说完了三层架构和MVC模型,接下来就谈谈Spring为我们提供的web前端开发框架SpringMVC

2.1,SpringMVC的优势?(了解)

  • 1、清晰的角色划分:
    前端控制器(DispatcherServlet)
    请求到处理器映射(HandlerMapping)
    处理器适配器(HandlerAdapter)
    视图解析器(ViewResolver)
    处理器或页面控制器(Controller)
    验证器( Validator)
    命令对象(Command 请求参数绑定到的对象就叫命令对象)
    表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
  • 2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。
  • 3、由于命令对象就是一个 POJO,无需继承框架特定 API,可以使用命令对象直接作为业务对象。
  • 4、和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。
  • 5、可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。
  • 6、可定制性, HandlerMapping、 ViewResolver 等能够非常简单的定制。
  • 7、功能强大的数据验证、格式化、绑定机制。
  • 8、利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
  • 9、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换等等。

2.2,SpringMVC 和 Struts2 的对比(了解)

共同点:

  • 它们都是表现层框架,都是基于 MVC 模型编写的。
  • 它们的底层都离不开原始 ServletAPI。
  • 它们处理请求的机制都是一个核心控制器。

区别:

  • Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
  • Spring MVC 是基于方法设计的,而 Struts2 是基于类, Struts2 每次执行都会创建一个动作类。所以 Spring MVC 会稍微比 Struts2 快些。
  • Spring MVC 使用更加简洁,同时还支持 JSR303, 处理 ajax 的请求更方便(JSR303 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,就可以在需要校验的时候进行校验了。 )
  • Struts2 的 OGNL 表达式使页面的开发效率相比 Spring MVC 更高些,但执行效率并没有比 JSTL 提升,尤其是 struts2 的表单标签,远没有 html 执行效率高

03,SpringMVC的入门

在这里插入图片描述

3.1,入门案例

  • 1,创建一个maven管理的web工程(是web工程)
    jar包坐标
<dependencies>
    <!--导入坐标-->
    <!--SpringMVC的两个包:spring-web和spring-webmvc-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>
    
    <!--servlet的两个包:servlet-api和jsp-api-->
    <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>
  • 2,配置核心控制器-一个 Servlet,这个servlet在webapp下的web.xml中配置
<!-- 配置 spring mvc 的核心控制器 -->
<servlet>
	<!-- dispatcherServlet:前端控制器,由SpringMVC框架提供 -->
	<servlet-name>dispatcherServlet</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>
  • 3,创建 SpringMVC 的配置文件:SpringMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 配置创建 spring 容器要扫描的包 -->
<context:component-scan base-package="com.aismall"></context:component-scan>
<!-- 配置视图解析器 -->
 <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 		<!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"></property>
 </bean>
</beans>
  • 4,编写控制器并使用注解配置
@Controller
public class HelloController {
	@RequestMapping("/hello")
	public String Hello() {
	System.out.println("HelloController的Hello 方法执行了。。。。 ");
	return "success";
	}
}
  • 5,index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
	<head>
	    <title>AISMALL</title>
	</head>
	<body>
		<h3>小白你好:Hello AISMALL</h3>
		<a href="hello">戳一下</a>
	</body>
</html>
  • 6,success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
	<head>
	    <title>Success</title>
	</head>
	<body>
		<h3>执行成功:么么哒AISMALL</h3>
	</body>
</html>
  • 7,配置好服务器,启动服务器就可以测试了

3.2,执行步骤

  • 先看一下这个图:
    在这里插入图片描述
  • 1、服务器启动,应用被加载。 读取到 web.xml 中的配置创建 spring 容器并且初始化容器中的对象(HelloController)。
  • 2、浏览器发送请求,被 dispatherServlet 捕获,该 Servlet 并不处理请求,而是把请求转发出去。转发的路径是根据请求URL,匹配@RequestMapping 中的内容。
  • 3、匹配到了后,执行对应方法。该方法有一个返回值。
  • 4、根据方法的返回值,借助视图解析器internalResourceViewResolver找到对应的结果视图。
  • 5、渲染结果视图,响应浏览器。

3.3,组件介绍

3.3.1,DispatcherServlet:前端控制器

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

3.3.2,HandlerMapping:处理器映射器

HandlerMapping 负责根据用户请求找到 Handler 即处理器

SpringMVC 提供了不同的映射器实现不同的映射方式
例如:配置文件方式,实现接口方式,注解方式等

3.3.3,Handler:处理器

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

3.3.4,HandlAdapter:处理器适配器

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

3.3.5 ,View Resolver:视图解析器

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

3.3.6 ,View:视图

SpringMVC 框架提供了很多的 View 视图类型的支持,包括: jstlView、 freemarkerView、 pdfView等。我们最常用的视图就是 jsp。

3.3.7 mvc:annotation-driven注解

  • 在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
  • 可 用 在 SpringMVC.xml 配 置 文 件 中 使 用
    <mvc:annotation-driven>替代配置处理映射器和处理适配器。
  • RequestMappingHandlerMapping( 处 理 映 射 器 )
  • RequestMappingHandlerAdapter( 处 理 适 配 器 ) ,

3.4,RequestMapping注解

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

出现位置:

  • 类上:
    请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录。 写的话需要以/开头。它出现的目的是为了使我们的 URL 可以按照模块化管理,使我们的 URL 更加精细。
  • 方法上:
    请求 URL 的第二级访问目录。
  • 属性:
    value:用于指定请求的 URL。 它和 path 属性的作用是一样的。
  • method:用于指定请求的方式。
  • params:用于指定限制请求参数的条件。 它支持简单的表达式。 要求请求参数的 key 和 value 必须和配置的一模一样。
    例如:
    params = {“accountName”},表示请求参数必须有 accountName
    params = {“moeny!100”},表示请求参数中 money 不能是 100。
  • headers:用于指定限制请求消息头的条件。
  • 注意:以上四个属性只要出现 2 个或以上时,他们的关系是与的关系。

04,请求参数的绑定

4.1概述

4.1.1,绑定的机制

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

  • 例如:
<a href="account/findAccount?accountId=10">查询账户</a>
  • 求参数是:accountId=10
  • 控制器中方法:
/**
* 查询账户
*/
@RequestMapping("/findAccount")
//方法参数accountId,类型为Integer类型
public String findAccount(Integer accountId) {
System.out.println("查询了账户。。。。 "+accountId);
return "success";
}

4.1.2 ,支持的数据类型

  • 基本类型参数:包括基本类型和 String 类型
  • POJO 类型参数:包括实体类,以及关联的实体类
  • 数组和集合类型参数:包括 List 结构和 Map 结构的集合(包括数组)
  • SpringMVC 绑定请求参数是自动实现的,但是要想使用,必须遵循使用要求

4.1.3 ,使用要求

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

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

  • 如果是集合类型,有两种方式:
    第一种:
    要求集合类型的请求参数必须在 POJO 中。在表单中请求参数名称要和 POJO 中集合属性名称相同。
    给 List 集合中的元素赋值, 使用下标。
    给 Map 集合中的元素赋值, 使用键值对。
    第二种:
    接收的请求参数是 json 格式数据。需要借助一个注解实现。

  • 注意:
    它还可以实现一些数据类型自动转换。 内置转换器全都在:
    org.springframework.core.convert.support包下

  • 如遇特殊类型转换要求,需要我们自己编写自定义类型转换器

4.2,中文请求乱码问题

  • post 请求方式:在 web.xml 中配置一个过滤器
 <!--配置解决中文乱码的过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!-- 设置过滤器中的属性值 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <!-- 过滤所有请求 -->
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  • 在 springmvc 的配置文件中可以配置,静态资源不过滤:
<!-- location 表示路径, mapping 表示文件, **表示该目录下的文件以及子目录的文件 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/scripts/" mapping="/javascript/**"/>
  • get 请求方式:tomacat 对 GET 和 POST 请求处理方式是不同的, GET 请求的编码问题, 要改 tomcat 的 server.xml
    配置文件,如下:
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"/>

改为:

<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"
useBodyEncodingForURI="true"/>
  • 如果遇到 ajax 请求仍然乱码,作以下修改:
useBodyEncodingForURI="true"改为 URIEncoding="UTF-8"

4.3,自定义类型转换器使用步骤

  • 第一步:定义一个类,实现 Converter 接口,该接口有两个泛型。S:表示接受的类型, T:表示目标类型
    例如:
/**
* 自定义类型转换器
*/
public class StringToDateConverter implements Converter<String, Date> {
/**
* 用于把 String 类型转成日期类型
*/
	@Override
	public Date convert(String source) {
		DateFormat format = null;
		try {
			if(StringUtils.isEmpty(source)) {
				throw new NullPointerException("请输入要转换的日期");
			}
			format = new SimpleDateFormat("yyyy-MM-dd");
			Date date = format.parse(source);
			return date;
		} catch (Exception e) {
		throw new RuntimeException("输入日期有误");
		}
	}
}

第二步:在 spring 配置文件中配置类型转换器。spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去
例如:

<!--配置自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.aismall.utils.StringToDateConverter"/>
            </set>
        </property>
    </bean>

第三步:在 annotation-driven 标签中引用配置的类型转换服务

<!-- 引用自定义类型转换器 -->
<mvc:annotation-driven conversion-service="converterService"></mvc:annotation-driven>

4.4,使用 ServletAPI 对象作为方法参数

  • SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。
  • 支持原始 ServletAPI 对象有:
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer
  • 我们可以把上述对象,直接写在控制的方法参数中使用。
  • jsp 代码:
<!-- 原始 ServletAPI 作为控制器参数 -->
<a href="account/testServletAPI">测试访问 ServletAPI</a>
  • 控制器中的代码:
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,
HttpServletResponse response,HttpSession session) {
	System.out.println(request);
	System.out.println(response);
	System.out.println(session);
	return "success";
}

05,常用注解

3.2.3访问链接的知识补充
当你的服务器项目启动后,访问项目的链接形式为:
协议+域名+端口号+虚拟目录+参数列表+锚
例如:
http://localhost:8080/helloworld/web/index.html
协议:http
域名(也叫IP):localhost
端口号:8080
虚拟目录(项目名开始):helloworld/web/index.html
参数列表:此处没有,做表单提交的时候会遇到,参数为前台向后台提交的数据

请求参数绑定,类似于在servlet中的getParameter方法,拿到链接中的参数列表中的数据

猜你喜欢

转载自blog.csdn.net/weixin_45583303/article/details/106728712