关于SpringMVC
基于MVC开发模式的框架,用来优化控制器,也是spring家族的一员,同样具备IoC和AOP特性
优点
- 轻量级,基于MVC架构
- 易上手,易理解
- 具备IoC和AOP
- 完全基于注解开发
基本开发步骤
- 新建项目,选择webapp模板
- 修改目录,添加缺失的test,java,resources(*2),并修改目录属性
- 修改pom.xml,添加springMVC依赖,添加servlet的依赖
- 添加springmvc.xml配置文件,指定扫描包,添加视图解析器
- 删除web.xml(原有版本过低),新建web.xml
- 在web.xml中注册springMVC框架(请求基于servlet)
- 删除index.jsp,新建,发送请求给服务器
- 开发控制器(servlet),它是一个普通的类
如何实操
- 访问权限public
- 返回值任意
- 名称任意
- 参数任意,可以为空
- 使用@RequeseMapping来声明访问路径(可以分级)
@RequestMapping
- 可以加在方法或类上,指定该方法(或类)的访问路径
1
2
3
4
5
6
7
8
public class qwq{
public String req(){
return "success";
}
}
//这样即可通过{path}/sr/firstController访问该类了 - 可以约定请求提交方式
1
2
3
4
5
6
7
8
9
public class qwq{
public String req(){
return "success";
}
//method留空默认接受所有类型请求
}
数据提交方式的优化
散提数据
1 | <form action="${pageContext.request.contextPath}/try"> |
1 | public class qwq{ |
对象封装
在提交请求中保证请求参数的名称与实体类中成员变量一致则可以自动提交数据,自动类型转换,自动封装数据到对象中
1 | <form action="${pageContext.request.contextPath}/try"> |
1 | public class Person{ |
动态占位符提交
仅限于超链接或地址栏直接提交,一杠一值
1 | <a href="${pageContext.request.contextPath}/try/张三/25">点我!</a> |
1 | public class qwq{ |
映射参数名称不一致
提交的参数名和形参不一致,使用@RequestParam解析
1 | <form action="${pageContext.request.contextPath}/try"> |
1 | public class qwq{ |
手工提取数据
1 | <form action="${pageContext.request.contextPath}/try"> |
1 | public class qwq{ |
如何解决中文乱码的问题
配置过滤器->web.xml
1 | <!--建议放在所有的配置之前--> |
servlet方法的返回值
String
客户端资源的地址,自动拼接前缀后缀,可以屏蔽自动拼接字符串,可以指定返回路径
Object
返回json格式的对象,自动将对象或集合转为json,依赖jackson工具,一般用于ajax请求
void
一般用于ajax请求
基本数据类型
用于ajax请求
ModelAndView
返回数据和试图对象,现在用的很少
完成ajax请求访问服务器,返回学生集合
- 添加jackson依赖
1
2
3
4
5<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency> - 在webapp下新建js目录,添加jQuery函数库
- 在index.jsp上导入函数库
- 在action上添加注解@ResponseBody,用来处理ajax请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<script src="js/jquery-3.3.1.js"></script>
<!--↑head↓body-->
<a href="javascript:showStu()">请求学生集合</a>
<div id="mydiv">等待返回数据</div>
<script type="text/javascript">
function showStu(){
$.ajax({
url:"${pageContext.request.contextPath}/list",
type:"get",
dataType:"json",
success:function(stuList){
var s="";
$.each(stuList,function(i,stu)){
s+=stu.name+"----"+stu.age+"<br>";
}}
//回显在div上
$("#mydiv").html(s);
})
}
</script>1
2
3
4
5
6
7
8
9//省略类的定义
public List<Student> list(){
List<Student> list=new ArrayList<>();
//添加数据...
return list;
//SpringMVC会协助将集合转为json数组
} - 在springMVC.xml文件中添加注解驱动<mvc:annotationdriven/>,用于解析@ResponseBody注解
SpringMVC的四种跳转方式
实质:[请求转发,重定向]到[页面,action]
请求转发和重定向最大的不同:请求转发地址栏不变,重定向地址栏改变
1 | public class qwq{ |
SpringMVC默认的参数类型
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model
- Map
- ModelMap
直接拿来即可用,作用域:Request,所以只有forward时数据仍然存在,如果使用redirect,则需要使用session保存数据
页面上日期的显示
日期提交
- 单个日期处理
使用注解@DateTimeFormat(),必须搭配springMVC配置文件中<mvc:annontationdriven\>共同使用1
2
3
4<form action="${pageContext.request.contextPath}/try">
姓名:<input type="date" name="ddate">
<input type="submit">
</form>1
2
3
4
5
6
public String req2({ Date ddate)
//注意,如果不使用@DateTimeFormat,无法成功注入
return "success";
}
} - 类中全局日期处理
上文方式的处理方法,如果需要注入多个日期,需要分别填写@DateTimeFormat,因此我们可以尝试复用日期格式1
2
3
4
5
6
7
8
9
10SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
public void init(WebDataBinder dataBinder){
dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sf,true));
}
public String req2(Date ddate){
return "success";
}
}
日期的显示处理
可以直接格式化日期并返回String
如果想在页面上自定义样式,需要使用JSTL,步骤如下
- 添加依赖
1
2
3
4
5
6
7<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0</version>
</dependency>
<!--spring6.0以上用jakarta--> - 在页面上导入标签库
1
2<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> - 使用标签显示数据
1
<fmt:formatDate value="${date} pattern="yyyy-MM-dd"></fmt:formatDate>
SpringMVC执行分析
关于annotation-drivern
会自动注册以下两个bean
- DefaultAnnotationHandlerMapping
解析服务器端资源地址,即地址映射器 - AnnotationMethodHandlerAdapter
构建对象,即处理器适配器
为什么资源放在WEB-INF目录下
该目录下资源对外不可直接访问
拦截器开发与应用
针对请求和响应进行的额外的处理,可以添加预处理、后处理和最终处理
处理流程:
ruquest->preHandle()->处理器->postHandle()->afterCompletion()->response
- preHandle():在请求被处理时进行操作
- postHandle():在请求被处理,但结果没渲染之前进行操作
- afterCompletion():在请求响应结束后进行善后
实现方式
- 继承父类HandlerInterceptorAdapter
- 实现接口HandlerInterceptor,推荐使用该方式
实现步骤
- 在springMVC.xml中注册
1
2
3
4
5
6
7<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="要拦截的请求地址"></mvc:mapping>
<mvc:exclude-mapping path="要放行的请求"></mvc:exclude-mapping>
</mvc:interceptor>
<!--如果配置多个拦截器,可以构成拦截器链-->
</mvc:interceptors> - 开发拦截器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class MyIntercrptor implements HandlerInterceptor{
boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{
return false;
}
/**
* 关于返回值类型
* boolean->true则继续执行,false则止步于此
*/
void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{
}
boolean afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{
}
/**
* Object handler
*
*/
}
51