java – 处理MaxUploadSizeExceededException不能停止上传文件

前端之家收集整理的这篇文章主要介绍了java – 处理MaxUploadSizeExceededException不能停止上传文件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想检查上传文件的大小,并防止完全载入到内存中的文件.我使用CommonsMultipartFile.上传文件将被处理并保存在数据库中. AbstractCoupleUploadController类处理包含文件的传入请求:
  1. public abstract class AbstractCoupleUploadController<T extends Serializable> extends RemoteServiceServlet implements ServletContextAware,UploadServlet<WorkshopHistoryModel>
  2. {
  3. ...
  4.  
  5. @RequestMapping(method={RequestMethod.GET,RequestMethod.POST})
  6. public ModelAndView handleRequest(@RequestParam("firstFile") CommonsMultipartFile firstFile,@RequestParam("secondFile") CommonsMultipartFile secondFile,HttpServletRequest request,HttpServletResponse response)
  7. {
  8. synchronized(this)
  9. {
  10. initThreads();
  11. perThreadRequest.set(request);
  12. perThreadResponse.set(response);
  13. }
  14.  
  15. handleUpload(firstFile,secondFile,request,response);
  16. response.getWriter().flush();
  17. response.flushBuffer();
  18. return null;
  19. }
  20.  
  21. private void handleUpload(CommonsMultipartFile firstFile,CommonsMultipartFile secondFile,HttpServletResponse response) throws IOException
  22. {
  23. response.setContentType("text/html");
  24. if(firstFile.getSize() == 0 || secondFile.getSize() == 0)
  25. {
  26. response.getWriter().print(AppConstants.UPLOAD_ZERO_SIZE_FILE);
  27. return;
  28. }
  29.  
  30. // other validations
  31. // uploading:
  32. try
  33. {
  34. String content = request.getParameter(CoupleUploadPanel.CONTENT);
  35. T model = deserialize(content);
  36. UploadResultModel resultModel = upload(model,firstFile,secondFile); // it's implemented in UploadFileServletImpl
  37. if(resultModel.hasCriticalError())
  38. {
  39. response.getWriter().print(AppConstants.UPLOAD_FAIL + "," + String.valueOf(resultModel.getWorkshopHistoryId()));
  40. }
  41. else
  42. {
  43. response.getWriter().print(AppConstants.UPLOAD_SUCCESS + "," + String.valueOf(resultModel.getWorkshopHistoryId()));
  44. }
  45. }
  46. catch(ProcessRequestException e)
  47. {
  48. // write upload error description in response.getWriter()
  49. }
  50. catch(Exception e)
  51. {
  52. e.printStackTrace();
  53. response.getWriter().print(AppConstants.UPLOAD_UNKOWN_ERROR);
  54. }
  55. }
  56.  
  57. ...
  58. }

我的app-servlet.xml(file.upload.max_size = 9437184)中有一个multipartResolver bean,另外还有一个用于处理UploadSizeExceededExceptions的maxUploadSizeExceptionExceptionHandler bean:

  1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  2. <property name="maxUploadSize" value="${file.upload.max_size}" />
  3. </bean>
  4. <bean id="maxUploadSizeExceededExceptionHandler" class="com.insurance.ui.server.uploadfile.MaxUploadSizeExceededExceptionHandler">
  5. <property name="order" value="1"/>
  6. </bean>

我的maxUploadSizeExceededExceptionHandler:

  1. public class MaxUploadSizeExceededExceptionHandler implements HandlerExceptionResolver,Ordered
  2. {
  3. private int order;
  4.  
  5. @Override
  6. public ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex)
  7. {
  8. if(ex instanceof MaxUploadSizeExceededException)
  9. {
  10. try
  11. {
  12. response.getWriter().print(ErrorConstants.UPLOAD_SIZE_EXCEED + "," + (((MaxUploadSizeExceededException) ex).getMaxUploadSize()/(1024*1024)));
  13. response.getWriter().flush();
  14. response.flushBuffer();
  15. return new ModelAndView();
  16. }
  17. catch(IOException e)
  18. {
  19. }
  20. }
  21. return null;
  22. }
  23. ...
  24. }

当我上传一个非常大的文件(超过${file.upload.max_size},大约700MB),CommonsMultipartResolver立即抛出MaxUploadSizeExceededException,它正在捕获和处理它(在response.getWriter()中写)).我的问题:我的浏览器上传进度条显示文件仍在上传!为什么?

更新:我正在使用:

> Spring – * – 3.0.5.RELEASE
> commons-fileupload-1.1.1

并尝试:

> Spring – * – 3.1.2.RELEASE
> commons-fileupload-1.3

和我的AS:

> Tomcat 6(开发中)
> Jboss 7(生产中)

更新2:在客户端,我使用GWT(我认为没关系):

点击submitRequestButton开始上传

  1. @UiHandler("submitRequestButton")
  2. public void submitRequestButtonClick(ClickEvent event)
  3. {
  4. try
  5. {
  6. // some validation
  7. submitRequestButton.setEnabled(false);
  8. uploadPanel.upload(model.getWorkshopHistoryModel()); // uploadPanel is from the CoupleUploadPanel type
  9. }
  10. catch(ValidationException exception)
  11. {
  12. // handle validation errors
  13. }
  14. catch(SerializationException e)
  15. {
  16. // handle serialization errors
  17. }
  18. }

我有一个CoupleUploadPanel小部件上传(两个文件):

  1. public class CoupleUploadPanel<T extends Serializable> extends FormPanel
  2. {
  3. public final static String CONTENT = "content";
  4. private static final String FIRST_FILE = "firstFile";
  5. private static final String SECOND_FILE = "secondFile";
  6.  
  7. private Hidden contentInput;
  8. private FileUpload firstFileUploadInput;
  9. private FileUpload secondFileUploadInput;
  10. private SerializationStreamFactory factory;
  11.  
  12. public CoupleUploadPanel(UploadServletAsync<T> factory)
  13. {
  14. this(null,factory);
  15. }
  16.  
  17. public CoupleUploadPanel(String url,UploadServletAsync<T> factory)
  18. {
  19. this.factory = (SerializationStreamFactory) factory;
  20. if(url != null)
  21. {
  22. setAction(url);
  23. }
  24. init();
  25. }
  26. public CoupleUploadPanel(String target,String url,UploadServletAsync<T> factory)
  27. {
  28. super(target);
  29. this.factory = (SerializationStreamFactory) factory;
  30. if(url != null)
  31. {
  32. setAction(url);
  33. }
  34. init();
  35. }
  36.  
  37. private void init()
  38. {
  39. setMethod("POST");
  40. setEncoding(ENCODING_MULTIPART);
  41. firstFileUploadInput = new FileUpload();
  42. firstFileUploadInput.setName(CoupleUploadPanel.FIRST_FILE);
  43. secondFileUploadInput = new FileUpload();
  44. secondFileUploadInput.setName(CoupleUploadPanel.SECOND_FILE);
  45. contentInput = new Hidden();
  46. contentInput.setName(CONTENT);
  47. VerticalPanel panel = new VerticalPanel();
  48. panel.add(firstFileUploadInput);
  49. panel.add(secondFileUploadInput);
  50. panel.add(contentInput);
  51. add(panel);
  52. }
  53.  
  54. public void upload(T input) throws SerializationException
  55. {
  56. contentInput.setValue(serialize(input));
  57. submit();
  58. }
  59.  
  60. private String serialize(T input) throws SerializationException
  61. {
  62. SerializationStreamWriter writer = factory.createStreamWriter();
  63. writer.writeObject(input);
  64. return writer.toString();
  65. }
  66. }

我们应该将UploadServletAsync传递给CoupleUploadPanel构造函数. UploadServletAsync和UploadServlet接口:

  1. public interface UploadServletAsync<T extends Serializable>
  2. {
  3. void upload(T model,AsyncCallback<Void> callback);
  4. }
  5.  
  6. public interface UploadServlet<T extends Serializable> extends RemoteService
  7. {
  8. void upload(T model);
  9. }

所以uploadPanel将以这种方式被实例化:

  1. uploadPanel= new CoupleUploadPanel<WorkshopHistoryModel>((UploadFileServletAsync) GWT.create(UploadFileServlet.class));
  2. uploadPanel.setAction(UploadFileServlet.URL);

并且添加到uploadPanel(onSumbitComplete()的SubmitCompeleteHandler将在提交完成时被调用,结果传递给客户端):

  1. uploadPanel.addSubmitCompleteHandler(new SubmitCompleteHandler()
  2. {
  3.  
  4. @Override
  5. public void onSubmitComplete(SubmitCompleteEvent event)
  6. {
  7. String s = event.getResults(); //contains whatever written by response.getWriter()
  8. if(s == null)
  9. {
  10. // navigate to request list page
  11. }
  12. else
  13. {
  14. String[] response = s.split(",");
  15. // based on response:
  16. // show error messages if any error occurred in file upload
  17. // else: navigate to upload result page
  18. }
  19. }
  20. });

UploadFileServlet和UploadFileServletAsync接口:

  1. public interface UploadFileServlet extends UploadServlet<WorkshopHistoryModel>
  2. {
  3. String URL = "**/uploadFileService.mvc";
  4. }
  5.  
  6. public interface UploadFileServletAsync extends UploadServletAsync<WorkshopHistoryModel>
  7. {
  8. public static final UploadFileServletAsync INSTANCE = GWT.create(UploadFileServlet.class);
  9. }

在服务器端:UploadFileServletImpl扩展AbstractCoupleUploadController并实现upload()方法(上传过程):

  1. @RequestMapping(UploadFileServlet.URL)
  2. public class UploadFileServletImpl extends AbstractCoupleUploadController<WorkshopHistoryModel>
  3. {
  4. ...
  5.  
  6. @Override
  7. protected UploadResultModel upload(WorkshopHistoryModel model,MultipartFile firstFile,MultipartFile secondFile)
  8. throws ProcessRequestException
  9. {
  10. return workshopHistoryService.submitList(model.getWorkshop(),secondFile);
  11. }
  12.  
  13. ...
  14. }

解决方法

那么,afaik Spring(一个servlet和一些过滤器)没有观察到上传过程,而只处理完成的过程的结果.这是因为上传由Tomcat本身处理(提示:web.xml中有一个上传大小限制选项).因此,可能会导致上传失败(哪些Spring不会被注意到)或上传太大的文件.只有当第二次发生时,特定的过滤器/拦截器才会拒绝进程.

在我最后一次安装过程中,我曾经用过Nginx作为Tomcat前面的代理:

>如果您的浏览器发送实际的文件大小(现代浏览器,至少IE7?或IE8?),Nginx将发送500,如果大小超过定义的限制.>我不是100%肯定:如果上传的大小超过指定的限制,Nginx也会发送一个500.这也将取消与Tomcat的底层连接.

猜你在找的Java相关文章