SpringMVC
第一章-SpringMVC入门
补充:浏览器地址中的绝对路径
/ ,代表的就是端口后面,哪怕你在配置文件中配置了项目的映射名,也是端口后面,不是映射名后面,它会直接忽视项目的映射名,只代表端口后边。
知识点-概述
1. 目标
2. 路径
- 三层架构
- SpringMVC介绍
3. 详解
3.1 三层架构
服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
-
三层架构 ? 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型 ? 业务层:处理公司具体的业务逻辑的 ? 持久层:用来操作数据库的 -
MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。 ? Model:数据模型,JavaBean的类,用来进行数据封装。 ? View:指JSP、HTML用来展示数据给用户 ? Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等(Hibernate Validator)
3.2 SpringMVC
3.2.1 概述
- SpringMVC是一种基于Java的、实现MVC设计模型的、请求驱动类型的(基于HTTP协议)、轻量级Web框架,属于 Spring FrameWork 的后续产品。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
- SpringMVC已经成为目前最主流的 MVC 框架之一,并且随着Spring3.0的发布,全面超越 Struts2,成为最优秀的 MVC(web层的) 框架。
- 它通过一套注解,让一个简单的Java类成为处理请求的控制器(Controller),而无须实现任何接口(跟Servlet对比)。同时它还支持RESTful编程风格的请求。
3.2.2 SpringMVC的优点
1.清晰的角色划分: 前端控制器(DispatcherServlet) 请求到处理器映射(HandlerMapping) :负责找controller类 处理器适配器(HandlerAdapter) : 负责调用controller类,得到结果,封装结果 视图解析器(ViewResolver) : 负责解析view 处理器或页面控制器(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风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配 置支持等等。
4. 小结
- Spring MVC 是Spring开发的关于Web层的框架
- 它的作用:接收请求,调用service,响应结果
案例-快速入门【重点】
1.需求
2. 分析
- 创建maven工程,导入依赖
- 创建Controller, 处理的请求
- 创建一个index.jsp页面, success.jsp
- 配置springmvc.xml
- 配置web.xml 启动时加载springmvc.xml 【配置DispatcherServlet】
3. 实现
3.1 导入依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
3.2 编写页面
在webapp里创建index.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/9
Time: 9:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>这是首页~</h2>
<a href="/sayHi">点我发起请求</a>
</body>
</html>
在webapp里创建success.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/9
Time: 9:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>这是成功的页面~</h2>
</body>
</html>
3.3 编写Controller
- 在
com.mingye.controller 包中创建类Controller01 - 类上增加
@Controller 注解,声明成为一个bean - 创建
sayHi方法 ,并在方法上增加@RequestMapping 注解,声明方法的访问路径
@Controller
public class Controller01 {
@RequestMapping(value = "/sayHi03", params ={"name=admin" , "password=123"}, method ={RequestMethod.POST , RequestMethod.GET} )
public String sayHi03(){
System.out.println("hi~03!~! springmvc...");
return "success";
}
@RequestMapping("/sayHi")
public String sayHi(){
System.out.println("hi~!~! springmvc...");
return "/success.jsp";
}
@RequestMapping("/sayHi02")
public String sayHi02(){
System.out.println("hi~02!~! springmvc...");
return "success";
}
}
3.4 编写配置文件
在resources 中创建springmvc的配置文件springmvc.xml , 这个名字可以随意,也可以写成前几天的 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.mingye"/>
</beans>
3.5 修改Web.xml
在webapp/WEB-INF/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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispacher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.6 运行测试
- 启动项目,点击首页的超链接访问Controller
sayHi 方法被访问到,并且页面跳转到了success.jsp
4. 小结
- 创建web工程,导入依赖:
spring-webmvc, servlet-api, jsp-api - 编写Controller
- 提供springmvc.xml:开启组件扫描
- 修改web.xml:配置前端控制器DispatcherServlet
知识点-配置详解
1. 目标
2. 路径
- 原理分析
- springmvc.xml的配置
- web.xml的配置
- controller的配置
3. 讲解
3.1. 原理分析
3.1.1 请求响应流程
代码运行流程
3.1.2 三大组件
HandlerMapping 处理器映射器
- 作用:根据客户端请求的资源路径,查找匹配的
Controller 及拦截器(类似过滤器)链 HandlerAdapter 处理器适配器
- 作用:用于适配调用不同的
Controller 执行Controller,得到模型和视图 ViewResolver 视图解析器
- 作用:用于解析视图,根据视图路径找到真实视图(页面)
3.1.3 详细执行流程
- 客户端发请求到
DispatcherServlet DispatcherServlet
- 通过
HandlerMapping 处理器映射器,根据请求路径,查找匹配的Controller 及拦截器 - 得到要执行的
Controller 和拦截器(执行链) DispatcherServlet
- 通过
HandlerAdapter 处理器适配器,调用控制器Controller - 得到
ModelAndView 对象(其中View指视图路径,Model要响应的数据对象) DispatcherServlet
- 通过
ViewResolver 解析视图,得到真实视图(视图路径对应的页面) - 渲染视图(把Model里的数据填充到View里 , 替换页面上的 EL表达式为真实的数据)
- 把最终渲染的结果,响应到客户端
3.2. springmvc.xml的配置
跟前几天的 applicationContext.xml 是一样的。只是换了个名字而已。springmvc和spring可以共用同一个配置文件!
3.2.1 基本配置示例
<context:component-scan base-package="com.mingye.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/>
3.2.2 mvc的注解驱动
配置语法
<mvc:annotation-driven/>
配置说明
- 在SpringMVC中,处理器映射器,处理器适配器,视图解析器 被称为三大组件
- 在springmvc.xml中配置
<mvc:annotation-driven/> 标签,可以加载SpringMVC的组件
- 如果没有此项配置,SpringMVC也会自动加载组件,所以快速入门中,不配置这一项也可以
- 但是后边课程中,这个标签还有其它作用,所以要配置上
3.2.3 视图解析器设置
1) 视图路径的配置方式
- SpringMVC把页面称为视图,例如JSP|HTML页面就是视图。在
Controller 的方法中,返回的字符串就是跳转的视图(页面)路径 - 视图的路径有两种写法:
- 物理视图:
/success.jsp | success.jsp ,即:视图的真实路径(完整路径)
- 直观,但是写起来麻烦
- 例如: 如果有一个页面page.jsp 位于 /webapp/a/b/c/page.jsp , 那么物理视图返回: “/a/b/c/page.jsp”;
- 逻辑视图:
success ,需要配合视图解析器,才能得到真实路径
- 不直观,但是写起来简单
- 例如: 如果有一个页面page.jsp 位于 /webapp/a/b/c/page.jsp , 那么逻辑视图返回: “page”
2) 物理视图的配置方式
- 在
Controller 的方法中,直接返回物理视图路径。 - 不需要配置视图解析器
@Controller
public class Controller01 {
@RequestMapping("/sayHi02")
public String sayHi02(){
System.out.println("调用了Controller01的sayHi02方法~!~");
return "/a/b/c/success.jsp";
}
}
3) 逻辑视图的配置方式
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
@Controller
public class Controller01 {
@RequestMapping("/sayHi03")
public String sayHi03(){
System.out.println("调用了Controller01的sayHi03方法~!~");
return "success";
}
}
- 由视图解析器,帮我们把
prefix + "success" + suffix ,拼接成物理视图/success.jsp
3.2.4 处理静态资源
2.4.1 请求静态资源的说明
-
使用SpringMVC时,客户端访问静态资源时,会访问不到 , 会得到404 -
Tomcat本身具备处理静态资源的能力,但是我们配置的DispatcherServlet 把Tomcat的默认处理器覆盖掉了;而DispatcherServlet 没有处理静态资源的能力,所以:访问不到静态资源 Tomcat里面有一个Servlet,可以处理静态资源: DefaultServlet,它的映射路径是 / 我们使用SpringMVC的时候,在web.xml中,配置DispatcherServlet,配置的地址路径也是 /
2.4.2 两种配置方式解决问题
方案一:指定静态资源的位置
- 针对客户端对静态资源的请求,指定资源所在的位置。让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.mingye.controller"/>
3.3. web.xml的配置
3.3.1 配置示例
<?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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.3.2 配置说明
load-on-startup :配置Servlet的创建时机,值是整数
- 如果是正整数,表示服务器一启动就要创建Servlet对象。数值越小,创建的越早
- 如果是0或者负数,表示默认的:第一次访问时,创建Servlet对象
DispatcherServlet 是SpringMVC一切功能的基础和核心,要求:服务器启动时就创建,并且要最早创建,所以设置值为1 init-param :配置Servlet的初始化参数
contextConfigLocation :配置springmvc.xml的路径,让DispatcherServlet被创建时,加载配置文件,初始化Spring容器 url-pattern :配置Servlet的路径,通常配置为/
拓展:DispatcherServlet 配置成/ 和/* 的区别:
-
对JSP的处理不同。当客户端请求了xxx.jsp 时 -
如果DispatcherServlet 配置的是/* ,不能正常访问JSP
/* 是目录匹配,优先级高于扩展名匹配(Tomcat里有JspServlet ,路径是*.jsp )- 必定是由
DispatcherServlet 来处理JSP,但是DispatcherServlet不具备查找和处理jsp的能力,会报错 -
如果DispatcherServlet 配置的是/ ,可以正常访问JSP
/ 是缺省匹配,优先级低于扩展名匹配(Tomcat里有JspServlet ,路径是*.jsp )- 必定是由Tomcat来处理JSP,Tomcat本身具备查找和处理JSP的能力,可以正常访问JSP
完全路径匹配 > 目录匹配 > 扩展名匹配 > 缺省匹配 /aa > /* > *.do > /
3.4. controller的配置
3.4.1 配置示例
package com.mingye.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
@RequestMapping("/controller01")
public class Controller01 {
@RequestMapping(value = "/sayHi04", method = RequestMethod.GET , params = "username")
public String sayHi04(){
System.out.println("调用了Controller01的sayHi04方法~!~");
return "success";
}
}
3.4.2 配置说明
@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
第二章-获取请求数据【重点】
知识点-请求参数的绑定
1.目标
2.路径
- 绑定机制
- 支持的数据类型
- 使用要求
3.讲解
<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集合等) -
使用要求
4.小结
- 绑定机制
SpringMVC的参数绑定过程是把表单提交的请求参数,作为controller里面方法的参数进行绑定的。
- 支持的数据类型 :
? 基本数据类型和字符串类型
? 实体类型(JavaBean)
? 集合数据类型(List、map集合等)
- 使用要求: 名字需要一样
知识点-获取请求参数
1.目标
2.路径
- 基本类型和String
- 对象类型
- 数组
- 对象包含属性
3.讲解
3.1 基本类型和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>
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/9/29
Time: 11:10
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>这是成功的页面~!~</h2>
</body>
</html>
package com.mingye.controller;
import com.mingye.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 {
@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";
}
}
3.2 对象类型 【重点】
SpringMVC会帮我们自动把表单参数,封装成对象,但是要求:
- 客户端提交的表单参数名称,必须和JavaBean的属性名一样!
package com.mingye.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>
package com.mingye.controller;
import com.mingye.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("/requestObjectParam")
public String requestObjectParam(User user){
System.out.println("user = " + user);
return "success";
}
}
3.3 数组【了解】
注:只能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>
package com.mingye.controller;
import com.mingye.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("/requestArrayParam")
public String requestArrayParam(String [] hobby){
System.out.println("hobby=" + Arrays.toString(hobby));
return "success";
}
}
4.小结
-
请求参数类型是简单(基本,String)类型
-
请求参数类型是pojo对象类型
- 形参就写pojo对象
- pojo的属性必须和请求参数的name一致就可以
-
提交数组,只能用数组接收,多个参数的name属性名一致,参数要与controller中的参数名一致。
知识点-细节处理和特殊情况
1.目标
2.路径
- 请求参数乱码处理
- 自定义类型转换器
- 使用 ServletAPI 对象作为方法参数
3.讲解
3.1 请求参数乱码
如果请求参数或者响应中有中文就会乱码。在web阶段,我们通过一个自定义的过滤器实现了统一乱码解决
req.setCharacterEncoding(“utf-8”)
resp.setContentType(“text/html;charset=utf-8”);
但是在springMVC中,处理post请求时,由于它的运作机制,DispatcherServlet很早就已经把数据(参数)拿出来了,此时的数据是乱码的,这个时候你在方法中设置了编码也没用了,所以只能用过滤器了,因为过滤器会先拦截请求,早于servlet。
现在SpringMVC本身 ,也给我们提供了一个过滤器CharacterEncodingFilter ,用于解决乱码问题 。 只有在post请求才会有中文乱码,如果tomcat > 8.5的版本,那么tomcat已经帮助修复了get请求的中文乱码。
如果使用了tomcat7的插件来跑项目, get请求还是会有乱码的!需要配置一下下!
<filter>
<filter-name>char</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>char</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 如果使用了tomcat7的插件,get请求会出现中文乱码,那么可以这么解决
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>82</port>
<path>/</path>
<uriEncoding>utf-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
3.2 自定义类型转换器
默认情况下,SpringMVC已经实现一些数据类型自动转换。 内置转换器全都在: org.springframework.core.convert.support 包下 ,如遇特殊类型转换要求,需要我们自己编写自定义类型转换器。
)
3.2.1 场景
<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>
package com.mingye.bean;
import lombok.Data;
import java.util.Date;
@Data
public class User04 {
private String username;
private String password;
private Date birthday;
}
package com.mingye.controller;
import com.mingye.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";
}
}
3.2.2 自定义类型转换器
步骤:
- 创建一个类实现Converter 接口
- 配置类型转换器
实现:
package com.mingye.converter;
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> {
public Date convert(String source) {
try {
System.out.println("来到我们的日期转化器了:" + source);
SimpleDateFormat sf =null ;
if(source .contains("-")){
sf = new SimpleDateFormat("yyyy-MM-dd");
}else if(source.contains("/")){
sf = new SimpleDateFormat("yyyy/MM/dd");
}
return sf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
<mvc:annotation-driven conversion-service="cs"/>
<bean id="cs" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<bean class="com.mingye.converter.DateConverter"/>
</property>
</bean>
第三章-常用注解【重点】
知识点-常用的注解
1. 目标
2. 路径
- @RequestParam 【重点】
- @RequestBody 【重点】
- @PathVariable 【重点】
- @RequestHeader【重点】
- @CookieValue【了解】
3. 讲解
3.0 环境准备
3.0.1 导入依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
</dependencies>
3.0.2 定义两个页面
<%--
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" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>这是首页~!</h2>
</body>
</html>
<%--
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" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>这是成功的页面~!</h2>
</body>
</html>
3.0.3 springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.mingye"/>
<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>
3.0.4 web.xml
<?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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>char</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>char</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3.1 @RequestParam【重点】
3.1.1 使用说明
3.1.2 使用示例
package com.mingye.controller;
import com.mingye.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 {
@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)
3.2 @RequestBody【重点】
3.2.1 使用说明
- @RequestBody 不能使用get请求, 在Controller的方法参数里,@RequestBody它只能出现一次!
- 匹配json数据的获取,例如:request.getInputStream()
3.2.2 使用实例
<h2>使用@RequestBody获取请求体:</h2>
<form action="/requestBody01" method="post">
用户名: <input type="text" name="username"/><br/>
密码: <input type="text" name="password"/><br/>
<input type="submit">
</form>
package com.mingye.controller;
import com.mingye.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 {
@RequestMapping("/requestBody01")
public String requestBody01(@RequestBody String body) throws UnsupportedEncodingException {
System.out.println("body = " + body);
}
String data = URLDecoder.decode(body, "utf-8");
System.out.println("data = " + data);
return "success";
}
}
3.2.3 接收json数据
需求描述
- 客户端发Ajax请求,提交json格式的数据
- 服务端接收json格式的数据,直接封装成User对象
前提条件
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
- springmvc.xml中,增加配置静态资源的处理
因为发请求,需要ajax的支持。
<mvc:default-servlet-handler/>
需求实现
<h2>使用@RequestBody来获取json数据</h2><input type="button" οnclick="sendJSON()" value="点我发送JSON数据"/><script src="js/axios-0.18.0.js"></script><script> function sendJSON(){ //1. 定义一份json数据 var data = {"username":"admin" , "password":"123456"}; //2. 使用axios发起异步请求 axios.post("/requestBody02" , data); }</script>
package com.mingye.controller;
import com.mingye.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 {
@RequestMapping("/requestBody02")
public String requestBody02(@RequestBody User user ) {
System.out.println("user = " + user);
return "success";
}
}
3.3 @PathVariable【重点】
3.3.1 使用说明
-
作用: 用于截取请求地址(url)里面的某些部分的数据。这个需要配合RestFul风格来说明 以前删除用户: localhost:82/deleteUser?id=3restFul : localhost:82/delete/3
-
属性: value: 用于指定 url 中占位符名称。 required:是否必须提供占位符。
- 场景:获取路径中的参数,与restful编程风格一起,通常微服架构中使用
3.3.2 使用实例
<h2>使用@PathVariable来获取地址中的参数</h2>
<a href="/delete/1">点我发请求</a>
<a href="/delete02/30/40">点我发请求2</a>
package com.mingye.controller;
import com.mingye.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 {
@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";
}
}
3.4 @RequestHeader【重点】
3.4.1 使用说明
- 作用:
获取指定名字的请求头数据,赋值给方法参数。 - 属性:
value:提供消息头名称 required:是否必须有此消息头 , 默认值是true - 从请求头中获取参数,鉴权(token 畅购open auth 2.0 jwt token) Authorization
3.4.2 使用实例
<h2>使用@ReqeustHeader来获取请求头的数据</h2>
<a href="/requestHeader">点我发请求</a>
package com.mingye.controller;
import com.mingye.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 {
@RequestMapping("/requestHeader")
public String requestHeader(@RequestHeader("User-Agent") String data) {
System.out.println("data = " + data);
return "success";
}
}
3.5 @CookieValue【了解】
3.5.1 使用说明
3.5.2 使用实例
<h2>使用@CookieValue来获取Cookie的值</h2>
<a href="/cookieValue">点我发请求</a>
package com.mingye.controller;
import com.mingye.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 {
@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String data) {
System.out.println("data = " + data);
return "success";
}
}
4. 小结
- 这几个注解都使用作用在方法的参数上,不是写在方法上。他们或多或少都是对客户端提交的数据有这样或者那样的要求
- @RequestParam : 要求客户端必须要携带指定的参数。
- @RequestBody: 要求必须有请求体,一般它是作用于 页面提交上来的json数据,转化成 javabean对象
- @PathVariable : 路径变量,配合RestFul风格使用,用于截取地址里面的数据
- @RequestHeader: 用来获取的指定的请求头数据,赋值给方法形参
- @CookieValue: 用来获取的cookie数据,赋值给方法的形参。
第四章-springMVC-纯注解方式
三个配置类
-
AppConfig
public class AppConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringmvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected Filter[] getServletFilters() {
return new Filter[]{new CharacterEncodingFilter("utf-8")};
}
}
-
SpringConfig 暂时还用不到 -
SpringmvcConfig @EnableWebMvc
@ComponentScan("com.mingye")
@Configuration
public class SpringmvcConfig extends WebMvcConfigurerAdapter {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/");
vr.setSuffix(".jsp");
registry.viewResolver(vr);
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
注意事项
一、两种错误:namespace导错、没有xml约束
- 如果xml文件上方的namespace不小心导错了,会报错,比如错导了core
? 会报以下错误,说:不认识cache相关的东西,就是因为错导了cache的命名空间。
-
命名空间导了,但是有的时候会出现约束没有导,也会报错 如果约束没写,会报以下错误
二、Tomcat7依赖运行部分jar包不兼容
Tomcat7依赖运行会有一些jar包不兼容的情况,有冲突的jar都是按照这种办法处理,tomcat8以上版本就不会有这个问题了
|