SpringMVC
1.什么是SpringMVC
它是基于MVC开发模式的框架,用来优化控制器;它是Spring家族的一员,也具备AOP和IOC。
2.什么是MVC
- 是一种开发者模式,是模型视图控制器的简称;所有的web应用都是基于MVC开发。
- M 模型层:包含实体类、业务逻辑层、数据访问层
- V 视图层:包含html、JavaScript、vue等都是视图层,用来呈现数据的
- C 控制器:它是用来接收客服端的请求,并返回响应到客服端的组件,Servlet就是这个组件
3.SpringMVC的优点
- 轻量级,基于MVC的框架
- 易于上手,功能强大
- 他具备IOC和AOP
- 完全基于注解开发
4.分析web请求
- web请求执行流程:
index.jsp(客服端的请求)<——————>DispatcherServlet(核心处理器)——————>SpringMVC的处理器 (一个普通方法)
- DispatcherServlet要在web.xml文件中注册才可用
5.@RequestMapping注解
-
该注解可加在方法上,是为此方法注册一个可以访问的名称(路径)
@RequestMapping("/demo")//通过注解来声明访问的路径 public String demo(){ return "main"; }
在index.jsp中有访问/demo的超链接:
<a href="${pageContext.request.contextPath}/demo.action">访问服务器</a>
-
此注解可加在类上,相当于包名(虚拟路径),用于区分不同类中相同的action名称
-
此注解可区分get和post请求
@RequestMapping(value = "/req",method = RequestMethod.GET) public String req(){ System.out.println("get req"); return "main"; } @RequestMapping(value = "/req",method = RequestMethod.POST) public String req1(){ System.out.println("post req"); return "main"; }
6.五种数据提交的优化
-
散提交数据
index.jsp中:
<form action="${pageContext.request.contextPath}/one.action" > 姓名:<input name="myname"> 年龄:<input name="age"> <input type="submit" value="提交"> </form>
Action控制类中:
@RequestMapping("/one") public String one(String myname,int age){//入参名直接与定义的<input name="myname">一致即可取数据 System.out.println("myname="+myname+",age="+(age+100)); return "main"; }
-
对象封装提交数据
在提交请求中,保证请求参数的名称与实体类中成员变量的名称一致,则可自动创建对象、自动提交数据、自动类型转换、自动封装数据到对象中。
页面:
<h2>对象封装数据提交</h2> <form action="${pageContext.request.contextPath}/two.action" > 姓名:<input name="name"> 年龄:<input name="age"> <input type="submit" value="提交"> </form>
Action和实体类:
//private String name; //private int age; @RequestMapping("/two") public String two(Users users){ System.out.println(users); return "main"; }
-
动态占位符提交
仅限于超链接或地址栏提交数据;它是一杠一值,一杠一大括号,使用@PathVariable(路径中的变量)注解来解析。
页面:
<h2>动态占位符提交</h2> <a href="${pageContext.request.contextPath}/three/张三/22.action" >动态占位符提交</a>
Action:
@RequestMapping("/three/{name}/{uage}") public String three( @PathVariable//路径中的变量 String name, @PathVariable("uage") //路径名和形参名不一致时要指定 int age){ System.out.println("name="+name+",age="+(age+100)); return "main"; }
-
映射名称不一致
提交请求参数与Action方法中形参的名称不一致,使用注解来解析@RequestParam来解析
页面:
<h2>参数名称不一致解决方案</h2> <form action="${pageContext.request.contextPath}/four.action" > 姓名:<input name="name"><br> 年龄:<input name="age"><br> <input type="submit" value="提交"> </form>
Action:
@RequestMapping("/four") public String four( @RequestParam("name")//请求参数 String uname, @RequestParam("age") int uage){ System.out.println("uname="+uname+",uage="+(uage+100)); return "main"; }
-
手工提取数据
原始的用HttpServletRequest去提取数据
@RequestMapping("/five") public String five(HttpServletRequest request){ String name = request.getParameter("name"); int age = Integer.parseInt(request.getParameter("age")); System.out.println("name="+name+",age="+(age+100)); return "main"; }
7.中文乱码解决方案
<!-- 中文编码过滤器-->
<!-- private String encoding;
private boolean forceRequestEncoding;
private boolean forceResponseEncoding;-->
<filter>
<filter-name>encode</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>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encode</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
8.Action方法的返回值
- String:客户端资源的地址,自动拼接前缀和后缀;还可屏蔽自动拼接字符串,可指定返回的路径。
- Object:返回json格式的对象,自动将对象或集合转换为json;使用的是jackson工具转换必须要添加jackson依赖。一般用于ajax请求。
- void:无返回值,一般用于ajax请求
- 基本数据类型,用于ajax请求
- ModelAndView:返回数据和视图对象,现在很少使用
9.四种跳转方式
本质还是两种跳转:转发和重定向,衍生出的四种是指:请求转发、转发action、重定向页面、重定向action。
-
//forward: 这组字符串可以屏蔽前缀和后缀的拼接.实现请求转发跳转
-
//redirect: 这组字符串可以屏蔽前缀和后缀的拼接.实现重定向跳转
@RequestMapping("/one")
public String one(){
System.out.println("这是请求转发页面跳转.........");
return "main"; //默认是请求转发,使用视图解析器拼接前缀后缀进行页面跳转
}
@RequestMapping("/two")
public String two(){
System.out.println("这是请求转发action跳转.........");
// /admin/ /other.action .jsp
//forward: 这组字符串可以屏蔽前缀和后缀的拼接.实现请求转发跳转
return "forward:/other.action"; //默认是请求转发,使用视图解析器拼接前缀后缀进行页面跳转
}
@RequestMapping("/three")
public String three(){
System.out.println("这是重定向页面.......");
//redirect: 这组字符串可以屏蔽前缀和后缀的拼接.实现重定向跳转
return "redirect:/admin/main.jsp";
}
@RequestMapping("/four")
public String four(){
System.out.println("这是重定向action.......");
//redirect: 这组字符串可以屏蔽前缀和后缀的拼接.实现重定向跳转
return "redirect:/other.action";
}
@RequestMapping("/five")
public String five(){
System.out.println("这是随便跳.......");
return "forward:/fore/login.jsp";
}
10.SpringMVC默认的参数类型
- HTTPServletRequest
- HttpServletResponse
- HttpSession
- Model
- Map
- ModelMap
注意:Map、Model、ModelMap和request一样,都使用请求作用域进行数据的传递,所以服务器的跳转必须是请求转发。
//做一个数据,传到main.jsp页面上
Users u = new Users("张三",22);
//传递数据
request.setAttribute("requestUsers",u);
session.setAttribute("sessionUsers",u);
model.addAttribute("modelUsers",u);
map.put("mapUsers",u);
modelMap.addAttribute("modelMapUsers",u);
11.日期处理
-
日期的提交
-
单个日期处理
要使用注解@DateTimeFormat,此注解必须搭配springmvc.xml文件中的mvc:annotationdriven标签
-
类中全局日期处理
注册一个注解,用来解析本类中所有的日期类型,自动转换。
@InitBinder public void initBinder(WebDataBinder dataBinder){ dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sf,true)); }
-
-
日期的显示
在页面上添加好看的日期需要使用JSTL
步骤:
A)添加依赖jstl<dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
B)在页面上导入标签库
如果是单个日期对象,直接转为好看的格式化的字符串进行显示.
如果是list中的实体类对象的成员变量是日期类型,则必须使用jstl进行显示.<%--导入jstl核心标签库--%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%--导入jstl格式化标签库--%> <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
C)使用标签显示数据
<table width="800px" border="1"> <tr> <th>姓名</th> <th>生日</th> </tr> <c:forEach items="${list}" var="stu"> <tr> <td>${stu.name}</td> <td>${stu.birthday}------ <fmt:formatDate value="${stu.birthday}" pattern="yyyy-MM-dd"></fmt:formatDate></td> </tr> </c:forEach> </table>
12.资源在WEB-INF目录
此目录下的动态资源不可被直接访问,只能通过请求转发的方式来访问。
增加登陆业务判断:
@Controller
public class WebInfAction {
@RequestMapping("/showIndex")
public String showIndex(){
System.out.println("访问index.jsp");
return "index";
}
@RequestMapping("/showMain")
public String showMain(){
System.out.println("访问main.jsp");
return "main";
}
@RequestMapping("/showLogin")
public String showLogin(){
System.out.println("访问login.jsp");
return "login";
}
//登录的业务判断
@RequestMapping("/login")
public String login(String name, String pwd, HttpServletRequest request){
if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
return "main";
}else{
request.setAttribute("msg","用户名或密码不正确!");
return "login";
}
}
}
13.SpringMVC的拦截器
针对请求和响应进行的额外的处理,在请求和响应的过程中添加预处理、后处理和最终处理。
14.拦截器的执行时机
- preHandle():在请求被处理前进行操作,预处理
- postHandle():在请求被处理后,但结果还未渲染前进行操作,可以改变响应结果,后处理
- afterCompletion:所有的请求响应结束后执行的善后工作;清理对象、关闭资源,最终处理
15.拦截器实现的两种方式
- 继承HandleerInterceptorAdapter的父类
- 实现HandleInterceptor接口,推荐使用实现接口的方式
16.拦截器的实现
-
改造登陆方法,在session中存储用户信息,用于权限判断
@RequestMapping("/login") public String login(String name, String pwd, HttpServletRequest request){ if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){ //在session中存储用户信息,用于进行权限验证 request.getSession().setAttribute("users",name); return "main"; }else{ request.setAttribute("msg","用户名或密码不正确!"); return "login"; } }
-
开发拦截器的功能,实现HandleInterceptor接口重写preHandle()方法
if(request.getSession().getAttribute("users") == null){ //此时就是没有登录,打回到登录页面,并给出提示 request.setAttribute("msg","您还没有登录,请先去登录!"); request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response); return false; } return true;//放行请求
-
在springmvc.xml文件中注册拦截器
<mvc:interceptors> <mvc:interceptor> <!--映射要拦截的请求--> <mvc:mapping path="/**"/> <!--设置放行的请求--> <mvc:exclude-mapping path="/showLogin"></mvc:exclude-mapping> <mvc:exclude-mapping path="/login"></mvc:exclude-mapping> <!--配置具体的拦截器实现功能的类--> <bean class="com.jv.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
17.SSM整合的步骤
- 建库和表、新建Maven项目webapp项目
- 修改目录、pom.xml文件(依赖)
- 添加jdbc.properties配置文件
- 添加SqlMapConfig.xml文件(模板)
- 添加applicationContext_dao.xml文件(数据访问层的核心配置文件)
- 添加applicationContext_service.xml文件(业务逻辑层的核心配置文件)
- 添加springmvc.xml文件
- 更新web.xml文件,设置中文编码,并注册springmvc框架和spring框架
- Bean:新建实体类User
- 数据访问层:新建UserDao.java接口及其对应的UserDao.xml文件实现增删查改功能
- 业务逻辑层:新建service接口和实现类
- 添加测试类,完成所有功能的测试
- 界面层:新建控制器,完成所有功能
- 浏览器测试功能