隨着微信的使用越來越多,更多的公司或者個人希望藉助微信的平臺創建自己的公衆號或者服務號。對於開發人員來說,可以將微信的公衆號看做一個瀏覽器,通過在微信端創建跳轉按鈕的方式來訪問到你自己創建的並且已經成功部署的web項目上。不過需要注意的是,微信只接受帶有域名的url訪問。web創建者要先申請域名。
下面進入正題:通過wechat訪問java+springMVC網站
首先附上微信用戶手冊,主要的流程爲
1.將項目地址(帶域名)配置在一個對應的微信按鈕上,具體操作可訪問微信用戶手冊。
2.通過該地址生成一個微信訪問地址
/**
* 微信授權
* @Title: forgetpw
* @Description: TODO
* @param @param request
* @param @param response
* @param @return 設定文件
* @return String 返回類型
* @throws
*/
@RequestMapping("/authority")
public String authority(HttpServletRequest request, HttpServletResponse response) {
String redisUrl = sendWechatMessage.<span style="color:#FF6666;">getWechatCodeURL()</span>;//
request.setAttribute("redisUrl", redisUrl);
System.out.println("redisUrl="+redisUrl);
return "wechat/authority";
}
/**
* 登錄授權
* @Title: getWechatCodeURL
* @Description: TODO
* @param @return 設定文件
* @return String 返回類型
* @throws
*/
public String getWechatCodeURL ()
{
//https://open.weixin.qq.com/connect/oauth2/authorize?
//appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
String appid = getParam.getParam("appid");//自己公衆號的appid,可能登錄微信公衆平臺查看
String redirect_uri = getParam.getParam("redirect_uri");//自己項目的登錄首頁地址
String snsapi_base = "snsapi_base";//只能獲得openid,當爲<strong>snsapi_userinfo</strong>時,可通過token獲取用戶基本信息
StringBuffer sb = new StringBuffer();
GetWechatCode getWechatCode = new GetWechatCode();
getWechatCode.setAppid(appid);
getWechatCode.setRedirect_url(redirect_uri);
getWechatCode.setResponse_type("code");
getWechatCode.setScope(snsapi_base);
sb.append("https://open.weixin.qq.com/connect/oauth2/authorize?");
sb.append("appid="+getWechatCode.getAppid());
sb.append("&redirect_uri="+getWechatCode.getRedirect_url());
sb.append("&response_type="+getWechatCode.getResponse_type());
sb.append("&scope="+getWechatCode.getScope());
return sb.toString();
}
3.將改地址傳給客戶端,並使用頁面跳轉將code返回給在上面設定的登錄首頁地址(redirect_uri)
$(document).ready(function(){
var url = "${redisUrl}";
if(url==null||url=="")
{
url= "<%=request.getContextPath() %>/wechat/authority";
}
window.location=url;
});
4.服務端接收到code後,使用httpclient訪問微信請求token地址,獲取最新token和openid String openid = "";
//微信獲取登錄用戶的openId
try {
openid = sendWechatMessage.getWechatOpenId(wechatcode, username);
} catch (ConnectException ce) {
request.setAttribute("InfoMessage", "微信端連接超時:"+ce.getMessage());
logger.error(TimeHelper.getCurrentDateTime()+"------------"+username+"微信端連接超時:"+ce.getMessage());
return "wechat/login";
} catch (Exception e) {
request.setAttribute("InfoMessage", "微信端https請求異常:"+e.getMessage());
logger.error(TimeHelper.getCurrentDateTime()+"------------"+username+"微信端https請求異常:"+e.getMessage());
return "wechat/login";
}
/**
* 獲取微信的登錄用戶id
* @Title: getWechatOpenId
* @Description: TODO
* @param @param code
* @param @param username
* @param @return
* @param @throws KeyManagementException
* @param @throws NoSuchAlgorithmException
* @param @throws NoSuchProviderException
* @param @throws MalformedURLException
* @param @throws ProtocolException
* @param @throws UnsupportedEncodingException
* @param @throws IOException 設定文件
* @return String 返回類型
* @throws
*/
public String getWechatOpenId(String code,String username)
throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException,
MalformedURLException, ProtocolException, UnsupportedEncodingException, IOException
{
//https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
String appid = getParam.getParam("appid");
String secret = getParam.getParam("secret");
String authorization_code = "authorization_code";
StringBuffer sb = new StringBuffer();
GetWechatOpenId getWechatOpenId = new GetWechatOpenId();
getWechatOpenId.setAppid(appid);
getWechatOpenId.setCode(code);
getWechatOpenId.setGrant_type(authorization_code);
getWechatOpenId.setSecret(secret);
sb.append("https://api.weixin.qq.com/sns/oauth2/access_token?");
sb.append("appid="+getWechatOpenId.getAppid());
sb.append("&secret="+getWechatOpenId.getSecret());
sb.append("&code="+getWechatOpenId.getCode());
sb.append("&grant_type="+getWechatOpenId.getGrant_type());
logger.info(TimeHelper.getCurrentDateTime()+"------------獲取"+username+"微信端請求地址"+sb.toString());
JSONObject jsonObject = CommonUtil.<span style="color:#33CC00;">httpsRequestToJsonObject</span>(sb.toString(), "GET", null,username);
logger.info(TimeHelper.getCurrentDateTime()+"------------獲取"+username+"微信端openid接收返回值"+jsonObject.toJSONString());
String wechatOpenId = jsonObject.getString("openid");
Date currTime = TimeHelper.getCurrentDateTime();
String wechatToken =jsonObject.getString("access_token");
String expires_in =jsonObject.getString("expires_in");
String refresh_token =jsonObject.getString("refresh_token");
//在數據庫記錄token
TWechatToken tWechatToken = new TWechatToken();
tWechatToken.setAccessToken(wechatToken);
tWechatToken.setOpenId(wechatOpenId);
tWechatToken.setGetTime(currTime);
tWechatToken.setKeepTime(expires_in);
tWechatToken.setRefreshToken(refresh_token);
tWechatTokenRepository.insert(tWechatToken);
return wechatOpenId;
}
public class CommonUtil {
private static final Logger logger = LoggerFactory.getLogger(CommonUtil.class);
public static JSONObject <span style="color:#33CC00;">httpsRequestToJsonObject</span>(String requestUrl, String requestMethod, String outputStr,String username)
throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, MalformedURLException,
ProtocolException, UnsupportedEncodingException, IOException {
JSONObject jsonObject = null;
StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr);
jsonObject = JSONObject.parseObject(buffer.toString());
return jsonObject;
}
private static StringBuffer httpsRequest(String requestUrl, String requestMethod, String output)
throws NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException, MalformedURLException, IOException, ProtocolException,
UnsupportedEncodingException {
URL url = new URL(requestUrl);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod(requestMethod);
if (null != output) {
OutputStream outputStream = connection.getOutputStream();
outputStream.write(output.getBytes("utf-8"));
outputStream.close();
}
// 從輸入流讀取返回內容
InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
connection.disconnect();
return buffer;
}
5.每次使用token時都需要根據超時時間和獲取時間判斷當前token是否有效,如果有效繼續使用,如果無效則要通過refresh_token重新刷新。
/**
* 獲取當前有效token
* @Title: getaccessToken
* @Description: TODO
* @param @param username
* @param @param openId
* @param @return
* @param @throws KeyManagementException
* @param @throws NoSuchAlgorithmException
* @param @throws NoSuchProviderException
* @param @throws MalformedURLException
* @param @throws ProtocolException
* @param @throws UnsupportedEncodingException
* @param @throws IOException 設定文件
* @return String 返回類型
* @throws
*/
public String getaccessToken(String username,String openId) throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, MalformedURLException, ProtocolException, UnsupportedEncodingException, IOException
{
List<TWechatToken> list = tWechatTokenRepository.getList(openId);
Date getTime = list.get(0).getGetTime();
Date currTime = TimeHelper.getCurrentDateTime();
String keepTime = list.get(0).getKeepTime();
String refresh_token = list.get(0).getRefreshToken();
long l = getTime.getTime()+Integer.valueOf(keepTime);
long l1 =currTime.getTime()-1000;
if(l>l1)
{
String accessToken = list.get(0).getAccessToken();
logger.info(TimeHelper.getCurrentDateTime()+"------------"+username+"數據庫獲取access_token"+accessToken);
return accessToken;
}
else
{
//https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
String appid = getParam.getParam("appid");
String grant_type = "refresh_token";
StringBuffer sb = new StringBuffer();
sb.append("https://api.weixin.qq.com/sns/oauth2/refresh_token?");
sb.append("&appid="+appid);
sb.append("&grant_typ="+grant_type);
sb.append("refresh_token="+refresh_token);
logger.info(TimeHelper.getCurrentDateTime()+"------------"+username+"微信端獲取access_token發送地址"+sb.toString());
JSONObject jsonObject = CommonUtil.httpsRequestToJsonObject(sb.toString(), "GET", null,username);
logger.info(TimeHelper.getCurrentDateTime()+"------------"+username+"微信端獲取access_token"+jsonObject.toJSONString());
String wechatToken =jsonObject.getString("access_token");
String expiresIn = jsonObject.getString("expires_in");
String refreshToken = jsonObject.getString("refresh_token");
String openIdNew = jsonObject.getString("openid");
TWechatToken tWechatToken = new TWechatToken();
tWechatToken.setAccessToken(wechatToken);
tWechatToken.setGetTime(currTime);
tWechatToken.setKeepTime(expiresIn );
tWechatToken.setRefreshToken(refreshToken);
tWechatToken.setOpenId(openIdNew);
tWechatTokenRepository.insert(tWechatToken);
return wechatToken;
}
}
6.向對應的openid發送信息
/**
* @throws IOException
* @throws UnsupportedEncodingException
* @throws ProtocolException
* @throws MalformedURLException
* @throws NoSuchProviderException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* 發送微信信息
* @Title: sendMessage
* @Description: TODO
* @param @param username
* @param @return 設定文件
* @return String 返回類型
* @throws
*/
public void sendMessage(String openid,String username,String message) throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, MalformedURLException, ProtocolException, UnsupportedEncodingException, IOException
{
//https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
String access_token = <span style="color:#FF6666;">getaccessToken</span>(username,openid);
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+access_token;
StringBuffer sb = new StringBuffer();
sb.append("{ ");
sb.append(" \"touser\":\""+openid+"\", ");
sb.append(" \"msgtype\":\"text\", ");
sb.append(" \"text\": ");
sb.append(" { ");
sb.append(" \"content\":\""+message+"\" ");
sb.append(" } ");
sb.append("} ");
logger.info(TimeHelper.getCurrentDateTime()+"------------"+username+"微信端發送信息發送地址"+url);
JSONObject jsonObject = CommonUtil.httpsRequestToJsonObject(url, "POST", sb.toString(),username);
logger.info(TimeHelper.getCurrentDateTime()+"------------"+username+"微信端向"+openid+"發送信息的返回值"+jsonObject.toJSONString());
}
/**
* 獲取當前有效token
* @Title: getaccessToken
* @Description: TODO
* @param @param username
* @param @param openId
* @param @return
* @param @throws KeyManagementException
* @param @throws NoSuchAlgorithmException
* @param @throws NoSuchProviderException
* @param @throws MalformedURLException
* @param @throws ProtocolException
* @param @throws UnsupportedEncodingException
* @param @throws IOException 設定文件
* @return String 返回類型
* @throws
*/
public String <span style="color:#FF6666;">getaccessToken</span>(String username,String openId) throws KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException, MalformedURLException, ProtocolException, UnsupportedEncodingException, IOException
{
//https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
StringBuffer sb = new StringBuffer();
String appid = getParam.getParam("appid");
String secret = getParam.getParam("secret");
String grantType = "client_credential";
sb.append("https://api.weixin.qq.com/cgi-bin/token?");
sb.append("grant_type="+grantType);
sb.append("&appid="+appid);
sb.append("&secret="+secret);
JSONObject jsonObject = CommonUtil.httpsRequestToJsonObject(sb.toString(), "POST", null,username);
return jsonObject.getString("access_token");
}
最後附上token表結構
CREATE TABLE `t_wechat_token` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`access_token` varchar(400) DEFAULT NULL,
`get_time` datetime DEFAULT NULL,
`keep_time` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ;