第一章 SpringMVC的基本概念
1. 概述
SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于Spring FrameWork的后续产品,已经融合在Spring Web Flow里面。Spring框架提供了构建Web应用程序的全功能模块。使用Spring可插入的MVC架构,从而在使用Spring进行Web开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架。
SpringMVC已经成为目前最主流的MVC框架之一,并且随着Spring3.0的发布,全面超越Struts2,成为最优秀的MVC架构。
它通过一套经理,让一个简单的Java类成为处理请求的控制器,而无需实现任何接口。而且它还支持RESTful编程风格的请求。
2.SpringMVC的架构
- M:model模型(javaBean)
指的就是我们的数据模型,一般情况下用于数据封装。 - V:View视图(jsp)
指的是jsp或者html,作用一般就是展示数据的。通常视图是依据模型数据创建的。 -
C:Controller控制器(Servlet)
应用程序中处理用户交互的部分。处理程序逻辑。
3.SpringMVC的优势
- ①清晰的角色划分
前端控制器:DispatcherServlet
请求到处理器映射:HandlerMapping
处理器适配器:HandlerAdapter
视图解析器:ViewResolver
处理器或页面控制器:Controller
验证器:Validator
命令对象:Command 请求参数绑定到的对象就叫命令对象
表单对象:From Object 提供给表单展示和提交到的对象就叫做表单对象。 - ②分工明确,而且拓展到相当灵活。可以很容易拓展,虽然不需要。
- ③由于命令对象就是一个POJO,无需继承框架特定API,可以使用命令对象直接作为业务对象。
- ④和Spring其他框架无缝集成,是其他web框架所不具备的。
- ⑤可适配,通过HandlerAdapter可以支持任意的类作为处理器。
- ⑥可定制,HandleMapping、ViewResolver等能够非常简单的定制。
- ⑦功能强大的数据验证、格式化、绑定机制。
- ⑧利用Spring提供的MOCK对象能够非常简单的进行web层单元测试。
- ⑨本地化、主题的解析的支持,使我们更容易的进行国际化和主题的切换。
- ⑩强大的JSP标签库,使JSP编写更容易。
4.SpringMVC和Struts2的优劣分析
共同点
- 它们都是表现出框架,都是基于MVC模型编写的。
- 它们的底层都离不开原始的ServletAPI。
- 它们处理请求的机制都是一个核心控制器。
区别 - SpringMVC的入口是Servlet,而Struts2是Filter
- SpringMVC是基于方法设计的,而Struts2是基于类,Struts2每次执行都会创建一个动作类,所以SpringMVC会比Struts2快些。
- SpringMVC使用更加简洁,同时还支持JSR303,处理ajax的请求更方便。
- Struts2的OGNL表达式使页面的开发效率相比Spring MVC更高些,但执行效率并没有JSTL提升,尤其是struts2的表单标签,远没有html执行效率高。
第二章 SpringMVC的入门
1. 目录结构
2.项目中maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.seapp</groupId>
<artifactId>springMVC-start</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>springMVC-start Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</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>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>springMVC-start</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
3. 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/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">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.seapp"></context:component-scan>
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--视图文件的文件路径(前缀)-->
<property name="prefix" value="/WEB-INF/pages/"/>
<!--文件名后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 开启SpringMVC对注解框架的支持
在SpringMVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为SpringMVC的三大组件。
使用<mvc:annotation-driven/>自动加载RequestMappingHandlerMapping(处理映射器)和
RequestMappingHandlerAdapter(处理适配器).
可用在SpringMVC.xml配置文件中使用 <mvc:annotation-driven/>替代注解处理器和适配器的配置。
-->
<mvc:annotation-driven/>
</beans>
3. web.xml中对SpringMVC控制器的配置
<!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>
<!-- SpringMVC的前端控制器的配置 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置机制Spring配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4.jsp文件的实现
<%--
Created by IntelliJ IDEA.
User: EDZ
Date: 2020/7/30
Time: 13:20
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>入门程序</h3>
<a href="hello" >入门程序</a>
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: EDZ
Date: 2020/7/30
Time: 14:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>成功页面</h3>
</body>
</html>
5.Controller的具体实现
package com.seapp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author seapp
* @date 2020/7/30 14:41
*/
@Controller
public class HelloController {
@RequestMapping(path = "/hello")
public String sayHello(){
System.out.println("hello springMVC");
return "success";
}
}
6. @RequestMapping详解
/**
* @RequestMapping 注解详解
* 作用:
* 用于建立请求URL和处理请求方式之间的对应关系
* *****************
* @Target({ElementType.METHOD, ElementType.TYPE}):
* 可作用在方法上或类上,两者结合可实现(分模块)。
* *****************
* @AliasFor("path")
* String[] value() default {};
* @AliasFor("value")
* String[] path() default {};
* value和path的作用是指定请求的URL,两者作用一样。当只有一个属性的情况下,可省略。
* ***********
* RequestMethod[] method() default {};
* method:指定该方法的请求方式
* 枚举:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
* ***********
* params :用于指定限制请求参数的条件,它支持简单的表达式。
* 要求请求的key和value必须和配置的一模一样。
* *********
* header:发送的请求中必须包含的请求头
* @return
*/
第三章 请求参数绑定
1.请求参数的绑定说明
绑定机制
- 表单提交的数据都是k=v格式的 例:username=haha&password=123
- SpringMVC的参数绑定过程就是把表单提交的请求参数,作为控制器中方法的参数进行绑定的。
- 要求:提交表单的name和参数的名称是相同的。
支持的数据类型
- 基本数据类型和字符串类型
- 实体类型(JavaBean)
- 集合数据类型(List、map集合等)
2.基本数据类型和字符串类型
- 提交表单的name和参数的名称是相同的。
- 区分大小写
3.实体类型(JavaBean)
- 提交表单的name和JavaBean中的属性名称需要一致。
- 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例:user.name
4.给集合属性数据封装
5. 参数中文乱码的问题
- 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>
6. 特殊情况(自定义类型转换器)
- Spring 提供的Converter类型转换基类
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.converter;
import org.springframework.lang.Nullable;
/**
* A converter converts a source object of type {@code S} to a target of type {@code T}.
*
* <p>Implementations of this interface are thread-safe and can be shared.
*
* <p>Implementations may additionally implement {@link ConditionalConverter}.
*
* @author Keith Donald
* @since 3.0
* @param <S> the source type
* @param <T> the target type
*/
@FunctionalInterface
public interface Converter<S, T> {
/**
* Convert the source object of type {@code S} to target type {@code T}.
* @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
* @return the converted object, which must be an instance of {@code T} (potentially {@code null})
* @throws IllegalArgumentException if the source cannot be converted to the desired target type
*/
@Nullable
T convert(S source);
}
- 自定义类型转换器的实现
package com.seapp.utils;
import org.springframework.core.convert.converter.Converter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author seapp
* @date 2020/8/1 16:15
* 将字符串转换为日期
*
* 两个泛型:
* 第一个泛型是源数据类型
* 第二个泛型是目标数据类型
*/
public class StringToDateConverter implements Converter<String, Date> {
/**
*
* @param source 传入进来的字符串
* @return
*/
@Override
public Date convert(String source) {
//非空判断
if(source == null){
throw new RuntimeException("请传入参数");
}
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
//将数据转换为指定数据类型
return dateFormat.parse(source);
} catch (ParseException e) {
throw new RuntimeException("数据类型转换失败");
}
}
}
- 自定义类型转换器的注册
<!-- 配置自定义类型转换器 -->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.seapp.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 开启SpringMVC对注解框架的支持
在SpringMVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为SpringMVC的三大组件。
使用<mvc:annotation-driven/>自动加载RequestMappingHandlerMapping(处理映射器)和
RequestMappingHandlerAdapter(处理适配器).
可用在SpringMVC.xml配置文件中使用 <mvc:annotation-driven/>替代注解处理器和适配器的配置。
-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
7.SpringMVC框架中获取Servlet原生的API
/*
* 对Servlet原生Api的获取,只需要在方法上直接添加参数即可。
* @return
*/
@RequestMapping(path = "/hello")
public String sayHello(HttpServletRequest request, HttpServletResponse response){
System.out.println("hello springMVC");
return "success";
}
第四章 常用注解
1. @RequestParam
- 作用:
把请求中指定名称的参数给控制器中的形参赋值。 - 属性:
value:请求参数中的名称
required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。
2. RequestBody
- 作用:
用于获取请求体的内容,直接使用得到的是key=value&key=value...结构的数据。
get请求方式不适用 - 属性:
required:是否必须有请求体。默认值是true,当取值为true时,get请求方式会报错。如果取值为false,get请求得到的是null。
3. PathVaribale
- 作用:
用于绑定url中的占位符。例如:请求url中/delete/{id},这个{id}就是url占位符。
url支持占位符是在spring3.0 之后加入的,是springMVC支持rest风格URL的一个重要标志。 - 属性:
value:用于指定url中占位符名称。
required:是否必须提供占位符。
4. requestHeader
- 作用:
用于获取请求头信息 - 属性:
value:提供消息头名称
required:是否必须有此消息头 - 注:在实际开发中一般不咋用
5. CookieValue:
- 作用:
用于把指定cookie名称的值传入控制器方法参数 - 属性:
value:指定cookie的名称
required:是否必须有此cookie
6. ModelAttribute
- 作用:
该注解是SpringMVC 4.3 版本以后新加入的,它可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。
出现在参数上,获取指定的参数给数据赋值。 - 属性:
value: 用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key。 - 应用场景:
当表单提交的数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原有的数据。 - 例:
我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据时肯定没有此字段的内容,一单更新会把该字段内容置为null,此时就可以使用此注解解决问题。
7.SessionAttribute
-作用:
用于多次执行控制器方法间参数共享。
- 属性:
value:用于指定存入的属性名称
type:用于指定存入的数据类型