翻了很多文章一群没用的。都在说是multiparResolver的大小设置有问题。
如果真的有请去自行百度或者看下面的
<!-- 上传拦截,如最大上传值及最小上传值 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" > <property name="maxUploadSize"> <value>524288000</value> </property> <property name="maxInMemorySize"> <value>4096</value> </property> <property name="defaultEncoding"> <value>utf-8</value> </property> </bean>
好了,现在该说我遇到的问题了直接贴部分代码。
@RequestMapping(value="/save",produces="application/json; charset=utf-8") @ResponseBody public String save(HttpServletRequest request) throws Exception{ CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext()); if (multipartResolver.isMultipart(request)) { MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; Iterator<String> iter = multiRequest.getFileNames(); //文件名称 1.png while (iter.hasNext()){ MultipartFile file = multiRequest.getFile(iter.next()); //其实这里我只是做个一个判断为了调试。上线请去掉。只需要调用一下file.getInputStream就好 //只要在这个action里面调用一次 file.getInputStream() 在upLoadFileThread这个线程中就可以取到file.getInputStream(); if(file.getInputStream() ==null){ System.out.println("--------------------------文件流为空--------------------------"); }else{ System.out.println("--------------------------文件流不为空--------------------------"); UpLoadFile upLoadFileThread=new UpLoadFile(file); //开启文件上传线程,把file传进去 Thread thread = new Thread(upLoadFileThread); thread.start(); } } } //------------------------------------------------------------------ return json.toJSONString(); }
线程中部分代码,代码不全,就意思意思,别抄
package com.xxxxx public class UpLoadFile implements Runnable{ private MultipartFile file; public UpLoadFile() { super(); } public UpLoadFile(MultipartFile ) { //这里的构造方法是接收外面参数的 this.file=file; } @Override public void run() { if (!file.isEmpty()) { String originalName = file.getOriginalFilename(); String contentType =file.getContentType(); //文件类型 image/png try { String no = UUID.randomUUID() + originalName.substring(originalName.indexOf(".")); OSSClient ossClient = OSSClientUtils.getPrivateClien(); //这里新加了一个初始化方法,每次都初始化一个新的 String[] folderPatterns = new String[] { "yyyy", "MM", "dd", "" }; GetProgressSample.PutObjectProgressListener getProgressSample= new GetProgressSample.PutObjectProgressListener(); ObjectMetadata meta = new ObjectMetadata(); meta.setContentDisposition("attachment;filename=\""+originalName+"\""); //设置请求头让文件直接下载 ossClient.putObject(new PutObjectRequest("lrbnews", no, file.getInputStream(),meta).withProgressListener(getProgressSample)); //带进度条的文件上传 } catch (Exception e) { } } } }
有人说为什么要这么折腾,我也不想啊,不过这样做可以每一个文件新启动一个线程,然后各种去上传。关键点当然在于,我昨天遇到的File has been moved - cannot be read again这个报错。一直不知道为什么,然后今天把request取文件的那部分放到了action中,因为我发现,如果不这样做,另起一个线程之后,request中的session会被GC回收,当然,你已经换了线程文件流已经关了。
然后我发现,文件名这些都可以取到,就是file.getInputStream()取不到值。最后我发现,只要在前面调用一次file.getInputStream(),这样在线程中就可以取到。这个问题....我本人不懂,如果有人可以解释,希望能告诉一下我。