必要前提
- form表单的enctype取值必须是:multipart/form-data (默认值是:
application/x-www-form-urlencoded
) enctype:是表单请求正文的类型 - method属性取值必须是Post
- 提供一个文件选择域
<input type="file" />
环境搭建
创建maven项目
导入相关依赖
在
pom.xml
中导入相关依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!--spring版本锁定-->
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>7.0.47</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>7.0.47</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
配置核心控制器
在
web.xml
中配置SpringMVC核心控制器
<web-app>
<!--配置SpringMVC核心控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet启动时加载对象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置springmvc过请求过滤器,/表示所有请求都经过springmvc处理-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
编写核心配置文件
编写SpringMVC核心配置文件
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 配置创建spring容器要扫描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--SpringMVC注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
单文件上传
配置文件解析器
在
springmvc.xml
中配置文件解析器
<!--
配置文件上传解析器
id的值是固定的
class的值也是固定的
-->
<beanid="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--上传文件总大小-->
<property name="maxUploadSize" value="5242800"/>
<!--上传单个文件的大小-->
<property name="maxUploadSizePerFile"value="5242800"/>
<!--上传文件的编码类型-->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
编写文件上传页面
编写文件上传页面
upload.jsp
<h1>SpringMVC方式文件上传</h1>
<form action="${pageContext.request.contextPath }/file/upload2" method="post" enctype="multipart/form-data" >
文件描述:<input type="text" name="desc"><br>
文件上传:<input type="file" name="file"><br>
<input type="submit" value="开始上传">
</form>
编写控制层代码
编写控制层代码
FileController
@RequestMapping(path="/upload2",method = RequestMethod.POST)
public String upload2(MultipartFile file) throws Exception {
//1. 获取一个文件输出的磁盘路径
String path = "C:\\Users\\Administrator\\Desktop\\upload";
File dir = new File(path);
if(!dir.exists()){
dir.mkdir();
}
//2. 获取文件名称
String filename = file.getOriginalFilename();
//3. 获取文件内容
InputStream is = file.getInputStream();//获取文件内容
//4. 创建输出流
OutputStream os = new FileOutputStream(path + "/" + filename);
//5. 将文件内容通过输出流写到磁盘文件中
int i = 0;
byte[] bys = new byte[1024];
while ((i = is.read()) != -1) {
os.write(bys, 0, i);
}
os.close();
return "success";
}
多文件上传
编写文件上传页面
编写文件上传页面
upload.jsp
<h1>SpringMVC方式多选文件上传</h1>
<form action="${pageContext.request.contextPath }/file/multi" method="post" enctype="multipart/form-data" >
文件描述:<input type="text" name="desc"><br>
文件上传:<input type="file" name="files"><br>
文件上传:<input type="file" name="files"><br>
<input type="submit" value="开始上传">
</form>
编写控制层代码
编写控制层代码
FileController
@RequestMapping(path="/multi",method = RequestMethod.POST)
public String upload3(MultipartFile[] files) throws Exception {
//1. 获取一个文件输出的磁盘路径
String path = "C:\\Users\\Administrator\\Desktop\\upload";
File dir = new File(path);
if(!dir.exists()){
dir.mkdir();
}
//遍历文件集合
for (MultipartFile file : files) {
//2. 获取文件名称
String filename = file.getOriginalFilename();
//3. 获取文件内容
InputStream is = file.getInputStream();//获取文件内容
//4. 创建输出流
OutputStream os = new FileOutputStream(path + "/" + filename);
//5. 将文件内容通过输出流写到磁盘文件中
int i = 0;
byte[] bys = new byte[1024];
while ((i = is.read()) != -1) {
os.write(bys, 0, i);
}
os.close();
}
return "success";
}
SpringMVC拦截器
1. SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
3. 拦截器和过滤器的功能比较类似,有区别
1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
2. 拦截器是SpringMVC框架独有的。
3. 过滤器配置了/*,可以拦截任何资源。
4. 拦截器只会对控制器中的方法进行拦截。
4. 拦截器也是AOP思想的一种实现方式
5. 想要自定义拦截器,需要实现HandlerInterceptor接口。
环境搭建
创建maven项目
导入相关依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!--spring版本锁定-->
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>7.0.47</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>7.0.47</version>
</dependency>
</dependencies>
</project>
编写核心控制器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!--配置SpringMVC核心控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet启动时加载对象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置springmvc过请求过滤器,/表示所有请求都经过springmvc处理-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
编写核心配置文件
编写核心配置文件
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 配置创建spring容器要扫描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--SpringMVC注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
编写页面代码
编写页面代码
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<title>SpringMVC拦截器</title>
</head>
<body>
<h1>SpringMVC拦截器</h1>
<a href="${pageContext.request.contextPath}/user/add">添加用户</a>
</body>
</html>
编写控制层代码
package com.itheima.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/add")
public String add(){
System.out.println("控制层add方法执行了.....");
return "success";
}
}
自定义拦截器
创建拦截器
编写一个普通类实现HandlerInterceptor接口
package com.itheima.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle拦截器执行了.....");
return true;
}
}
配置拦截器
在
springmvc.xml
中配置拦截器(掌握)
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!--
配置拦截器拦截的方法
/** 代表拦截所有方法
/user/* 代表拦截/user路径下的所有方法
-->
<mvc:mapping path="/user/*"/>
<!--配置不拦截的方法
<mvc:exclude-mapping path="" />
-->
<bean id="myInterceptor1" class="com.itheima.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截器的细节
拦截器的放行
放行的含义是指,如果有下一个拦截器就执行下一个,如果该拦截器处于拦截器链的最后一个,则执行控制器中的方法。
拦截器中方法的说明
方法名 | 说明 |
---|---|
preHandle() | 方法将在请求处理之前进行调用, 该方法的返回值是布尔值Boolean类型的,当它返回为false时, 表示请求结束, 后续的Interceptor和Controller都不会再执行; 当返回值为true时就会继续调用下一个Interceptor的preHandle方法 |
postHandle() | 该方法是在当前请求进行处理之后被调用, 前提是preHandle方法的返回值为true时才能被调用, 且它会在DispatcherServlet进行视图返回渲染之前被调用, 所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作 |
afterCompletion() | 该方法将在整个请求结束之后, 也就是在Dispatcher Servlet渲染了对应的视图之后执行, 前提是preHandle方法的返回值为true时才能被调用,常用于接口返回修改 |
1. `preHandle()`是controller方法执行前拦截的方法
1. 可以使用request或者response跳转到指定的页面
2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
3. return false不放行,不会执行controller中的方法。
2. `postHandle()`是controller方法执行后执行的方法,在JSP视图执行前。
1. 可以使用request或者response跳转到指定的页面
2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
3. `afterCompletion()`方法是在JSP执行后执行
1. request或者response不能再跳转页面了
拦截器的作用路径
<mvc:interceptor>
<!--
配置拦截器拦截的方法
/** 代表拦截所有方法
/user/* 代表拦截/user路径下的所有方法
-->
<mvc:mapping path="/user/*"/>
<!--配置不拦截的方法
<mvc:exclude-mapping path="" />
-->
<bean id="myInterceptor1" class="com.itheima.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
多个拦截器配置
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*"/>
<bean id="myInterceptor1" class="com.itheima.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/*"/>
<bean id="myInterceptor2" class="com.itheima.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截器实现权限控制
登录代码编写
在登陆页面输入用户名密码,点击登陆,通过用户名密码进行查询,如果登陆成功,则将用户信息实体存入session,然后跳转到首页,如果登陆失败则继续回到登陆页面
表现层
package com.itheima.web;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* @Author 王磊
* @Date 2019/11/1/001
*/
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login")
public String login(@RequestParam(name="user") String username , String password , Model model , HttpSession session){
//用户登录
User user = userService.login(username, password);
//判断是否登录成功 , 响应页面
//用户登录失败
if(user==null){
model.addAttribute("msg","用户名或密码错误");
return "login";
}
//登录成功 , 跳转到用户列表页面
//保存到Session域对象
session.setAttribute("user",user);
//页面跳转 , 注意不能直接跳转到list.jsp页面
return "redirect:/user/findAll";
}
}
业务层
package com.itheima.service;
import com.itheima.pojo.User;
import java.util.List;
/**
* @Author 王磊
* @Date 2019/11/1/001
*/
public interface UserService {
/**
* 用户登录
* @return
*/
public User login(String username , String password);
}
package com.itheima.service.impl;
import com.itheima.dao.UserDao;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Author 王磊
* @Date 2019/11/1/001
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao ;
@Override
public User login(String username, String password) {
return userDao.findByUsernameAndPassword(username,password);
}
}
数据访问层
package com.itheima.dao;
import com.itheima.pojo.User;
import java.util.List;
/**
* @Author 王磊
* @Date 2019/11/1/001
*/
public interface UserDao {
/**
* 根据用户名或密码查询用户数据
* @param username
* @param password
* @return
*/
public User findByUsernameAndPassword(String username , String password);
}
package com.itheima.dao.impl;
import com.itheima.dao.UserDao;
import com.itheima.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Author 王磊
* @Date 2019/11/1/001
*/
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate ;
@Override
public User findByUsernameAndPassword(String username, String password) {
try {
//queryForObject如果查询到数据会封装返回 , 如果查询不到数据抛出异常
String sql = select * from tb_user where username=? and password = ?";
return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),username,password);
} catch (DataAccessException e) {
e.printStackTrace();
return null ;
}
}
}
配置文件
druid.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/springmvc_02
jdbc.username=root
jdbc.password=zl
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">
<!--开启组件扫描-->
<context:component-scan base-package="com.itheima"> </context:component-scan>
<!--加载属性配置文件-->
<context:property-placeholder location="classpath:druid.properties"></context:property-placeholder>
<!--配置数据库连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--配置jdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--释放静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--配置视图解析器 list /list.jsp-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!--配置字符串编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载SpringMVC配置文件-->
<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>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/js/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/fonts/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/css/*</url-pattern>
</servlet-mapping>
</web-app>
定义拦截器
package com.itheima.interceptor;
import com.itheima.pojo.User;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author 黑马程序员
*/
public class PrivilegeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断用户是否登录
//1. 获取session中保存的用户信息
User user = (User) request.getSession().getAttribute("user");
//2. 判断用户信息是否为null
if (user == null) {
//3. 如果为null代表用户为登录, 返回到登录页面
request.setAttribute("msg", "权限不足 , 请登录!!");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return false;
}
//4. 如果不为null代表用户登录成功 ,放行
return true;
}
}
配置拦截器
此时仍然登陆不上,因为我们需要将登陆请求url让拦截器放行,添加资源排除的配置
<!--配置拦截器信息-->
<mvc:interceptors>
<mvc:interceptor>
<!--配置哪些请求需要拦截-->
<mvc:mapping path="/**"/>
<!--配置哪些请求不需要拦截-->
<mvc:exclude-mapping path="/user/login"></mvc:exclude-mapping>
<mvc:exclude-mapping path="/js/**"></mvc:exclude-mapping>
<mvc:exclude-mapping path="/fonts/**"></mvc:exclude-mapping>
<mvc:exclude-mapping path="/css/**"></mvc:exclude-mapping>
<bean class="com.itheima.interceptor.PrivilegeInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
SpringMVC异常处理
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:
异常环境搭建
导入相关依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!--spring版本锁定-->
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>7.0.47</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>7.0.47</version>
</dependency>
</dependencies>
</project>
编写核心控制器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!--配置SpringMVC核心控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet启动时加载对象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置springmvc过请求过滤器,/表示所有请求都经过springmvc处理-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
编写核心配置文件
编写核心配置文件
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 配置创建spring容器要扫描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--SpringMVC注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
编写前端页面
编写前端页面
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>SpringMVC异常处理</title>
</head>
<body>
<h2>SpringMVC异常处理</h2>
<a href="${pageContext.request.contextPath}/exception/test">异常处理</a>
</body>
</html>
编写控制层代码
编写控制代码
ExceptionController
package com.itheima.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/exception")
public class ExceptionController {
@RequestMapping("/test")
public String testException() throws Exception{
System.out.println("控制器执行成功...");
int i = 10/0;
return "success";
}
}
异常处理方式
在SpringMVC中提供了二种异常处理方式 :
使用Spring MVC提供的简单异常处理器
SimpleMappingExceptionResolver
实现Spring的异常处理接口
HandlerExceptionResolver
自定义自己的异常处理器
简单异常处理器
SpringMVC已经定义好了该类型转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置
<!--配置简单映射异常处理器-->
<bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”> <property name=“defaultErrorView” value=“error”/> 默认错误视图
<property name=“exceptionMappings”>
<map> 异常类型 错误视图
<entry key="com.itheima.exception.MyException" value="error"/>
<entry key="java.lang.ClassCastException" value="error"/>
</map>
</property>
</bean>
自定义异常处理器
编写自定义异常
CustomException
①创建异常处理器类实现HandlerExceptionResolver
②配置异常处理器
③编写异常页面
④测试异常跳转
package com.itheima.exception;
public class CustomException extends Exception {
private String message;
public CustomException(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
定义异常处理器
自定义异常处理器
CustomExceptionResolver
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
ex.printStackTrace();
CustomException customException = null;
//如果抛出的是系统自定义异常则直接转换
if (ex instanceof CustomException) {
customException = (CustomException) ex;
} else {
//如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
customException = new CustomException("系统错误,请与系统管理 员联系!");
}
//创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
//保存错误信息
modelAndView.addObject("message", customException.getMessage());
//设置跳转的视图名称
modelAndView.setViewName("error");
return modelAndView;
}
}
编写错误页面
编写错误页面
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>执行失败</title>
</head>
<body>
执行失败! ${message }
</body>
</html>
配置异常处理器
在
springmvc.xml
中配置异常处理器
<!-- 配置自定义异常处理器 -->
<bean id="handlerExceptionResolver" class="com.itheima.exception.CustomExceptionResolver"/>