SpringMVC图示:
文字描述:
前提:
web.xml文件中设置了DispatcherServlet的<url-pattern>为“/”
执行:
1. 用于发起请求 --> 请求一个控制器
2. 执行DispatcherServlet
3. DispatcherServlet调用 HandlerMapping的DefaultAnnotatiionHandlerMapping解析URL
4. 调用HandlerAdatper的AnnotationMethodHandlerAdapter
5. 调用Controller中的HandlerMethod
6. 当HandlerMehod执行完毕会返回view
7. view会被viewResovler进行视图解析 --> 调用jsp对应的.class文件 --> 运行
8. 将运行结果响应给客户端
发送请求时被拦截器拦截,在控制器(注解类的@RequestMapping)前后添加额外功能
1. AOP在特定方法前后进行扩充(对ServiceImpl实现类)
2. 拦截器对控制器方法(对Controller注解类)
1. SpringMVC拦截器 拦截控制器Controller
2. Filter过滤器 拦截任何请求
1 | public class DemoInterceptor implements HandlerInterceptor { |
拦截所有的控制器
1 | <mvc:interceptors> |
拦截特定的控制器
1 | <mvc:interceptors> |
1 | @Controller |
1 | <body> |
方法分析(3个):
1. preHandle : 控制器前(可以获得拦截的是哪个控制器)
2. @RequestMapping的注解方法 : 控制器 (写跳转哪个jsp页面)
3. postHandle : 控制器后 jsp前(日志记录/敏感词语过滤)
4. xxx.jsp jsp页面
5. afterCompletion : jsp之后(记录异常/异常写入日志)
最终执行结果:
多个拦截器同时生效 –> 拦截器栈
执行顺序和springmvc.xml里面配置的顺序有关
配置顺序 : 拦截器A --> 拦截器B
执行顺序(圆环!!!) :
preHandle(A) 最外层
preHandle(B) 次外层
控制器方法 中心(上面都是A在前 下面都是B在前)
postHandle(B)
postHandle(A)
JSP页面
afterCompletion(B)
afterCompletion(A)
1. 响应头没有设置:Content-Disposition(浏览器默认按照inline值处理)
1.1 inline 就是能显示就显示,不能显示就下载
2. 响应头设置:Content-Disposition="attachment;filename=文件名"
2.1 attachment 以附加形式下载
2.2 filename 就是下载时显示的下载文件名
1 | //添加files文件的静态资源配置 |
1 | <a href="download?fileName=a.txt">下载</a> |
1 | @Controller |
1. 基于apache的commons-fileupload.jar完成文件上传
2. MultipartResovler作用
2.1 客户端上传的文件 -->MutipartFile封装类
2.2 通过MutipartFile封装类获取到文件流
//enctype属性取值:
1. application/x-www-form-urlencoded(默认值) :普通表单数据(少量文字信息)
2. text/plain :大量文字信息(邮件/论文)
3. multipart/form-data : 表单中包含二进制文件内容
注解类传过去的类的对象和文件标签的name必须一致!!!
1 | <form action="upload" enctype="multipart/form-data" method="post"> //enctype属性取值是表单中包含二进制文件的值 |
编写MultipartResovler解析器和异常解析器
1 | <!-- MultipartResovler解析器 --> |
注解类MultipartFile类的对象和文件标签的name必须一致!!!
1 | @Controller |
1. page(当前页面)
2. request(一次请求中同一个对象)
3. session(一次会话)
3.1 只要客户端Cookie中传递的Jsessionid不变 --> session就不会重新实例化(不超过默认时间)
3.2 实际有效时间:
3.2.1 浏览器关闭 : cookie失效
3.2.2 默认时间 :tomcat的web.xml中配置
4 .application(关闭tomcat)
1. 使用原生Servlet(HandlerMethod参数中添加作用域对象)
2. 使用Map集合
3. 使用SpringMVC中Model接口
4. 使用SpringMVC中ModelAndView类
在HandlerMethod参数中 + 作用域对象
注解类:
1 | @Controller |
index.jsp页面(取出来):
1 | request:${requestScope.req }</br> |
map中的内容放入request作用域
spring会对map集合通过BindingAwareModelMap进行实例化
1 | @RequestMapping("demo02") |
内容最终放入到request作用域
1 | @RequestMapping("demo03") |
1 | @RequestMapping("demo04") |
1. spring的上下文参数(地址)
2. 监听器
3. springmvc的前端控制器(地址)
4. 字符编码过滤器(防止中文乱码)
具体代码
1 | <?xml version="1.0" encoding="UTF-8"?> |
1. 注解扫描
2. 加载属性文件(要写好db.properties文件)
3. 数据源
4. 扫描器
5. 事务管理器
6. 声明式事务
7. aop
具体代码
1 | <?xml version="1.0" encoding="UTF-8"?> |
db.properties文件:
1 | jdbc.driver=com.mysql.jdbc.Driver |
1. 扫描注解
2. 注解驱动
3. 静态资源
4. 视图解析器
1 | <?xml version="1.0" encoding="UTF-8"?> |
1 | public class Menu { |
1 | //准备接口写方法 |
准备接口展示结果:
1 | // |
准备实现类
1 | @Service |
1 | @Controller |
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
直接运行界面
运行结果就会下载文件show.json
查看json文件内容
1. DispatcherServlet : 前端控制器 (接收所有请求)
2. HandlerMapping : 解析请求格式 (判断执行哪个方法)
3. HandlerAdapter : 调用具体方法
4. ViewResovler : 视图解析器 (准备跳转到具体的物理视图)
1 | <?xml version="1.0" encoding="UTF-8"?> |
配置思路:
1 | 1. 导入spring的xmlns:xxx信息 |
完整代码:
1 | <?xml version="1.0" encoding="UTF-8"?> |
1 | public class DemoController implements Controller{ |
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
1 |
|
Spring容器和SpringMVC容器是父子容器(SpringMVC容器可以调用Spring容器中所有内容)
1 | <!-- 配置前端控制器 --> |
1 | <?xml version="1.0" encoding="UTF-8"?> |
1 | @Controller |
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
1. 导入jar包
2. 配置web.xml文件
2.1 配置servlet和servlet-mapping标签
2.2 在servlet标签中配置init-param标签 去配置springmvc.xml文件的地址和访问
3. 配置springmvc.xml文件
3.1 配置mvc框架的xmlns:mvc和location地址
3.2 扫描注解(context:component-scan标签 配置哪些类有注解)
3.3 注解驱动(mvc:annotation-driven标签 配置相当于配置了两个组件)
3.4 静态资源(mvc:resources标签 配置要访问的js/css/images地址)
4. 配置注解类
4.1 使用@Controller 注解整个类
4.2 使用@RequestMapping("xxx") 注解访问访问的地址
4.3 return 放入要返回的主页地址
代码结构框架:
把内容写到方法(HandlerMethod)参数内,springmvc只要有这个内容就会注入内容
1 | <form action="demo" method="post"> |
1 | <filter> |
1 | @Controller |
直接从项目运行(run)
填写信息(已经做了预防中文乱码的操作):
把内容写到方法(HandlerMethod)参数内,springmvc只要有这个内容就会注入内容
1 | public class People { |
1 | public class DemoController { |
1 |
|
例如:前端程序员和后端java对于同一个name和age不同!!(使用@RequestParam(value=”前端的参数名”))方式让匹配上)
1 |
|
设置默认值解决500问题(@RequestParam(defaultValue=”XXX”))
1 | @RequestMapping("page") |
设置必要值为true(@RequestParam(required))
1 | @RequestMapping("demo2") |
复选框传递的参数是多个同名参数(@RequestParam(“复选框的name名”)List
x)
1 |
|
1 | //页面中: |
1 | //页面中: |
简化jsp中参数编码格式
1 | <a href="demo07/123/abc">跳转</a> |
注意事项:
1 | 1. @RequestMapping里面一定要和请求格式对应 |
具体代码:
1 | @RequestMapping("demo7/{id}/{name}") |
1. 默认跳转方式 请求转发
2. 设置返回字符串内容
2.1 添加 redirect:资源路径 (重定向)
2.2 添加 forward:资源路径/省略forward (转发)
可以自定义使用ViewResovler底层的InternalResourceViewResolver接口
1 | <!-- 使用ViewResovler底层的InternalResourceViewResolver接口 --> |
** 如果希望不执行自定义视图解析器,可以在注解类方法返回值前添加forward: / redirect: **
1 | //注解类 |
一般使用@RequestMapping (恒跳转)
1. 响应头设置为 application/json;charset=utf-8
2. 方法返回值 : 输出流
1. 响应头设置为 text/htmln;charset=utf-8
2. 方法返回值 : 流
一定要导入jackson的jar包
spring4.1.6对jackson不支持较高版本(jackson2.7无效)
局部刷新:通过异步请求,请求到服务器资源数据后,过脚本修改页面中部分内容
本层是jquery中功能最全(代码写起来相对麻烦)
1 | <script type="text/javascript"> |
其中属性:
1. url:请求服务器地址
2. data:请求参数
3. dataType:服务器返回数据类型
4. error:请求出错执行的功能
5. success:请求成功执行的功能(function(data):data是服务器返回的数据)
1. $.get(url,data,success,dataType)
2. $.post(url,data,success,dataType) --常用 但是没有出错提示!!
1. $.getJSON(url,data,success) 相当于设置dataType="json"
2. $.getScript(url,data,success) 相当于设置dataType="script"
服务器返回数据是从表取出,为了方便服务器操作返回的数据,服务器返回的数据设置为json
json数据类型:
1. JsonObject -- json对象
{"key":value,"key":value}
2. JsonArray -- json数组
[{"key":value,"key":value},{}]
1 | public class Users { |
1 | @WebServlet("/demo") |
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
1. @Component 创建类对象 (相当于配置文件中的<bean>标签)
2. @Service(Component功能相同)
2.1 写在ServiceImpl类
3. @Repository(Component功能相同)
3.1 写在数据访问层
4. @Controller(Component功能相同)
4.1 写在控制器类
1. @Resource(java的注解)
1.1 按照byName注入(默认) 按照byType注入(没有名称对象)
1.2 一般将对象名称和spring容器中对象名相同
2. @Autowired(spring的注解)
1.1 按照byType注入(默认)
1. @Pointcut() 定义切点
2. @Aspect() 定义切面类
3. @Before() 前置通知
4. @After() 后置通知 (切点正不正确都可以)
5. @AfterReturing() 后置通知 (必须切点正确才执行)
6. @AfterThrowing 异常通知
7. @Arround() 环绕通知
1. @Value() 获取xxx.properties文件内容
程序员编程 事务控制代码
Spring写好 事务控制代码
程序员只需要声明哪些方法需要进行事务控制和如何进行事务控制
事务管理器基于通知(advice) – 切点(AOP)
1 | 1. 导入xmlns:tx 和location地址 |
1 | <?xml version="1.0" encoding="UTF-8"?> |
声明式事务例子:
1 | <!-- 配置声明式事务 --> |
1. name="" 哪些方法需要被事务控制 (支持 * 通配符)
2. read-only="true/false" 是否是只读事务
2.1 true : 告诉数据库此事务是只读事务 数据化优化,会对性能有一定提升(查询)
2.2 false(默认) : 告诉数据库此事务是需要提交的事务 (新增/删除/修改)
当一个具有事务控制的方法被另外一个有事务控制的方法调用后,需要如何管理事务?
1. REQUIRED(默认) :
1.1 有事务 --> 在此事务中执行
1.2 无事务 --> 新建事务
2. SUPPORTS(随遇而安 有就有 没有就没有) :
2.1 有事务 --> 在此事务中执行
2.2 无事务 --> 非事务状态下执行
3. MANDATORY(必须在事务内执行) :
3.1 有事务 --> 在此事务中执行
3.2 无事务 --> 报错
4. REQUIRES_NEW(必须在事务内执行) :
4.1 有事务 --> 挂起
4.2 无事务 --> 新建事务
5. NOT_SUPPORTED(必须在非事务执行) :
5.1 有事务 --> 挂起
5.2 无事务 --> 正常执行
6. NEVER(必须在非事务执行) :
6.1 有事务 --> 报错
6.2 无事务 --> 正常执行
7. NESTED(必须在事务内执行) :
7.1 有事务 --> 创建一个嵌套事务
7.2 无事务 --> 新建事务
多线程/并发访问保证数据具有完整性
脏读(两个事务)
事务A读取到事务B中未提交的数据 --> B可能数据改变 --> A读的数据可能和数据库中的不一致
不可重复读(同一事务)
1. 主要针对某行数据数据 (行中某列)
2. 主要针对 修改 操作
3. 事务A读取事务 --> 事务B对事务A读取的数据修改 --> A再次读取和之前的不一致
幻读(两个事务)
1. 主要针对 新增/删除 操作
2. 事务A按照特定条件查询结果 --> 事务B新增了数据(符合A查询条件) --> A查询的数据和数据库的数据不一致
1. DEFAULT(默认) : 底层数据库自动判断用什么隔离界别
2. READ_UNCOMMITTED(效率最高) : 可以读取未提交的数据 ( 可能出现 脏读 / 不可重复读 / 幻读 )
3. READ_COMMITTED(避免脏读) : 只能读取其他事务已经提交的数据 (可能出现 不可重复读 / 幻读)
4. REPEATABLE_READ(避免脏读和不可重复读) : 读的数据被添加锁(一行) (可能出现 幻读)
5. SERIALIZABLE(最安全和效率最低) : 整个表添加锁(排队操作)
1. rollback-for="异常类型全限定路径" 出现什么异常时候需要进行回滚
给定该属性值 (手动抛异常一定要给该属性值!!!)
2. no-rollback-for=" " 当出现什么异常时不滚回事务