SpringMVC
简介
Spring框架提供的轻量级MVC框架。类似Struts2.
学习内容: 1. 框架环境搭建 2. 第一个Controller/Action开发。 3. 接受请求参数 4. 作用域操作 5. 跳转 思想(技术概念) + 编码
特点
1. SpringMVC天然集成Spring(SpringMVC本身就是spring技术的一部分)
2. SpringMVC自带小Spring工厂,SpringMVC控制器可以使用spring工厂管理。
3. Struts2性能低于SpringMVC
4. SpringMVC映射控制器的访问路径,可以使用注解的方式。
public class UserAction{
@RequestMapping("请求访问路径")
public String regist(){
}
}
环境搭建
核心思路
![1545100891842](a
编码:
1. 导入jar
spring相关的jar(webmvc.jar) 日志的jar
2. 导入配置文件
mvc.xml log4.properties;
3. 初始化配置
web.xml初始化
① 配置DispatcherServlet核心控制器[Servlet]
【org.springframework.web.servlet.DispatcherServlet】
② 指定mvc.xml文件路径。
mvc.xml初始化
① 开启注解管理对象。
② 开启springmnv注解开发mvc;(使用注解映射访问路径)
web.xml初始化
mvc.xml初始化
第一个Controller
核心思想
编码步骤
1. 编写一个控制器程序
public class FirstController{
@RequestMapping("/controller的方法路径")
public String hello(){
}
}
2. 交给spring工厂管理
@Controller
3. 映射控制方法的访问路径。
@RequestMapping
4. 访问的时候
http://ip:port/项目名/方法上的RequestMapping指定的路径
控制器的生命周期
Struts2的action创建多个:每次请求都要创建新的。
SpringMVC的Controller,只需要一个即可。没有数据属性,本质是线程安全的(不能再属性中定义数据变量)。
创建时机:tomcat启动时,(初始化mvc的核心控制器,读取mvc配置文件,注解生效,扫描控制器),就创建了Controller,只创建一个
使用Servlet的API
HttpServletRequest
HttpServletResponse
使用方式:
public class XxxController{
public String xx(HttpServletRequest req,HttpServletResponse resp){
//使用req,和resp
}
}
namespace
@RequestMapping
作用: 映射访问路径。 语法: ① 写在方法上----表明方法的访问路径。 ② 写在类上------表明控制器方法访问的namespace a: 访问控制器方法访问路径: /类上的RequestMapping的路径/方法上的RequestMapping的路径。 b: 将同一个业务模块下的多个控制器方法,放在一个控制器类。 将同一个业务模块下的多个控制器方法访问路径,放在同一个namespace下。
控制器跳转
核心思路(编码)
return "跳转方式:/目标路径的url-pattern";
请求转发:
服务器内部跳转
Controller--->JSP 返回值: return "forward:/目标jsp的url-pattern路径"; Controller---->Controller 返回值: return "forward:/类上的RequestMapping路径/目标跳转方法上的Requestmapping路径.do"; 总结: return "forward:/目标路径的url-pattern";
重定向:
服务器外部跳转
方式: return "redirect:/目标路径的url-pattern";
接受请求参数
基本数据类型+String数据数据收集
使用方式: 直接在方法上声明变量接受即可。
优点:
1. 不用像struts2提供set和get 2. 自动转化类型
>
接受数组类型的值
在方法上声明数组类型参数即可
直接接受对象类型
① 在方法上声明对象类型参数
② 请求参数的name,必须接受控制器的方法形参的实体属性名一致。
乱码问题
get请求
解决办法
修改tomcat的conf/server.xml <Connector port="8888" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
Post请求
解决办法:
request.setCharacterEncoding("UTF-8");
设置响应数据编码
response.setCharacterEncoding("UTF-8");
Post请求和响应编码设置核心思想
>
Springweb提供该编码设置的Filter
org.springframework.web.filter.CharacterEncodingFilter
使用:
作用域操作
方式1:
在方法上声明HttpServletRequest对象。
源码包介绍
SSM整合
Spring+SpringMVC+MyBatis
案例:注册?
环境搭建
1. 导入jar
spring的jar 日志的jar mybatis的jar mybatis-spring的jar oracle的jar 连接池的jar aop的依赖(asm cglib aspectj)
2. 导入配置文件
web.xml
mvc.xml[开启注解开发mvc 注解管理Controller] 小spring工厂
applicationContext.xml[管理连接池 事务相关 mybatis相关 开启注解管理service] 大spring工厂
自定义的application.properties
注意: springmvc的小spring工厂,能够使用到spring的大工厂中的对象。
3. 初始化配置
web.xml
springmvc核心控制器
指定mvc配置文件的路径
编码设置的filter
spring工厂初始化的监听器
spring配置文件初始化
mvc.xml
注解管理controller
注解开发mvc
applicationContext.xml
引入外部properties配置文件
开启注解管理service[除了controller以外的对象]
连接池
事务相关[事务管理器 事务增强 aop]
mybatis相关配置[SqlSessionFactoryBean MapperScannerConfigurer]
总结
1. 环境搭建
SpringMVC核心控制器: DispatcherServlet
指定mvc.xml配置文件的路径
配置 load-on-startup 1
mvc.xml:
开启注解管理控制器
mvc:annotation-driven
2. 控制器开发
@Controller
@RequestMapping("/demo")
public class MyController{
@RequestMapping("/hehe")
public String hehe(){
}
}
3. 接收请求参数:
基本 string 包装:
方法参数名===请求参数名
数组
方法参数 === 请求参数名
实体对象
方法参数声明实体 属性名===请求参数名
4. 跳转:
return "跳转方式:目标路径的url-pattern";
跳转方式:
请求转发: forward:
重定向: redirect:
SpringMVC作用域
Request作用域[存]
ModelMap
作用: 代替request作用域,数据存入ModelMap,自动讲数据放入Request作用域。获得ModelMap:
方法上参数声明ModelMap mm
存入方法:
modelMap.addAttribute("name",值 对象 数据)
JSP获取:
${requestScope.name}
Session作用域[存]
ModelMap
使用:
在类上添加
@SessionAttribute({"modelmap数据的name","modelmap数据的name"})
作用: 对应的moldelmap中的数据,自动拷贝到Session作用域中。
使用方式:
ModelMap+@SessionAttributes({"modelmap中数据的name"})
其他作用操作相关的对象
作用域操作相关的对象 ModelMap Model java.util.Map 作用: 数据存入,相当于放入request作用域。 使用: 同ModelMap Map作用域 作用: 相当于request作用域。 获得: 方法声明 Map map 使用: map.put("name",值);
ModelAndView
作用: model作用+跳转路径的作用
获得: 参数声明ModelAndView
向request作用域存入:
mav.addObject("作用域数据的name",值);
设置跳转路径L:
mav.setViewName("跳转方式:/目标资源url-pattern");
使用:
public ModelAndView xxx(ModelAndView mav){
//1. 向requset作用域存入一个数据
mav.addObject("name",值);
//2. 跳转到xxx.jsp
mav.setViewName("跳转方式:/目标资源url-pattern");
return mav;
}
SpringMVC作用域高级[面试+获得作用域中的值,使用web相关对象]
- 在方法上声明Servlet相关的对象。
HttpServletRequest
HttpServletResponse
HttpSession
>
- 允许直接从spring工厂中获得
HttpServletRequest
HttpServletResponse
HttpSession
>
原理:
从spring工厂中,获得的所有为的HttpSession HttpServletRequest,其实是spring提供的代理对象。
通过在代理对象方法内部,获得真正的session和request,调用对应的方法。
- 方式3:RequestContextHolder
RequestAttributes attris = RequestContextHolder.getRequestAttributes(); // RequestAttributes作用:可以获得httpServletReq HttpServletResp对象。 ServletRequestAttributes attrs = (ServletRequestAttributes) attributes; attrs.getRequest();//获得request对象。 attrs.getResponse();//获得response对象。 //RequestAttributes作用:可以操作request和session作用域 attrs.setAttribute("user1", "讲文明", RequestAttributes.SCOPE_SESSION);;//将数据存入session作用域 attrs.setAttribute("user1", "讲文明", RequestAttributes.SCOPE_REQUEST);//将数据存入request作用域 attrs.getAttribute("name",RequestAttributes.SCOPE_SESSION);//从session作用域中获得name对应的数据。
SpringMVC复杂请求参数接受
集合对象的收集
场景: 如果一次性提交多个对象的数据?(基本数据,实体对象)
SpringMVC复杂对象类型收集核心: 基于控制器方法参数的属性名
封装DTO对象
Data Transfer Object 数据传输对象 客户端传递给控制器。
命名:
XxxDTO
日期类型的接受
日期数据接受。
核心思路
>
类型转化器的开发步骤
- 自定义一个类实现,Converter接口(Spring提供)
>
将类型转起对象管理类型转化工厂内部。(使用springmvc的工厂)
在mvc:annotation-drive中开启使用自定义类型转起的使用。
日期接收方案2:
SpringMVC应用
验证码
- 作用:
防止机器人程序访问服务器(数据库大量连接消耗,导致数据库中大量无效数据) 尽可能确保,访问数据的请求,是人为通过客户端发起。
- 生成验证码图片
hutool.jar Captcha cap = CaptchaUtil.createLineCaptcha(长度,高度);//获得验证码对象[验证码图片,验证码码值] //1. 将验证码图片写出到输出流 cap.write(OutputStream 指向输出位置); //2. 获得真正的验证码的值 String code = cap.getCode();
展示一个验证码
使用验证码,验证用户登录。
>
文件上传
核心思路
1. SpringMVC提供了MultipartFile对象接收文件。 2. SpringMVC使用CommonsMultipartResolver文件解析器,完成文件解析,转化MultipartFile对象。
>
- 准备工作(搭建环境)
① 导入文件上传相关的jar commons-fileupload-1.3.jar commons-io-2.2.jar ② 注册管理文件解析器对象 <bean id="multipartResolver" class="xx.xx.xx.CommonsMultipartResolver"> 文件上传的大小。 <property name="maxUploadSize" value="100000000"></property> </bean> 注意: 文件上传解析器在springmvc工厂内部的ID必须叫"multipartResolver" ③ springmvc内部使用文件解析器对象时,通过id获得对象。 id="multipartResolver" CommonsMultipartResolver resolver = ctx.getBean("multipartResolver");
- SpringMVC的文件对象的方法
multipartFile.getOrignalFilename();//获得文件名。 multipartFile.transferTo(输出流);//将文件输出到流对应的位置。
- 接受上传的文件
实力代码
>
文件下载
核心思想:
回顾:文件拷贝的工具类: Commons-IO包 FileUtils.copyFile(源文件File对象, 拷贝后的文件所对应的输出流);
编码:
拦截器
作用: 将控制器中存在重复代码,抽取拦截器去完成。
权利:
1. 在控制器访问之前执行一段代码 2. 有权中断或者放行,请求到达Controller 3. 在控制器执行完毕之后,执行一段代码
SpringMVC拦截器的工作机制
开发步骤:
- 自定义拦截器:
public class Lanjieqi implements HandlerInterceptor{ 方法1: 控制器之前执行 方法2: 控制器之后,跳转前 方法3: 跳转之后执行。 }
将控制器管理拦截器
<bean>
映射要拦截的路径。
<mapping path="被拦截的控制器的namespace/方法上RequestMapping"></mapping>
配置标签书写书序解读:
细节补充
-
postHandle方法中ModelAndView参数
作用:
1. 操作作用域中的值 mav.addObejct() 2. 设置修改跳转路径 mav.setViewName("xxx");
-
一次性拦截多个路径
方式1:在一个拦截器标签内些多个mapping标签 <!-- 配置拦截器 --> <mvc:interceptors> <!-- 配置多个拦截器 --> <mvc:interceptor> <!-- 拦截路径 --> <mvc:mapping path="/inter/test1.do"/> <mvc:mapping path="/inter/test2.do"/> <!-- 拦截器对象 --> <bean class="com.baizhi.demo4.MyInterceptor1"></bean> </mvc:interceptor> </mvc:interceptors> 方式2:配置拦截路径的通配符。 <mvc:mapping path="/inter/*"/>
-
排除拦截路径
<mvc:exclude-mapping path="不拦截的控制访问路径 url-pattern">
全局异常
概念:
一个异常处理工具,对项目所有控制器发生异常,做统一处理。
开发步骤
- 书写一个异常处理的类。
HandlerExceptionResolver
- 将全局异常处理类,交给springmvc工厂管理。
<bean class="全局异常处理全类名"></bean>
SpringMVC执行流程(执行原理)
执行流程
1. 浏览器发起了请求 "http://localhost:8888/SSM2/user/regist.do"; 请求路径-----控制器的类+方法。 /user/regist.do-----UserController.regist(); 2. 请求参数接受,转化,绑定。 3. 执行对应访问的控制器拦截的,拦截器中的代码。[HandlerInterceptor] 控制器的拦截器 Handler----控制器 4. 该执行控制器-----mav[跳转返回值] 5. 执行控制器拦截器之后的一段代码。------mav[跳转返回值] 6. 将返回mav,解析出跳转路径,和跳转方式。"跳转方式:跳转路径" 7. 跳转 request.getRequestDispatcher("路径").forward(req,resp); response.sendRedirect(项目名/路径);
执行原理
总结:
DispatcherServlet: SpringMVC核❤控制器 作用: springmvc所有组件所有功能的核心控制器。 HandlerMapping: 控制器映射器 作用: 根据请求路径,找到对应控制器的方法 HandlerAdapter: 控制器适配器 作用: ① 请求参数的接受,封装,转化 ② 拦截器的调用过程。 ③ 调用控制器。 ViewResolver:视图解析器 作用: 根据控制器返回值 String|ModelAndView / 拦截器修改后mav ① 解析跳转方式 ② 解析出跳转的路径 ③ 解析出model中的数据,为了放入作用域。
MyBatis分页插件
作用: 针对mybatis开发了插件
1. 接受pageNum和pageSize, 2. 自动根据pageNum和pageSize计算start和end; 3. 自动根据计算出的start和end,修改sql,改成分页结构,自动讲计算出来的start和end,绑定上去; 4. 执行查询,将查询结果,返回list+count(page)
使用:
- 导入jar
jsqlparser-1.2 pagehelper-5.1.2
- 将插件配置在mybatis配置文件中,plugins标签
- 编码
//产生的效果 //1. 根据pageNum,pageSize获得page(总数) //2. 自动修改接下来紧跟着执行的查询语句,改为分页查询 //3. 自动讲pageNum和pageSiz计算出来的start和end绑定sql 1. page = PageHelper.startPage(pageNum,pageSize) page.getTotal();//数据总行数 2. 调用service查询。 list = service.getAll(); 3. 将查询结果的list和表总数count封装pageBean
POI-hutool工具
POI: java技术,操作excel文档。
hutool-excel: 常用poi功能,简化封装成工具类。
数据写出文档
导出数据报表
1. 获得能够向excel表格中输出信息对象[流] writer = ExcelUtil.getWriter("文件路径"); 注释: excel表格文件标准后缀: *.xls *.xlsx 2. excel表格数据包含 表头: 指明当前列数据的含义。 每行: 多个单元格的数据;List<Object> | Map<字符串标题,Object> 表格: 多行数据。List<Map<表头,Object数据>> 3. 将数据写出到Excel文档 writer.write(list); 4. 关闭流 writer.close();
向输出流中写入数据。
1. 创建一个写出的工具 ExcelWriter ew = ExcelUtil.getWriter(); 2. 将list多行数据集合写入。 writer.write(list); 3. flush,将数据写入到指定输出流中 writer.flush(outputStream); 4. 关闭流 writer.close();
设置表格的sheet的名字
writer.renameSheet(“xxx”)
读入文档数据
1. 创建一个读入的工具
ExcelReader reader = ExcelUtil.getReader("文件路径");
2. 读取里面的数据
List<Map<String,Object>> list = reader.readAll();
3. 关闭流
reader.close();