SpringMVC入门的简单知识点总结第一弹,分享给大家。希望对大家有帮助!
SpringMVC-1
SpringMVC大纲
1.MVC的简单原理
2.SpringMVC入门案例
3.@RequestMapping注解
4.请求参数绑定
5.常用注解
重点:
SpringMVC入门案例
@RequestMapping注解的使用
@RequestParam注解的使用。
重点掌握请求参数绑定
第一章:三层架构和MVC
1.1 三层架构
1. 咱们开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序
2. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
3. 三层架构
a. 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
b. 业务层:处理公司具体的业务逻辑的
c. 持久层:用来操作数据库的
1.2 MVC模型
1. MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
2. Model:数据模型,JavaBean的类,用来进行数据封装。
3. View:指JSP、HTML用来展示数据给用户
4. Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。
第二章:SpringMVC的入门案例
2.1 SpringMVC的概述(查看大纲文档)
2.1.1 SpringMVC的概述
1. 是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架。
2. Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
3. 使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2等。
4. SpringMVC在三层架构中的位置
1. 表现层框架
5. SpringMVC的优势
Spring框架提供了构建Web应用程序的全功能MVC模块——Spring MVC。Spring MVC框架提供了一个DispatcherServlet作用前端控制器来分派请求,同时提供灵活的配置处理程序映射、视图解析、语言环境和主题解析,并支持文件上传。Spring MVC还包含了多种视图技术,例如JSP、Velocity、Tiles、iText和POI等。Spring MVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
6. SpringMVC和Struts2框架的对比
2.2 SpringMVC的入门程序
2.2.1 创建WEB工程,引入开发的jar包
2.2.1.1 具体的坐标如下
<!-- 版本锁定 -->
<properties>
<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>
</dependencies>
这里用的Servlet版本是2.5,不支持注解,如果希望支持注解,用下面这个版本
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
2.2.2 配置核心的控制器(配置DispatcherServlet)
2.2.2.1 在web.xml配置文件中核心控制器DispatcherServlet
<?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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- SpringMVC的核心控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet启动时加载对象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.2.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.lovejava"></context:component-scan>
<!-- 配置spring开启注解mvc的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
2.2.4 编写index.jsp和HelloController控制器类
2.2.4.1 index.jsp
<body>
<h3>入门案例</h3>
<a href="${ pageContext.request.contextPath }/hello">入门案例</a>
</body>
2.2.4.2 HelloController
package com.lovejava.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
/**
* 接收请求
* @return
*/
@RequestMapping(path="/hello")
public String sayHello() {
System.out.println("Hello SpringMVC!!");
return "success";
}
}
2.2.5 在WEB-INF目录下创建pages文件夹,编写success.jsp的成功页面
<body>
<h3>入门成功!!</h3>
</body>
2.2.6 启动Tomcat服务器,进行测试
输入访问地址 http://localhost:8080/
2.3 入门案例的执行过程分析
2.3.1 入门案例的执行流程******
1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件
2. 开启了注解扫描,那么HelloController对象就会被创建
3. 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法
4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
5. Tomcat服务器渲染页面,做出响应
2.3.2 SpringMVC官方提供图形
2.3.3 入门案例中的组件分析
-
前端控制器(DispatcherServlet)拦截用户请求,调用HandlerMapping
-
处理器映射器(HandlerMapping)
作用是根据当前请求的找到对应的 Handler,并将 Handler(执行程序)与一堆 HandlerInterceptor(拦截器)封装到 HandlerExecutionChain 对象中。在 HandlerMapping 接口的内部只有一个方法,如下:
- HandlerExecutionChain getHandler(HttpServletRequest request);
HandlerMapping 是由 DispatcherServlet 调用,DispatcherServlet 会从容器中取出所有 HandlerMapping 实例并遍历,让 HandlerMapping 实例根据自己实现类的方式去尝试查找 Handler,
Spring MVC 默认提供了4种 HandlerMapping的实现
- org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
通过配置请求路径和Controller映射建立关系,找到相应的Controller - org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping
通过 Controller 的类名找到请求的Controller。 - org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
通过定义的 beanName 进行查找要请求的Controller - org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
通过注解 @RequestMapping("/userlist") 来查找对应的Controller。**
-
处理器(Handler)
1. 当DispatcherServlet接受到客户端的请求后,SpringMVC 通过 HandlerMapping 找到请求的Controller。 HandlerMapping 在这里起到路由的作用,负责找到请求的Controller。
-
处理器适配器(HandlAdapter)
1. HandlerAdapter字面上的意思就是处理适配器,它的作用用一句话概括就是调用具体的方法对用户发来的请求来进行处理。当handlerMapping获取到执行请求的controller时,DispatcherServlte会根据controller对应的controller类型来调用相应的HandlerAdapter来进行处理。
-
视图解析器(View Resolver)可以加载方法返回值的前部分和后部分的字符串拼接找到需要服务器加载的资源
-
视图(View)服务器加载好的页面
2.4 RequestMapping注解
源码:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
2.4.1 RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系
出现位置:
类上:
请求 URL 的第一级访问目录。此处不写的话,就相当于应用的根目录。 写的话需要以/开头。
它出现的目的是为了使我们的 URL 可以按照模块化管理:
例如:
账户模块:
/account/add
/account/update
/account/delete
...
订单模块:
/order/add
/order/update
/order/delete
红色的部分就是把 RequsetMappding 写在类上,使我们的 URL 更加精细。
方法上:
请求 URL 的第二级访问目录。
2.4.2 RequestMapping注解可以作用在方法和类上
作用在类上:第一级的访问目录
作用在方法上:第二级的访问目录
细节:路径可以不编写 / 表示应用的根目录开始
细节:${ pageContext.request.contextPath }也可以省略不写
案例:处理的请求路径是 http://localhost:8080/user/hello
@Controller
@RequestMapping(value = "/user")
public class HelloController {
/**
* 接收请求
* @return
*/
@RequestMapping(value = "/hello")
public String sayHello() {
System.out.println("Hello SpringMVC!!");
return "success";
}
}
2.4.3 RequestMapping的属性
2.4.3.1 path
指定请求路径的url
在HelloController方法上加了@RequestMapping(path="/hello"),而sayHello方法上加了@RequestMapping(path="/say"),此时用户可以直接访问 http://localhost:8080/user/hello 来访问该方法.
@Controller
@RequestMapping(path = "/user")
public class HelloController {
/**
* 此时用户访问此方法路径为 http://localhost:8080/user/hello
* @return
*/
@RequestMapping(value = "/hello")
public String sayHello() {
System.out.println("Hello SpringMVC!!");
return "success";
}
}
2.4.3.2 value
value属性和path属性是一样的
把上述方法中的path换成value即可,用户可以直接访问 http://localhost:8080/user/hello 来访问该方法。
@Controller
@RequestMapping(value = "/user")
public class HelloController {
/**
* 此时用户访问此方法路径为 http://localhost:8085/hello/say
* @return
*/
@RequestMapping(value = "/hello")
public String sayHello() {
System.out.println("Hello SpringMVC!!");
return "success";
}
}
2.4.3.3 mthod
指定该方法的请求方式
我们这里写了sayHello()和sayYourName()2个方法,但他们请求路径相同,而method属性的值不一样,如果是RequestMethod.GET,则只能以方式请求,如果是RequestMethod.POST则只能以POST方式请求。
@Controller
@RequestMapping(value = "/user")
public class HelloController {
/**
* 加了method = RequestMethod.GET
* 此时此方法只接收 http://localhost:8080/user/hello 的GET提交方式请求
* @return
*/
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String sayHello() {
System.out.println("Hello SpringMVC!!调用了GET方法");
return "success";
}
/**
* 加了method = RequestMethod.POST
* 此时此方法只接收 http://localhost:8080/user/hello 的POST提交方式请求
* @return
*/
@RequestMapping(value = "/hello",method = RequestMethod.POST)
public String sayYourName() {
System.out.println("Hello SpringMVC!!调用了POST方法");
return "success";
}
}
2.4.3.4 params
指定限制请求参数的条件,数组形式params={“name”,"!age",“address!=usa”}
params用的比较少。
param1: 表示请求必须包含名为 param1 的请求参数
!param1: 表示请求不能包含名为 param1 的请求参数
param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
{“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
如下案例:
/**
* params参数:
* "name":表示请求必须包含name参数
* "!age":表示请求不能包含age参数
* "address!=usa":表示请求中address参数的值不能为usa
* "working=sz":表示请求参数中的working参数必须为sz
* @return
*/
@RequestMapping(params = {"name","!age","address!=usa","working=sz"},
value = "/say",method = RequestMethod.GET)
public String sayHello() {
System.out.println("Hello SpringMVC!!调用了GET方法");
return "success";
}
2.4.3.5 headers 发送的请求中必须包含的请求头
headers用的比较少。
param1: 表示请求头必须包含名为 param1 的请求头信息
!param1: 表示请求头不能包含名为 param1 的请求头信息
param1 != value1: 表示请求头包含名为 param1 的请求头信息,但其值不能为 value1
{“param1=value1”, “param2”}: 请求必头须包含头信息 param1 和param2的两个请求头信息 ,且 param1 的值必须为 value1
如下案例:
/**
* headers参数:
* "Accept":表示请求头必须包含Accept头信息
* "!Date":表示请求头中不能包含Date的头信息
* "Accept-Encoding!=zh-CN":表示请求头中Accept-Encoding头信息的值不能为zh-CN
* "Host=localhost:18081":表示请求头中Host的值必须为localhost:18081
*
* @return
*/
@RequestMapping(headers = {"Accept","!Date","Accept-Encoding!=zh-CN","Host=localhost:8080"},
value = "/say",method = RequestMethod.GET)
public String sayHello() {
System.out.println("Hello SpringMVC!!调用了GET方法");
return "success";
}
第三章:请求参数的绑定******
3.1 请求参数的绑定说明
绑定机制
表单提交的数据都是k=v格式的 username=haha&password=123
SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
要求:提交表单的name和参数的名称是相同的
支持的数据类型
3.1.1 基本数据类型和字符串类型
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收基本数据类型和String
* 此时可以访问 http://localhost:8080/user/add?id=9&name=葛温
* 注意:此时请求地址的id和name和addUser(int id,String name)中的入参名字要一致才能接到参数。
* @return
*/
@RequestMapping(value = "/add")
public String addUser(int id,String name){
System.out.println("ID:"+id+",NAME:"+name);
return "success";
}
}
3.1.2 实体类型(JavaBean)
创建User实体Bean
public class User {
private String name;
private Integer age;
//get...set...
}
修改addUser方法
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 这里直接接收一个User 对象即可
* 注意:
* 页面表单需要和user对应的属性名字一致
* 姓名:<input name="name" /> name="name"和User的name属性名一样
* 年龄:<input name="age" /> name="age"和User的age属性名一样
* @return
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("AGE:"+user.getAge()+",NAME:"+user.getName());
return "success";
}
}
创建index.jsp,在index.jsp中加入如下表单
<form action="/user/add" method="post">
<div>
名字:<input name="name" >
</div>
<div>
年龄:<input name="age" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
3.1.3 集合数据类型(Map、List)
3.1.3.1 接收Map类型
在上面案例中,修改addUser方法,注意需要加上一个注解@RequestParam来接收Map数据
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收Map
* @return
*/
@RequestMapping(value = "/add")
public String addUser(@RequestParam Map userMap){
System.out.println(userMap);
return "success";
}
}
3.1.3.2 接收List类型
在上面案例中,把addUser方法修改一下,注意需要加上一个注解@RequestParam来接收List数据
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收List
* 注意:接收List,需要在方法中加入注解@RequestParam
* 一会儿页面传过来的表单参数名字也要和方法名字id一致
* 例如:
* ID1:<input name="id">
* ID2:<input name="id">
* ID3:<input name="id">
* @return
*/
@RequestMapping(value = "/add")
public String addUser(@RequestParam List<Integer> id){
System.out.println(id);
return "success";
}
}
修改index.jsp表单
<form action="/user/add">
<div>
ID1:<input name="id" >
</div>
<div>
ID2:<input name="id" >
</div>
<div>
ID3:<input name="id" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
3.2 入参参数总结
- 提交表单的name和参数的名称是相同的
- 如果接收JavaBean则必须和JavaBean的属性名相同
- 区分大小写
3.3 实体引用类型(JavaBean)
比如现在有一个User对象,它里面有个属性IdCard,也可以直接接收,只需要页面表单的名字和JavaBean属性名字保持一致即可。
3.3.1 定义JavaBean
创建IdCard
public class IdCard {
//身份证号
private String number;
//身份证地址
private String address;
//get..set..
}
修改User
public class User {
private String name;
private Integer age;
//引用IdCard作为子属性
private IdCard idCard;
//get.. set..
}
修改addUser方法
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收引用JavaBean
* 注意:页面填充表单的时候,name的值仍然要和后台接收的JavaBean的属性名一样。
* 但如果有引用属性填充,就写[引用属性名].[引用属性自身对应属性名]
* 例如:
* 身份证号:<input name="idCard.number" >
* 地址:<input name="idCard.address" >
*
* @return
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("用户" + user.getName() + "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
return "success";
}
}
修改index.jsp的表单
<form action="/user/add">
<div>
名字:<input name="name" >
</div>
<div>
年龄:<input name="age" >
</div>
<div>
身份证号:<input name="idCard.number" >
</div>
<div>
地址:<input name="idCard.address" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
3.4 给JavaBean集合属性数据封装
如果JavaBean有集合属性,JSP页面编写方式:list[0].属性
我们在上面案例基础上添加一个Mobile对象,再在User中添加一个集合属性List mobiles属性。
3.4.1 创建Mobile并修改User
我们保持addUser方法不变,只修改JavaBean和页面即可。
创建Mobile
public class Mobile {
//手机名字
private String mobileName;
//手机价格
private Float price;
//get..set..
}
修改User
public class User {
private String name;
private Integer age;
//引用IdCard作为子属性
private IdCard idCard;
//一个人买了多个手机
private List<Mobile> mobiles;
//get.. set..
}
addUser方法不变,我们可以打印一些信息
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 接收引用JavaBean
* 注意:页面填充表单的时候,name的值仍然要和后台接收的JavaBean的属性名一样。
* 但如果有引用属性填充,就写[引用属性名].[引用属性自身对应属性名]
* 例如:
* 身份证号:<input name="idCard.number" >
* 地址:<input name="idCard.address" >
*
* 接收的JavaBean里如果存在List集合,则页面需要每次用下标来告诉程序是第几个,其他的用法和单个JavaBean用法一样
* 例如:
* 第1个手机名字:<input name="mobiles[0].mobileName" >
* 第1个手机价格:<input name="mobiles[0].price" >
*
* 第2个手机名字:<input name="mobiles[1].mobileName" >
* 第2个手机价格:<input name="mobiles[1].price" >
* @return
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("用户" + user.getName() + "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
for (Mobile mobile : user.getMobiles()) {
System.out.println(mobile.getMobileName()+"花了"+mobile.getPrice());
}
return "success";
}
}
修改index.jsp的表单
<form action="/user/add">
<div>
名字:<input name="name" >
</div>
<div>
年龄:<input name="age" >
</div>
<div>
身份证号:<input name="idCard.number" >
</div>
<div>
地址:<input name="idCard.address" >
</div>
<div>
第1个手机名字:<input name="mobiles[0].mobileName" >
</div>
<div>
第1个手机价格:<input name="mobiles[0].price" >
</div>
<div>
第2个手机名字:<input name="mobiles[1].mobileName" >
</div>
<div>
第2个手机价格:<input name="mobiles[1].price" >
</div>
<div>
<input type="submit" value="提交">
</div>
</form>
3.5 请求参数POST请求中文乱码的解决*****
在web.xml中配置Spring提供的过滤器类
<!-- 配置过滤器,解决中文乱码的问题 -->
<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>
3.6 自定义类型转换器
表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明Spring框架内部会默认进行数据类型转换。但Date类型并不能实现转换,需要我们手动解决。
如果想自定义数据类型转换,可以实现Converter的接口
自定义类型转换器
package com.livejava.util;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConverter implements Converter<String,Date>{
/***
* 将String类型转成Date类型
* @param str
* @return
*/
public Date convert(String str) {
try {
//定义一个时间转换工具对象
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//将字符串转Date并返回
return simpleDateFormat.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<!-- 配置spring开启注解mvc的支持-->
<mvc:annotation-driven conversion-service="conversionService" />
<!--
注册自定义类型转换器
-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<bean class="com.itheima.util.DateConverter" />
</property>
</bean>
3.7 在控制器中使用原生的ServletAPI对象
只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象
第四章:常用的注解
4.1 RequestParam注解
作用:把请求中的指定名称的参数传递给控制器中的形参赋值
属性
value:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值是true,必须提供
代码如下
/**
* 接收请求
* @return
*/
@RequestMapping(path="/hello")
public String sayHello(@RequestParam(value="username",required=false)String name) {
System.out.println("aaaa");
System.out.println(name);
return "success";
}
4.2 RequestBody注解
作用:用于获取请求体的内容(注意:get方法不可以)
属性
required:是否必须有请求体,默认值是true
代码如下
/**
* 接收请求
* @return
*/
@RequestMapping(path="/hello")
public String sayHello(@RequestBody String body) {
System.out.println("aaaa");
System.out.println(body);
return "success";
}
4.3 PathVariable注解
作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
属性
value:指定url中的占位符名称
Restful风格的URL
请求路径一样,可以根据不同的请求方式去执行后台的不同方法
restful风格的URL优点
结构清晰
符合标准
易于理解
扩展方便
4.4 PathVariable案例代码如下
<a href="user/hello/1">入门案例</a>
/**
* 接收请求
* @return
*/
@RequestMapping(path="/hello/{id}")
public String sayHello(@PathVariable(value="id") String id) {
System.out.println(id);
return "success";
}
4.5 RequestHeader注解
作用:获取指定请求头的值
属性
value:请求头的名称
代码如下
@RequestMapping(path="/hello")
public String sayHello(@RequestHeader(value="Accept") String header) {
System.out.println(header);
return "success";
}
4.6 CookieValue注解
作用:用于获取指定cookie的名称的值
属性
value:cookie的名称
代码
@RequestMapping(path="/hello")
public String sayHello(@CookieValue(value="JSESSIONID") String cookieValue) {
System.out.println(cookieValue);
return "success";
}
4.7 ModelAttribute注解
作用
出现在方法上:表示当前方法会在控制器方法执行前先执行。
出现在参数上:获取指定的数据给参数赋值。
应用场景
当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。
4.7.1 修饰的方法有返回值
在上面的案例基础之上,给User中添加一个sex属性,再到UserController中添加一个parameterUser()方法,并创建User再赋值返回,方法上加上注解@ModelAttribute注解。
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 优先执行
* @return
*/
@ModelAttribute
public User parameterUser(){
User user = new User();
user.setSex("男");
return user;
}
/***
* 此时的user已经被上面的parameterUser先执行了修改,已经给sex赋值
*/
@RequestMapping(value = "/add")
public String addUser(User user){
System.out.println("用户" + user.getName() +",性别:"+user.getSex()+","+ "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
for (Mobile mobile : user.getMobiles()) {
System.out.println(mobile.getMobileName()+"花了"+mobile.getPrice());
}
return "success";
}
}
4.7.2 修饰的方法没有返回值
在上面案例基础上,把parameterUser的返回值去掉,增加一个Map来存储数据,存储的key为user,在addUser中使用@ModelAttribute(“user”)User user获取在parameterUser()方法中赋值的数据。程序运行后,我们发现addUser方法的user参数能取到parameterUser方法赋值的数据。
@Controller
@RequestMapping(value = "/user")
public class UserController {
/***
* 优先执行
* @return
*/
@ModelAttribute
public void parameterUser(Map<String,User> userMap){
User user = new User();
user.setSex("男");
userMap.put("user",user);
}
/***
* 此时的user已经被上面的parameterUser先执行了修改,已经给sex赋值
*/
@RequestMapping(value = "/add")
public String addUser(@ModelAttribute("user")User user){
System.out.println("用户" + user.getName() +",性别:"+user.getSex()+","+ "今年" + user.getAge() + "岁,住在" + user.getIdCard().getAddress() + ",身份证号是" + user.getIdCard().getNumber());
for (Mobile mobile : user.getMobiles()) {
System.out.println(mobile.getMobileName()+"花了"+mobile.getPrice());
}
return "success";
}
}
4.8 Model使用
SpringMVC会把Model(模型信息)中的的数据放入到request域对象中,页面可以通过EL表达式来取request域中的数据。我们可以先写一个案例,在后台使用Model的addAttribute方法,页面使用EL表达式取数据。
创建 ModelController
@Controller
@RequestMapping(value = "/model")
public class ModelController {
/***
* Model的使用
* @param model
* @return
*/
@RequestMapping(value = "/add")
public String add(Model model){
model.addAttribute("msg","张三");
return "success";
}
}
success.jsp页面从request域中取数据
${msg}
${requestScope}
4.9 SessionAttributes注解
作用:用于多次执行控制器方法间的参数共享
属性
value:指定存入属性的名称
代码如下
@Controller
@RequestMapping(path="/user")
@SessionAttributes(value= {"username","password","age"},types= {String.class,Integer.class}) // 把数据存入到session域对象中
public class HelloController {
/**
* 向session中存入值
* @return
*/
@RequestMapping(path="/save")
public String save(Model model) {
System.out.println("向session域中保存数据");
model.addAttribute("username", "root");
model.addAttribute("password", "123");
model.addAttribute("age", 20);
return "success";
}
/**
* 从session中获取值
* @return
*/
@RequestMapping(path="/find")
public String find(ModelMap modelMap) {
String username = (String) modelMap.get("username");
String password = (String) modelMap.get("password");
Integer age = (Integer) modelMap.get("age");
System.out.println(username + " : "+password +" : "+age);
return "success";
}
/**
* 清除值
* @return
*/
@RequestMapping(path="/delete")
public String delete(SessionStatus status) {
status.setComplete();
return "success";
}
}
总结
- SpringMVC的概述
- 入门
- 创建工程,导入坐标
- 在web.xml中配置前端控制器(启动服务器,加载springmvc.xml配置文件)
- 编写springmvc.xml配置文件
- 编写index.jsp的页面,发送请求
- 编写Controller类,编写方法(@RequestMapping(path="/hello")),处理请求
- 编写配置文件(开启注解扫描),配置视图解析器
- 执行的流程
- @RequestMapping注解
- path
- value
- method
- …
- 参数绑定
- 参数绑定很重要
- 解决中文乱码,配置过滤器(类似配置核心控制器)
- 自定义数据类型转换器(实现converter接口)