1、SpringMVC方式上传文件
SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的name属性值相同
案例:
下面是我的目录结构:
1、导入上传组件的依赖 ,下面是我的pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ayit</groupId>
<artifactId>springmvc-03</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>springmvc-03 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.10</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
<!--上传组件依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>
2、创建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">
<!--配置组件-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--扫描包下的注解-->
<context:component-scan base-package="com.ayit.controller"></context:component-scan>
<!--放行静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp"></property>
</bean>
<!--配置上传组件解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--配置上传文件的大小-->
<property name="maxUploadSize" value="102400"></property>
</bean>
</beans>
3、在web.xml文件配置前端控制器DispatcherServlet和加载springmvc.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>
<display-name>Archetype Created Web Application</display-name>
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载springmvc.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4、创建上传文件页面upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="/user/upload">
文件:<input type="file" name="file">
<input type="submit" value="上传">
</form>
</body>
</html>
5、编写UserController类
package com.ayit.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("upload")
public String upload(MultipartFile file, Model model){//MultipartFile的变量名和type=file表单中name属性的属性值一致
//获取上传的文件的名称
String uploadFileName = file.getOriginalFilename();
//使用UUID作为文件名的前缀,防止文件名冲突
uploadFileName = UUID.randomUUID().toString().replace("-","") + uploadFileName;
//指定上传路径
String uploadPath = "E:\\apache-tomcat-8.5.31\\webapps\\upload\\";
//开始上传
try {
file.transferTo(new File(uploadPath,uploadFileName));
} catch (IOException e) {
e.printStackTrace();
}
//保存文件名
model.addAttribute("uploadFileName",uploadFileName);
//跳转页面
return "/list.jsp";
}
}
6、编写跳转页面list.jsp
<%--
Created by IntelliJ IDEA.
User: Mriacles21
Date: 2021/10/21
Time: 19:13
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
list.jsp
<hr>
<img src="http://localhost:8086/upload/${uploadFileName}" align="这是张图片">
</body>
</html>
7、启动服务器,开始测试(为了能访问图片资源,我配置了两个tomcat服务器,端口号不同,一个tomcat服务器专门用来存放图片资源)
启动存放图片资源的服务器
启动idea中配置的tomcat服务器,输入网址,开始访问资源
点击浏览
选择要上传的图片,点击打开
点击上传:
2、SpringMVC的异常处理
Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理
1.创建自定义异常类MyException
package com.qf.exception;
public class MyException extends Exception {
public MyException(String message){
super(message);
}
}
2.创建异常处理类MyExceptionResolver
package com.qf.exception;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
ModelAndView modelAndView = new ModelAndView();
if (ex instanceof NullPointerException){
modelAndView.addObject("msg","空指针异常");
}else if(ex instanceof MyException){
modelAndView.addObject("msg",ex.getMessage());
}else {
modelAndView.addObject("msg","其他异常");
}
modelAndView.setViewName("/error.jsp");
return modelAndView;
}
}
3.在springmvc.xml文件中配置全局异常类
<!--配置全局异常处理类-->
<bean class="com.qf.exception.MyExceptionResolver"></bean>
4.在MyController类中编写对应的测试方法
@RequestMapping("testException")
//测试异常方法
public void testException() throws MyException {
//空指针异常
// String str = null;
// str.length();
throw new MyException("自定义异常");
}
3.SpringMVC框架中的拦截器
拦截器的概述
SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按照定义的顺序执行。
拦截器和过滤器的功能比较类似,有以下区别:
过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
拦截器是SpringMVC框架独有的
过滤器配置了/*,可以拦截任何资源
拦截器只会对控制器中的方法进行拦截
拦截器也是AOP思想的一种实现方式,需要实现HandlerInterceptor接口
1.创建自定义拦截器MyInterceptor
package com.qf.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
//在调用controller方法之前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle:调用controller方法之前执行!");
return true;//true表示继续向下执行,false表示不想下执行
}
//在调用controller方法之后执行,(发生异常不执行)
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle:调用controller方法之后执行!");
}
//最后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion:最后执行!");
}
}
2.在springmvc.xml文件配置全局异常类处理器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--指定拦截的路径-->
<mvc:mapping path="/user/*"/>
<!--指定放行的路径-->
<mvc:exclude-mapping path="/user/testInterceptor"/>
<!--配置拦截器-->
<bean class="com.qf.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
3.测试
@RequestMapping("testInterceptor")
public String testInterceptor(){
System.out.println("testInterceptor...");
return "/list.jsp";
}