SpringMVC 上传下载 异常处理

上一章节对SpringMVC的表单验证进行了详细的介绍,本章节介绍SpringMVC文件的上传和下载(重点),国际化以及异常处理问题。这也是SpringMVC系列教程中的最后一节,文章底部会提供该系列的源码地址。

首先看效果图(文件上传,下载和异常处理)

文件上传和下载是需要两个jar包: commons-fileupload.jar 和 commons-io.jar

<?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.springmvc</groupId>
<artifactId>springmvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging> <!-- 若不配置,打包时会提示错误信息
Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project springmvc: Compilation failure:
提示 未结束的字符串文字 ,若字符串后面加上空格后可以打包成功,但会乱码。
原因是:maven使用的是默认的compile插件来进行编译的。complier是maven的核心插件之一,然而complier插件默认只支持编译Java 1.4
-->
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build> <properties>
<spring.version>4.1.3.RELEASE</spring.version>
</properties>
<dependencies>
<!-- spring begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency> <!-- spring end -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- 缺少则提示 javax.servlet.jsp.JspException cannot be resolved to a type -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- JSR 303 start -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- JSR 303 end -->
<!-- 文件上传 start -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- 文件上传 end --> </dependencies>
</project>

SpringMVC配置文件

<?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-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- 配置自定扫描的包 -->
<context:component-scan base-package="com.itdragon.springmvc" /> <!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean> <!-- 配置注解驱动 -->
<mvc:annotation-driven /> <!-- 配置视图 BeanNameViewResolver 解析器
使用视图的名字来解析视图
通过 order 属性来定义视图解析器的优先级, order 值越小优先级越高
-->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="100"></property>
</bean> <!-- 配置直接跳转的页面,无需经过Controller层
http://localhost:8080/springmvc/index
然后会跳转到 WEB-INF/views/index.jsp 页面
-->
<mvc:view-controller path="/index" view-name="index"/> <mvc:default-servlet-handler/> <!-- 配置国际化资源文件 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property>
</bean> <!-- 配置 SessionLocaleResolver 根据 Session 中特定属性确定本地化类型
必须将区域解析器的Bean名称设置为localeResolver,这样DispatcherServlet才能自动侦测到它。
请注意,每DispatcherServlet只能注册一个区域解析器。
* 第一步,把Locale对象设置为Session属性
* 第二步,从Session中获取Locale对象给应用程序
-->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean> <!-- 配置 LocaleChangeInterceptor 从请求参数中获取本次请求对应本地化类型
* 第一步,获取name=locale的请求参数
* 第二步,把locale的请求参数解析为Locale对象
* 第三步,获取LocaleResolver对象
-->
<mvc:interceptors>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors> <!-- 配置 CommonsMultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="2048000"></property>
</bean> <!-- 配置使用 SimpleMappingExceptionResolver 来映射异常 -->
<bean id="simpleMappingExceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 这里是模型 exception -->
<property name="exceptionAttribute" value="exception"></property>
<property name="exceptionMappings">
<props>
<!-- 如果是该异常,则跳转到视图 exception 页面-->
<prop key="java.lang.ArrayIndexOutOfBoundsException">exception</prop>
</props>
</property>
</bean>
</beans>

FileUploadController.java 文件上传,下载和国际化知识点

国际化步骤

第一步,在SpringMVC配置文件中配置 SessionLocaleResolver(bean的id必须是localeResolver) 和 LocaleChangeInterceptor(bean放在mvc:interceptors 拦截器中)两个bean。

第二步,视图页面引入 fmt 标签,并用 <fmt:message key="xxx" /> 设置值。

第三步,语言切换的链接,其格式:English

第四步,创建链接的目标方法,其参数为Locale 类型参数。

第五步,准备语言文件,i18n_en_US.properties 和 i18n_zh_CN.properties,配置xxx的对应语言。

文件上传和下载

第一步,在SpringMVC配置文件中配置 CommonsMultipartResolver,并设置默认编码格式和最大尺寸

第二步,视图页面创建一个form表单,并设置 enctype="multipart/form-data"

第三步,目标方法接收参数的类型为 MultipartFile ,然后是文件流的操作。

第四步,看代码吧!

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile; @Controller
public class FileUploadController { @Autowired
private ResourceBundleMessageSource messageSource; /**
* 国际化
* 第一步,在SpringMVC配置文件中,配置 SessionLocaleResolver 和 LocaleChangeInterceptor
* 第二步,准备语言文件,i18n_en_US.properties 和 i18n_zh_CN.properties
* 第三步,目标方法中,参数加入Locale对象。
*/
@RequestMapping("/fileUpload")
public String fileUpload(Locale locale) {
// String val = messageSource.getMessage("file", null, locale);
// System.out.println(val);
return "fileUpload";
} // MultipartFile 上传文件必用的变量类型
@RequestMapping("/testFileUpload")
public String testFileUpload(@RequestParam("desc") String desc, @RequestParam("file") MultipartFile file,
Map<String, Object> map, HttpServletRequest request) {
InputStream in = null;
OutputStream out = null;
String fileName = file.getOriginalFilename(); // 获取文件名
try {
String realPath = request.getServletContext().getRealPath("uploads/");
in = file.getInputStream();
byte[] buffer = new byte[1024];
String filePath = realPath + "/" + fileName; // 文件上传路径
out = new FileOutputStream(filePath);
int len = 0;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != out) {
out.close();
}
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
map.put("fileName", fileName);
return "fileUpload";
} // 不适合大文件的下载,适用于简单的下载场景。
@RequestMapping("/downLoadFile")
public ResponseEntity<byte[]> downLoadFile(@RequestParam("fileName") String fileName, HttpSession session) {
byte [] body = null;
ServletContext servletContext = session.getServletContext();
InputStream in = null;
ResponseEntity<byte[]> response = null;
try {
in = servletContext.getResourceAsStream("/uploads/"+fileName);
body = new byte[in.available()];
in.read(body);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment;filename="+fileName);
HttpStatus statusCode = HttpStatus.OK;
response = new ResponseEntity<byte[]>(body, headers, statusCode);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return response;
} }

fileUpload.jsp 文件上传下载前端页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SpringMVC 快速入门</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body> <div class="container">
<div class="row">
<div class="col-sm-6">
<div class="panel panel-info" style="margin-top:10px;">
<div class="panel-heading">
<h3 class="panel-title"><fmt:message key="file.upload" /></h3>
</div>
<div class="panel-body">
<!-- 缺少 enctype="multipart/form-data" 会提示
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
-->
<form action="${pageContext.request.contextPath }/testFileUpload" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label class="col-sm-2 control-label"><fmt:message key="file" /></label>
<div class="col-sm-10">
<input type="file" name="file" class="form-control" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"><fmt:message key="desc" /></label>
<div class="col-sm-10">
<input type="text" name="desc" class="form-control" />
</div>
</div>
<input type="submit" value="Submit" class="btn btn-success" />
</form>
<a href="fileUpload?locale=zh_CN" class="btn" >中文</a>
<a href="fileUpload?locale=en_US" class="btn" >English</a>
</div>
</div>
</div>
<hr />
<a href="downLoadFile?fileName=${fileName}" >${fileName}</a>
<hr />
</div>
</div>
</body>
</html>

常用的三种异常处理

@ExceptionHandler 注解

第一步,创建一个用注解@ControllerAdvice 修饰的切面类(也可以是普通类)。

第二步,创建一个目标方法,并用注解@ExceptionHandler 修饰,value值是一个数组,值是异常类。

第三步,目标方法的的参数必须有Exception 类型的参数,用于获取运行时发生的异常。

第四步,目标方法若想把异常返回给页面,可以用ModelAndView 类型作为返回值,而不能用Map作为参数返回。

@ResponseStatus 注解

第一步,创建一个被注解@ResponseStatus 修饰的自定义异常类,value值是状态码,reason值是字符串。

第二步,在目标方法执行时抛出自定义异常。

SimpleMappingExceptionResolver Bean

第一步,在SpringMVC的配置文件中 配置Bean SimpleMappingExceptionResolver 。

第二步,设置exceptionAttribute 模型Model,必须和页面上的值一致。

第三步,设置exceptionMappings 视图View,只有当异常触发时跳转到视图页面。

注意细节,看代码

StudyExceptionHandlerAdvice.java 切面类

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView; /**
* 1 @ExceptionHandler 注解修饰的方法可以放在普通类中,也可以放在切面类中(@ControllerAdvice 注解修饰的类)。前者表示只处理当前类的异常,后者表示处理全局的异常。
* 2 @ExceptionHandler 注解修饰的方法参数中,不能有Map,否则会提示:。若希望把异常信息返回给前端,可以使用ModelAndView
* 3 @ExceptionHandler 注解修饰的多个方法中,优先级原则是就近原则(和异常精度越近的异常,优先执行)。
*/
@ControllerAdvice
public class StudyExceptionHandlerAdvice { @ExceptionHandler({ArithmeticException.class})
public ModelAndView handleArithmeticException(Exception exception){
System.out.println("ArithmeticException 出异常了: " + exception);
ModelAndView mv = new ModelAndView("exception");
mv.addObject("exception", "ArithmeticException 出异常了: " + exception);
return mv;
} /*@ExceptionHandler({RuntimeException.class})
public ModelAndView handleRuntimeException(Exception exception){
System.out.println("RuntimeException 出异常了: " + exception);
ModelAndView mv = new ModelAndView("exception");
mv.addObject("exception", "RuntimeException 出异常了: " + exception);
return mv;
}*/ }

ResponseStatusException.java 自定义异常类

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "ResponseStatusException : 自定义异常原因")
public class ResponseStatusException extends RuntimeException{ }

StudyExceptionController.java 异常处理测试类

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; @Controller
public class StudyExceptionController { @RequestMapping("/exception")
public String exception(){
return "exception";
} @RequestMapping("/simpleMappingExceptionResolver")
public String simpleMappingExceptionResolver(@RequestParam("num") int num){
String [] args = new String[10];
System.out.println("通过配置bean,来处理某一种异常导致的所有问题。" + args[num]);
return "exception";
} @RequestMapping(value="/testResponseStatus")
public String testResponseStatus(@RequestParam("num") Integer num){
System.out.println("@ResponseStatus 自定义异常");
if (0 == num) {
throw new ResponseStatusException();
}
return "exception";
} @RequestMapping("/testExceptionHandler")
public String testExceptionHandler(@RequestParam("num") Integer num){
System.out.println("@ExceptionHandler - result: " + (10 / num));
return "exception";
} }

exception.jsp 异常处理前端页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  

<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SpringMVC 快速入门</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body> <div class="container">
<div class="row">
<h2>SpringMVC 异常处理</h2>
<hr/>
@ExceptionHandler : <a href="testExceptionHandler?num=0" class="btn" >testExceptionHandler?num=0</a>
<hr/>
SimpleMappingExceptionResolver : <a href="simpleMappingExceptionResolver?num=20" class="btn" >simpleMappingExceptionResolver?num=20</a>
<hr/>
@ResponseStatus : <a href="testResponseStatus?num=0" class="btn" >testResponseStatus?num=0</a>
<hr/>
${exception}
</div>
</div>
</body>
</html>

到这里,SpringMVC的教程就结束了,有什么好的建议和问题,可以提出来。大家一起成长!

SpringMVC源码地址:https://gitee.com/itdragon/springmvc

SpringMVC 上传下载 异常处理的更多相关文章

  1. springmvc 上传下载

    springmvc文件上传下载在网上搜索的代码 参考整理了一份需要使用的jar.commons-fileupload.jar与commons-io-1.4.jar 二个文件 1.表单属性为: enct ...

  2. SpringMVC上传下载

    springmvc上传和下载功能 写在一个简单的示例在线基准码 1.导入的必要性jar包:ant.jar.commons-fileupload.jar.connom-io.jar. 当然spring ...

  3. springmvc文件上传下载简单实现案例(ssm框架使用)

    springmvc文件上传下载实现起来非常简单,此springmvc上传下载案例适合已经搭建好的ssm框架(spring+springmvc+mybatis)使用,ssm框架项目的搭建我相信你们已经搭 ...

  4. SpringMVC文件上传下载

    不多说,代码: Spring-config.xml<!-- spring可以自动去扫描base-pack下面的包或者子包下面的java文件, 如果扫描到有Spring的相关注解的类,则把这些类注 ...

  5. SSM框架之中如何进行文件的上传下载

    SSM框架的整合请看我之前的博客:http://www.cnblogs.com/1314wamm/p/6834266.html 现在我们先看如何编写文件的上传下载:你先看你的pom.xml中是否有文件 ...

  6. SpringMVC文件上传下载

    在Spring MVC的基础框架搭建起来后,我们测试了spring mvc中的返回值类型,如果你还没有搭建好springmvc的架构请参考博文->http://www.cnblogs.com/q ...

  7. SpringMVC 文件上传下载

    目录 文件上传 MultipartFile对象 文件下载 上传下载示例 pom.xml增加 创建uploadForm.jsp 创建uploadForm2.jsp 创建userInfo.jsp spri ...

  8. SocketIo+SpringMvc实现文件的上传下载

    SocketIo+SpringMvc实现文件的上传下载 socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示: GIT地址 ...

  9. SpringMVC整合fastdfs-client-java实现web文件上传下载

    原文:http://blog.csdn.net/wlwlwlwl015/article/details/52682153 本篇blog主要记录一下SpringMVC整合FastDFS的Java客户端实 ...

随机推荐

  1. Prometheus 架构 - 每天5分钟玩转 Docker 容器技术(83)

    Prometheus 是一个非常优秀的监控工具.准确的说,应该是监控方案.Prometheus 提供了监控数据搜集.存储.处理.可视化和告警一套完整的解决方案. 让我们先来看看 Prometheus ...

  2. Java设计模式(四)——再谈观察者模式

    在本系列的上一篇文章中,我们讨论了JDK对于观察者模式的一套实现.今天我们将要从另一个角度来探索Tomcat中是如何利用观察者模式加载各个组件.不过今天的任务不是解释Tomcat,所以我会单独把重点抽 ...

  3. 如何在Windows上搭建Android开发环境

    Android开发越来越火,许多小伙伴们纷纷学习Android开发,学习Android开发首要任务是搭建Android开发环境,由于大家 主要实在Windows 上开发Android,下面就详细给大家 ...

  4. Hibernate映射类型

  5. Element ui表格展示多张图片问题

    显示一张图片的方法: <el-table-column label="头像" width="100"> <template scope=&qu ...

  6. 版本控制之一:SVN服务器搭建与安装(转)

    Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网站上了,下载地址: http:// ...

  7. [Scikit-learn] 4.4 Dimensionality reduction - PCA

    2.5. Decomposing signals in components (matrix factorization problems) 2.5.1. Principal component an ...

  8. Oil Deposits

    Problem Description The GeoSurvComp geologic survey company is responsible for detecting underground ...

  9. 暑假练习赛 007 A - Time

    A - Time Description standard input/outputStatements A plane can go from city X to city Y in 1 hour ...

  10. ⑧bootstrap组件 文字图片 下拉菜单 按钮组 使用基础案例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...