最近在项目开发中,有一个在微信WEB项目中上传图片的需求,一开始使用了传统的<input type="file">的方式去实现,但是后面发现在使用这种传统模式时会由于手机系统的差异而导致一系列的问题,后改用微信JSSDK的方式来实现,做的过程中也遇到了一些小坑,把经验贴出来给大家分享一下,让大家少走点弯路。
总的来说,利用JSSDK来实现该功能一共分为四步。
1. 调用wx.config(),初始化jssdk的配置,并在jsApiList中配置上传图片需要的四个api('chooseImage','previewImage','uploadImage','downloadImage')
wx.config({ debug : false, appId : data.appId, timestamp : data.timestamp, nonceStr : data.nonceStr, signature : data.signature, jsApiList : [ 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage' ]});
2.点击图片时,调用wx.chooseImage(),让用户去选择图片或拍照
1 function wxChooseImage() { 2 wx.chooseImage({ 3 count: 1, 4 sizeType: ['original', 'compressed'], 5 sourceType: ['album', 'camera'], 6 success: function (data) { 7 var localIds = data.localIds[0].toString(); 8 wxuploadImage(localIds); 9 }10 });11 }
3.选择完图片后调用wx.chooseImage(),将图片上传到微信服务器
1 function wxuploadImage(e) { 2 layer.load(1); 3 wx.uploadImage({ 4 localId: e, 5 isShowProgressTips: 0, 6 success: function (res) { 7 fileUpload(res.serverId); 8 } 9 }); 10 }
4.利用mediaId将图片从微信服务器下载到本地或项目的图片服务器路径下,并展示图片
1 function fileUpload(mediaId) { 2 $.ajax({ 3 url: KY.basePath + "/image/upload.htm", 4 dataType: 'json', 5 data: { 6 "mi": mediaId 7 }, 8 type: "post", 9 success: function(result) { 10 $("#imghead").attr("src", KY.imageServer + result.path);11 }12 }); 13 }
附:服务端从微信服务器下载图片的代码,在此处,我是将图片从微信服务器下载后调用另一个专门负责上传图片的项目去进行的上传操作,大家也可以在第73行代码获取到流之后下载到本地。
1 package com.hyde.carelink2.wechat.utils; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8 import java.util.ArrayList; 9 import java.util.HashMap; 10 import java.util.List; 11 import java.util.Map; 12 13 import org.apache.commons.httpclient.NameValuePair; 14 import org.apache.http.entity.ContentType; 15 import org.apache.http.entity.mime.content.ByteArrayBody; 16 import org.slf4j.Logger; 17 import org.slf4j.LoggerFactory; 18 19 import com.fasterxml.jackson.databind.ObjectMapper; 20 import com.hyde.carelink2.wechat.domain.upload.UploadImagResponse; 21 import com.hyde.carelink2.wechat.service.wechat.WechatServerCenter; 22 import com.hyde.common.StatusCode; 23 import com.hyde.common.enums.ImageToken; 24 import com.hyde.common.enums.ProjectType; 25 import com.hyde.common.utils.HttpUtil; 26 import com.hyde.config.enums.ConfigType; 27 import com.hyde.config.impl.CommonConfig; 28 29 /** 30 * @author WangHuijie 31 */ 32 public class DownloadImageUtil { 33 34 private final static Logger LOGGER = LoggerFactory.getLogger(DownloadImageUtil.class); 35 36 private static ObjectMapper objectMapper = new ObjectMapper(); 37 38 /** 39 * 从微信服务器获取媒体文件 40 * 41 * @param param 42 * @param mediaId 43 * @param request 44 * @return 45 */ 46 public static MapgetImageFromWechat(String mediaId) { 47 48 Map map = new HashMap (); 49 String accessToken = ""; // 接口访问凭证 50 try { 51 accessToken = WechatServerCenter.getAccessToken(); 52 } catch (Exception e) { 53 LOGGER.error(e.getMessage(), e); 54 } 55 String filePath = ""; 56 // 拼接请求地址 57 String requestUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + accessToken + "&media_id=" + mediaId; 58 try { 59 URL url = new URL(requestUrl); 60 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 61 conn.setDoInput(true); 62 conn.setDoOutput(true); 63 conn.setRequestMethod("GET"); 64 conn.setRequestProperty("Content-Type", "application/form-data"); 65 InputStream inputStream = conn.getInputStream(); 66 67 if (inputStream != null) { 68 HttpURLConnection conn1 = (HttpURLConnection) url.openConnection(); 69 conn1.setDoInput(true); 70 conn1.setDoOutput(true); 71 conn1.setRequestMethod("GET"); 72 conn1.setRequestProperty("Content-Type", "application/form-data"); 73 InputStream inputStream1 = conn1.getInputStream(); 74 75 if (inputStream1 != null) { 76 // 根据内容类型获取扩展名 77 String contentType = conn1.getHeaderField("Content-Type"); 78 String expandName = getFileexpandedName(contentType); 79 String fileName = mediaId + expandName; 80 filePath = getUploadServerPath(inputStream1, contentType, fileName); 81 map.put("path", filePath); 82 map.put("code", String.valueOf(StatusCode.SUCCESS.getIndex())); 83 map.put("msg", StatusCode.SUCCESS.getMessage()); 84 } else { 85 map.put("code", String.valueOf(StatusCode.ERROR.getIndex())); 86 map.put("msg", StatusCode.ERROR.getMessage()); 87 } 88 } else { 89 map.put("code", String.valueOf(StatusCode.ERROR.getIndex())); 90 map.put("msg", StatusCode.ERROR.getMessage()); 91 } 92 inputStream.close(); 93 conn.disconnect(); 94 } catch (Exception e) { 95 LOGGER.error(e.getMessage(), e); 96 } 97 return map; 98 } 99 100 public static String getUploadServerPath(InputStream inputStream, String contentType, String fileName) {101 102 String filePath = null;103 byte[] bytes = new byte[0];104 try {105 bytes = toByteArray(inputStream);106 } catch (IOException e) {107 LOGGER.error(e.getMessage(), e);108 }109 String token = "DM5344d93e19c41adb5e0f5531bdd0336";110 ProjectType projectType = ProjectType.CARELINK2;111 ImageToken type = ImageToken.CARELINK2_USER_PORTRAIT;112 UploadImagResponse response = uploadImage(bytes, token, contentType, fileName, projectType, type);113 if (response != null) {114 filePath = response.getFilePath();115 }116 return filePath;117 }118 119 /**120 * 执行文件上传到图片服务器121 * 122 * @param bytes123 * @param token124 * @param contentType125 * @param fileName126 * @param param127 * @return128 */129 protected static UploadImagResponse uploadImage(byte[] bytes, String token, String contentType, String fileName, ProjectType projectType, ImageToken type) {130 131 try {132 ByteArrayBody arrayBody = new ByteArrayBody(bytes, ContentType.create(contentType), fileName);133 List pairs = new ArrayList ();134 NameValuePair projectTypePair = new NameValuePair("p", String.valueOf(projectType.getIndex()));135 pairs.add(projectTypePair);136 NameValuePair typePair = new NameValuePair("type", String.valueOf(type.getIndex()));137 pairs.add(typePair);138 String url = CommonConfig.getConfig(ConfigType.UPLOAD_SERVICE_URL, String.class);139 String status = HttpUtil.postFile(url, arrayBody, token, pairs);140 UploadImagResponse response = objectMapper.readValue(status, UploadImagResponse.class);141 return response;142 } catch (Exception e) {143 LOGGER.error(e.getMessage(), e);144 }145 return null;146 }147 148 /**149 * 将输入流转为byte数组150 * @param input151 * @return152 * @throws IOException153 */154 public static byte[] toByteArray(InputStream input) throws IOException {155 ByteArrayOutputStream output = new ByteArrayOutputStream();156 byte[] buffer = new byte[4096];157 int n = 0;158 while (-1 != (n = input.read(buffer))) {159 output.write(buffer, 0, n);160 }161 return output.toByteArray();162 }163 164 /**165 * 根据内容类型判断文件扩展名166 * @param contentType 内容类型167 * @return168 */169 public static String getFileexpandedName(String contentType) {170 171 String fileEndWitsh = "";172 if ("image/jpeg".equals(contentType)) {173 fileEndWitsh = ".jpg";174 } else if ("audio/mpeg".equals(contentType)) {175 fileEndWitsh = ".mp3";176 } else if ("audio/amr".equals(contentType)) {177 fileEndWitsh = ".amr";178 } else if ("video/mp4".equals(contentType)) {179 fileEndWitsh = ".mp4";180 } else if ("video/mpeg4".equals(contentType)) {181 fileEndWitsh = ".mp4";182 }183 return fileEndWitsh;184 }185 186 }