由于自己最近在搞微信小程序,然后要做一个上传商品的模块,当然就需要上传图片了,然而一开始网上查了好几天关于微信小程序上传图片到服务器的,但是一直没搞定,总是报错。最后在搜索的过程中看到了一句评论说“如果找不到错误的话那就重新做吧”,就是这句话启发了我,所以我决定不上网查别人的方法,而是自己查看官方提供的API自己摸索着尝试,结果还真的给做出来了。因为之前自己网上查找了许多文章都无法解决我的问题,因此我决定写下这篇文章,希望能帮到有需要的人吧。
需要用到的接口
1、选择图片接口
首先看一下官方提供的API接口的参数说明
wx.chooseImage(OBJECT)
从本地相册选择图片或使用相机拍照。
OBJECT参数说明:
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
count | Number | 否 | 最多可以选择的图片张数,默认9 |
sizeType | StringArray | 否 | original 原图,compressed 压缩图,默认二者都有 |
sourceType | StringArray | 否 | album 从相册选图,camera 使用相机,默认二者都有 |
success | Function | 是 | 成功则返回图片的本地文件路径列表 tempFilePaths |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
注:文件的临时路径,在小程序本次启动期间可以正常使用,如需持久保存,需在主动调用 wx.saveFile,在小程序下次启动时才能访问得到。
success返回参数说明:
参数 | 类型 | 说明 | 最低版本 |
---|---|---|---|
tempFilePaths | StringArray | 图片的本地文件路径列表 | |
tempFiles | ObjectArray | 图片的本地文件列表,每一项是一个 File 对象 | 1.2.0 |
File 对象结构如下:
字段 | 类型 | 说明 |
---|---|---|
path | String | 本地文件路径 |
size | Number | 本地文件大小,单位:B |
示例代码:
-
wx.chooseImage({
-
count: 1, // 默认9
-
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
-
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
-
success: function (res) {
-
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
-
var tempFilePaths = res.tempFilePaths
-
}
-
})
结合上面的参数说明,看懂这段代码应该不难,不过就算看不懂也没什么关系,毕竟这只是官方提供的一个API。
2、图片上传接口
wx.uploadFile(OBJECT)
将本地资源上传到开发者服务器。如页面通过 wx.chooseImage 等接口获取到一个本地资源的临时文件路径后,可通过此接口将本地资源上传到指定服务器。客户端发起一个 HTTPS POST 请求,其中content-type
为multipart/form-data
。
OBJECT参数说明:
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
url | String | 是 | 开发者服务器 url |
filePath | String | 是 | 要上传文件资源的路径 |
name | String | 是 | 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容 |
header | Object | 否 | HTTP 请求 Header , header 中不能设置 Referer |
formData | Object | 否 | HTTP 请求中其他额外的 form data |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success返回参数说明:
参数 | 类型 | 说明 |
---|---|---|
data | String | 开发者服务器返回的数据 |
statusCode | Number | HTTP状态码 |
示例代码:
-
wx.chooseImage({
-
success: function(res) {
-
var tempFilePaths = res.tempFilePaths
-
wx.uploadFile({
-
url: 'https://example.weixin.qq.com/upload', //仅为示例,非真实的接口地址
-
filePath: tempFilePaths[0],
-
name: 'file',
-
formData:{
-
'user': 'test'
-
},
-
success: function(res){
-
var data = res.data
-
//do something
-
}
-
})
-
}
-
})
同样的,结合上面提供的参数说明,这段代码要看懂也是不难的,主要就是需要知道这两段代码如何结合使用,也就是这篇文章主要的内容。
选择图片以及上传图片
这里页面我就不做多好看了。。。
相应的代码:
-
<text>index.wxml</text>
-
<view class="">
-
<form bindsubmit="uploadImg">
-
<label bindtap="chooseImg">点击选择图片</label>
-
<image src="{{photos}}"></image>
-
<button form-type="submit">提交</button>
-
</form>
-
</view>
其中image标签中src属性里面的{{photos}}参数则是选择图片后的图片的本地文件路径,就是说选择图片后则会在页面中显示该图片。
当点击选择图片的label时则会调用chooseImg这个方法,也就是需要调用到官方的那个选择图片的接口,然后当点击提交按钮的时候,则会调用uploadImg这个方法,也就是需要调用到官方的那个上传图片的接口。
1、选择图片
index.js中的代码
-
// index.js
-
Page({
-
/**
-
* 页面的初始数据
-
*/
-
data: {
-
photos: ""
-
},
-
/**
-
* 选择照片
-
*/
-
chooseImg: function() {
-
var that = this
-
wx.chooseImage({
-
count: 1, // 默认9
-
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
-
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
-
success: function (res) {
-
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
-
var tempFilePaths = res.tempFilePaths
-
that.setData({
-
photos: tempFilePaths
-
})
-
console.log(that.data.photos)
-
}
-
})
-
}
-
})
这里将官方提供的API封装到chooseImg这个方法中,就是当点击“点击选择图片”的label的时候就会调用该方法。
同时在页面也会显示所选择的图片
选择图片就已经完成了,接下来就是上传图片了。
2、上传图片
上传图片应该才是这篇文章的核心内容吧。。。
uploadImg方法代码(同样在index.js中):
-
/**
-
* 上传照片
-
*/
-
uploadImg: function() {
-
var that = this
-
wx.uploadFile({
-
url: 'http://localhost:8080/weshop/goods/upload', //仅为示例,非真实的接口地址
-
filePath: that.data.photos[0],
-
name: 'file',
-
formData: {
-
'user': '黑柴哥'
-
},
-
success: function (res) {
-
var data = res.data
-
console.log(data)
-
//do something
-
}
-
})
-
}
这里的url就是Java后台的上传图片接口,实际可以更改为自己服务器的地址。
下面开始介绍后台代码
-
import org.apache.log4j.Logger;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RequestParam;
-
import org.springframework.web.bind.annotation.ResponseBody;
-
import org.springframework.web.multipart.MultipartFile;
-
import javax.servlet.http.HttpServletRequest;
-
import java.io.File;
-
import java.io.IOException;
-
/**
-
* 商品信息页面跳转控制类
-
* @author a柴大队长
-
* @createtime 2017年8月20日10:34:55
-
*/
-
@Controller
-
@RequestMapping("goods")
-
public class GoodsController {
-
private Logger logger = Logger.getLogger(GoodsController.class);
-
/**
-
* @createtime 2017年8月20日17:15:41
-
* @param request
-
* @param file
-
* @return 上传成功返回“success”,上传失败返回“error”
-
* @throws IOException
-
*/
-
@ResponseBody
-
@RequestMapping("upload")
-
public String upload(HttpServletRequest request, @RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
-
System.out.println("执行upload");
-
request.setCharacterEncoding("UTF-8");
-
logger.info("执行图片上传");
-
String user = request.getParameter("user");
-
logger.info("user:"+user);
-
if(!file.isEmpty()) {
-
logger.info("成功获取照片");
-
String fileName = file.getOriginalFilename();
-
String path = null;
-
String type = null;
-
type = fileName.indexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()) : null;
-
logger.info("图片初始名称为:" + fileName + " 类型为:" + type);
-
if (type != null) {
-
if ("GIF".equals(type.toUpperCase())||"PNG".equals(type.toUpperCase())||"JPG".equals(type.toUpperCase())) {
-
// 项目在容器中实际发布运行的根路径
-
String realPath = request.getSession().getServletContext().getRealPath("/");
-
// 自定义的文件名称
-
String trueFileName = String.valueOf(System.currentTimeMillis()) + fileName;
-
// 设置存放图片文件的路径
-
path = realPath + "/uploads/" + trueFileName;
-
logger.info("存放图片文件的路径:" + path);
-
file.transferTo(new File(path));
-
logger.info("文件成功上传到指定目录下");
-
}else {
-
logger.info("不是我们想要的文件类型,请按要求重新上传");
-
return "error";
-
}
-
}else {
-
logger.info("文件类型为空");
-
return "error";
-
}
-
}else {
-
logger.info("没有找到相对应的文件");
-
return "error";
-
}
-
return "success";
-
}
-
}
由于图片是以content-type为multipart/form-data的格式上传的,所以使用spring-mvc可以通过使用参数的形式以二进制的格式获取到该图片。
<strong>@RequestParam(value = "file", required = false) MultipartFile file</strong>
并且需要在spring-mvc.xml文件中加入以下代码:
-
<!-- 文件上传配置 -->
-
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
-
<!-- 默认编码 -->
-
<property name="defaultEncoding" value="UTF-8"/>
-
<!-- 上传文件大小限制为31M,31*1024*1024 -->
-
<property name="maxUploadSize" value="32505856"/>
-
<!-- 内存中的最大值 -->
-
<property name="maxInMemorySize" value="4096"/>
-
</bean>
上传图片所需要添加的依赖为:
-
<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>
-
<dependency>
-
<groupId>commons-codec</groupId>
-
<artifactId>commons-codec</artifactId>
-
<version>1.9</version>
-
</dependency>
完成后,当点击“提交”按钮时则会上传图片到服务器。
Java控制台输出代码:
执行upload
[INFO][http-bio-8080-exec-7][2017-08-20 17:35:02][com.wechat.weshop.controller.GoodsController] - 执行图片上传
[INFO][http-bio-8080-exec-7][2017-08-20 17:35:02][com.wechat.weshop.controller.GoodsController] - user:黑柴哥
[INFO][http-bio-8080-exec-7][2017-08-20 17:35:02][com.wechat.weshop.controller.GoodsController] - 成功获取照片
[INFO][http-bio-8080-exec-7][2017-08-20 17:35:02][com.wechat.weshop.controller.GoodsController] - 图片初始名称为:tmp_756953327o6zAJs-NzXAG_mUCqaBz3dPQyMMc99f14abd61cbebac2b728924beaaecb3.jpg 类型为:jpg
[INFO][http-bio-8080-exec-7][2017-08-20 17:35:02][com.wechat.weshop.controller.GoodsController] - 存放图片文件的路径:D:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\weshop\/uploads/1503221702072tmp_756953327o6zAJs-NzXAG_mUCqaBz3dPQyMMc99f14abd61cbebac2b728924beaaecb3.jpg
[INFO][http-bio-8080-exec-7][2017-08-20 17:35:02][com.wechat.weshop.controller.GoodsController] - 文件成功上传到指定目录下
图片也上传到相应的位置了
最后将代码发布到CentOS上测试是否成功,也就是将url中的localhost:8080更改为服务器的地址。
上传后通过ls查看uploads文件夹下的文件
[root@iZi1ozk35hjgizZ uploads]# ls
1503222548424tmp_756953327o6zAJs-NzXAG_mUCqaBz3dPQyMMccdc2a843464cd3c3ae2d3c79a2b181a7.jpg
以及查看日志文件信息
因此,发布到CentOS也是可以运行的。