前台代码:
bindPhoto(e) {
var that = this;
wx.chooseImage({
count: 1,
sizeType: ['original','compressed'],// 指定原图或者压缩图
sourceType: ['album', 'camera'], // 指定图片来源
success: function (res) {
var tempFilePaths = res.tempFilePaths;
wx.uploadFile({
url: 'http://192.168.31.111:8007/goods/wx_upload.do',
filePath: tempFilePaths[0],
name: 'file',
header: { "Content-Type": "multipart/form-data" },
formData:{
'session_token': token
},
success:function(res){
var cur_data = res.data;
console.log(cur_data.fileName);
},
fail: function (res) {
console.log('上传失败');
}
})
}
})
},
后台代码
/*微信小程序上传图片测试*/
@RequestMapping("wx_upload.do")
public void wx_upload(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setCharacterEncoding("utf-8"); //设置编码
//获得磁盘文件条目工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
String fileId = null;
String json = "{\"success\":false,\"fileName\":\"" + fileId + "\"}";
String pathUrl = FSDefaultMgr.E_DEFAULT.getDefaultUploadPathUrl();//获取图片服务器路径
InputStream inStream = null;
try {
//可以上传多个文件
List<FileItem> list = (List<FileItem>)upload.parseRequest(request);
for(FileItem item : list){
//获取表单的属性名字
String name = item.getFieldName();
//如果获取的 表单信息是普通的 文本 信息
if(item.isFormField()){
//获取用户具体输入的字符串 ,名字起得挺好,因为表单提交过来的是 字符串类型的
String value = item.getString() ;
request.setAttribute(name, value);
}else {
//获取路径名
String filename = item.getName();
request.setAttribute(name, filename);
inStream = item.getInputStream() ;
}
}
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = inStream.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
byte[] bytes = swapStream.toByteArray();
fileId = FastDFSClient.uploadFile(bytes, "20161545454.png", null);
if (fileId != null) {
json = "{\"success\":true,\"pathUrl\":\"" + pathUrl + "\",\"fileName\":\"" + fileId + "\"}";
}
response.getWriter().write(json);
response.getWriter().flush();
response.getWriter().close();
}catch (Exception e) {
e.printStackTrace();
}
}
当使用的是springMVC框架时:
原因分析
首先我们来看下Spring mvc 中文件上传的配置
- <bean
- class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="UTF-8" />
-
- <property name="maxUploadSize" value="2000000000" />
- </bean>
再来看看Controller中使用
- public void upload2(HttpServletRequest request) {
-
- try {
- MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
- List<MultipartFile> fileList = multipartRequest.getFiles("file");
- for (MultipartFile mf : fileList) {
- if(!mf.isEmpty()){
-
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
方式二
- public String upload(HttpServletRequest request,
- @RequestParam(value = "file") MultipartFile[] files) {
- try {
- for (MultipartFile mf : files) {
- if(!mf.isEmpty()){
-
- }
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "upload";
- }
-
- 这里springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置的CommonsMultipartResolver这个转换器里面下面再来看看它的源码
他的转换器里面就是调用common-fileupload的方式解析,然后再使用parseFileItems()方法封装成自己的文件对象 .
List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
大家应该发现了上面的这句代码,已经使用过fileUpload解析过request了,你在Controller里面接收到的request都已经是解析过的,你再次使用upload进行解析获取到的肯定是空,这个就是问题的所在(大家可以在servlet里面实验,看看第二次解析后能不能获取到数据,当然是不能的)
解决方案
1)删除Spring MVC文件上传配置
- <!--
- <bean
- class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="UTF-8" />
-
- <property name="maxUploadSize" value="2000000000" />
- </bean>
- -->
在控制器里面自己完成request的解析(当然上面spring MVC提供的两种方法是不能用的,所有上传的地方都需要自己做处理)
- public void upload3(HttpServletRequest request) {
- DiskFileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload upload = new ServletFileUpload(factory);
- try {
- List<FileItem> list = upload.parseRequest(request);
- for(FileItem item : list){
- if(item.isFormField()){
-
- }else{
-
- }
- }
- } catch (FileUploadException e) {
- e.printStackTrace();
- }
-
- }
2)如果是需要使用的ProgressListener监听器我们可以重写 CommonsMultipartResolver的parseRequest方法
- package com.lwp.spring.ext;
-
- import java.util.List;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.FileUpload;
- import org.apache.commons.fileupload.FileUploadBase;
- import org.apache.commons.fileupload.FileUploadException;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- import org.springframework.web.multipart.MaxUploadSizeExceededException;
- import org.springframework.web.multipart.MultipartException;
- import org.springframework.web.multipart.commons.CommonsMultipartResolver;
- import com.lwp.listener.FileUploadListener;
- public class CommonsMultipartResolverExt extends CommonsMultipartResolver {
- @Override
- protected MultipartParsingResult parseRequest(HttpServletRequest request)
- throws MultipartException {
- FileUploadListener listener = new FileUploadListener();
- String encoding = determineEncoding(request);
- FileUpload fileUpload = prepareFileUpload(encoding);
- fileUpload.setProgressListener(listener);
- try {
- List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
- return parseFileItems(fileItems, encoding);
- }
- catch (FileUploadBase.SizeLimitExceededException ex) {
- throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
- }
- catch (FileUploadException ex) {
- throw new MultipartException("Could not parse multipart servlet request", ex);
- }
- }
- }
监听器方法
- import org.apache.commons.fileupload.ProgressListener;
-
- public class FileUploadListener implements ProgressListener {
-
- @Override
- public void update(long arg0, long arg1, int arg2) {
-
-
-
- System.out.println(arg0 +"\t" + arg1 +"\t" + arg2);
- }
-
- }
配置文件改为我们自己的(这种方式的缺陷是,所有文件上传都需要使用到Listener)
- <bean
- class="com.lwp.spring.ext.CommonsMultipartResolverExt">
- <property name="defaultEncoding" value="UTF-8" />
- <property name="maxUploadSize" value="2000000000" />
- </bean>
注: 综上所述,如果只是普通的文件上传spring MVC 完全可以完成,如果需要使用进度条的listener前段可以使用假的进度条或者是上面的两种方式.
|
请发表评论