学习目标
第一章-异常处理
知识点-异常处理的思路
1.目标
2.路径
- 异常分类
3.讲解
3.1 异常分类
- 编译时异常,通过try...catch捕获异常|向上抛出异常,否则代码没法写了,从而获取异常信息
- 运行时异常RuntimeException,通过规范代码开发、测试等,减少运行时异常的发生
3.2 处理思路
- dao异常通常抛给Service
- Service异常通常抛给Controller
- Controller把异常抛给前端控制器(SpringMVC框架)
- 由前端控制器(DispatcherServlet)把异常交给异常处理器进行处理
4.小结
- 异常分类
- 编译期异常 : 代码在编译的时候,就已经发现有异常了
- 运行期异常: 代码在运行的额时候,才会出现异常。
- 异常处理思路
- 一级一级的向上抛出,最终交给异常处理器处理
知识点-异常处理的方式
1.目标
2.路径
-
异常处理两种方式
-
自定义异常处理器
-
简单异常处理器
3.讲解
3.1 异常处理两种方式
- 实现Spring的异常处理器接口
HandlerExceptionResolver
,自定义异常处理器- 需要自己编写代码
- 也需要进行配置,配置比较简单。只需要在sringmvc.xml里,配置bean对象即可
- 使用SpringMVC提供好的简单异常处理器
SimpleMappingExceptionResolver
- 不需要自己编写代码
- 但需要进行配置,配置略微麻烦
3.2 自定义异常处理器
3.2.1 步骤
- 创建异常页面,出现异常之后,会打开这个页面给客户端看。
- 创建异常处理器,实现
HandlerExceptionResolver
接口 - 在springmvc.xml中配置异常处理器,把自定义异常处理器类声明成为bean对象
3.2.2 配置示例
- 创建项目,导入依赖
<dependencies>
<!--servlet-api-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
- 编写Controller 模拟抛出异常
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Controller01 {
@RequestMapping("/show")
public void show(int no){
if(no == 1 ){
throw new NullPointerException("出现空指针异常了~!");
}else if(no == 2) {
throw new ClassCastException("出现类型转化异常了~!");
}else{
throw new RuntimeException("出现运行时异常了~!");
}
}
}
- 准备异常页面 error.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/10/6
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>服务器开小差了,一会再过来试试吧~!${msg}</h2>
</body>
</html>
- 创建自定义异常处理器
package com.itheima.exception;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
自定义异常处理器
1. 定义类,实现接口HandlerExceptionResolver
2. 实现方法resolveException方法,通过返回值来跳转到页面,带上数据显示
3. 要配置这个类,只要把这个类交给spring管理即可
*/
//@Component
public class MyExceptionResolver implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
//1. 创建ModelAndView对象
ModelAndView mv = new ModelAndView();
//2. 设置跳转的页面
mv.setViewName("error");
//3. 设置数据
mv.addObject("msg" , ex.getMessage());
return mv;
}
}
- 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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1. 扫描包-->
<context:component-scan base-package="com.itheima"/>
<!--2. 注解驱动-->
<mvc:annotation-driven/>
<!--3. 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--4. 静态资源处理-->
<mvc:default-servlet-handler/>
</beans>
3.3 简单异常处理器
SpringMVC已经定义好了异常处理器,在使用时根据项目情况,配置异常与视图的映射关系
3.3.1 配置步骤
- 创建异常页面。可以根据实际需求创建错误页面,比如:
- 所有异常,都使用同一页面error02.jsp
- 不同异常,配置不同的错误页面
- 类转换异常,配置castError.jsp
- 空指定异常,配置nullError.jsp
- ...
- 在springmvc.xml中,配置简单异常处理器
SimpleMappingExceptionResolver
3.3.2 配置示例
- 准备通用的异常页面
error02.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/10/6
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>服务器开小差了,一会再过来试试吧~!22222222</h2>
</body>
</html>
- 空指针异常页面 nullpoint.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/10/6
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>服务器开小差了,一会再过来试试吧~!2 空指针异常!</h2>
</body>
</html>
- 类型转换异常页面 classcast.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/10/6
Time: 8:58
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>服务器开小差了,一会再过来试试吧~!2 类型转换异常!</h2>
</body>
</html>
- 在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">
<!--1. 扫描包-->
<context:component-scan base-package="com.itheima"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:default-servlet-handler/>
<!--
5. 配置简单异常处理器
5.1 只要配置这个类SimpleMappingExceptionResolver ,注入属性即可
defaultErrorView : 通用的异常映射,只要报错就会跳转到这个指定的error02页面
exceptionMappings:给某一种特定的异常,指定的跳转的页面,如果出现了这种特定的异常
那么springmvc就会跳转到这些页面,而不是通用的页面!
-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error02"/>
<property name="exceptionMappings">
<props>
<prop key="java.lang.NullPointerException">nullpoint</prop>
<prop key="java.lang.ClassCastException">classcast</prop>
</props>
</property>
</bean>
</beans>
4.小结
- 创建一个Java类,实现
HandlerExceptionResolver
接口:编写代码处理异常 - 把创建好的异常处理器注册bean
第二章-拦截器
知识点-拦截器入门
1. 目标
2. 路径
- 拦截器概述
- 自定义拦截器入门
- 创建自定义的拦截器实现handlerInterceptor接口,实现preHandler的方法 前置拦截
- 配置它 springmvc.xml mvc:interceptors标签 1. 拦截的路径规则, 2.处理类
3. 讲解
3.1 拦截器概述
- SpringMVC中的拦截器 (Interceptor),相当于web开发中的过滤器Filter,用于对Controller进行预处理(前置增强)和后处理(后置增强)
- 多个拦截器形成的一条链,称为拦截器链(Interceptor chain)
- 当访问被拦截的(具体的目标Controller)方法时,拦截器链中的拦截器就会按照之前定义的顺序被调用
- 拦截器也是AOP思想的具体实现
3.2 拦截器和过滤器的区别
区别 | 过滤器Filter | 拦截器 |
---|---|---|
使用范围 | 是Servlet规范的一部分,任何Javaweb项目都可以使用 | 是SpringMVC自己的,只有使用了SpringMVC框架,才可以使用拦截器 |
拦截范围 | 配置了urlPatterns="/*"之后,可以对所有要访问的资源进行拦截 | 如果配置的是 /** , 会拦截DispatcherServlet抓到的所有资源(请求) |
拦截精度 | 只能拦截某个请求,不能对Servlet里某个方法进行拦截 , | 可以精细到拦截Controller里的某个方法 |
- 拦截精度答疑:
- 因为servlet里面写映射地址的时候,是在类上面写的,一个servlet只会有一个映射地址,
- controller不一样,它里面可以有很多方法,每一个方法都对应一个不同的路径地址。
3.3 快速入门
3.3.1 准备工作
- 创建maven项目,准备SpringMVC的环境
- 创建控制器
Controller01
,准备一个目标方法show()
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Controller01 {
@RequestMapping("/show")
public String show(){
System.out.println("调用了Controller01的show方法~!");
return "success";
}
}
3.3.2 实现步骤
- 创建一个Java类,实现
HandlerInterceptor
接口- 重写接口的方法,共三个方法:
preHandle, postHandle, afterCompletion
- 重写接口的方法,共三个方法:
- 在springmvc.xml中配置拦截器
3.3.3 功能实现
- 创建Java类,实现
HandlerInterceptor
接口
package com.itheima.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
定义拦截器
1. 定义类,实现接口HandlerInterceptor
2. 重写3个方法 preHandle | postHandle | afterCompletion
*/
public class MyInterceptor implements HandlerInterceptor {
//拦截到请求的时候调用
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
return false;
}
//controller方法调用之后,执行这个方法
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
//页面渲染完毕之后,调用这个方法!
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
- 在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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1. 扫描包-->
<context:component-scan base-package="com.itheima"/>
<!--2. 注解驱动-->
<mvc:annotation-driven/>
<!--3. 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--4. 静态资源处理-->
<mvc:default-servlet-handler/>
<!--5. 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/show"/>
<bean class="com.itheima.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
4. 小结
- 拦截器,在进入 controller之前拦截。
- 实现HandlerInterceptor接口, preHandler方法, 返回true则可以调用controller方法,false则不会调用controller
- 需要在springmvc.xml配置
- 作用:权限控制(认证,有没有登陆),微服的链路跟踪, 记录用户的访问日志
知识点-拦截器进阶
1.目标
2.路径
- 拦截器的放行
- 拦截后跳转
- 拦截器的路径
- 拦截器的其它方法
- 多个拦截器执行顺序
3.讲解
3.2.3.1 拦截器的放行
3.2.3.2 拦截后跳转
拦截器的处理结果,莫过于两种:
放行: 如果后面还有拦截器就执行下一个拦截器,如果后面没有了拦截器,就执行Controller方法
拦截: 但是注意,拦截后也需要返回到一个具体的结果(页面,Controller)。
- 在preHandle方法返回false,通过reque
- st进行转发,或者通过response对象进行重定向,输出
package com.itheima.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
定义拦截器
1. 定义类,实现接口HandlerInterceptor
2. 重写3个方法 preHandle | postHandle | afterCompletion
*/
public class MyInterceptor implements HandlerInterceptor {
/*
拦截到请求的时候调用, 可以在这个方法里面拦截请求或者放行请求, 到底放行还是不放行,取决于返回值。
返回true : 即表示放行这个请求,把这个请求交给下一个拦截器或者controller去处理
返回false : 即表示不放行!不放行请求,也需要对这个请求进行处理,一般有两种方式:
1. 直接把一句简单的话写出去!
2. 也可以跳转到某一个页面
2.1 跳转页面的时候,可以使用请求转发,也可以使用重定向来跳转
2.2 跳转页面的路径写法最好使用绝对路径的写法,尽量不要使用相对路径来跳转!。
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
//1. 作出响应: 把一句简单的话写出去!
//response.setContentType("text/html;charset=utf-8");
//response.getWriter().write("您没有访问权限!");
//2. 作出响应: 跳转到某个页面 :index.jsp
//request.getRequestDispatcher("/index.jsp").forward(request,response);
//response.sendRedirect("/index.jsp");
return false;
}
}
3.2.3.3 拦截器的路径
<!--
5. 配置拦截器
mvc:interceptors : 用来配置拦截器的,可以配置很多个拦截器
mvc:interceptor : 用来配置拦截器,具体的配置
mvc:mapping:用于配置拦截什么样的地址
path: 指定具体拦截的地址
bean : 配置具体的拦截器来,也就是用什么拦截器去拦截上面的请求地址!
-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截路径解释:
1. 可以拦截具体某一种请求路径
path="/show" =========== localhost:82/show 可以拦截
path="/show" =========== localhost:82/haha 不可以拦截
2. 也可以使用通配符来拦截某一类|所有的请求 (仅局限于DispatcherServlet能抓到的请求)
/user/** =========== localhost:82/user/add localhost:82/user/update/a/b/c 可以拦截
/** =========== 只要是DispatcherServlet能抓到的请求,都能拦截
/* 只能匹配一级目录下的任意名字
/** 能匹配任意级别目录下的任意名字。
2.1 为什么配置成/**了之后, jsp页面不拦截,但是静态资源就会拦截呢?
a. DispatcherServlet 映射路径是 / 覆盖了Tomcat了里面的DefaultServlet的 / 所以能抓到静态资源的
请求,也就能拦截静态资源
b. 之所以没有办法拦截jsp的页面,是因为DispatcherServlet没有办法抓到有关jsp页面的请求,
DispatcherServlet 映射路径是 /
Tomcaty里面处理jsp页面请求的 JspServlet 映射路径是 *.jsp
*.jsp > /
3. 可以在这里让这个拦截器,不要拦截静态资源。
<mvc:exclude-mapping path="/html/**"/>
<mvc:exclude-mapping path="/css/**"/>
<mvc:exclude-mapping path="/js/**"/>
-->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/html/**"/>
<mvc:exclude-mapping path="/css/**"/>
<mvc:exclude-mapping path="/js/**"/>
<bean class="com.itheima.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
3.2.3.4 拦截器的其它方法
- afterCompletion 在目标方法完成视图层渲染后执行。
- postHandle 在被拦截的目标方法执行完毕获得了返回值后执行。
- preHandle 被拦截的目标方法执行之前执行。
package com.itheima.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
定义拦截器
1. 定义类,实现接口HandlerInterceptor
2. 重写3个方法 preHandle | postHandle | afterCompletion
*/
public class MyInterceptor implements HandlerInterceptor {
...
//controller方法调用之后,执行这个方法 , 如果controller方法不执行,那么这个postHandle方法不会执行!
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
//页面渲染完毕之后,调用这个方法!
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
3.2.3.5 多个拦截器执行顺序
我们可以配置多个拦截器, 所以就存在一个优先级问题了.多个拦截器的优先级是按照配置的顺序决定的。
- 如果有多个拦截器的,并且最终也执行到了Controller的方法,那么一定会执行他们的postHandle方法和afterCompletion方法
- 只要是到了Controller,那么一定会有postHandle方法执行
- 如果一开始就不放行,那么只会执行一个preHandle方法
- 如果有拦截器链存在,第一个选择放行,第二个(后面的某一个拦截器)选择不放行,那么最后也还是会执行前面放行的拦截器的afterCompletion方法
- 拦截器
拦截器1
package com.itheima.interceptor02;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor01 implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor01::preHandle...");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor01::postHandle...");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor01::afterCompletion...");
}
}
拦截器2
package com.itheima.interceptor02;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor02 implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor02::preHandle...");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor02::postHandle...");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor02::afterCompletion...");
}
}
拦截器3
package com.itheima.interceptor02;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor03 implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor03::preHandle...");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor03::postHandle...");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor03::afterCompletion...");
}
}
- controller
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Controller01 {
@RequestMapping("/show")
public String show(){
System.out.println("调用了Controller01 的show方法~!");
return "success";
}
}
- 配置
<!--拦截器链-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/show"/>
<bean class="com.itheima.interceptor02.MyInterceptor01"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/show"/>
<bean class="com.itheima.interceptor02.MyInterceptor02"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/show"/>
<bean class="com.itheima.interceptor02.MyInterceptor03"/>
</mvc:interceptor>
</mvc:interceptors>
- 结果
4.小结
-
拦截器属于链式模式
-
只有preHandler方法才有返回true 放行,false 拦截
-
拦截后也需要对此次请求做出响应(跳转页面|跳转Controller)
-
拦截器执行方法顺序 preHandle->postHandle->afterCompletion
-
存在拦截器链时,按照配置文件顺序执行,自上而下。先进(preHandle)后出(postHandle,afterCompletion)
-
当我们的springmvc配置了静态资源处理,并且拦截器配置成了 /** ,那么拦截器也会拦截静态资源。如果非要让拦截器不拦截静态资源:
-
手动指定静态资源的路径,然后拦截器排除具体静态资源
-
mvc:default-servlet-handler 和 拦截器 /** 还是照常写
需要在web.xml中,添加DefaultServlet的映射路径
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> <url-pattern>*.html</url-pattern> <url-pattern>*.js</url-pattern> </servlet-mapping>
- DispatcherServlet 只拦截*.do
-
第三章 SSM整合【重点】
案例-环境准备
1.需求
2.分析
- 创建数据库和表
- 创建Maven工程(web工程)
- 导入坐标
- 创建实体类
- 拷贝log4J日志到工程
3.实现
4.3.1 创建数据库和表结构
create database ssm;
use ssm;
create table account(
id int primary key auto_increment,
name varchar(40),
money double
)character set utf8 collate utf8_general_ci;
insert into account(name,money) values('zs',1000);
insert into account(name,money) values('ls',1000);
insert into account(name,money) values('ww',1000);
4.3.2 创建Maven工程
-
创建web项目
-
导入依赖
<properties>
<!-- 版本锁定 -->
<spring.version>5.0.2.RELEASE</spring.version>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.6.6</slf4j.version>
<mysql.version>5.1.47</mysql.version>
<mybatis.version>3.4.6</mybatis.version>
</properties>
<dependencies>
<!--Spring:ioc和aop,事务-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!--SpringMVC,jstl,json转换-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.19</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
</dependencies>
- 编写实体类
package com.itheima.bean;
import lombok.Data;
@Data
public class Account {
private int id;
private String name;
private double money;
}
- 拷贝log4J配置文件到工程
在resource目录下创建一个
log4j.properties
文件
##设置日志记录到控制台的方式
log4j.appender.std=org.apache.log4j.ConsoleAppender
log4j.appender.std.Target=System.err
log4j.appender.std.layout=org.apache.log4j.PatternLayout
log4j.appender.std.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n
##设置日志记录到文件的方式
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=mylog.txt
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
##日志输出的级别,以及配置记录方案 debug info warn error
log4j.rootLogger= trace,std,file
4 小结
- 按步骤操作
案例-整合SpringMVC
1.需求
2.分析
- 创建AccountController, 定义方法 添加注解
- 创建springmvc.xml(开启包扫描, 注册视图解析器,静态资源处理, 注解驱动)
- 配置web.xml(前端控制器, 编码过滤器)
- 测试
3.实现
- 创建AccountController.java
package com.itheima.controller;
import com.itheima.bean.Account;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class AccountController {
/*
查询所有
*/
@RequestMapping("/findAll")
public String findAll(){
System.out.println("调用了AccountController的findAll方法~!");
return "success";
}
}
- 创建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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1. 扫描包-->
<context:component-scan base-package="com.itheima"/>
<!--2. 注解驱动-->
<mvc:annotation-driven/>
<!--3. 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--4. 静态资源处理-->
<mvc:default-servlet-handler/>
</beans>
- 在web.xml里面配置前端控制器和编码过滤器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--配置前端控制器 DispatcherServlet-->
<servlet>
<servlet-name>dispatcher</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>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--springmvc已经定义好了过滤器,可以帮助我们解决post请求,中文乱码的问题,我们只需要配置即可-->
<filter>
<filter-name>char</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>
</filter>
<filter-mapping>
<filter-name>char</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
4. 小结
- 创建Controller, 创建方法 添加注解
- 创建springmvc.xml(开启包扫描, 注册视图解析器,忽略静态资源,开启注解驱动)
- 配置web.xml(前端控制器, 编码过滤器)
案例-整合Spring
1. 需求
2. 分析
- 编写Service
- 在Controller里面注入Service
- 在controller里面调用service的方法
3. 实现
- 编写AccountService.java
package com.itheima.service;
import com.itheima.bean.Account;
import java.util.List;
public interface AccountService {
/*
查询所有账户
*/
List<Account> findAll();
}
- 编写AccountServiceImpl.java
package com.itheima.service.impl;
import com.itheima.bean.Account;
import com.itheima.dao.AccountDao;
import com.itheima.service.AccountService;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Service
public class AccountServiceImpl implements AccountService {
public List<Account> findAll() {
System.out.println("调用了AccountServiceImpl的findAll方法~!~");
return null;
}
}
- 在AccountController调用AccountService
package com.itheima.controller;
import com.itheima.bean.Account;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class AccountController {
//注入service
@Autowired
private AccountService as;
/*
查询所有
*/
@RequestMapping("/findAll")
public String findAll(){
System.out.println("调用了AccountController的findAll方法~!");
//调用service
List<Account> list = as.findAll();
System.out.println("list = " + list);
return "success";
}
}
4. 小结
- 创建业务接口与实现类
- 在实现类上加@Service 把交给spring容器管理
- AccountController 注入进来 @Autowired, 调用业务方法
案例-整合Mybatis
1. 初级版本 (独立运行)
1.目标
2.路径
- 创建Dao接口, 定义方法, 添加注解
- 创建SqlMapConfig.xml
- 编写Java代码测试
3.讲解
- 创建AccountDao.java, 添加注解
package com.itheima.dao;
import com.itheima.bean.Account;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import java.util.List;
public interface AccountDao {
@Select("select * from account")
List<Account> findAll();
}
- 编写MyBatis核心配置文件:SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--核心配置文件,包含两部分内容: 如何连接数据库, dao文件|映射在哪里-->
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.itheima.dao"/>
</mappers>
</configuration>
- 测试运行结果
package com.itheima.test;
import com.itheima.bean.Account;
import com.itheima.dao.AccountDao;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestAccountDao {
@Test
public void testFindAll() throws IOException {
//1. 读取核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//2. 构建构建器SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. 构建SqlSessionFactory
SqlSessionFactory sessionFactory = builder.build(is);
//4. 构建SqlSession
SqlSession session = sessionFactory.openSession();
//5. 问SqlSession要dao的代理对象
AccountDao dao = session.getMapper(AccountDao.class);
//6. 调用方法
List<Account> list = dao.findAll();
System.out.println("list = " + list);
//7. 收尾: 关闭sqlsession | 提交事务
session.commit();
session.close();
}
}
4.小结
- 创建Dao接口, 定义方法, 添加注解
- 创建SqlMapConfig.xml
- 编写Java测试代码
2. 终极版本(整合运行)
1.需求
2.分析
- 初级版本存在的问题
- 连接池还是用的MyBatis自带的 ----> 用第三方的连接池,通过Spring管理
- 事务还是由MyBatis管理 ----> 通过Spring管理事务
- 扫描Dao还是由MyBatis加载的 ----> 通过Spring扫描Dao
- SqlSessionFactory还是我们自己构建的 ----> 通过Spring管理SqlSessionFactory
3. 实现
3.1 Spring接管Mybatis的SqlSessionFactory工厂
- 创建applicationContext.xml (由于整合Mybatis的配置有点多,所以这里可以写一个新的配置文件。)
- 引入外部的数据源(连接池)
- 由Spring来管理SqlSessionFactory工厂
- 由Spring来扫描dao接口包
- 这么做的目的只有一个: 就是顶替掉mybatis的核心配置文件SqlMapConfig.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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1. 导入外部的连接池(数据源)-->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driverClass}"/>
<property name="jdbcUrl" value="${db.jdbcUrl}"/>
<property name="user" value="${db.user}"/>
<property name="password" value="${db.password}"/>
</bean>
<!--
2. 由Spring来接管mybatis的SqlSessionFactory工厂
2.1 由Spring来接管|创建SqlSessionFactory工厂是有好处的。
2.2 其实在背后Spring不仅创建了SqlSessionFactory的工厂,它还会创建出来SqlSession对象
2.3 不仅创建了SqlSession对象,还会创建出来dao的代理对象,并且会把这个代理对象丢到
Spring的容器|工厂里面管理起来。
2.4 这样子做了之后,我们在service层里面想要dao对象就很简单了,只要让spring注入即可!
-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--由于SqlsessionFactory最终是可以操作数据库的,所以要给它注入DataSource-->
<property name="dataSource" ref="dataSource"/>
<!--给JavaBean类起别名-->
<property name="typeAliasesPackage" value="com.itheima.bean"/>
<!--可以把一部分内容配置在SQLMapConfig.xml里面,然后在这里导入!-->
<!--<property name="configLocation" value="SqlMapConfig.xml"/>-->
</bean>
<!--3. 由Spring来扫描 dao| 映射文件-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.dao"/>
</bean>
</beans>
3.2 配置 spring 的事务
mybatis默认不会自动提交: setAutoCommit(false) , 所以对于增伤改的动作,需要提交事务才行。在 applicationContext.xml中编写
<!--
4. 由Spring来管理事务
4.1 Spring管理事务,有一个特征: 就是由管理员来管理事务
4.2 管理员是谁,得看dao层使用的技术来决定。
如果dao层使用的技术是 jdbc|mybatis ======= DataSourceTransactionManager
如果dao层使用的技术是 hibernate ========= HibernateTransactionManager
4.3 操作事务需要用到连接对象,所以要把DataSource对象给注入进来
-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务的注解开关-->
<tx:annotation-driven transaction-manager="transactionManager"/>
3.3 配置applicationContext
由于配置
springmvc
的时候,写了springmvc.xml
, 配置Mybatis
的时候,有applicationContext.xml
但是项目启动的时候,解析的入口是在web.xml
里面配置。此时存在两个文件,如何抉择呢?有三种方式可供选择。
-
方式一:别写applicationContext.xml了, 直接把applicationContext.xml里面的配置定义在springmvc.xml
-
方式二: 名字上面下功夫.
<!--初始化参数:加载配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</init-param>
- 方式三: 在springmvc.xml 引入applicationContext.xml【推荐】
在springmvc.xml中导入applicationContext.xml , 然后在web.xml中只需要引入springmvc.xml即可
<!--5. 导入applicationContext.xml-->
<import resource="applicationContext.xml"/>
3.4 在service中调用dao
package com.itheima.service.impl;
import com.itheima.bean.Account;
import com.itheima.dao.AccountDao;
import com.itheima.service.AccountService;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Transactional
@Service
public class AccountServiceImpl implements AccountService {
//注入dao
@Autowired
private AccountDao dao;
public List<Account> findAll() {
System.out.println("调用了AccountServiceImpl的findAll方法~!");
return dao.findAll();
}
}
4. 小结
- 细节处理
-
- 使用xml管理事务!
- 数据源连接的账号密码可以提出来使用properties来写!
- mapper能不能使用xml来做!
- 别名怎么整?
- sqlMapconfig.xml文件还有没有存在的必要!
-
第四章-HibernateValidator【拓展】
表单校验重要性
表单校验保障了数据有效性、安全性
表单校验分类
校验位置
客户端校验(前端页面)
服务端校验
校验内容与方式
格式校验
- 客户端:使用js, 利用正则表达式等 (校验)
- 服务端:使用校验框架(Hibernate Validator) , 如果以后做后台的,那么一般都需要对数据进行校验!
业务校验
- 客户端:使用ajax发送要校验的数据,后台完成逻辑校验后返回结果 (校验用户名是否可用)
- 服务端:接收到完整请求后,在执行业务操作前,完成逻辑校验
表单校验规则
-
长度:例如用户名长度,评论字符数量
-
非法字符:例如用户名组成
-
数据格式:例如Email格式、IP地址格式
-
边界值:例如转账金额上限,年龄上下限
-
重复性:例如用户名是否重复
-
...等
表单校验框架
hibernate-validator
Hibernate框架中包含一套独立的校验框架hibernate-validator,实现了JSR303的规范
JSR介绍
JSR全称(Java Specification Requests):Java 规范提案
第303个:提供bean属性相关校验规则
JSR是由JCP(Java Community Process):Java社区提出来的,每年都找各行业的人来提需求,之后就来制定成JSR规提案
依赖说明
tomcat7:搭配hibernate-validator版本5.x.x.Final
tomcat8.5以上的:搭配hibernate-validator版本6.x.x.Final
在这里,我们使用6.1.0.Final
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
如果使用tomcat7插件运行项目,那么应该使用5.x的版本
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
</dependency>
使用案例
创建maven web工程 略
① pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
<!--tomcat7 ,请使用以下依赖替换上面的6.1.0的版本 -->
<!--
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
</dependency> -->
</dependencies>
② User
package com.itheima.bean;
import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.Min;
@Data
public class User {
@NotBlank(message = "用户名不能为空!")
private String username;
@Min(value = 18 , message = "年龄不达标!")
private int age;
}
③ UserController
package com.itheima.controller;
import com.itheima.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
import java.util.List;
@Controller
public class UserController {
/*
接收一个用户信息,并且封装到user对象里面去。
1. 如果无法封装,那么可以从errors参数里面得到错误的信息
2. 如果希望把这个错误的信息归还给页面显示,可以往model对象里面设置
*/
@RequestMapping("/add")
public String add(@Valid User user , Errors errors , Model model){
//1. 判断校验是否有错误
if(errors.hasErrors()){ // 表示有错误
//2. 得到所有的错误信息
List<FieldError> list = errors.getFieldErrors();
//3. 遍历集合,取出每一个错误的属性。
for (FieldError fieldError : list) {
//4. 得到报错的属性名称
String field = fieldError.getField();
//5. 得到报错的具体信息
String message = fieldError.getDefaultMessage();
if( message.contains("NumberFormatException")){
message = "输入有误!";
}
//6. 把信息装到model里面去。
model.addAttribute(field , message);
}
return "index";
}
System.out.println("user=" + user);
//表示没有错误!
return "success";
}
}
④ 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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--1. 扫描包-->
<context:component-scan base-package="com.itheima"/>
<!--2. 注解驱动-->
<mvc:annotation-driven/>
<!--3. 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--4. 静态资源处理-->
<mvc:default-servlet-handler/>
</beans>
⑤ index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<form action="/add" method="post">
<table>
<tr>
<td>用户名</td>
<td><input name="username"/></td>
<td>${username}</td>
</tr>
<tr>
<td>年龄</td>
<td><input name="age"/></td>
<td>${age}</td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="提交"/></td>
</tr>
</table>
</form>
</body>
</html>
⑥ success.jsp
<%--
Created by IntelliJ IDEA.
User: xiaomi
Date: 2021/8/26
Time: 14:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>这是成功的页面~!</h2>
</body>
</html>
⑦ web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--配置前端控制器 DispatcherServlet-->
<servlet>
<servlet-name>dispatcher</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>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
总结:
异常处理
1. 自定义异常处理器
2.2 定义类,实现接口: HandlerExceptionResolver
2.3. 配置成Bean即可
2. 简单异常处理器
2.1 不需要去代码了,只需要配置即可,只能让错误出现的时候,跳转到某一个页面上!
拦截器
1. 拦截器属于SpringMVC的产物,只有使用springmvc环境,才能使用它。
2. 它主要是用来拦截controller的请求,可以看成是对controller进行前置处理和后置处理。
3. 怎么使用?
3.1 定义类,实现接口HandlerInterceptor
3.2 配置拦截器即可
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/show"/>
<bean class="拦截器的具体路径"/>
4. 细节:
4.1 拦截器里面有3个方法: preHandle | postHandle | afterCompletion
preHandle : 在执行目标(controller)方法之前调用。
postHandle : 在执行目标方法之后调用
afterCompletion: 在页面渲染完毕,调用
4.2 当我们在拦截器里面拦截下来了某一个请求,那么还是需要对这个请求进行处理的
可以写一句话出去或者跳转到某个页面显示。否则用户将会看到一片空白!
4.3 到底是拦截还是放行,取决的是preHandle里面的返回值:
true : 放行
false : 拦截
SSM整合
SqlSessionFactoryBean : 用于帮助创建Dao的代理对象,丢到spring的容器里面
MapperScannnerConfiguer : 用于扫描dao的映射文件