必要前提
- form表單的enctype取值必須是:multipart/form-data (默認(rèn)值是:
application/x-www-form-urlencoded
) enctype:是表單請(qǐng)求正文的類型 - method屬性取值必須是Post
- 提供一個(gè)文件選擇域
<input type="file" />
環(huán)境搭建
創(chuàng)建maven項(xiàng)目
導(dǎo)入相關(guān)依賴
在
pom.xml
中導(dǎo)入相關(guān)依賴
<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的初始化參數(shù)钻心,讀取springmvc的配置文件翁逞,創(chuàng)建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet啟動(dòng)時(shí)加載對(duì)象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置springmvc過(guò)請(qǐng)求過(guò)濾器套才,/表示所有請(qǐng)求都經(jīng)過(guò)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">
<!-- 配置創(chuàng)建spring容器要掃描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--SpringMVC注解驅(qū)動(dòng)-->
<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"/>
<!--上傳單個(gè)文件的大小-->
<property name="maxUploadSizePerFile"value="5242800"/>
<!--上傳文件的編碼類型-->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
編寫文件上傳頁(yè)面
編寫文件上傳頁(yè)面
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="開(kāi)始上傳">
</form>
編寫控制層代碼
編寫控制層代碼
FileController
@RequestMapping(path="/upload2",method = RequestMethod.POST)
public String upload2(MultipartFile file) throws Exception {
//1. 獲取一個(gè)文件輸出的磁盤路徑
String path = "C:\\Users\\Administrator\\Desktop\\upload";
File dir = new File(path);
if(!dir.exists()){
dir.mkdir();
}
//2. 獲取文件名稱
String filename = file.getOriginalFilename();
//3. 獲取文件內(nèi)容
InputStream is = file.getInputStream();//獲取文件內(nèi)容
//4. 創(chuàng)建輸出流
OutputStream os = new FileOutputStream(path + "/" + filename);
//5. 將文件內(nèi)容通過(guò)輸出流寫到磁盤文件中
int i = 0;
byte[] bys = new byte[1024];
while ((i = is.read()) != -1) {
os.write(bys, 0, i);
}
os.close();
return "success";
}
多文件上傳
編寫文件上傳頁(yè)面
編寫文件上傳頁(yè)面
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="開(kāi)始上傳">
</form>
編寫控制層代碼
編寫控制層代碼
FileController
@RequestMapping(path="/multi",method = RequestMethod.POST)
public String upload3(MultipartFile[] files) throws Exception {
//1. 獲取一個(gè)文件輸出的磁盤路徑
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. 獲取文件內(nèi)容
InputStream is = file.getInputStream();//獲取文件內(nèi)容
//4. 創(chuàng)建輸出流
OutputStream os = new FileOutputStream(path + "/" + filename);
//5. 將文件內(nèi)容通過(guò)輸出流寫到磁盤文件中
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框架中的攔截器用于對(duì)處理器進(jìn)行預(yù)處理和后處理的技術(shù)羔味。
2. 可以定義攔截器鏈泡挺,連接器鏈就是將攔截器按著一定的順序結(jié)成一條鏈桶唐,在訪問(wèn)被攔截的方法時(shí),攔截器鏈中的攔截器會(huì)按著定義的順序執(zhí)行。
3. 攔截器和過(guò)濾器的功能比較類似绍填,有區(qū)別
1. 過(guò)濾器是Servlet規(guī)范的一部分,任何框架都可以使用過(guò)濾器技術(shù)凹联。
2. 攔截器是SpringMVC框架獨(dú)有的沐兰。
3. 過(guò)濾器配置了/*,可以攔截任何資源蔽挠。
4. 攔截器只會(huì)對(duì)控制器中的方法進(jìn)行攔截住闯。
4. 攔截器也是AOP思想的一種實(shí)現(xiàn)方式
5. 想要自定義攔截器,需要實(shí)現(xiàn)HandlerInterceptor接口澳淑。
環(huán)境搭建
創(chuàng)建maven項(xiàng)目
導(dǎo)入相關(guān)依賴
<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的初始化參數(shù)比原,讀取springmvc的配置文件,創(chuàng)建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet啟動(dòng)時(shí)加載對(duì)象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置springmvc過(guò)請(qǐng)求過(guò)濾器杠巡,/表示所有請(qǐng)求都經(jīng)過(guò)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">
<!-- 配置創(chuàng)建spring容器要掃描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--SpringMVC注解驅(qū)動(dòng)-->
<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>
編寫頁(yè)面代碼
編寫頁(yè)面代碼
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方法執(zhí)行了.....");
return "success";
}
}
自定義攔截器
創(chuàng)建攔截器
編寫一個(gè)普通類實(shí)現(xiàn)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攔截器執(zhí)行了.....");
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>
攔截器的細(xì)節(jié)
攔截器的放行
放行的含義是指量窘,如果有下一個(gè)攔截器就執(zhí)行下一個(gè),如果該攔截器處于攔截器鏈的最后一個(gè)氢拥,則執(zhí)行控制器中的方法蚌铜。
攔截器中方法的說(shuō)明
方法名 | 說(shuō)明 |
---|---|
preHandle() | 方法將在請(qǐng)求處理之前進(jìn)行調(diào)用, 該方法的返回值是布爾值Boolean類型的嫩海,當(dāng)它返回為false時(shí)冬殃, 表示請(qǐng)求結(jié)束, 后續(xù)的Interceptor和Controller都不會(huì)再執(zhí)行叁怪; 當(dāng)返回值為true時(shí)就會(huì)繼續(xù)調(diào)用下一個(gè)Interceptor的preHandle方法 |
postHandle() | 該方法是在當(dāng)前請(qǐng)求進(jìn)行處理之后被調(diào)用审葬, 前提是preHandle方法的返回值為true時(shí)才能被調(diào)用, 且它會(huì)在DispatcherServlet進(jìn)行視圖返回渲染之前被調(diào)用奕谭, 所以我們可以在這個(gè)方法中對(duì)Controller處理之后的ModelAndView對(duì)象進(jìn)行操作 |
afterCompletion() | 該方法將在整個(gè)請(qǐng)求結(jié)束之后涣觉, 也就是在Dispatcher Servlet渲染了對(duì)應(yīng)的視圖之后執(zhí)行, 前提是preHandle方法的返回值為true時(shí)才能被調(diào)用血柳,常用于接口返回修改 |
1. `preHandle()`是controller方法執(zhí)行前攔截的方法
1. 可以使用request或者response跳轉(zhuǎn)到指定的頁(yè)面
2. return true放行官册,執(zhí)行下一個(gè)攔截器,如果沒(méi)有攔截器混驰,執(zhí)行controller中的方法攀隔。
3. return false不放行皂贩,不會(huì)執(zhí)行controller中的方法栖榨。
2. `postHandle()`是controller方法執(zhí)行后執(zhí)行的方法昆汹,在JSP視圖執(zhí)行前。
1. 可以使用request或者response跳轉(zhuǎn)到指定的頁(yè)面
2. 如果指定了跳轉(zhuǎn)的頁(yè)面婴栽,那么controller方法跳轉(zhuǎn)的頁(yè)面將不會(huì)顯示满粗。
3. `afterCompletion()`方法是在JSP執(zhí)行后執(zhí)行
1. request或者response不能再跳轉(zhuǎn)頁(yè)面了
攔截器的作用路徑
<mvc:interceptor>
<!--
配置攔截器攔截的方法
/** 代表攔截所有方法
/user/* 代表攔截/user路徑下的所有方法
-->
<mvc:mapping path="/user/*"/>
<!--配置不攔截的方法
<mvc:exclude-mapping path="" />
-->
<bean id="myInterceptor1" class="com.itheima.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
多個(gè)攔截器配置
<!-- 配置攔截器 -->
<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>
攔截器實(shí)現(xiàn)權(quán)限控制
登錄代碼編寫
在登陸頁(yè)面輸入用戶名密碼,點(diǎn)擊登陸愚争,通過(guò)用戶名密碼進(jìn)行查詢映皆,如果登陸成功,則將用戶信息實(shí)體存入session轰枝,然后跳轉(zhuǎn)到首頁(yè)捅彻,如果登陸失敗則繼續(xù)回到登陸頁(yè)面
表現(xiàn)層
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);
//判斷是否登錄成功 , 響應(yīng)頁(yè)面
//用戶登錄失敗
if(user==null){
model.addAttribute("msg","用戶名或密碼錯(cuò)誤");
return "login";
}
//登錄成功 , 跳轉(zhuǎn)到用戶列表頁(yè)面
//保存到Session域?qū)ο? session.setAttribute("user",user);
//頁(yè)面跳轉(zhuǎn) , 注意不能直接跳轉(zhuǎn)到list.jsp頁(yè)面
return "redirect:/user/findAll";
}
}
業(yè)務(wù)層
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);
}
}
數(shù)據(jù)訪問(wèn)層
package com.itheima.dao;
import com.itheima.pojo.User;
import java.util.List;
/**
* @Author 王磊
* @Date 2019/11/1/001
*/
public interface UserDao {
/**
* 根據(jù)用戶名或密碼查詢用戶數(shù)據(jù)
* @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如果查詢到數(shù)據(jù)會(huì)封裝返回 , 如果查詢不到數(shù)據(jù)拋出異常
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">
<!--開(kāi)啟組件掃描-->
<context:component-scan base-package="com.itheima"> </context:component-scan>
<!--加載屬性配置文件-->
<context:property-placeholder location="classpath:druid.properties"></context:property-placeholder>
<!--配置數(shù)據(jù)庫(kù)連接池-->
<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對(duì)象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--開(kāi)啟注解驅(qū)動(dòng)-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--釋放靜態(tài)資源-->
<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>
<!--配置字符串編碼過(guò)濾器-->
<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代表用戶為登錄, 返回到登錄頁(yè)面
request.setAttribute("msg", "權(quán)限不足 , 請(qǐng)登錄!!");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return false;
}
//4. 如果不為null代表用戶登錄成功 ,放行
return true;
}
}
配置攔截器
此時(shí)仍然登陸不上,因?yàn)槲覀冃枰獙⒌顷懻?qǐng)求url讓攔截器放行,添加資源排除的配置
<!--配置攔截器信息-->
<mvc:interceptors>
<mvc:interceptor>
<!--配置哪些請(qǐng)求需要攔截-->
<mvc:mapping path="/**"/>
<!--配置哪些請(qǐng)求不需要攔截-->
<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異常處理
系統(tǒng)中異常包括兩類:預(yù)期異常和運(yùn)行時(shí)異常RuntimeException鞍陨,前者通過(guò)捕獲異常從而獲取異常信息步淹,后者主要通過(guò)規(guī)范代碼開(kāi)發(fā)、測(cè)試通過(guò)手段減少運(yùn)行時(shí)異常的發(fā)生诚撵。
系統(tǒng)的dao缭裆、service、controller出現(xiàn)都通過(guò)throws Exception向上拋出寿烟,最后由springmvc前端控制器交由異常處理器進(jìn)行異常處理澈驼,如下圖:
異常環(huán)境搭建
導(dǎo)入相關(guān)依賴
<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的初始化參數(shù),讀取springmvc的配置文件筛武,創(chuàng)建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet啟動(dòng)時(shí)加載對(duì)象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置springmvc過(guò)請(qǐng)求過(guò)濾器缝其,/表示所有請(qǐng)求都經(jīng)過(guò)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">
<!-- 配置創(chuàng)建spring容器要掃描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--SpringMVC注解驅(qū)動(dòng)-->
<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>
編寫前端頁(yè)面
編寫前端頁(yè)面
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("控制器執(zhí)行成功...");
int i = 10/0;
return "success";
}
}
異常處理方式
在SpringMVC中提供了二種異常處理方式 :
使用Spring MVC提供的簡(jiǎn)單異常處理器
SimpleMappingExceptionResolver
實(shí)現(xiàn)Spring的異常處理接口
HandlerExceptionResolver
自定義自己的異常處理器
簡(jiǎn)單異常處理器
SpringMVC已經(jīng)定義好了該類型轉(zhuǎn)換器,在使用時(shí)可以根據(jù)項(xiàng)目情況進(jìn)行相應(yīng)異常與視圖的映射配置
<!--配置簡(jiǎn)單映射異常處理器-->
<bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”> <property name=“defaultErrorView” value=“error”/> 默認(rèn)錯(cuò)誤視圖
<property name=“exceptionMappings”>
<map> 異常類型 錯(cuò)誤視圖
<entry key="com.itheima.exception.MyException" value="error"/>
<entry key="java.lang.ClassCastException" value="error"/>
</map>
</property>
</bean>
自定義異常處理器
編寫自定義異常
CustomException
①創(chuàng)建異常處理器類實(shí)現(xiàn)HandlerExceptionResolver
②配置異常處理器
③編寫異常頁(yè)面
④測(cè)試異常跳轉(zhuǎn)
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;
//如果拋出的是系統(tǒng)自定義異常則直接轉(zhuǎn)換
if (ex instanceof CustomException) {
customException = (CustomException) ex;
} else {
//如果拋出的不是系統(tǒng)自定義異常則重新構(gòu)造一個(gè)系統(tǒng)錯(cuò)誤異常徘六。
customException = new CustomException("系統(tǒng)錯(cuò)誤内边,請(qǐng)與系統(tǒng)管理 員聯(lián)系!");
}
//創(chuàng)建ModelAndView對(duì)象
ModelAndView modelAndView = new ModelAndView();
//保存錯(cuò)誤信息
modelAndView.addObject("message", customException.getMessage());
//設(shè)置跳轉(zhuǎn)的視圖名稱
modelAndView.setViewName("error");
return modelAndView;
}
}
編寫錯(cuò)誤頁(yè)面
編寫錯(cuò)誤頁(yè)面
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>執(zhí)行失敗</title>
</head>
<body>
執(zhí)行失斔敦假残! ${message }
</body>
</html>
配置異常處理器
在
springmvc.xml
中配置異常處理器
<!-- 配置自定義異常處理器 -->
<bean id="handlerExceptionResolver" class="com.itheima.exception.CustomExceptionResolver"/>