SpringMVC 基础知识一分析

java哥 阅读:123 2021-03-31 14:14:00 评论:0

第一:SpringMVC 基础概念

1.1 三层架构:

表现层(Controller: 
也就是我们常说的web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求 
web 层,web 需要接收 http 请求,完成 http 响应。 
表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。 
表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。 
表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系) 
 
业务层(Service): 
也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web 层依赖业 
务层,但是业务层不依赖 web 层。 
业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的, 
事务应该放到业务层来控制) 
 
持久层(dao): 
也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进 
行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库 
中。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的。

1.2 MVC 模型

MVC 概念: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 开发框架,如 Struts1(现在一般不用),Struts2 等。
        SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。

       它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求。

1.4 SpringMVC 在三层架构的位置

1.5 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、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。 
10、强大的 JSP 标签库,使 JSP 编写更容易。 
………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配 
置支持等等

第二:SpringMVC 入门

2.1 eclipse 创建Maven web 项目

参考文章地址:https://blog.csdn.net/erlian1992/article/details/53942096

2.1.1 添加依赖的jar 包文件

<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> 
	<groupId>com.zzg.springmvc</groupId> 
	<artifactId>panda</artifactId> 
	<packaging>war</packaging> 
	<version>0.0.1-SNAPSHOT</version> 
	<name>panda Maven Webapp</name> 
	<url>http://maven.apache.org</url> 
	<dependencies> 
		<!-- 添加cglib jar包依赖 --> 
		<dependency> 
			<groupId>cglib</groupId> 
			<artifactId>cglib</artifactId> 
			<version>3.2.5</version> 
		</dependency> 
		<!--spring 核心框架 --> 
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-context</artifactId> 
			<version>5.0.2.RELEASE</version> 
		</dependency> 
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-core</artifactId> 
			<version>5.0.2.RELEASE</version> 
		</dependency> 
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-beans</artifactId> 
			<version>5.0.2.RELEASE</version> 
		</dependency> 
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-expression</artifactId> 
			<version>5.0.2.RELEASE</version> 
		</dependency> 
		<!--spring aop 依赖jar 包 --> 
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-aop</artifactId> 
			<version>5.0.2.RELEASE</version> 
		</dependency> 
		<dependency> 
			<groupId>org.springframework</groupId> 
			<artifactId>spring-aspects</artifactId> 
			<version>5.0.2.RELEASE</version> 
		</dependency> 
		<dependency> 
			<groupId>org.aspectj</groupId> 
			<artifactId>aspectjweaver</artifactId> 
			<version>1.8.7</version> 
		</dependency> 
		<dependency> 
			<groupId>aopalliance</groupId> 
			<artifactId>aopalliance</artifactId> 
			<version>1.0</version> 
		</dependency> 
		<!--springmvc 框架 --> 
		<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> 
		<!--日志框架 --> 
		<dependency> 
			<groupId>commons-logging</groupId> 
			<artifactId>commons-logging</artifactId> 
			<version>1.2</version> 
		</dependency> 
		<!--测试框架  --> 
		<dependency> 
			<groupId>junit</groupId> 
			<artifactId>junit</artifactId> 
			<version>3.8.1</version> 
			<scope>test</scope> 
		</dependency> 
	</dependencies> 
	<build> 
		<finalName>panda</finalName> 
	</build> 
</project> 

2.1.2 web.xml 添加springMVC 核心控制器

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
	id="WebApp_ID" version="2.5"> 
	<!-- 配置 spring mvc 的核心控制器 --> 
	<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> 
 
	<!-- 项目默认首页 --> 
	<welcome-file-list> 
		<welcome-file>/index.jsp</welcome-file> 
	</welcome-file-list> 
</web-app>

2.1.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/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.zzg.panda"></context:component-scan> 
 
	<!-- 配置视图解析器 --> 
	<bean 
		class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
		<property name="prefix" value="/WEB-INF/pages/"></property> 
		<property name="suffix" value=".jsp"></property> 
	</bean> 
</beans>

2.1.4 使用注解编写控制器和相关jsp页面

package com.zzg.panda.controller; 
 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
 
@Controller("helloController") 
public class HelloController { 
	@RequestMapping("/hello") 
	public String sayHello() { 
		System.out.println("HelloController 的 sayHello 方法执行了。。。。"); 
		return "success"; 
	} 
} 
<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>成功页面</title> 
</head> 
<body> 
	<a href="${pageContext.request.contextPath}/hello">SpringMVC 入门案例</a> <br/> 
	<a href="hello">SpringMVC 入门案例</a> 
</body> 
</html>

2.1.5 功能演示:

项目结构图:

2.2 SpringMVC请求响应流程图

2.3 入门案例涉及SpringMVC相关组件

DispatcherServlet:前端控制器 
	用户请求到达前端控制器,它就相当于 mvc 模式中的 c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。 
 
HandlerMapping:处理器映射器 
	HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,[email protected]("/*")等。 
 
Handler:处理器 
	它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。 
 
HandlAdapter:处理器适配器 
	通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。 
 
View Resolver:视图解析器 
	View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。 
 
View:视图 
	SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是 jsp。 
	一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

第三:SpringMVC 请求参数说明

3.1 支持请求参数类型说明

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

3.2 请求参数使用要求

如果是基本类型或者 String 类型: 
	要求我们的参数名称必须和控制器中方法的形参名称保持一致。(严格区分大小写) 
 
如果是 POJO 类型,或者它的关联对象: 
	要求表单中参数名称和 POJO 类的属性名称保持一致。并且控制器方法的参数类型是 POJO 类型。 
 
如果是集合类型,有两种方式: 
    第一种: 
	要求集合类型的请求参数必须在 POJO 中。在表单中请求参数名称要和 POJO 中集合属性名称相同。给 List 集合中的元素赋值,使用下标。给 Map 集合中的元素赋值,使用键值对。 
    第二种: 
	接收的请求参数是 json 格式数据。需要借助一个注解实现。 
 
注意: 
它还可以实现一些数据类型自动转换。内置转换器全都在: 
org.springframework.core.convert.support 包下。有: 
java.lang.Boolean -> java.lang.String : ObjectToStringConverter 
java.lang.Character -> java.lang.Number : CharacterToNumberFactory 
java.lang.Character -> java.lang.String : ObjectToStringConverter 
java.lang.Enum -> java.lang.String : EnumToStringConverter 
java.lang.Number -> java.lang.Character : NumberToCharacterConverter 
java.lang.Number -> java.lang.Number : NumberToNumberConverterFactory 
java.lang.Number -> java.lang.String : ObjectToStringConverter 
java.lang.String -> java.lang.Boolean : StringToBooleanConverter 
java.lang.String -> java.lang.Character : StringToCharacterConverter 
java.lang.String -> java.lang.Enum : StringToEnumConverterFactory 
java.lang.String -> java.lang.Number : StringToNumberConverterFactory 
java.lang.String -> java.util.Locale : StringToLocaleConverter 
java.lang.String -> java.util.Properties : StringToPropertiesConverter 
java.lang.String -> java.util.UUID : StringToUUIDConverter 
java.util.Locale -> java.lang.String : ObjectToStringConverter 
java.util.Properties -> java.lang.String : PropertiesToStringConverter 
java.util.UUID -> java.lang.String : ObjectToStringConverter 
...... 
如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。

3.3 使用示例:

3.3.1 基本类型和 String 类型作为参数

Controller 代码片段

package com.zzg.panda.controller; 
 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
 
/** 
 * 基础参数绑定 
 *  
 * @author Administrator 
 * 
 */ 
@Controller("basicController") 
@RequestMapping("/basic") 
public class BasicController { 
	 
	@RequestMapping("/findAccount") 
	public String findAccount(Integer accountId, String accountName) { 
		System.out.println("查询了账户。。。。" + accountId + "," + accountName); 
		return "success"; 
	} 
} 

JSP 代码片段

<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<title>Insert title here</title> 
</head> 
<body> 
	<a href="basic/findAccount?accountId=10&accountName=zhangsan">查询账户</a> 
</body> 
</html>

 

3.3.2 POJO 类型作为参数

Entity 对象代码

package com.zzg.panda.entity; 
 
import java.io.Serializable; 
 
@SuppressWarnings("serial") 
public class Address implements Serializable { 
	private String provinceName; 
	private String cityName; 
	 
	public String getProvinceName() { 
		return provinceName; 
	} 
	public void setProvinceName(String provinceName) { 
		this.provinceName = provinceName; 
	} 
	public String getCityName() { 
		return cityName; 
	} 
	public void setCityName(String cityName) { 
		this.cityName = cityName; 
	} 
} 
 
package com.zzg.panda.entity; 
 
import java.io.Serializable; 
 
@SuppressWarnings("serial") 
public class Account implements Serializable { 
	private Integer id; 
	private String name; 
	private Float money; 
	private Address address; 
	 
	public Integer getId() { 
		return id; 
	} 
	public void setId(Integer id) { 
		this.id = id; 
	} 
	public String getName() { 
		return name; 
	} 
	public void setName(String name) { 
		this.name = name; 
	} 
	public Float getMoney() { 
		return money; 
	} 
	public void setMoney(Float money) { 
		this.money = money; 
	} 
	public Address getAddress() { 
		return address; 
	} 
	public void setAddress(Address address) { 
		this.address = address; 
	} 
} 
 

Controller代码

/** 
	* 保存账户 
	* @param account 
	* @return 
	*/ 
	@RequestMapping(value="/saveAccount", method = {RequestMethod.POST}) 
	public String saveAccount(Account account) { 
	System.out.println("保存了账户。。。。"+account); 
	return "success"; }

JSP 代码

 
	<!-- pojo 类型演示 --> 
	<form action="basic/saveAccount" method="post"> 
		账户名称:<input type="text" name="name"><br />  
		账户金额:<input type="text" name="money"><br />  
		账户省份:<input type="text"name="address.provinceName"><br />  
		账户城市:<input type="text"name="address.cityName"><br />  
		<input type="submit" value="保存"> 
	</form>

3.3.3 POJO 类中包含集合类型参数

Entity 实体对象

package com.zzg.panda.entity; 
 
import java.io.Serializable; 
import java.util.List; 
import java.util.Map; 
 
@SuppressWarnings("serial") 
public class User implements Serializable { 
	private String username; 
	private String password; 
	private Integer age; 
	private List<Account> accounts; 
	private Map<String,Account> accountMap; 
	 
	public String getUsername() { 
		return username; 
	} 
	 
	public void setUsername(String username) { 
		this.username = username; 
	} 
 
	public String getPassword() { 
		return password; 
	} 
 
	public void setPassword(String password) { 
		this.password = password; 
	} 
 
	public Integer getAge() { 
		return age; 
	} 
 
	public void setAge(Integer age) { 
		this.age = age; 
	} 
 
	public List<Account> getAccounts() { 
		return accounts; 
	} 
 
	public void setAccounts(List<Account> accounts) { 
		this.accounts = accounts; 
	} 
 
	public Map<String, Account> getAccountMap() { 
		return accountMap; 
	} 
 
	public void setAccountMap(Map<String, Account> accountMap) { 
		this.accountMap = accountMap; 
	} 
 
	@Override 
	public String toString() { 
	return "User [username=" + username + ", password=" + password + ", age=" 
	+ age + ",\n accounts=" + accounts 
	+ ",\n accountMap=" + accountMap + "]"; 
	} 
} 

Controller 控制层

	/** 
	 * 更新账户 
	 *  
	 * @return 
	 */ 
	@RequestMapping("/updateAccount") 
	public String updateAccount(User user) { 
		System.out.println("更新了账户。。。。" + user); 
		return "success"; 
	}

JSP页面

	<!-- POJO 类包含集合类型演示 --> 
	<form action="basic/updateAccount" method="post"> 
		用户名称:<input type="text" name="username"><br /> 用户密码:<input 
			type="password" name="password"><br /> 用户年龄:<input 
			type="text" name="age"><br /> 账户 1 名称:<input type="text" 
			name="accounts[0].name"><br /> 账户 1 金额:<input type="text" 
			name="accounts[0].money"><br /> 账户 2 名称:<input type="text" 
			name="accounts[1].name"><br /> 账户 2 金额:<input type="text" 
			name="accounts[1].money"><br /> 账户 3 名称:<input type="text" 
			name="accountMap['one'].name"><br /> 账户 3 金额:<input 
			type="text" name="accountMap['one'].money"><br /> 账户 4 名称:<input 
			type="text" name="accountMap['two'].name"><br /> 账户 4 金额:<input 
			type="text" name="accountMap['two'].money"><br /> <input 
			type="submit" value="保存"> 
	</form>

第四:SpringMVC 编码器和静态资源映射

4.1  请求参数乱码

在 web.xml 中配置一个过滤器

<!-- 配置 springMVC 编码过滤器 -->  
	<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>  
		<!-- 启动过滤器 -->  
		<init-param>  
			<param-name>forceEncoding</param-name>  
 			<param-value>true</param-value>  
		</init-param>  
	</filter>  
	 
	<!-- 过滤所有请求 -->  
	<filter-mapping>  
		<filter-name>CharacterEncodingFilter</filter-name>  
		<url-pattern>/*</url-pattern>  
	</filter-mapping>

4.2  静态资源映射配置

在 springmvc 的配置文件中可以配置,静态资源不过滤

<!-- location 表示路径,mapping 表示文件,**表示该目录下的文件以及子目录的文件 --> 
<mvc:resources location="/css/" mapping="/css/**"/> 
<mvc:resources location="/images/" mapping="/images/**"/> 
<mvc:resources location="/scripts/" mapping="/javascript/**"/>

第五:类型转换器

5.1 实现自定义转换器一般步骤:

1、第一步:定义一个类,实现 Converter 接口,该接口有两个泛型。 
 
public interface Converter<S, T> {//S:表示接受的类型,T:表示目标类型 
    /** 
    * 实现类型转换的方法 
    */ 
    @Nullable 
    T convert(S source); 
} 
 
package com.zzg.panda.convert; 
 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import org.springframework.core.convert.converter.Converter; 
import org.springframework.util.StringUtils; 
 
/** 
 * 自定义字符串转日期格式 
 *  
 * @author Administrator 
 * 
 */ 
public class StringToDate implements Converter<String, Date> { 
 
	@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="converterService" 
    class="org.springframework.context.support.ConversionServiceFactoryBean"> 
        <!-- 给工厂注入一个新的类型转换器 --> 
        <property name="converters"> 
        <array> 
             <!-- 配置自定义类型转换器 --> 
             <bean class="com.zzg.panda.convert.StringToDate "></bean> 
         </array> 
     </property> 
</bean> 
 
第三步:在 annotation-driven 标签中引用配置的类型转换服务 
<!-- 引用自定义类型转换器 -->  
<mvc:annotation-driven 
    conversion-service="converterService"></mvc:annotation-driven>

5.1.1  验证自定义自定义类型转换器

     <!-- 特殊情况之:类型转换问题 --> 
	 <a href="basic/deleteAccount?date=2018-01-01">根据日期删除账户</a>
	/** 
	 * 删除账户 
	 *  
	 * @return 
	 */ 
	@RequestMapping("/deleteAccount") 
	public String deleteAccount(Date date) { 
		System.out.println("删除了账户。。。。" + date); 
		return "success"; 
	}

第六:支持Servlet

SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。支持原始 ServletAPI 对象有:

HttpServletRequest  
HttpServletResponse 
HttpSession 
java.security.Principal 
Locale 
InputStream  
OutputStream  
Reader  
Writer 
重点注意:我们可以把上述对象,直接写在控制的方法参数中使用。

示例代码:

     index.jsp 
     <!-- 原始 ServletAPI 作为控制器参数 -->  
	 <a href="basic/testServletAPI">测试访问 ServletAPI</a>
BasicController.java 
 
	/** 
	* 测试访问 testServletAPI 
	* @return 
	*/ 
	@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"; 
	}

第七 常用注解

7.1 RequestParam

作用: 
    把请求中指定名称的参数给控制器中的形参赋值。 
属性: 
    value:请求参数中的名称。 
    required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。

示例

     index.jsp 
     <!-- requestParams 注解的使用 -->  
	 <a href="annotation/useRequestParam?name=test">requestParam 注解</a>
package com.zzg.panda.controller; 
 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestParam; 
 
/** 
 * 常用注解 
 *  
 * @author Administrator 
 * 
 */ 
@Controller 
@RequestMapping("/annotation") 
public class AnnotationController { 
 
	/** 
	 * requestParams 注解的使用 
	 *  
	 * @param username 
	 * @return 
	 */ 
	@RequestMapping("/useRequestParam") 
	public String useRequestParam(@RequestParam("name") String username, 
			@RequestParam(value = "age", required = false) Integer age) { 
		System.out.println(username + "," + age); 
		return "success"; 
	} 
 
} 

7.2 RequestBody

作用: 
    用于获取请求体内容。直接使用得到是 key=value&key=value...结构的数据。 
get 请求方式不适用。 
属性: 
    required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值 
为 false,get 请求得到是 null。

示例代码

index.jsp 
<!-- request body 注解 -->  
<form action="annotation/useRequestBody" method="post"> 
    用户名称:<input type="text" name="username" ><br/> 
    用户密码:<input type="password" name="password" ><br/> 
    用户年龄:<input type="text" name="age" ><br/> 
    <input type="submit" value="保存"> 
</form>
AnnotationController.java 
 
/** 
* RequestBody 注解 
* @param user 
* @return 
*/ 
@RequestMapping("/useRequestBody") 
public String useRequestBody(@RequestBody(required=false) String body){ 
    System.out.println(body); 
    return "success";  
} 

7.3 PathVaribale

作用: 
    用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。 
url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。 
属性: 
    value:用于指定 url 中占位符名称。 
    required:是否必须提供占位符。

示例代码

    index.jsp 
    <!-- PathVariable 注解 -->  
	<a href="annotation/usePathVariable/100">pathVariable 注解</a>
AnnotationController.java 
 
	/** 
	* PathVariable 注解 
	* @param user 
	* @return 
	*/ 
	@RequestMapping("/usePathVariable/{id}") 
	public String usePathVariable(@PathVariable("id") Integer id){ 
		System.out.println(id); 
		return "success";  
	}

7.4 RequestHeader

作用: 
    用于获取请求消息头。 
属性: 
    value:提供消息头名称 
    required:是否必须有此消息头 
注: 
    在实际开发中一般不怎么用。

示例代码

    index.jsp 
    <!-- RequestHeader 注解 -->  
	<a href="annotation/useRequestHeader">获取请求消息头</a>
AnnotationController.java 
 
	/** 
	* RequestHeader 注解 
	* @param user 
	* @return 
	*/ 
	@RequestMapping("/useRequestHeader") 
	public String useRequestHeader(@RequestHeader(value="Accept-Language", required=false)String requestHeader){ 
		System.out.println(requestHeader); 
		return "success";  
	} 

 

7.5 CookieValue

作用: 
    用于把指定 cookie 名称的值传入控制器方法参数。 
属性: 
    value:指定 cookie 的名称。 
    required:是否必须有此 cookie

示例代码

    index.jsp 
    <!-- CookieValue 注解 -->  
	<a href="annotation/useCookieValue">绑定 cookie 的值</a>
AnnotationController.java 
 
	/** 
	* Cookie 注解注解 
	* @param user 
	* @return 
	*/ 
	@RequestMapping("/useCookieValue") 
	public String useCookieValue(@CookieValue(value="JSESSIONID",required=false) String cookieValue){ 
		System.out.println(cookieValue); 
		return "success"; 
	}

 

7.6  重点:ModelAttribute

作用: 
    该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。 
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可 
以修饰有具体返回值的方法。出现在参数上,获取指定的数据给参数赋值。 
 
属性: 
    value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。 
 
应用场景: 
    当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。 
例如: 
    我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数 
据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。

示例代码:

基于 POJO 属性的基本使用:

    index.jsp 
    <!-- ModelAttribute 注解的基本使用 --> 
	<a href="annotation/testModelAttribute?username=test">测试 modelattribute</a>
AnnotationController.java 
 
    /** 
	* 被 ModelAttribute 修饰的方法 
	* @param user 
	*/ 
	@ModelAttribute 
	public void showModel(User user) { 
		System.out.println("执行了 showModel 方法"+user.getUsername()); 
	} 
 
	/** 
	* 接收请求的方法 
	* @param user 
	* @return 
	*/ 
	@RequestMapping("/testModelAttribute") 
	public String testModelAttribute(User user) { 
		System.out.println("执行了控制器的方法"+user.getUsername()); 
		return "success"; 
	}

基于 Map 的应用场景示例 1:ModelAttribute 修饰方法带返回值

index.jsp 
 
    <!-- 修改用户信息 --> 
	<form action="annotation/updateUser" method="post"> 
		用户名称:<input type="text" name="username" ><br/> 
		用户年龄:<input type="text" name="age" ><br/> 
		<input type="submit" value="保存"> 
	</form>
AnnotationController.java 
    /** 
	* 查询数据库中用户信息 
	* @param user 
	*/ 
	@ModelAttribute 
	public User showModel(String username) { 
		//模拟去数据库查询 
		User abc = findUserByName(username); 
		System.out.println("执行了 showModel 方法"+abc); 
		return abc;  
	} 
	 
	/** 
	* 模拟修改用户方法 
	* @param user 
	* @return 
	*/ 
	@RequestMapping("/updateUser") 
	public String updateUser(User user) { 
		System.out.println("控制器中处理请求的方法:修改用户:"+user); 
		return "success"; 
	} 
	 
	/** 
	* 模拟去数据库查询 
	* @param username 
	* @return 
	*/ 
	private User findUserByName(String username) { 
		User user = new User(); 
		user.setUsername(username); 
		user.setAge(19); 
		user.setPassword("123456"); 
		return user;  
	}

基于 Map 的应用场景示例 2:ModelAttribute 修饰方法不带返回值

index.jsp 
 
	<!-- 修改用户信息 --> 
	<form action="annotation/updateUser" method="post"> 
		用户名称:<input type="text" name="username" ><br/> 
		用户年龄:<input type="text" name="age" ><br/> 
		<input type="submit" value="保存"> 
	</form>
AnnotationController.java 
 
/** 
* 查询数据库中用户信息 
* @param user 
*/ 
@ModelAttribute 
public void showModel(String username,Map<String,User> map) { 
    //模拟去数据库查询 
    User user = findUserByName(username); 
    System.out.println("执行了 showModel 方法"+user); 
    map.put("abc",user); 
} 
 
/** 
* 模拟修改用户方法 
* @param user 
* @return 
*/ 
@RequestMapping("/updateUser") 
public String testModelAttribute(@ModelAttribute("abc")User user) { 
    System.out.println("控制器中处理请求的方法:修改用户:"+user); 
    return "success";  
} 
 
/** 
* 模拟去数据库查询 
* @param username 
* @return 
*/ 
private User findUserByName(String username) { 
    User user = new User(); 
    user.setUsername(username); 
    user.setAge(19); 
    user.setPassword("123456"); 
    return user; 
 }

7.7 SessionAttribute

作用: 
    用于多次执行控制器方法间的参数共享。 
属性: 
    value:用于指定存入的属性名称 
    type:用于指定存入的数据类型

示例代码

index.jsp 
	<!-- SessionAttribute 注解的使用 --> 
	<a href="session/testPut">存入 SessionAttribute</a> <hr/> 
	<a href="session/testGet">取出 SessionAttribute</a> <hr/> 
	<a href="session/testClean">清除 SessionAttribute</a>
package com.zzg.panda.session; 
 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.ui.ModelMap; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.SessionAttributes; 
import org.springframework.web.bind.support.SessionStatus; 
 
@Controller 
@RequestMapping("/session") 
@SessionAttributes(value ={"username","password"},types={Integer.class}) 
public class SessionAttributeController { 
	/** 
	* 把数据存入 SessionAttribute 
	* @param model 
	* @return 
	* Model 是 spring 提供的一个接口,该接口有一个实现类 ExtendedModelMap 
	* 该类继承了 ModelMap,而 ModelMap 就是 LinkedHashMap 子类 
	*/ 
	@RequestMapping("/testPut")  
	public String testPut(Model model){  
		model.addAttribute("username", "泰斯特");  
		model.addAttribute("password","123456");  
		model.addAttribute("age", 31);  
		//跳转之前将数据保存到 username、password 和 age 中,[email protected] 中有这几个参数  
		return "success";  
	 }  
	  
	 @RequestMapping("/testGet")  
	 public String testGet(ModelMap model){  
		 System.out.println(model.get("username")+";"+model.get("password")+";"+model.get("age"));  
		 return "success";  
	 }  
	  
	 @RequestMapping("/testClean")  
	 public String complete(SessionStatus sessionStatus){  
		 sessionStatus.setComplete();  
		 return "success";  
	 }  
	 
} 

 

声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
关注我们

可以免费观看全网VIP电影的公众号