
服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
三层架构:
表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
业务层:处理公司具体的业务逻辑的
持久层:用来操作数据库的
MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
Model:数据模型,JavaBean的类,用来进行数据封装。
View:指JSP、HTML用来展示数据给用户
Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等(Hibernate Validator)
SpringMVC
SpringMVC是一种基于Java的、实现MVC设计模型的、请求驱动类型的(基于HTTP协议)、轻量级Web框架,属于 Spring FrameWork 的后续产品。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
SpringMVC已经成为目前最主流的 MVC 框架之一,并且随着Spring3.0的发布,全面超越 Struts2,成为最优秀的 MVC(web层的) 框架。
它通过一套注解,让一个简单的Java类成为处理请求的控制器(Controller),而无须实现任何接口(跟Servlet对比)。同时它还支持RESTful编程风格的请求。
SpringMVC的优点
清晰的角色划分:
前端控制器(DispatcherServlet)
请求到处理器映射(HandlerMapping) :负责找controller类
处理器适配器(HandlerAdapter) : 负责调用controller类,得到结果,封装结果
视图解析器(ViewResolver) : 负责解析view
处理器或页面控制器(Controller)
验证器( Validator)
命令对象(Command 请求参数绑定到的对象就叫命令对象)
表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。
由于命令对象就是一个 POJO, 无需继承框架特定 API,可以使用命令对象直接作为业务对象。
和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。
可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。
可定制性, HandlerMapping、 ViewResolver 等能够非常简单的定制。
功能强大的数据验证、格式化、绑定机制。
利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
强大的 JSP 标签库,使 JSP 编写更容易。
有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配
置支持等等。
小结
Spring MVC 是Spring开发的关于Web层的框架
它的作用:接收请求,调用service,响应结果
导入依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.2.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
dependencies>
编写页面
在webapp里创建
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h2>这是首页~h2>
<a href="/sayHi">点我发起请求a>
body>
html>
在webapp里创建
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h2>这是成功的页面~h2>
body>
html>
编写Controller
在com.execise.controller包中创建类Controller01
类上增加@Controller注解,声明成为一个bean
创建sayHi方法,并在方法上增加@RequestMapping注解,声明方法的访问路径
package com.execise.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/*
入门案例
1. 定义类,类上打注解 @Controller
2. 定义方法, 方法上打注解 @RequestMapping
3. 这个controller能处理 /sayHi的请求,但是要想处理请求,首先必须能抓住请求。
4. 所以要在web.xml配置servlet :: DispatcherServlet
*/
@Controller
public class Controller01 {
@RequestMapping("/sayHi")
public String sayHi(){
System.out.println("调用了Controller01的sayHi方法~!~");
return "/success.jsp";
}
}
编写配置文件
在
resources中创建springmvc的配置文件springmvc.xml, 这个名字可以随意,也可以写成前几天的applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.execise"/>
beans>
修改Web.xml
在
webapp/WEB-INF/web.xml中配置前端控制器DispatcherServlet
<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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispacherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
运行测试
启动项目,点击首页的超链接访问Controller
sayHi方法被访问到,并且页面跳转到了success.jsp
小结
创建web工程,导入依赖:spring-webmvc, servlet-api, jsp-api
编写Controller
提供springmvc.xml:开启组件扫描
修改web.xml:配置前端控制器DispatcherServlet
求响应流程

三大组件
HandlerMapping处理器映射器
Controller及拦截器(类似过滤器)链HandlerAdapter处理器适配器
Controller 执行Controller,得到模型和视图ViewResolver视图解析器
详细执行流程
客户端发请求到DispatcherServlet
DispatcherServlet
通过HandlerMapping处理器映射器,根据请求路径,查找匹配的Controller及拦截器
得到要执行的Controller和拦截器(执行链)
DispatcherServlet
通过HandlerAdapter处理器适配器,调用控制器Controller
得到ModelAndView对象(其中View指视图路径,Model要响应的数据对象)
DispatcherServlet
通过ViewResolver解析视图,得到真实视图(视图路径对应的页面)
渲染视图(把Model里的数据填充到View里 , 替换页面上的 EL表达式为真实的数据)
把最终渲染的结果,响应到客户端
springmvc.xml的配置
跟之前的 applicationContext.xml 是一样的。只是换了个名字而已。springmvc和spring可以共用同一个配置文件!
基本配置示例
<context:component-scan base-package="com.execise.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-Handler/>
mvc的注解驱动
<mvc:annotation-driven/>
配置说明
在SpringMVC中,处理器映射器,处理器适配器,视图解析器 被称为三大组件
在springmvc.xml中配置标签,可以加载SpringMVC的组件
如果没有此项配置,SpringMVC也会自动加载组件,所以现在的使用中不配置这一项也可以
但是在之后,这个标签还有其它作用,所以要配置上
视图解析器设置
视图路径的配置方式
SpringMVC把页面称为视图,例如JSP|HTML页面就是视图。在Controller的方法中,返回的字符串就是跳转的视图(页面)路径
视图的路径有两种写法:
物理视图:/success.jsp | success.jsp ,即:视图的真实路径(完整路径)
直观,但是写起来麻烦
例如: 如果有一个页面page.jsp 位于 /webapp/a/b/c/page.jsp , 那么物理视图返回: “/a/b/c/page.jsp”;
逻辑视图:success,需要配合视图解析器,才能得到真实路径
物理视图的配置方式
在Controller的方法中,直接返回物理视图路径。
不需要配置视图解析器
@Controller
public class Controller01 {
//物理视图跳转: 要写完整的路径地址
@RequestMapping("/sayHi02")
public String sayHi02(){
System.out.println("调用了Controller01的sayHi02方法~!~");
return "/a/b/c/success.jsp";
}
}
逻辑视图的配置方式
在springmvc.xml中增加以下内容:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
在Controller中修改代码,简化方法返回值
@Controller
public class Controller01 {
//逻辑视图跳转:只要写页面的名字即可,需要搭配视图解析器来使用
@RequestMapping("/sayHi03")
public String sayHi03(){
System.out.println("调用了Controller01的sayHi03方法~!~");
return "success";
}
}
由视图解析器,帮我们把prefix + "success" + suffix,拼接成物理视图/success.jsp
处理静态资源
请求静态资源的说明
使用SpringMVC时,客户端访问静态资源时,会访问不到 , 会得到404
Tomcat本身具备处理静态资源的能力,但是我们配置的DispatcherServlet把Tomcat的默认处理器覆盖掉了;而DispatcherServlet没有处理静态资源的能力,所以:访问不到静态资源
Tomcat里面有一个Servlet,可以处理静态资源: DefaultServlet,它的映射路径是 /
我们使用SpringMVC的时候,在web.xml中,配置DispatcherServlet,配置的地址路径也是 /

两种配置方式解决问题
指定静态资源的位置
针对客户端对静态资源的请求,指定资源所在的位置。让SpringMVC直接去指定目录下加载
示例:
<mvc:resources mapping="/html/**" location="/html/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
由Tomcat处理静态资源(推荐)
如果客户端请求了静态资源,DispatcherServlet处理不了,就交给Tomcat的原生Servlet来处理
示例:
<mvc:default-servlet-handler/>
小结
配置视图解析器
Controller里的方法返回值要写逻辑视图
再配置视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
如果有静态资源要访问,把静态资源仍然交给Tomcat处理
<mvc:default-servlet-handler/>
开启mvc的注解驱动:会注册一些组件,提供一些功能
<mvc:annotation-driven/>
开启组件扫描
<context:component-scan base-pcakge="com.execise.controller"/>
web.xml的配置
<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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
配置说明
load-on-startup:配置Servlet的创建时机,值是整数
如果是正整数,表示服务器一启动就要创建Servlet对象。数值越小,创建的越早
如果是0或者负数,表示默认的:第一次访问时,创建Servlet对象
DispatcherServlet是SpringMVC一切功能的基础和核心,要求:服务器启动时就创建,并且要最早创建,所以设置值为1
init-param:配置Servlet的初始化参数
contextConfigLocation:配置springmvc.xml的路径,让DispatcherServlet被创建时,加载配置文件,初始化Spring容器
url-pattern:配置Servlet的路径,通常配置为/
拓展:
DispatcherServlet配置成/和/*的区别:
xxx.jsp时如果DispatcherServlet配置的是/*,不能正常访问JSP
/*是目录匹配,优先级高于扩展名匹配(Tomcat里有JspServlet,路径是*.jsp)
必定是由DispatcherServlet来处理JSP,但是DispatcherServlet不具备查找和处理jsp的能力,会报错
如果DispatcherServlet配置的是/,可以正常访问JSP
/是缺省匹配,优先级低于扩展名匹配(Tomcat里有JspServlet,路径是*.jsp)
必定是由Tomcat来处理JSP,Tomcat本身具备查找和处理JSP的能力,可以正常访问JSP
完全路径匹配 > 目录匹配 > 扩展名匹配 > 缺省匹配
/aa > /* > *.do > /
controller的配置
package com.execise.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.Servlet;
/*
@Controller :
1. 表示这个类是一个控制器,可以处理请求。
2. spring会把这个类管理起来, 创建这个类的对象。
RequestMapping :
1. 表示方法的映射地址,当什么请求来的时候,会执行这个方法。
2. 属性:
value|path : 用来设置映射路径
method : 用来设置请求方式,表示什么样的请求方式,才能执行这个方法。【默认是都支持!】
RequestMethod.GET : 允许get请求到这里来
RequestMethod.POST : 允许post请求到这里来
如果设置了post,页面还是用get请求过来,那么会报错:
Request method 'GET' not supported
params : 用来要求请求一定要携带指定名称的参数
params="username"`:必须提交了 名称为username的表单参数,才可以访问
params="username=tom"`:必须提交了 名称为username、值为tom的表单参数,才可以访问
params="username!=tom"`:提交了表单参数 名称为username、值不是tom, 才可以访问
3. 这个注解可以打在方法身上,也可以打在类身上!
3.1 在类身上写@RequestMapping,访问方法时,需要加上类上面的映射路径
3.2 这样子做的好处主要是为了和其他的模块进行区分。有前缀的划分。
*/
@Controller
@RequestMapping("/user")
public class Controller01 {
@RequestMapping(value = "/sayHi04", method = RequestMethod.GET , params = "username")
public String sayHi04(){
System.out.println("调用了Controller01的sayHi04方法~!~");
return "success";
}
}
配置说明
@RequestMapping注解 , 通常用在Controller里,用于设置访问路径
注解语法
@RequestMapping(
value="访问路径",
method=请求方式,
params="请求参数"
)
常用属性:
value/path:访问路径,即:什么路径能够访问到这个方法
method:请求方式,即:什么请求方式能够访问这个方法。从枚举RequestMethod中取值
RequestMethod.POST:必须是POST方式,才可以访问到
RequestMethod.GET:必须是GET方式,才可以访问到
params:请求参数,即:请求携带了什么样的参数能够访问这个方法(了解)
params="username":必须提交了 名称为username的表单参数,才可以访问
params="username=tom":必须提交了 名称为username、值为tom的表单参数,才可以访问
params="username!=tom":提交了表单参数 名称为username、值不是tom, 才可以访问
如果注解用在Controller类上
表示设置访问路径的一级目录,要和方法上的路径组装成访问路径。用于模块化管理,例如:
类上有注解@RequestMapping("/user")
类里方法上有注解@RequestMapping("/save")
那么方法的访问路径是:/user/save
绑定机制
表单提交的数据都是key=value格式的(username=zs&password=123), SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的(要求:提交表单的name和方法的参数的名称是相同的)
<form action="">
用户名:<input type="text" name="username"/>
密码: <input type= "password" name="password"/>
<input type="submit"/>
form>
public String register(String username , String password){
}
//======================================================
class User{
private String username;
private String password;
}
public String register02(User user){
}
支持的数据类型
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map集合等)
使用要求
如果是基本类型或者 String 类型: 要求我们的参数名称必须和controller中方法的形参名称保持一致。 (严格区分大小写) .
如果是 对象 类型,或者它的关联对象: 要求表单中参数名称和对象类的属性名称保持一致
如果是集合类型,有两种方式:
第一种:要求集合类型的请求参数必须在对象类 中。在表单中请求参数名称要和 对象类中集合属性名称相同。给 List 集合中的元素赋值, 使用下标【】。给 Map 集合中的元素赋值, 使用键值对。
第二种:接收的请求参数是 json 格式数据。需要借助一个注解实现 @RequestBody
小结
SpringMVC的参数绑定过程是把表单提交的请求参数,作为controller里面方法的参数进行绑定的。
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map集合等)
基本类型和String
说明
客户端提交的表单参数名称, 和Controller里方法参数名称相同
SpringMVC会自动绑定同名参数,并自动转换类型
页面
index.jsp
<h2>提交简单的参数:h2>
<form action="/requestSimpleParam" method="post">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="text" name="password"/><br/>
年 龄:<input type="text" name="age"/><br/>
<input type="submit"/>
form>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<h2>这是成功的页面~!~h2>
body>
html>
controller
package com.execise.controller;
import com.execise.bean.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取简单的参数:
要求:
1. 方法的参数名字必须和页面的form表单中的name属性的值 一样!
用户名:
*/
@RequestMapping("/requestSimpleParam")
public String requestSimpleParam(String username, String password , int age){
System.out.println("username = " + username);
System.out.println("password = " + password);
System.out.println("age = " + age);
return "success";
}
}
对象类型
SpringMVC会帮我们自动把表单参数,封装成对象,但是要求:
客户端提交的表单参数名称,必须和JavaBean的属性名一样!
Pojo(User)
package com.execise.bean;
import lombok.Data;
@Data
public class User {
private String username;
private String password;
private int age;
}
前端页面
<h2>提交对象的参数:h2>
<form action="/requestObjectParam">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="text" name="password"/><br/>
年 龄:<input type="text" name="age"/><br/>
<input type="submit"/>
form>
controller
package com.execise.controller;
import com.execise.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取对象参数:
要求:
1. 页面提交上来的form表单的name属性值必须和JavaBean的属性名字一样!
用户名:
public class User {
private String username;
}
*/
@RequestMapping("/requestObjectParam")
public String requestObjectParam(User user){
System.out.println("user = " + user);
return "success";
}
}
嵌套POJO类型参数
POJO对象中包含POJO对象
public class User {
private String name;
private int age;
private Address address;
//同学们自己添加getter/setter/toString()方法
}
public class Address {
private String province;
private String city;
}
嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数

//嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "{'module':'pojo contain pojo param'}";
}
注意事项:请求参数key的名称要和POJO中属性的名称一致,否则无法封装。
数组
注:只能2接前端多个参数(一个名字对应多个值),不能用List集合。确实需要List集合接收时,使用包装user.list
页面
<h2>提交数组的参数:h2>
<form action="/requestArrayParam">
请选择您的爱好:<br/>
<input type="checkbox" name="hobby" value="smoke"/>抽烟
<input type="checkbox" name="hobby" value="drink"/>喝酒
<input type="checkbox" name="hobby" value="firehead"/>烫头<br/>
<input type="submit"/>
form>
Controller01
package com.execise.controller;
import com.execise.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取数组参数:
要求:
1. 页面上的表单项,name属性值必须一样!
2. 方法参数的名字必须和name属性的值一样!
*/
@RequestMapping("/requestArrayParam")
public String requestArrayParam(String [] hobby){
System.out.println("hobby=" + Arrays.toString(hobby));
return "success";
}
}
集合类型参数
集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系

//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
日期类型参数传递
代码演示
日期类型数据基于系统不同格式也不尽相同
2088-08-18
2088/08/18
08/18/2088
接收形参时,根据不同的日期格式设置不同的接收方式

//日期参数 http://localhost:80/dataParam?date=2088/08/08&date1=2088-08-18&date2=2088/08/28 8:08:08
//使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
@DateTimeFormat注解介绍
名称:@DateTimeFormat
类型:形参注解
位置:SpringMVC控制器方法形参前面
作用:设定日期时间型数据格式
属性:pattern:指定日期时间格式字符串
json数据参数传递
问题:@EnableWebMvc注解和@ResponseBody注解有什么用?
json数据参数介绍
json普通数组([“”,“”,“”,…])
json对象({key:value,key:value,…})
json对象数组([{key:value,…},{key:value,…}])
传递json普通数组
代码演示
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.6version>
dependency>

//集合参数:json格式
//1.开启json数据格式的自动转换,在springmvc.xml配置文件中配置开启注解驱动
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
@RequestBody注解介绍
名称:@RequestBody
类型:形参注解
位置:SpringMVC控制器方法形参定义前面
作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次
范例:
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
传递json对象
POJO参数:json数据与形参对象属性名相同,定义POJO类型形参即可接收参数

//POJO参数:json格式
//1.开启json数据格式的自动转换,在springmvc.xml配置文件中配置开启注解驱动
//2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
传递json对象数组
POJO集合参数:json数组数据与集合泛型属性名相同,定义List类型形参即可接收参数

//集合参数:json格式
//1.开启json数据格式的自动转换,在springmvc.xml配置文件中配置开启注解驱动
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
@RequestBody与@RequestParam区别
@RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
@RequestBody用于接收json数据【application/json】
应用
后期开发中,发送json格式数据为主,@RequestBody应用较广
如果发送非json格式数据,选用@RequestParam接收请求参数
小结
请求参数类型是简单(基本,String)类型
请求参数类型是pojo对象类型
形参就写pojo对象
pojo的属性必须和请求参数的name一致就可以
提交数组,只能用数组接收,多个参数的name属性名一致,参数要与controller中的参数名一致。
请求参数时json数据类型
添加jackson-databind依赖
springmvc.xml中开启注解驱动
在参数前面加上@RequestBody注解 并且注意对象的属性要和json数据的key一致
请求参数乱码
如果请求参数或者响应中有中文就会乱码。在web阶段,我们通过一个自定义的过滤器实现了统一乱码解决
req.setCharacterEncoding(“utf-8”)
resp.setContentType(“text/html;charset=utf-8”);
现在SpringMVC本身 ,也给我们提供了一个过滤器
CharacterEncodingFilter,用于解决乱码问题 。 只有在post请求才会有中文乱码,如果tomcat > 8.5的版本,那么tomcat已经帮助修复了get请求的中文乱码。如果使用了tomcat7的插件来跑项目, get请求还是会有乱码的!需要配置一下下!
在web.xml里面配置编码过滤器
<filter>
<filter-name>charfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>charfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
如果使用了tomcat7的插件,get请求会出现中文乱码,那么可以这么解决
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.2version>
<configuration>
<port>82port>
<path>/path>
<uriEncoding>utf-8uriEncoding>
configuration>
plugin>
plugins>
build>
自定义类型转换器
默认情况下,SpringMVC已经实现一些数据类型自动转换。 内置转换器全都在:
org.springframework.core.convert.support包下 ,如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。

场景
页面
<h2>提交包含日期的参数:h2>
<form action="/requestDateParam">
用户名:<input type="text" name="username"/><br/>
密 码:<input type="text" name="password"/><br/>
出生日期:<input type="text" name="birthday"/><br/>
<input type="submit"/>
form>
User04
package com.execise.bean;
import lombok.Data;
import java.util.Date;
@Data
public class User04 {
private String username;
private String password;
private Date birthday;
}
Controller01.java
package com.execise.controller;
import com.execise.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@Controller
public class Controller01 {
/*
获取日期格式的数据
*/
@RequestMapping("/requestDateParam")
public String requestDateParam(User04 user04){
System.out.println("user04 = " + user04);
return "success";
}
}
报错了:

自定义类型转换器
步骤:
创建一个类实现Converter 接口
配置类型转换器
实现:
定义一个类,实现 Converter 接口
该接口有两个泛型,S:表示接受的类型, T:表示目标类型(需要转的类型)
package com.execise.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
自定义日期格式转换器
1. 定义类,实现接口Converter
里面有两个泛型: S : 表示的是源数据的类型 , T: 表示的是目标数据的类型
2. 实现方法convert
*/
public class DateConverter implements Converter<String , Date> {
/**
*
* @param source 从页面接收到的数据
* @return 转化出来的日期对象。
*/
public Date convert(String source) {
try {
System.out.println("来到我们的日期转化器了:" + source);
//1. 定义SimpleDateFormat对象
SimpleDateFormat sf =null ;
if(source .contains("-")){
sf = new SimpleDateFormat("yyyy-MM-dd");
}else if(source.contains("/")){
sf = new SimpleDateFormat("yyyy/MM/dd");
}
//2. 转化
return sf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
在springmvc.xml里面配置转换器
spring 配置类型转换器的机制是,将自定义的转换器注册到类型转换服务中去
<mvc:annotation-driven conversion-service="cs"/>
<bean id="cs" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<bean class="com.execise.converter.DateConverter"/>
property>
bean>
返回页面文件名
controller方法返回的字符串会被解析成页面视图(即:页面的地址路径)
返回逻辑视图名称
方法返回的字符串,和视图解析器里的前缀、后缀拼接得到真实路径,再进行跳转
不管是物理视图(完整的写法)还是逻辑视图(简写),默认采用的都是请求转发跳转

返回带前缀的物理视图
请求转发:forward:/success.jsp
重定向:redirect:/success.jsp
注意:如果带有forward或者redirect,那么路径必须是完整的真实路径 , 不受视图解析器影响*
使用示例
package com.execise.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/*
响应视图: 跳转页面
1. springmvc跳转页面的时候,默认是采用请求转发去跳转
2. 跳转的写法:
2.1 逻辑视图
只要写上页面的名字即可
2.2 物理视图
要写完整的页面的路径地址才行。
a. 不带前缀的写法
会受到视图解析器的影响
b. 带前缀的写法
不会受到视图解析器的影响
forward:物理视图路径 表示使用请求转发跳转
redirect:物理视图路径 表示使用重定向跳转
*/
@Controller
public class Controller02 {
//逻辑视图跳转: 只要写上视图的名字即可
@RequestMapping("/page01")
public String page01(){
System.out.println("page01...");
return "success";
}
//物理视图跳转: 写上视图的完整路径
@RequestMapping("/page02")
public String page02(){
System.out.println("page02...");
return "/success.jsp";
}
//物理视图跳转:加上前缀 forward:
// forward: 表示 使用请求转发跳转,并且它不会受到视图解析器的影响
@RequestMapping("/page03")
public String page03(){
System.out.println("page03...");
return "forward:/success.jsp";
}
//物理视图跳转,加上前缀 redirect:
// redirect: 表示使用重定向跳转,并且不会受到视图解析器的影响
@RequestMapping("/page04")
public String page04(){
System.out.println("page04...");
return "redirect:/success.jsp";
}
}
请求转发并传递数据
ModelAndView是SpringMVC提供的组件之一,其中
Model,模型,用于封装数据(Springmvc会把数据放到了request域中)
View,视图,就是页面,用于展示数据
如果我们设置了视图名称,并且封装了数据模型,SpringMVC会:
把Model的数据放到request域对象中,然后请求转发到指定的视图(页面)
我们可以视图页面中获取数据显示出来
使用示例
package com.execise.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/*
跳转页面,并且携带数据到页面上显示!
1. 使用ModelAndView来封装数据和视图
*/
@Controller
public class Controller03 {
//1. 自己new ModelAndView对象
@RequestMapping("/page05")
public ModelAndView page05(){
//1. 创建ModelAndView对象
ModelAndView mv = new ModelAndView();
//2. 装数据: 会把这份数据保存到request作用域里面
mv.addObject("username", "page05");
//3. 装视图 : 会受视图解析器的影响。
mv.setViewName("success");
//4. 返回mv;
return mv ;
}
//在参数里面定义ModelAndView,要求springmvc传递进来对象
@RequestMapping("/page06")
public ModelAndView page06(ModelAndView mv){
//2. 装数据: 会把这份数据保存到request作用域里面
mv.addObject("username", "page06");
//3. 装视图 : 会受视图解析器的影响。
mv.setViewName("success");
//4. 返回mv;
return mv ;
}
//参数传递进来Model对象,封装数据,使用返回值返回视图。
@RequestMapping("/page07")
public String page07(Model model){
//装数据
model.addAttribute("username","page07");
//4. 返回mv;
return "success" ;
}
//========================可以使用以前的request对象或者session对象来存值===============
@RequestMapping("/page08")
public String page08(HttpServletRequest req){
//装数据
req.setAttribute("username", "page08");
//4. 返回mv;
return "success" ;
}
@RequestMapping("/page09")
public String page09(HttpSession session){
//装数据
session.setAttribute("username", "page09");
//4. 返回mv;
return "success" ;
}
//是用重定向的方式跳转页面
@RequestMapping("/page10")
public String page10(HttpSession session){
//装数据
session.setAttribute("username", "page10");
//4. 返回mv;
//return "success" ; //请求转发方式跳转
return "redirect:/success.jsp" ; //重定向方式跳转!
}
}
在index.jsp视图页面中,取出数据显示出来
这是成功的页面 ${username}
小结
返回页面文件名
返回逻辑视图
方法返回的字符串,和视图解析器里的前缀、后缀拼接得到真实路径,再进行跳转
是请求转发跳转
返回带前缀的物理视图 (不受视图解析器的影响)
请求转发:forward:/success.jsp
重定向:redirect:/success.jsp
方法返回ModelAndView
public ModelAndView jump(){
ModelAndView mav = new ModelAndView();
mav.setViewName("视图名称");
mav.addObject("数据名称", "值");
return mav;
}
public ModelAndView jump(ModelAndView mav){
mav.setViewName("视图名称");
mav.addObject("数据名称", "值");
return mav;
}
public String jump(Model model){
model.addAttribute("数据名称", "值");
return "视图名称";
}
直接响应字符串
两种方式
使用Servlet原生的response对象,返回响应数据 response.getWrite().write(“xxxx”);
方法上使用@ResponseBody注解,springmvc就会把方法的返回值当成字符串来看待,不会再识别成页面的地址路径
使用示例
package com.execise.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
返回数据给页面: 字符串 & JSON
*/
@Controller
public class Controller04 {
/*
返回字符串: 使用response对象, 把字符串写出去!
*/
@RequestMapping("/returnStr01")
public void returnStr01(HttpServletResponse resp) throws IOException {
resp.getWriter().write("returnStr01...");
}
/*
返回字符串:
1. 直接在方法的返回值返回字符串
2. 要加上注解 @ResponseBody, springMVC会把返回值看成是字符串,否则会被看成是页面的路径
*/
@ResponseBody
@RequestMapping("/returnStr02")
public String returnStr02(){
return "returnStr02...";
}
}
拓展
如果使用@ResponseBody响应的中文字符串,即使配置了CharacterEncodingFilter,也会有乱码
package com.execise.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
返回数据给页面: 字符串 & JSON
*/
@Controller
public class Controller04 {
//=================返回字符串(包含中文)=========================
/*
使用@ResponseBody 返回字符串的时候,如果返回中文字符串,即使设置了编码过滤器,那么页面看到的仍然是乱码!
解决:
有两种办法解决:
1. 使用标准的写法来设置编码,在springmvc.xml中设置
只要配置了,那么对全局都是有效的!
2. 使用投机取巧的办法!
在requestMapping里面使用produces来设置编码,仅对当前的方法生效!
*/
@ResponseBody
@RequestMapping("/returnStr03")
public String returnStr03(){
return "中文03...";
}
// 在requestMapping里面使用produces来设置编码,仅对当前的方法生效!
@ResponseBody
@RequestMapping(value = "/returnStr04", produces = "text/html;charset=utf-8")
public String returnStr04(){
return "中文04...";
}
}
解决方法:在springmvc.xml里配置如下:
配置SpringMVC的StringHttpMessageConverter进行字符串处理转换,设置采用utf-8字符集
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="utf-8"/>
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8value>
<value>application/json;charset=utf-8value>
list>
property>
bean>
mvc:message-converters>
mvc:annotation-driven>
返回json数据
两种方式介绍
自己把JavaBean对象转换成json格式的字符串,响应给客户端
方法返回JavaBean对象,使用@ResponseBody注解Springmvc帮我们转换成json格式 【推荐】
前提条件
在pom.xml中导入依赖:jackson-databind
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.6version>
dependency>
springmvc.xml中开启mvc注解开关
<mvc:annotation-driven/>
使用示例
package com.execise.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.execise.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/*
返回json字符串
1. 手动把JavaBean和转化成json字符串,然后返回字符串
2. 直接返回javaBean即可
*/
@Controller
public class Controller05 {
// 手动把JavaBean对象转化成Json字符串,返回。
@ResponseBody
@RequestMapping(value = "/returnJson01" , produces = "application/json;charset=utf-8")
public String returnJson01() throws JsonProcessingException {
//1. 构建User
User user = new User("管理员01","xxx");
//2. 把这个对象手动转化成Json字符串
ObjectMapper om = new ObjectMapper();
String json = om.writeValueAsString(user);
return json;
}
/*
1. 直接返回JavaBean,springmvc会把这个JavaBean转化成json字符串返回。
2. 要想使用这种操作,那么必须要在pom.xml里面添加jackson-databind的依赖
*/
@ResponseBody
@RequestMapping("/returnJson02")
public User returnJson02() throws JsonProcessingException {
return new User("管理员02","xxx");
}
}
小结
public void method1(HttpServletResponse response){
//如果响应普通文本数据
//response.setContentType("text/html;charset=utf-8");
//如果响应json格式的字符串
response.setContentType("application/json;charset=utf-8");
response.getWriter().print("xxxx");
}
如果要bean对象 , 使用注解@ResponseBody
如果返回的是json数据,需要添加jackson-databind的依赖!
@RequestMapping("/method2")
@ResponseBody
public User method2(){
return new User();
}
导入依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.2.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.18version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.6version>
dependency>
dependencies>
定义两个页面
index.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/10
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
这是首页~!
success.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/10
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
这是成功的页面~!
springmvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.execise"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:default-servlet-handler/>
beans>
web.xml
<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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>charfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>charfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
@RequestParam
作用:
可以对浏览器请求做出参数上的要求,要求一定要有指定名字的参数,如果没有,就报错!
可以把请求提交上来的参数赋值给方法的形参。
属性
value: 要求携带的参数名字
required:请求参数中是否必须提供此参数。 默认值: true。表示必须提供,如果不提供将报错。
defaultValue:默认值
使用示例
Controller01.java
package com.execise.controller;
import com.execise.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestParam:
作用: 要求客户端来访问的时候,一定要携带指定名称的参数,否则报错!
步骤:
1. 在方法参数的前面打注解 @RequestParam
属性:
name|value : 用来指定携带的参数名称,如果不指定,那么就以参数名为参考标准。
required: 表示是否一定要携带参数,默认值是true,
defaultValue: 默认值
*/
@RequestMapping("/requestParam")
public String requestParam(@RequestParam(value="abc" , required = false , defaultValue = "张三") String username , @RequestParam String password){
System.out.println("username = " + username);
System.out.println("password = " + password);
return "success";
}
}
@RequestParam 只能用于接收 url 的传参 ?name=xxx, form表单的提交。
无法接收提交的json数据(contentType=application/json)
@RequestBody
作用
用于获取请求体内容。 直接使用得到是 key=value&key=value…结构的字符串。【不常用】
把获得json类型的数据转成JavaBean对象(后面再讲)【推荐】
注意: get 请求方式不适用
属性
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false, get 请求得到是 null。
@RequestBody 不能使用get请求, 在Controller的方法参数里,@RequestBody它只能出现一次!
匹配json数据的获取,例如:request.getInputStream()
使用实例
index.jsp 页面 追加以下内容
<h2>使用@RequestBody获取请求体:h2>
<form action="/requestBody01" method="post">
用户名: <input type="text" name="username"/><br/>
密码: <input type="text" name="password"/><br/>
<input type="submit">
form>
Controller01.java
package com.execise.controller;
import com.execise.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestBody
作用:
1. 可以获取表单提交上来的请求体,只有post请求才有请求体,get请求是没有请求体【不常用】
拿到的是一个字符串: username=admin&password=xxx;
2. 可以接收页面提交上来的json数据,封装到JavaBe里面【常用】
步骤:
1. 方法参数的前面打上注解 @RequestBody,springmvc就会把请求体赋值给方法的参数。
*/
@RequestMapping("/requestBody01")
public String requestBody01(@RequestBody String body) throws UnsupportedEncodingException {
System.out.println("body = " + body);
}
/*
页面提交中文的时候,默认情况下,浏览器会对内容进行编码,使用URLEncoder.encode("张三","utf-8");
6张三7 ----URLEncoder.encode("张三","utf-8")-----6%E5%BC%A0%E4%B8%897
如果我们希望看到正常的张三:
1. 必须要设置过滤器,真正的解决中文乱码的问题。
2. 对这份数据解码即可:
6%E5%BC%A0%E4%B8%897 ----------URLDecoder.decode("6%E5%BC%A0%E4%B8%897", utf-8);
*/
String data = URLDecoder.decode(body, "utf-8");
System.out.println("data = " + data);
return "success";
}
}
接收json数据
客户端发Ajax请求,提交json格式的数据
服务端接收json格式的数据,直接封装成User对象
前提条件
pom.xml中添加jackson的依赖:
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.6version>
dependency>
springmvc.xml中,增加配置静态资源的处理
因为发请求,需要ajax的支持。
<mvc:default-servlet-handler/>
需求实现
index.jsp 添加以下内容
使用@RequestBody来获取json数据
Controller01
package com.execise.controller;
import com.execise.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestBody:
接收页面提交上来的json数据,封装到JavaBean对象身上。
步骤:
1. 前端页面必须提交的是一份json数据
2. 添加进来jackson-databind的依赖
如果不加依赖,会报错: 415 Unsupported Media Type
3. 定义一个JavaBean,属性名字不能乱写,必须和json里面的KEY一样。
4. 在Controller方法参数的前面加上注解@RequestBody
如果不打注解,那么得到都是null.
*/
@RequestMapping("/requestBody02")
public String requestBody02(@RequestBody User user ) {
System.out.println("user = " + user);
return "success";
}
}
@PathVariable
作用:
用于截取请求地址(url)里面的某些部分的数据。这个需要配合RestFul风格来说明
以前删除用户: localhost:82/deleteUser?id=3restFul : localhost:82/delete/3
属性:
value: 用于指定 url 中占位符名称。
required:是否必须提供占位符。
场景:获取路径中的参数,与restful编程风格一起,通常微服架构中使用
使用实例
index.jsp 页面添加以下内容
<h2>使用@PathVariable来获取地址中的参数h2>
<a href="/delete/1">点我发请求a>
<a href="/delete02/30/40">点我发请求2a>
package com.execise.controller;
import com.execise.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
现在以 按照id来删除用户举例:
以前的写法: localhost:82/delete?id=1
restFul: localhost:82/delete/1
@PathVariable:
作用: 用来截取地址栏中的参数,赋值给方法的形参
步骤:
1. 在映射地址里面使用 {占位符名字} 来占位,表示匹配这个位置的数据
2. 在方法参数的前面加上注解 @PathVariable("占位的名字")
属性:
name | value : 用来指定|设置 占位符的名称。
如果name和value不写,只有一种情况可以不写,就是占位符的名字和方法的参数名字一样!
*/
@RequestMapping("/delete/{id}")
public String pathVariable(@PathVariable(value="id") int id) {
System.out.println("id = " + id);
return "success";
}
@RequestMapping("/delete02/{id}/{id2}")
public String pathVariable02(@PathVariable int id , @PathVariable int id2) {
System.out.println("id = " + id);
System.out.println("id2 = " + id2);
return "success";
}
}
@RequestHeader
作用:
属性:
value:提供消息头名称
required:是否必须有此消息头 , 默认值是true
从请求头中获取参数,鉴权(token 畅购open auth 2.0 jwt token) Authorization
使用实例
index.jsp 页面 添加以下内容
<h2>使用@ReqeustHeader来获取请求头的数据h2>
<a href="/requestHeader">点我发请求a>
Controller01.java
package com.execise.controller;
import com.execise.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@RequestHeader:
作用: 用来获取指定名称的请求头数据,赋值给方法的参数
*/
@RequestMapping("/requestHeader")
public String requestHeader(@RequestHeader("User-Agent") String data) {
System.out.println("data = " + data);
return "success";
}
}
@CookieValue
作用:
属性:
value:指定 cookie 的名称。
required:是否必须有此 cookie, 默认值是:true
使用实例
index.jsp 页面添加以下内容
<h2>使用@CookieValue来获取Cookie的值h2>
<a href="/cookieValue">点我发请求a>
Controller01.java
package com.execise.controller;
import com.execise.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/*
常用的注解:
*/
@Controller
public class Controller01 {
/*
@CookieValue
作用: 用来获取指定名称的cookie的值,赋值给方法的形参。
属性:
name&value : 指定cookie的名字!
JESSIONID:
1. 这是session作用域的id的名称,它会存放到cookie里面去。
2. 当我们打开首页的时候,访问的是index.jsp ----背后会被翻译成========> Servlet
3. 在这个翻译成的servlet里面,它会创建session对象,并且把session的地址存放到cookie里面去。
存放的cookie的KEY 叫做: JSESSIONID.
*/
@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String data) {
System.out.println("data = " + data);
return "success";
}
}
小结
这几个注解都使用作用在方法的参数上,不是写在方法上。他们或多或少都是对客户端提交的数据有这样或者那样的要求
@RequestParam : 要求客户端必须要携带指定的参数。
@RequestBody: 要求必须有请求体,一般它是作用于 页面提交上来的json数据,转化成 javabean对象
@PathVariable : 路径变量,配合RestFul风格使用,用于截取地址里面的数据
@RequestHeader: 用来获取的指定的请求头数据,赋值给方法形参
@CookieValue: 用来获取的cookie数据,赋值给方法的形参。