在web.xml上的相关配置
SpringMVC前端控制器
<!-- SpringMVC前端控制器 -->
<servlet>
<servlet-name>springmvc</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>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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的核心配置文件一样的 配置SpringMVC的内容 -->
<!-- 开启MVC注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置注解扫描器 spingmvc的注解扫描器 扫描controller包-->
<context:component-scan base-package="com.hadwinling.controller"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--视图类型 默认jsp视图 (省略) -->
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>-->
<!-- 视图前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器,这个接下来就会讲到。
SpringMVC 中重要组件
- 1.1 DispatcherServlet : 前端控制器,接收所有请求(如果配置/不包 含 jsp)
- 1.2 HandlerMapping: 解析请求格式的.判断希望要执行哪个具体 的方法.
- 1.3 HandlerAdapter: 负责调用具体的方法.
- 1.4 ViewResovler:视图解析器.解析结果,准备跳转到具体的物理视 图
spring web mvc 框架
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200402160730538.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FsaW5neXV6aQ==,size_16,color_FFFFFF,t_70)
第一步: 发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求 HandlerMapping 查找 handler
可以通过 xml 配置或者通过注解配置
第三步: 处理器映射器向前端控制器返回 Handler
第四步: 前端控制器再去调用处理器适配器执行 Handler
第五步: 处理器适配器真正执行 Handler
第六步: Handler 执行完返回 ModelAndView
第七步: 处理器适配器向前端控制器返回 ModelAndView,ModelAndView 是 SprinveMVC
框架中的一个底层对象,该对象中包括 Model 和 View
第八步: 前端控制器请视图解析器解析视图
根据逻辑视图名解析成真正的视图,返回个 View
第九步: 视图解析器向前端控制器返回 View
第十步: 由前端控制器进行视图渲染
视图渲染将模型数据填充到 Request 域中.
第十一步: 前端控制器向用户响应结果.
Springmvc执行流程分析
- 当启动Tomcat服务器的时候,因为配置了web.xml中load-on-startup标签,所以会创建DispatcherServlet对象, 会加载springmvc.xml配置文件
- 开启了注解扫描,那么HelloController对象就会被创建
- 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法
- 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
- Tomcat服务器渲染页面,做出响应
RequestMapping注解
- RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系
- RequestMapping注解可以作用在方法和类上
作用在类上:第一级的访问目录
作用在方法上:第二级的访问目录
路径可以不编写 / 表示应用的根目录开始 - RequestMapping的属性
- path 指定请求路径的url
- value value属性和path属性是一样的
- mthod 指定该方法的请求方式
- params 指定限制请求参数的条件
- headers 发送的请求中必须包含的请求头
请求参数的绑定
请求参数的绑定说明
绑定机制
- 表单提交的数据都是k=v格式的 username=haha&password=123
- SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
- 要求:提交表单的name和参数的名称是相同的
支持的数据类型
- 基本数据类型和字符串类型
- 实体类型(JavaBean)
- 集合数据类型(List、map集合等)
基本数据类型和字符串类型 - 提交表单的name和参数的名称是相同的
- 区分大小写
实体类型(JavaBean) - 提交表单的name和JavaBean中的属性名称需要一致
- 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如: address.name
给集合属性数据封装
请求参数中文乱码的解决
在web.xml中配置Spring提供的过滤器类
!--配置springmvc字符集过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 设置过滤器中的属性值 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 启动过滤器 -->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
自定义类型转换器
特殊数据类型 Date 不能直接转换 默认数据类型转换器没有String–>Date
方式1.自定义类型转换器 springmvc.xml中配置
方式2.在属性上使用注解@DateTimeFormat(pattern=“yyyy-MM-dd”) *
注意:在springmvc.xml中开启mvc注解驱动 * mvc:annotation-driven/
方式一:自定义类型转换器
Date时间的转换
public class StringToDate implements Converter<String,Date>{
@Override
public Date convert(String source) {
if(source=null) {
throw new RuntimeException("请输入时间");
}
DateFormat df=new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(source);
} catch (ParseException e) {
// TODO Auto-generated catch block
throw new RuntimeException("转换错误");
}
}
}
.2.注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<bean id="conversionUtil" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.gem.springmvcdemo.util.StringToDate"/>
</set>
</property>
</bean>
修改 springmvc.xml注解:
<mvc:annotation-driven conversion-service="conversionUtil"/>
- 方式2.在属性上使用注解@DateTimeFormat(pattern=“yyyy-MM-dd”) *
注意:在springmvc.xml中开启mvc注解驱动 * mvc:annotation-driven/
方式二:在实体类中,使用注解
package com.hadwinling.entity;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String username;
private String password;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
}
常用的注解
RequestParam
作用:
把请求中指定名称的参数给控制器中的形参赋值。
属性:
value:请求参数中的名称。
required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。
@RequestMapping(value="/say02",method=RequestMethod.GET)
public String say02(@RequestParam(name="username",required=true,defaultValue="admin")String name,
@RequestParam(name="id",defaultValue="1") int uid) {
System.out.println(uid+":"+name);
return "main";
}
RequestBody
作用:
用于获取请求体内容。直接使用得到是 key=value&key=value…结构的数据。
get 请求方式不适用。
属性:
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值
为 false,get 请求得到是 null
/**
* @RequestBody:以k=v&k=v的形式请求参数
*
* post请求 ,get请求不可以使用
*
*/
@RequestMapping("say05")
public String say05(@RequestBody String body) {
System.out.println(body);
return "main";
}
- 1.在方法上只有@RequestMapping 时,无论方法返回值是什么认为需 要跳转
- 2.在方法上添加@ResponseBody(恒不跳转)
- 2.1 如果返回值满足 key-value 形式(对象或 map)
- 2.1.1 把响应头设置为 application/json;charset=utf-8
- 2.1.2 把转换后的内容输出流的形式响应给客户端.
- 2.2 如果返回值不满足 key-value,例如返回值为 String
- 2.2.1 把相应头设置为 text/html
- 2.2.2 把方法返回值以流的形式直接输出.
- 2.2.3 如果返回值包含中文,出现中文乱码
- 2.2.3.1 produces 表示响应头中 Content-Type 取值.
@RequestMapping(value="demo12",produces="text/html; charset=utf-8")
- 2.1 如果返回值满足 key-value 形式(对象或 map)
PathVaribale
作用:
用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。
url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的
一个重要标志。
属性:
value:用于指定 url 中占位符名称。
required:是否必须提供占位符。
/**
* restful风格
* 简约 安全
* /say06/{uid}
* {uid} url中的占位符
* @PathVariable 蒋将url中的占位符的值赋值形参
*/
@RequestMapping("/say06/{uid}")
public String say06(@PathVariable(value="uid")int id){
System.out.println(id);
return "main";
}
RequestHeader
作用:
用于获取请求消息头。
属性:
value:提供消息头名称
required:是否必须有此消息头
注:
在实际开发中一般不怎么用
/**
* 获取请求头信息
*/
@RequestMapping("/say07")
public String say07(@RequestHeader(value="Accept") String header) {
System.out.println(header);
return "main";
}
ModelAttribute
作用:
该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可
以修饰有具体返回值的方法。
出现在参数上,获取指定的数据给参数赋值。
属性:
value:用于获取数据的 key
key 可以是 POJO 的属性名称,也可以是 map 结构的 key
应用场景:
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
例如:
我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数
据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。
SessionAttribute
作用:
用于多次执行控制器方法间的参数共享。
属性:
value:用于指定存入的属性名称
type:用于指定存入的数据类型。
/**
* @ModelAttribute:
* 作用在方法上 :这个方法会优先执行,一般用来做预处理
* 作用在参数上:获取指定的数据给参数赋值。
* 应用场景:
* 当在提交表单 时 ,提交的信息不足。先@ModelAttribute修饰的方法中保存一些字段,处理请求时,将保存的字段赋值给参数
*/
@ModelAttribute
public void method(String username,Map<String, User> map) {
System.out.println("@ModelAttribute方法先执行。。。");
User user=new User(username, null);
user.setPassword("123456");
//保存在map中
map.put("currUser", user);
}
@RequestMapping("/say08")
public String say08(@ModelAttribute("currUser") User user) {
System.out.println(user);
return "main";
}
响应数据和结果视图
程序员自定义视图解析器
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalR esourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean>
如果希望不执行自定义视图解析器,在方法返回值前面添加 forward:或 redirect:
返回值分类
- 返回值是void:
如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。
@RequestMapping("/login")
public void login(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
System.out.println("访问成功!!");
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
}
- 返回值是ModelAndView对象
ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图
控制器的代码块:
@RequestMapping("/findAll")
public ModelAndView findAll() {
List<User> list=new ArrayList<User>();
list.add(new User("张三", 30));
list.add(new User("张三", 30));
list.add(new User("张三", 30));
list.add(new User("张三", 30));
ModelAndView mv=new ModelAndView();
mv.setViewName("main");
mv.addObject("list",list);
return mv;
}
jsp的代码块:
<table>
<c:forEach items="${list }" var="user">
<tr>
<td>${user.uname }</td>
<td>${user.age }</td>
</tr>
</c:forEach>
</table>
SpringMVC框架提供的转发和重定向
@RequestMapping("test")
public String test() {
//转发 不经过视图解析器对象
//return "forward:/WEB-INF/pages/success.jsp";
//重定向不能访问web-inf中的jsp文件
return "redirect:/index.jsp";
}
ResponseBody响应json数据
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。
解决问题:就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置
- mvc:resources标签配置不过滤
Location属性表示webapp目录下的包下的所有文件
Mapping属性表示以/static开头的所有请求路径,如/static/a 或者/static/a/b
代码示例
<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
发送ajax请求,返回json数据
@RequestMapping("/ajaxtest")
public @ResponseBody User ajaxtest(@RequestBody User user) {
System.out.println(user);
user.setUname("张三");
user.setAge(20);
return user;
}
<!-- json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<script type="text/javascript" src="/springmvcdemo/js/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(function () {
$("#btn").click(function(){
//发送ajax请求
$.ajax({
url:"ajaxtest", //服务器地址
contentType:"application/json;charset=UTF-8",//
data:'{"uname":"rose","age":30}',//参数 json
dataType:"json",//预期服务返回数据类型
type:"post",//post
success:function(data){//访问成功 :执行函数 data:服务器返回数据
console.log(data);
console.log(data.uname);
console.log(data.age);
}
})
});
})
</script>
跳转方式
- 默认跳转方式请求转发.
- 设置返回值字符串内容
2.1 添加 redirect:资源路径 重定向
2.2 添加 forward:资源路径 或省略 forward: 转发