文章目录
- 一、SpringMVC概述
- 1.1、什么是三层架构
- 1.2、什么是MVC
- 1.3、什么是SpringMVC
- 1.3.1、SpringMVC工作流程图
- 1.3.2、SpringMVC架构图
- 二、 SpringMVC入门案例
- 2.1、环境准备
- 2.2、案例编写
- 2.3、@RequestMapping注解
- 三、请求参数绑定
- 3.1、请求参数绑定基本类型
- 3.2、请求参数绑定实体类型
- 3.3、解决中文乱码的过滤器
- 3.4、请求参数绑定集合类型
- 3.5、自定义类型转换器
- 3.6、获取Servlet原生API
- 四、常用注解
- 4.1、@ResquestParam
- 4.2、@RequestBody
- 4.3、REST风格URL
- 4.4、@PathVaribale
- 4.5、@RequestHeader
- 4.6、@CookieValue
- 4.7、@ModelAttribute
- 4.8、@SessionAttribute
一、SpringMVC概述
开发架构一般都是基于两种形式:一种是C/S架构,也就是客户端/服务器,另一种是B/S架构,也就是浏览器服务器。
在JavaEE开发中,几乎全都是基于B/S架构的开发。那么在B/S架构中,系统标准的三层架构包括:表现层、业务层、持久层。
1.1、什么是三层架构
其中每一层都分工明确:
表现层
:负责接收客户端请求,向客户端响应结果,负责与用户进行交互。表现层的设计一般都使用MVC模型
业务层
:主要是针对不同请求业务逻辑的处理,也可理解为对数据业务逻辑处理。
持久层
:主要是对非原始数据(数据库或者文本文件等存放数据的形式)的操作层,也就是说是对数据库,而不是对数据的操作,具体为业务逻辑层或用户界面层提供数据服务。
常用的基于三层开发架构的框架有:
SSH:
Struct(表示层) + Spring(业务层) + Hibernate(持久层)
SSM:
SpringMVC(表示层) + Spring(业务层) + MyBatis(持久层)
如上图
面试题:Struts2 和 StringMVC的区别?
(1)Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,因此容易实现Restful API;
(2)Struts2是多例的,每次请求都创建一个Action,类属性被方法共享,而SpringMVC是单例的,只有一个实例,方法之间变量不共享;
(3)Struts2的核心控制器是Filter,SpringMVC的核心控制器是Servlet;
(4)拦截器方面,Struts2有自己的interceptor机制,SpringMVC用的是独立的AOP方式;
(5)SpringMVC是Spring的一个模块,项目管理和安全性比Struts2好,配置文件少,并且集成了Ajax,处理ajax请求,直接通过返回数据,方法中使用注解@ResponseBody,能自动将对象转换为JSON数据。
1.2、什么是MVC
MVC是一个架构,或者说是一个设计模式,它就是强制性使应用程序的输入,处理和输出分开。将一个应用程序分为三个部分:Model,View,Controller
Model 模型
:
完成业务逻辑:由javaBean构成,在MVC的三个部件中,模型拥有最多的处理任务。View 视图
:
负责跟用户交互的界面。一般就是由HTML,css元素组成的界面。 在视图层里没有真正的处理发生,只负责数据输出。MVC能为应用程序处理很多不同的视图。Controller 控制器
:
接收请求—>调用模型—>根据结果派发页面并经过模型处理返回相应数据
注:所有的表现层框架都是基于MVC开发的。例如SpringMVC和Strtus(Strtus、Strtus2)
1.3、什么是SpringMVC
我们通常所说的Spring指的是Spring Framework
。而Spring Framework也只是Spring家族中的一个分支而已。
在 Spring 的基本架构中,Spring Web MVC 也就是 SpringMVC,它是属于Spring基本架构里面的一个组成部分,属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面,所以我们在后期和 Spring 进行整合的时候,几乎不需要别的什么配置。
SpringMVC又是基于mvc模式开发,在SpringMVC模块中,将MVC的分工划分为多个组件来完成,以此来提高MVC的执行效率:
DispatcherServlet:前端控制器
用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。HandlerMapping:映射处理器
HandlerMapping负责根据用户请求url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。Handler:处理器
Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。HandlAdapter:处理适配器
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。ViewResolver:视图解析器
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。View:视图
springmvc框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。
说明:
在springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。需要用户开发的组件有handler、view
1.3.1、SpringMVC工作流程图
1.3.2、SpringMVC架构图
步骤:
第一步:用户发送请求到前端控制器(DispatcherServlet)。
第二步:前端控制器请求 HandlerMapping 查找 Handler,可以根据 xml 配置、注解进行查找。
第三步: 处理器映射器 HandlerMapping 向前端控制器返回 Handler
第四步:前端控制器调用处理器适配器去执行 Handler
第五步:处理器适配器执行 Handler
第六步:Handler 执行完成后给适配器返回 ModelAndView
第七步:处理器适配器向前端控制器返回 ModelAndView
ModelAndView 是SpringMVC 框架的一个底层对象,包括 Model 和 View
第八步:前端控制器请求试图解析器去进行视图解析,根据逻辑视图名来解析真正的视图。
第九步:试图解析器向前端控制器返回 view
第十步:前端控制器进行视图渲染
就是将模型数据(在 ModelAndView 对象中)填充到 request 域
二、 SpringMVC入门案例
2.1、环境准备
1、新建一个project或module,选择webapp的骨架来创建web项目:
2、pom.xml导入所需jiar包:
<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>
3、新建spring配置文件(spring-context-5.0.5.RELEASE版本)
4、配置一个DispatcherServlet前端控制器
,这个必须有:
5、配置Tomcat服务器,并部署项目:
(1)在idea中也是可以配置多个服务的。点击add Configurations
按钮,然后点击“+”
号(也可以直接点击Templates
):
拉到最下面找到tomcat :
(2)配置Tomcat服务器所在位置:
(3)Tomcat其他基本配置:
(4)部署项目:
注:
On Update action 里面有四个选项(一般选
Update classes and resources
):
-Update resources
:如果发现有更新,而且更新的是资源文件(.jsp,.xml等,不包括java文件),就会立刻生效
-Update classes and resources
: 如果发现有更新,这个是同时包含java文件和资源文件的,就会立刻生效
这里需要注意一下:在运行模式下,修改java文件时不会立刻生效的;而debug模式下,修改java文件时可以立刻生效的。当然,两种运行模式下,修改resources资源文件都是可以立刻生效的。
-Redploy : 重新部署,只是把原来的war删掉,不重启服务器
-Restart : 重启服务器
On Frame deactivation:
-Do nothing : 不做任何事 (一般推荐这个,因为失去焦点的几率太大)
-Update resources : 失去焦点后,修改的resources文件都会立刻生效
-Update classes and resources : 失去焦点后,修改的java ,resources文件都会立刻生效(与On update action中的Update classes and resources一样,也是运行模式修改的java文件不会生效,debug模式修改的java文件会立刻生效)
另外,如果Artifact是war包形式的话,On Update action与On frame deactivation中的选项也是不一样的:没有Update resources和 Update classes and resources这种选项,取而代之的是Hot Swap Classes选项,本质的意思是一样的。
6、启动项目,并且能正常访问:
2.2、案例编写
1、由于要使用注解的方式来进行编写,所以需要在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">
</beans>
2、新增一个index.jsp文件:
再新建一个success.jsp作为成功跳转页面:
3、新建一个HelloController控制器:
4、将HellerController.java类配置到spring容器中,并配置好当接收到请求的时候调用该bean对象中的sayHello()
方法:
服务启动的时候,容器创建了bean对象,当收到
/hello
请求的时候,由bean对象自动请求调用sayHello()
方法
问题:
(1)容器是如何知道需要去创建HellerController的bean对象?
(2)如果成功调用了sayHello()
方法,如何让页面跳转到success.jsp页面
?
5、配置springmvc.xml文件,让Spring容器自动扫描注解,从而创建bean对象:
注1:
<mvc:annotation-driven/>
该注解默认开启了以下组件:
(1)HandlerMapping
:处理器映射器
(2)Handler
:处理器
(3)HandlAdapter
:处理器适配器
视图解析器底层会对sayHello()返回的“success”字符串
作为跳转到“success.jsp”。跳转的前提是:
(1)返回的字符串与jsp页面名称匹配
(2)需要在视图解析器中配置jsp文件的位置和文件后缀问题:刚刚说,Tomcat一启动的时候,spring容器就创建对象,那么问题来了,谁去创建Spring容器?怎么去创建?
答案:
当然是交给tomcat服务器去创建Spring容器。那么该如何让Tomcat去获取容器呢?大家都知道在服务启动的时候都是先加载web.xml
文件,只要里面的配置信息存在一点问题,服务都无法正常启动。所以我们可以在web.xml中设置变量,让前端处理器去读取springmvc.xml配置文件,从而创建Spring容器。
6、配置web.xml
,使其读取配置文件,并创建Spring容器:
7、测试:
跳转成功:
整个入门案例原理图如图所示:
核心架构的具体流程步骤如下:
1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为HandlerExecutionChain 对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名);
5、ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
下边两个组件通常情况下需要开发:
Handler:处理器,即后端控制器用controller表示。
View:视图,即展示给用户的界面,视图中通常需要标签语言展示模型数据。
HandlerMapping的实现类的作用:
实现类RequestMappingHandlerMapping,它会处理@RequestMapping 注解,并将其注册到请求映射表中。
HandlerAdapter的实现类的作用:
实现类RequestMappingHandlerAdapter,则是处理请求的适配器,确定调用哪个类的哪个方法,并且构造方法参数,返回值。
当配置了mvc:annotation-driven/
后,Spring就知道了我们启用注解驱动。然后Spring通过context:component-scan/标签的配置,会自动为我们将扫描到的@Component,@Controller,@Service,@Repository等注解标记的组件注册到工厂中,来处理我们的请求。
注:使用<mvc:annotation-driven/>
自动加载RequestMappingHandlerMapping(处理映射器)和RequestMappingHandlerAdapter(处理适配器)。相当于在web.xml中配置了如下:
<!-- HandlerMapping -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
</bean>
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
</bean>
<!-- HandlerAdapter -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
</bean>
<bean
class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter">
</bean>
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter">
</bean>
<!-- HadnlerExceptionResolvers -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
</bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver">
</bean>
<bean
class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver">
</bean>
2.3、@RequestMapping注解
知识:
RequestMapping注解
作用:
用于建立请求URL和处理请求方法之间的对应关系。要配置 Web 请求的映射,就需要你用上 @RequestMapping 注解。
出现位置:
(1)类头部:
请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以/
开头。 它出现的目的是为了使我们的URL可以按照模块化管理:
例如:账户模块:/account/add
例如:订单模块:/order/delete
一般将/account
写在类头部,将/add
写在方法头部来使用。例如:
(2)方法头部:请求URL的第二级访问目录。
属性:
value:用于指定请求的URL。
它和path属性的作用是一样的。如果@RequestMapping注解此时同时用到两个或者两个以上属性,value或者path不能省略不写
path:和value属性是一样的。
method:用于指定请求的方式。如果前端的请求方式的get,服务端RequestMapping注解的请求方式是post,那么无法响应到该方法。
params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样。
例如:
params =
{"accountName"}
,表示请求参数必须有accountName
params =
{"moeny!100"}
,表示请求参数中money不能是100。
headers:用于指定限制请求消息头的条件。
注意
:以上四个属性只要出现2个或以上时,他们的关系是与的关系。
具体RequestMapping注解
的使用参考:
三、请求参数绑定
3.1、请求参数绑定基本类型
我们都知道,表单中请求参数都是基于
key=value
的。
SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行直接绑定的。
例如:<a href="hello?username=ZhangSan">开始学习</a>
<a href="user/login?userName=lisi&password=123">登录</a>
注
:
1、方法头部存在@RequestMapping注解
2、方法中的参数名称必须和请求参数中的key保持一致。
3.2、请求参数绑定实体类型
以上学习了基本类型作为请求参数的封装,那如果 想要把请求参数封装成一个bean实体对象,并作为请求参数发送服务端怎么做呢?
1、新建Account和User两个实体类,并生成set和get方法
2、准备一个表单:
注:封装成bean对象,
name
属性的值必须和Account.java
类中定义的成员变量名称保持一致。原理:
SpringMVC会根据name中的属性值去找到对应的实体类,并调用实体中的set()
来给变量赋值,然后封装成bean对象。
3、准备服务端代码:
3.3、解决中文乱码的过滤器
以上例子发现,如果表单的提交方式是get
的时候,在表单提交前输入中文是没有任何问题。但是当修改成post
的时候,在表单提交之后就发现中文出现了乱码。
之前还没学SpringMVC的时候,是通过设置请求参数的字符集来解决的:req.setCharacterEncoding(“utf-8”);
然而在SpringMVC中,提供了一个解决中文乱码的过滤器,在web.xml
文件下面配置即可:
3.4、请求参数绑定集合类型
如果 想要把请求参数封装成一个bean实体对象,并放到一个List集合
或者Map集合
中,并作为请求参数发送服务端怎么做呢?
1、 Account类中增加一个List和一个Map:
2、制作一个表单:
3、控制器:
4、测试结果:
Account{ username='admin', password='423432', money=32132.0, list=[User{uname='张三', age=32, date=null}], map={one=User{uname='李四', age=100, date=null}}}
3.5、自定义类型转换器
在请求参数传递的过程中,我们的请求参数都是字符串,但是传递到服务端会发现可以匹配int
,double
,甚至user
类型。其实SpringMVC是做了请求参数类型转换的。
在请求转换的过程中,会存在个别特殊类型转化不了,比如Date
类型。如果请求参数是‘2020/03/21’
,那么SpringMVC可以正常转换成Date。那如果请求参数是‘2020-03-21’
,那么SpringMVC是不能自动转化成SpringMVC的。
1、User类中新增Date成员变量:
2、新增加表单:
3、控制器中增加一个保存用户的方法:
此时大家可以传错误日期格式进行测试,代码是会报错。因为在Spring提供的所以转换器中,没有提供String
转Date
的。如图:
4、写一个String
转Date
的类型转化器:
5、将该Bean对象注册到容器中:
6、测试:
结果:
3.6、获取Servlet原生API
如果想要在控制器中获取常用的HttpServletRequest
和HttpServletResponse
对象,很简单。想要获取哪个对象,直接在控制器方法的请求参数中写上该请求参数即可。如:
四、常用注解
4.1、@ResquestParam
以上的Demo我们发现一个问题,只要想要获取请求中的请求参数,直接在contraller
里的方法加入参数即可映射获取。但是,要求方法中变量名必须和请求参数的key大小写一致,才能获取。现在我们可以使用@ResquestParam
注解来解决这个问题。
知识:
@ResquestParam
作用:把请求中指定名称的参数给控制器中的形参赋值。
属性:
value/name
:请求参数中的名称。
required
:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。
1、写一个请求:
2、编写controller
由于required
属性默认值是true,所以请求参数中必须有key为name这个参数,如果没有也会报错。
4.2、@RequestBody
知识:
@RequestBody
作用:
用于获取请求体内容。直接使用得到key=value&key=value…结构的数据。 get请求方式不适用,因为get请求是将参拼接到url后面,没有请求体。
属性:
required
:是否必须有请求体。默认值是:true。当取值为true时,get请求方式会报错。如果取值为false,get请求得到是null。
1、写一个表单:
2、写一个Controller:
4.3、REST风格URL
什么是rest:
REST(英文:Representational State Transfer
,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。一般称为RESTFUL,是一种编码风格,不是规范。不要求强行使用
。在目前主流的三种Web服务交互方案中,REST
相比于SOAP(Simple Object Access protocol,简单对象访问协议)
以及XML-RPC
更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。
它本身并没有什么实用性,其核心价值在于如何设计出符合REST风格的网络接口。
restful的优点:
它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
restful的特性:资源(Resources)
:网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符。表现层(Representation)
:把资源具体呈现出来的形式,叫做它的表现层 (Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。状态转化(State Transfer)
:每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
restful的示例:
/account/1 HTTPGET
: 得到 id = 1 的 account
/account/1 HTTPDELETE
: 删除 id = 1的 account
/account/1 HTTPPUT
: 更新id = 1的 account
/account HTTPPOST
: 新增 account
以前的风格:通过一个URL来区别调用哪个方法
:
在
UserController
中:
@RequestMapping(path=“user/add”) //新增方法
public void save(){}@RequestMapping(path=“user/update”) //修改方法
public void update(){}@RequestMapping(path=“user/query”) //查询方法
public void findAll(){}@RequestMapping(path=“user/queryByID”) //查询方法
public void findById(){}
restful的风格:通过相同的URL和请求方式来区别调用哪个方法
:
在
UserController
中:
@RequestMapping(path="/user" ,method =RequestMethod.GET
)
public void save(){}@RequestMapping(path="/user",method =
RequestMethod.PUT
)
public void update(){}@RequestMapping(path="/user" ,method =
RequestMethod.POST
)
public void findAll(){}@RequestMapping(path="/user/{id}" ,method =
RequestMethod.POST
)
public void findById(int id){}
4.4、@PathVaribale
作用:
用于绑定url中的占位符。例如:请求url中 /delete/{id},这个{id}就是url占位符。 url支持占位符是spring3.0之后加入的。是springmvc支持rest风格URL的一个重要标志。
属性:value
:用于指定url中占位符名称。required
:是否必须提供占位符。
1、编写一个请求:
2、编写一个controller:
4.5、@RequestHeader
注: 在实际开发中一般不怎么用。
作用:
用于获取请求消息头信息。
属性:
value
:提供消息头名称
required
:是否必须有此消息头
4.6、@CookieValue
作用:
用于把指定cookie名称的值传入控制器方法参数。
属性:
value
:指定cookie的名称。
required
:是否必须有此cookie。
1、写一个请求
2、获取Cookie的值:
4.7、@ModelAttribute
作用:
该注解是SpringMVC4.3版本以后新加入的。它可以用于修饰方法和参数。
(1)出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
(2)出现在参数上,获取指定的数据给参数赋值。
属性:
value:用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key。
应用场景:
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
例如:
我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段的内容,一旦更新会把该字段内容置为null,此时就可以使用此注解解决问题。
1、写一个表单:
2、@ModelAttribute
作用在方法头上:
当然,也可以这样:
3、@ModelAttribute
作用在变量上:
4.8、@SessionAttribute
多用于方法之间的参数共享。
作用:
用于多次执行控制器方法间的参数共享
。
属性:value
:用于指定存入的属性名称type
:用于指定存入的数据类型。
使用例子:(该例子位于控制器头,用于保存session信息)@SessionAttributes(value ={"username","password"},types={Integer.class})
1、请求:
2、控制器:
3、将值也存入session域中:
4、跳转页面取域中值:
5、启动服务测试。6、从session中取值和session中删值:
再次启动服务,测试即可。