第一章 SpringMVC的基本概念
1. 概述
SpringMVC是一種基于Java的實(shí)現(xiàn)MVC設(shè)計(jì)模型的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,屬于Spring FrameWork的后續(xù)產(chǎn)品芯肤,已經(jīng)融合在Spring Web Flow里面蜀细。Spring框架提供了構(gòu)建Web應(yīng)用程序的全功能模塊。使用Spring可插入的MVC架構(gòu)盈滴,從而在使用Spring進(jìn)行Web開(kāi)發(fā)時(shí)慧妄,可以選擇使用Spring的Spring MVC框架或集成其他MVC開(kāi)發(fā)框架。
SpringMVC已經(jīng)成為目前最主流的MVC框架之一单旁,并且隨著Spring3.0的發(fā)布,全面超越Struts2饥伊,成為最優(yōu)秀的MVC架構(gòu)。
它通過(guò)一套經(jīng)理蔫饰,讓一個(gè)簡(jiǎn)單的Java類成為處理請(qǐng)求的控制器琅豆,而無(wú)需實(shí)現(xiàn)任何接口。而且它還支持RESTful編程風(fēng)格的請(qǐng)求篓吁。
2.SpringMVC的架構(gòu)
- M:model模型(javaBean)
指的就是我們的數(shù)據(jù)模型茫因,一般情況下用于數(shù)據(jù)封裝。 - V:View視圖(jsp)
指的是jsp或者h(yuǎn)tml,作用一般就是展示數(shù)據(jù)的杖剪。通常視圖是依據(jù)模型數(shù)據(jù)創(chuàng)建的冻押。 -
C:Controller控制器(Servlet)
應(yīng)用程序中處理用戶交互的部分驰贷。處理程序邏輯。
3.SpringMVC的優(yōu)勢(shì)
- ①清晰的角色劃分
前端控制器:DispatcherServlet
請(qǐng)求到處理器映射:HandlerMapping
處理器適配器:HandlerAdapter
視圖解析器:ViewResolver
處理器或頁(yè)面控制器:Controller
驗(yàn)證器:Validator
命令對(duì)象:Command 請(qǐng)求參數(shù)綁定到的對(duì)象就叫命令對(duì)象
表單對(duì)象:From Object 提供給表單展示和提交到的對(duì)象就叫做表單對(duì)象洛巢。 - ②分工明確括袒,而且拓展到相當(dāng)靈活「遘裕可以很容易拓展锹锰,雖然不需要。
- ③由于命令對(duì)象就是一個(gè)POJO,無(wú)需繼承框架特定API,可以使用命令對(duì)象直接作為業(yè)務(wù)對(duì)象漓库。
- ④和Spring其他框架無(wú)縫集成恃慧,是其他web框架所不具備的。
- ⑤可適配渺蒿,通過(guò)HandlerAdapter可以支持任意的類作為處理器痢士。
- ⑥可定制,HandleMapping茂装、ViewResolver等能夠非常簡(jiǎn)單的定制怠蹂。
- ⑦功能強(qiáng)大的數(shù)據(jù)驗(yàn)證、格式化训唱、綁定機(jī)制褥蚯。
- ⑧利用Spring提供的MOCK對(duì)象能夠非常簡(jiǎn)單的進(jìn)行web層單元測(cè)試。
- ⑨本地化况增、主題的解析的支持赞庶,使我們更容易的進(jìn)行國(guó)際化和主題的切換。
- ⑩強(qiáng)大的JSP標(biāo)簽庫(kù)澳骤,使JSP編寫更容易歧强。
4.SpringMVC和Struts2的優(yōu)劣分析
共同點(diǎn)
- 它們都是表現(xiàn)出框架,都是基于MVC模型編寫的为肮。
- 它們的底層都離不開(kāi)原始的ServletAPI摊册。
- 它們處理請(qǐng)求的機(jī)制都是一個(gè)核心控制器。
區(qū)別 - SpringMVC的入口是Servlet,而Struts2是Filter
- SpringMVC是基于方法設(shè)計(jì)的颊艳,而Struts2是基于類茅特,Struts2每次執(zhí)行都會(huì)創(chuàng)建一個(gè)動(dòng)作類,所以SpringMVC會(huì)比Struts2快些棋枕。
- SpringMVC使用更加簡(jiǎn)潔白修,同時(shí)還支持JSR303,處理ajax的請(qǐng)求更方便。
- Struts2的OGNL表達(dá)式使頁(yè)面的開(kāi)發(fā)效率相比Spring MVC更高些重斑,但執(zhí)行效率并沒(méi)有JSTL提升兵睛,尤其是struts2的表單標(biāo)簽,遠(yuǎn)沒(méi)有html執(zhí)行效率高。
第二章 SpringMVC的入門
1. 目錄結(jié)構(gòu)
2.項(xiàng)目中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">
<!-- 開(kāi)啟注解掃描 -->
<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>
<!-- 開(kāi)啟SpringMVC對(duì)注解框架的支持
在SpringMVC的各個(gè)組件中祖很,處理器映射器笛丙、處理器適配器、視圖解析器稱為SpringMVC的三大組件假颇。
使用<mvc:annotation-driven/>自動(dòng)加載RequestMappingHandlerMapping(處理映射器)和
RequestMappingHandlerAdapter(處理適配器).
可用在SpringMVC.xml配置文件中使用 <mvc:annotation-driven/>替代注解處理器和適配器的配置胚鸯。
-->
<mvc:annotation-driven/>
</beans>
3. web.xml中對(duì)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>
<!-- 配置機(jī)制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文件的實(shí)現(xiàn)
<%--
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>成功頁(yè)面</h3>
</body>
</html>
5.Controller的具體實(shí)現(xiàn)
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 注解詳解
* 作用:
* 用于建立請(qǐng)求URL和處理請(qǐng)求方式之間的對(duì)應(yīng)關(guān)系
* *****************
* @Target({ElementType.METHOD, ElementType.TYPE}):
* 可作用在方法上或類上,兩者結(jié)合可實(shí)現(xiàn)(分模塊)拆融。
* *****************
* @AliasFor("path")
* String[] value() default {};
* @AliasFor("value")
* String[] path() default {};
* value和path的作用是指定請(qǐng)求的URL,兩者作用一樣蠢琳。當(dāng)只有一個(gè)屬性的情況下,可省略镜豹。
* ***********
* RequestMethod[] method() default {};
* method:指定該方法的請(qǐng)求方式
* 枚舉:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
* ***********
* params :用于指定限制請(qǐng)求參數(shù)的條件傲须,它支持簡(jiǎn)單的表達(dá)式。
* 要求請(qǐng)求的key和value必須和配置的一模一樣趟脂。
* *********
* header:發(fā)送的請(qǐng)求中必須包含的請(qǐng)求頭
* @return
*/
第三章 請(qǐng)求參數(shù)綁定
1.請(qǐng)求參數(shù)的綁定說(shuō)明
綁定機(jī)制
- 表單提交的數(shù)據(jù)都是k=v格式的 例:username=haha&password=123
- SpringMVC的參數(shù)綁定過(guò)程就是把表單提交的請(qǐng)求參數(shù)泰讽,作為控制器中方法的參數(shù)進(jìn)行綁定的。
- 要求:提交表單的name和參數(shù)的名稱是相同的昔期。
支持的數(shù)據(jù)類型
- 基本數(shù)據(jù)類型和字符串類型
- 實(shí)體類型(JavaBean)
- 集合數(shù)據(jù)類型(List已卸、map集合等)
2.基本數(shù)據(jù)類型和字符串類型
- 提交表單的name和參數(shù)的名稱是相同的。
- 區(qū)分大小寫
3.實(shí)體類型(JavaBean)
- 提交表單的name和JavaBean中的屬性名稱需要一致硼一。
- 如果一個(gè)JavaBean類中包含其他的引用類型累澡,那么表單的name屬性需要編寫成:對(duì)象.屬性 例:user.name
4.給集合屬性數(shù)據(jù)封裝
5. 參數(shù)中文亂碼的問(wèn)題
- web.xml文件中對(duì)過(guò)濾器的配置
<!-- 配置解決中文亂碼的過(guò)濾器-->
<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. 特殊情況(自定義類型轉(zhuǎn)換器)
- Spring 提供的Converter類型轉(zhuǎn)換基類
/*
* 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);
}
- 自定義類型轉(zhuǎn)換器的實(shí)現(xiàn)
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
* 將字符串轉(zhuǎn)換為日期
*
* 兩個(gè)泛型:
* 第一個(gè)泛型是源數(shù)據(jù)類型
* 第二個(gè)泛型是目標(biāo)數(shù)據(jù)類型
*/
public class StringToDateConverter implements Converter<String, Date> {
/**
*
* @param source 傳入進(jìn)來(lái)的字符串
* @return
*/
@Override
public Date convert(String source) {
//非空判斷
if(source == null){
throw new RuntimeException("請(qǐng)傳入?yún)?shù)");
}
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
//將數(shù)據(jù)轉(zhuǎn)換為指定數(shù)據(jù)類型
return dateFormat.parse(source);
} catch (ParseException e) {
throw new RuntimeException("數(shù)據(jù)類型轉(zhuǎn)換失敗");
}
}
}
- 自定義類型轉(zhuǎn)換器的注冊(cè)
<!-- 配置自定義類型轉(zhuǎn)換器 -->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.seapp.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 開(kāi)啟SpringMVC對(duì)注解框架的支持
在SpringMVC的各個(gè)組件中,處理器映射器般贼、處理器適配器愧哟、視圖解析器稱為SpringMVC的三大組件。
使用<mvc:annotation-driven/>自動(dòng)加載RequestMappingHandlerMapping(處理映射器)和
RequestMappingHandlerAdapter(處理適配器).
可用在SpringMVC.xml配置文件中使用 <mvc:annotation-driven/>替代注解處理器和適配器的配置哼蛆。
-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
7.SpringMVC框架中獲取Servlet原生的API
/*
* 對(duì)Servlet原生Api的獲取蕊梧,只需要在方法上直接添加參數(shù)即可。
* @return
*/
@RequestMapping(path = "/hello")
public String sayHello(HttpServletRequest request, HttpServletResponse response){
System.out.println("hello springMVC");
return "success";
}
第四章 常用注解
1. @RequestParam
- 作用:
把請(qǐng)求中指定名稱的參數(shù)給控制器中的形參賦值腮介。 - 屬性:
value:請(qǐng)求參數(shù)中的名稱
required:請(qǐng)求參數(shù)中是否必須提供此參數(shù)肥矢。默認(rèn)值:true。表示必須提供叠洗,如果不提供將報(bào)錯(cuò)甘改。
2. RequestBody
- 作用:
用于獲取請(qǐng)求體的內(nèi)容,直接使用得到的是key=value&key=value...結(jié)構(gòu)的數(shù)據(jù)灭抑。
get請(qǐng)求方式不適用 - 屬性:
required:是否必須有請(qǐng)求體十艾。默認(rèn)值是true,當(dāng)取值為true時(shí),get請(qǐng)求方式會(huì)報(bào)錯(cuò)名挥。如果取值為false,get請(qǐng)求得到的是null。
3. PathVaribale
- 作用:
用于綁定url中的占位符。例如:請(qǐng)求url中/delete/{id},這個(gè){id}就是url占位符禀倔。
url支持占位符是在spring3.0 之后加入的榄融,是springMVC支持rest風(fēng)格URL的一個(gè)重要標(biāo)志。 - 屬性:
value:用于指定url中占位符名稱救湖。
required:是否必須提供占位符愧杯。
4. requestHeader
- 作用:
用于獲取請(qǐng)求頭信息 - 屬性:
value:提供消息頭名稱
required:是否必須有此消息頭 - 注:在實(shí)際開(kāi)發(fā)中一般不咋用
5. CookieValue:
- 作用:
用于把指定cookie名稱的值傳入控制器方法參數(shù) - 屬性:
value:指定cookie的名稱
required:是否必須有此cookie
6. ModelAttribute
- 作用:
該注解是SpringMVC 4.3 版本以后新加入的,它可以用于修飾方法和參數(shù)鞋既。
出現(xiàn)在方法上力九,表示當(dāng)前方法會(huì)在控制器的方法執(zhí)行之前,先執(zhí)行邑闺。
出現(xiàn)在參數(shù)上跌前,獲取指定的參數(shù)給數(shù)據(jù)賦值。 - 屬性:
value: 用于獲取數(shù)據(jù)的key陡舅。key可以是POJO的屬性名稱抵乓,也可以是map結(jié)構(gòu)的key。 - 應(yīng)用場(chǎng)景:
當(dāng)表單提交的數(shù)據(jù)不是完整的實(shí)體類數(shù)據(jù)時(shí)靶衍,保證沒(méi)有提交數(shù)據(jù)的字段使用數(shù)據(jù)庫(kù)對(duì)象原有的數(shù)據(jù)灾炭。 - 例:
我們?cè)诰庉嬕粋€(gè)用戶時(shí),用戶有一個(gè)創(chuàng)建信息字段颅眶,該字段的值是不允許被修改的蜈出。在提交表單數(shù)據(jù)時(shí)肯定沒(méi)有此字段的內(nèi)容,一單更新會(huì)把該字段內(nèi)容置為null,此時(shí)就可以使用此注解解決問(wèn)題涛酗。
7.SessionAttribute
-作用:
用于多次執(zhí)行控制器方法間參數(shù)共享铡原。
- 屬性:
value:用于指定存入的屬性名稱
type:用于指定存入的數(shù)據(jù)類型