前台代码:
<!doctype html>
<html lang="en" class="feedback">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>问题反馈</title>
<link rel="stylesheet" type="text/css" href="../assets/mui/css/mui.min.css" />
<link rel="stylesheet" href="../css/ask.css">
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script type="text/javascript" src="http://res2.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
</head>
<body>
<div class="mui-content bg-white">
<form class="mui-input-group" id="fm-post" method="post" action="#">
<input type="hidden" name="pic">
<div><button id="addBtn" class="mui-btn" type="button"></button></div>
<div id='image-list' class="row image-list">
</div>
<div class="sub-div">
<button id="submit" class="mui-btn mui-btn-danger w90" type="submit">提交</button>
</div>
</form>
</div>
<script src="../assets/mui/js/mui.min.js"></script>
<script src="../js/jquery/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="../js/jquery/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
mui.init();
var localIds=[];
var _data = {
url: location.href,
t: Math.random()
};
var _getWechatSignUrl = back_url_prefix + '/wx/setting/sign';
var _saveImgUrl = back_url_prefix + '/wx/setting/saveImg';
var _savePostUrl = back_url_prefix+ '/wx/post/save';
// var _savePostUrl = "http://localhost:8080/jeeplus_union"+ '/wx/post/save';
// 获取微信签名
$.ajax({
url: _getWechatSignUrl,
data: _data,
async: true,
success: function(o) {
if(o.errCode == 1) {
wxConfig(o.data.appid, o.data.timestamp, o.data.nonceStr, o.data.signature);
} else {
mui.alert("获取微信签名失败");
}
}
});
$(function() {
$("#fm-post :submit").click(function() {
alert("imgList==>"+imgList.join(","));
});
});
function wxConfig(_appId, _timestamp, _nonceStr, _signature) {
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: _appId, // 必填,公众号的唯一标识
timestamp: _timestamp, // 必填,生成签名的时间戳
nonceStr: _nonceStr, // 必填,生成签名的随机串
signature: _signature, // 必填,签名,见附录1
jsApiList: ['chooseImage', 'uploadImage','getLocalImgData']
// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
}
wx.ready(function() {})
wx.error(function(res) {
mui.alert("调用微信jsapi返回的状态:" + res.errMsg);
});
var imgList=[];
/**
* 当点击添加按钮
*/
$('#addBtn').click(function() {
wx.chooseImage({
count: 6,
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function(res) {
localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
if (localIds.length == 0) {
mui.alert('请选择图片');
return;
}
for(var i = 0;i<localIds.length;i++){
imgList.push(localIds[i]);
$("#image-list").append('<div style="width:50%;padding: 0 5px;float: left;"><img width="100%" height="80px" style="margin-right: 10px;" src="'+localIds[i]+'"/></div>');
}
}
});
});
</script>
</body>
</html>
================================================================================================
后台获取签名的方法:
@ResponseBody
@RequestMapping(value="/sign",method = RequestMethod.GET)
public WxRtnMap sign(@RequestParam(value="url") String url,
@RequestParam(value="t") String t) throws Exception {
Long timestamp = System.currentTimeMillis() / 1000;
String nonceStr = StringUtils2.randomStr(10);
//获取access_token
//根据access_token 获取js-ticket
String jsapi_ticket=WeixinUtils.getJsTicket();
if(StringUtils.isBlank(jsapi_ticket)){
return new WxRtnMap(2,"获取js-tikect出错");
}
Map<String ,Object> rsMap = new HashMap<String ,Object>();
rsMap.put("appid", Constant.WEIXIN_UNIION_APPID);
rsMap.put("timestamp", timestamp);
rsMap.put("nonceStr", nonceStr);
rsMap.put("signature", getSign(jsapi_ticket,nonceStr,timestamp,url));
return new WxRtnMap(1,"获取成功",rsMap);
}
private String getSign(String jsapi_ticket, String noncestr, Long timestamp, String url)
throws NoSuchAlgorithmException {
String shaStr = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url="
+ url;
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(shaStr.getBytes());
StringBuffer signature = new StringBuffer();
for (int i = 0; i < result.length; i++) {
signature.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
return signature.toString();
}
================================================================================================
后台保存图片的方法:
/**
* 根据serverId获取图片并保存到本地
* @param serverId 微信图片服务器id
* @return
* @throws Exception
*/
@ResponseBody
@RequestMapping(value="/saveImg",method = RequestMethod.POST)
public WxRtnMap saveImg(@RequestParam(value="serverId",required=true) String serverId) throws Exception {
Map<String ,Object> rsMap = new HashMap<String ,Object>();
//1.根据serverId ,从微信服务器获取图片,保存到本地
//2.返回前台图片地址
if(StringUtils.isBlank(serverId)){
return new WxRtnMap(2,"参数serverId为空");
}
//保存到本地
String filePath = Global.USERFILES_BASE_URL+"weixin/ask/";
String fileName = serverId;
WeixinUtils.saveImageToDisk(serverId,Global.getUserfilesBaseDir()+filePath,fileName);
//返回本地图片url
rsMap.put("imgUrl", filePath+fileName+".jpg");
rsMap.put("servId", serverId);
return new WxRtnMap(1,"保存图片成功",rsMap);
}
================================================================================================
WeixinUtils:
package com.jeeplus.weixin.utils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jeeplus.common.constant.Constant;
import com.jeeplus.common.mapper.JsonMapper;
import com.jeeplus.common.utils.HttpClientUtils;
import com.jeeplus.common.utils.JedisUtils;
import net.sf.json.JSONObject;
/**
* 微信公共类
*
*/
public class WeixinUtils {
private static Logger logger = LoggerFactory.getLogger(WeixinUtils.class);
/**
* 获取access_token
* @return
*/
public static String getAccessToken() {
String access_token = "";
// 判断redis是否有,没有的话,请求接口
if (JedisUtils.exists(Constant.WEIXIN_UNIION_REDIS_PREFIX + "ACCESS_TOKEN")) {
access_token = JedisUtils.get(Constant.WEIXIN_UNIION_REDIS_PREFIX + "ACCESS_TOKEN");
} else {
HttpClientUtils httpUtils = new HttpClientUtils();
// 解析成Json格式
JSONObject jsonObject = JSONObject.fromObject(httpUtils.doGet(Constant.WEIXIN_UNIION_ACCESS_TOKEN_URL));
// {"errcode":40164,"errmsg":"invalid ip 58.59.67.122, not in
// whitelist hint: [W40i2a07822994]"}
// {"access_token":"17_-bOQwJcHwo_M55_vi4VBp7Is7DlGgy-fZTbO_LxH0ObfZCV6pucyqz9RpzQ1Rb2EUp6CNIBrbMLnVx9cnX_fSXJoDipz4QQ4ZWWaHyqxFiIOIsl4DcFGFmClMliUnWtDMU1BJ89vRWuliFQ5VRIfAJAIEV","expires_in":7200}
access_token = jsonObject.getString("access_token");
JedisUtils.set(Constant.WEIXIN_UNIION_REDIS_PREFIX + "ACCESS_TOKEN", access_token, 7200);
}
logger.info("getAccessToken 方法返回:" + access_token);
return access_token;
}
/**
* 获取js_ticket
* @return
*/
public static String getJsTicket() {
String js_ticket = "";
// 判断redis是否有,没有的话,请求接口
if (JedisUtils.exists(Constant.WEIXIN_UNIION_REDIS_PREFIX + "JS_TICKET")) {
js_ticket = JedisUtils.get(Constant.WEIXIN_UNIION_REDIS_PREFIX + "JS_TICKET");
} else {
HttpClientUtils httpUtils = new HttpClientUtils();
// 解析成Json格式
// {
// "errcode":0,
// "errmsg":"ok",
// "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
// "expires_in":7200
// }
JSONObject jsonObject = JSONObject.fromObject(httpUtils
.doGet(Constant.WEIXIN_UNIION_JS_TICKET_URL + "?access_token=" + getAccessToken() + "&type=jsapi"));
// {"access_token":"17_-bOQwJcHwo_M55_vi4VBp7Is7DlGgy-fZTbO_LxH0ObfZCV6pucyqz9RpzQ1Rb2EUp6CNIBrbMLnVx9cnX_fSXJoDipz4QQ4ZWWaHyqxFiIOIsl4DcFGFmClMliUnWtDMU1BJ89vRWuliFQ5VRIfAJAIEV","expires_in":7200}
logger.info("获取ticket微信接口-返回:" + jsonObject.toString());
if (jsonObject.getInt("errcode") == 0) {
js_ticket = jsonObject.getString("ticket");
JedisUtils.set(Constant.WEIXIN_UNIION_REDIS_PREFIX + "JS_TICKET", js_ticket, 7200);
}
}
logger.info("getJsTicket 方法返回:" + js_ticket);
return js_ticket;
}
/**
* 获取临时素材
* @param mediaId
* @return
* @throws IOException
*/
public static InputStream getMediaStream(String mediaId) throws IOException {
logger.info("getMediaStream 方法--进入:" + mediaId);
String access_token = getAccessToken();
String params = "access_token=" + access_token + "&media_id=" + mediaId;
InputStream is = null;
try {
String urlNameString = Constant.WEIXIN_UNIION_MEDIA_URL + params;
URL urlGet = new URL(urlNameString);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
http.setRequestMethod("GET"); // 必须是get方式请求
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
http.connect(); // 获取文件转化为byte流
is = http.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
logger.info("getMediaStream 方法--离开");
return is;
}
/**
* 临时素材保存到本地
* @param mediaId
* @param picPath
* @param picName
* @throws Exception
*/
public static void saveImageToDisk(String mediaId,String picPath,String picName)
throws Exception {
logger.info("saveImageToDisk 方法--进入:" + mediaId+",picPath:"+picPath+picName);
InputStream inputStream = getMediaStream(mediaId);
byte[] data = new byte[10240];
int len = 0;
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(picPath+picName+".jpg");
while ((len = inputStream.read(data)) != -1) {
fileOutputStream.write(data, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
logger.info("saveImageToDisk 方法--离开");
}
public static void main(String[] args) throws Exception {
saveImageToDisk("987654321123456789", "D:", "987654321123456789");
}
/**
* 根据用户的openid 获取用户头像
* @param openid
* @return
* @throws IOException
*/
public static String getWeixinPhoto(String openid) throws IOException {
logger.info("getWeixinPhoto 方法--进入:" + openid);
String wxPhotoUrl=null;
String access_token = getAccessToken();
String params = "access_token=" + access_token + "&openid=" + openid+"&lang=zh_CN";
logger.info("接口参数:" + params);
try {
HttpClientUtils httpUtils = new HttpClientUtils();
// 解析成Json格式
JSONObject jsonObject = JSONObject.fromObject(httpUtils.doGet(Constant.WEIXIN_UNIION_USER_INFO_URL + params));
// {"errcode":40164,"errmsg":"invalid ip 58.59.67.122, not in
// {
// "subscribe": 1,
// "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
// "nickname": "Band",
// "sex": 1,
// "language": "zh_CN",
// "city": "广州",
// "province": "广东",
// "country": "中国",
// "headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
// "subscribe_time": 1382694957,
// "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
// "remark": "",
// "groupid": 0,
// "tagid_list":[128,2],
// "subscribe_scene": "ADD_SCENE_QR_CODE",
// "qr_scene": 98765,
// "qr_scene_str": ""
// }
logger.info("getWeixinPhoto 方法--调用微信接口返回值:" + jsonObject.toString());
if(jsonObject.containsKey("errcode")){
logger.error("getWeixinPhoto 方法--调用微信接口返回错误:" + jsonObject.getString("errcode")+":"+jsonObject.getString("errmsg"));
}else{
wxPhotoUrl = jsonObject.getString("headimgurl");
}
logger.info("getWeixinPhoto 方法--头像:" + wxPhotoUrl);
return wxPhotoUrl;
} catch (Exception e) {
e.printStackTrace();
}
logger.info("getWeixinPhoto 方法--离开");
return wxPhotoUrl;
}
}