您的位置:首页 > 编程语言 > Java开发

Spring MVC 多文件上传大小限制及异常处理

2015-11-26 10:25 537 查看
Spring MVC  多文件上传大小限制及异常处理(包括 MaxUploadSizeExceededException 异常)
太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)本文遵循“署名-非商业用途-保持一致”创作公用协议转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。

补充如下:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-multipart
官方文档中关于 multipart 上传文件的相关链接。

------------------------

在 spring mvc 的默认配置文件 WEB-INF/xxx-servlet.xml 中加入如下 bean 配置,

<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
<property name="maxUploadSize">
<!-- 上传文件大小限制为31M,31*1024*1024 -->
<value>32505856</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
</bean>

那么当在 html 页面 form 中使用 martpart 的 文件上传组件 <input type="file" name="xxx"/>上传文件到 spring mvc 时,
如果某一个文件超出大小,则会抛出异常,使整个 WEB 应用崩溃,
如何能在自定义的控制器中捕获这一 spring mvc 框架级的异常呢?

我们还是看一下官方文档是怎么说的吧!

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-exceptionhandlers-resolver

Spring HandlerExceptionResolver 接口的实现会处理控制器执行过程中发生的未捕获异常。HandlerExceptionResolver 稍许重组了你在 web 应用描述文件 web.xml 中定义的异常映射。然而,它们提供了更灵活的方式来做到这一点。例如,你来提供异常抛出来哪一个处理器被执行的相关信息。更进一步,编程方式处理异常给你更多的选择性以便在请求转向另一 URL 之前合理做出响应。(和你使用 Servlet 专有异常映射时一样的最终结果)

除了实现 HandlerExceptionResolver 接口外,唯一需要做的事情就是实现 resolveException(Exception, Handler) 方法并返回一个 ModelAndView,你也可以使用预先提供的 SimpleMappingExceptionResolver 或创建一个 @ExceptionHandler 方法。

下面贴出整个控制器的内容,
后三个方法分别是上传多文件处理、处理后结果呈现、还有文件大小超限异常处理。
第一个是通过 jsp 模板呈现页面并替换变量,这个其实很简单,可是好多方法处理后,都无法替换变量,包括重布署,清除重编译等等,甚至重建工程。
          后来发现,好多问题并不是问题本身,而是该死的 Maven ,在配置了国内 Maven 镜像并购买的梯子配上后,才算消停。
          总结来说,Maven 的思路是好的,但在国内并不适用,因为我们不是随处都有 WIFI 可用,即使有网速度也很调皮,即使速度还可以,没有梯子也是狒狒一个!
                            解决办法,一是在有好网的环境下,用 Maven 把包自动下下来就够了,剩下去除 Maven。
                                              二是搭建本机的 Maven 镜像服务器,这个不仅可以用于 JavaWeb ,而且 Android Studio 的 Gradle 也可以用,有时间偿试一下,后文再补。
          说到 Maven 不得不插一句苹果的 CocoaPods,这类东西,在国内 WIFI 没有随处可用的情况下,还是尽量别碰为好,可能苹果的会好些吧!
          想来,也许本地 Maven 或 CocoaPods 镜像服务器应该作为各自开发环境的标准才好,在有网的环境下一次性下载到本地或更新,其它任何时侯都不用关心这些问题了。
第二个和第三个是 JSON 输出,没有使用 Spring MVC 自带的方式,配置上就会死循环,不知哪里问题,而 4.2 的方式看官方文档有些麻烦,注解用多了,整个应用都细碎了。
          这里使用 fastjson 直接把列表或对象转换成 String 再输出,其实如果想简化的话,也可以自已构建一层父类,来对返回的对象或列表进行处理。

@Controller
@RequestMapping("/test")
public class TestController implements HandlerExceptionResolver {

@RequestMapping("/welcome")
public ModelAndView helloWorld() {

String message = "<br><div style='text-align:center;'>"
+ "<h3>********** Hello World, Spring MVC Tutorial</h3>This message is coming from CrunchifyHelloWorld.java **********</div><br><br>";
return new ModelAndView("welcome", "message", message);
}

@RequestMapping("/say")
@ResponseBody
public String say() {

List<User> userList = new ArrayList<>();
User user01 = new User("aaa", "123");
User user02 = new User("bbb", "567");
User user03 = new User("ccc", "789");
userList.add(user01);
userList.add(user02);
userList.add(user03);

String result = JSON.toJSONString(userList, true);

return result;
}

@RequestMapping(path = "/user", method = RequestMethod.GET)
@ResponseBody
public String getUser() {

User user01 = new User("aaa", "123");
String result = JSON.toJSONString(user01, true);
return result;
}

@RequestMapping(value = "/upload", method = RequestMethod.GET)
public String crunchifyDisplayForm() {
return "uploadfile";
}

@RequestMapping(value = "/savefiles", method = RequestMethod.POST)
public String crunchifySave(
@ModelAttribute("uploadForm") FileUploadModel uploadForm,
Model map) throws IllegalStateException, IOException {

String saveDirectory = "D:/TestResult/crunchify/";
//String saveDirectory = "/root/workspace/upload/";

List<MultipartFile> crunchifyFiles = uploadForm.getFiles();
List<String> fileNames = new ArrayList<String>();

if (null != crunchifyFiles && crunchifyFiles.size() > 0) {
for (MultipartFile multipartFile : crunchifyFiles) {

String fileName = multipartFile.getOriginalFilename();
if (!"".equalsIgnoreCase(fileName)) {
// Handle file content - multipartFile.getInputStream()
multipartFile.transferTo(new File(saveDirectory + fileName));
fileNames.add(fileName);
}
}
}

map.addAttribute("files", fileNames);
return "uploadfilesuccess";
}

@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception exception) {
Map<String, Object> model = new HashMap<String, Object>();
if (exception instanceof MaxUploadSizeExceededException)
{
model.put("errors", exception.getMessage());
} else
{
model.put("errors", "Unexpected error: " + exception.getMessage());
}
model.put("uploadedFile", new FileUploadModel());
return new ModelAndView("/uploadfile", model);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: