Java微信公眾號開發之使用攔截器獲取粉絲openID
目的
本次實現的目的是:在微信公眾號專案中,可能在每次訪問頁面的時候需要帶上openID或者授權,查資料庫太耗效能、多次多個地方去調授權介面也不是最佳的方案,如果能利用攔截器攔截到每次請求訪問後臺,這個時候在攔截器裡判斷是否已經有這個粉絲的openID,如果獲取到了openid,就不用去走授權獲取使用者資訊介面了,那麼從哪裡取這個openID呢,可以從Redis或其他快取庫裡取,我使用了最簡單:從Session裡去取openID,取的前提是在第一次授權獲取使用者資訊後,你需要將openId存到session裡去,然每次請求攔截器會攔截請求從session獲取openID,來做業務判斷,如果取不到就去授權;
一、實現
1.建立一個攔截器,攔截器配置如下,對攔截器不熟悉的請看:如何自定義一個攔截器
在spring-mvc.xml檔案中新增一個攔截器 (注:如果是SpringBoot專案,請按照SpringBoot建立攔截器方式建立攔截器)
<!-- 攔截器配置,攔截順序:先執行後定義的,排在第一位的最後執行。-->
<mvc:interceptors>
<!-- 微信授權攔截器 -->
<mvc:interceptor>
<mvc:mapping path="/mobile/**" />
<bean class="com.thinkgem.jeesite.modules.sys.interceptor.WXOAuthInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
2.新建一個攔截器類WXOAuthInterceptor
WXOAuthInterceptor.java
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.thinkgem.jeesite.common.service.BaseService;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.wechat.service.WXOAuthService;
/**
* 微信
*
* <pre>
*
* @author cao_wencao
* @date 2018年8月13日
* </pre>
*/
@Slf4j
public class WXOAuthInterceptor extends BaseService implements HandlerInterceptor {
@Autowired
private WXOAuthService wXOAuthService;
@Override
@Transactional(readOnly = false)
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 獲取 seesion openid
log.warn("==============執行順序: 1、preHandle================");
String openid = (String) request.getSession().getAttribute("openid");
if (StringUtils.isNotBlank(openid)){
return true;
}
String code = request.getParameter("code"); // 獲取引數中 的 code 引數
if (StringUtils.isNotBlank(code)) {
wXOAuthService.userInfo(request, response);
} else {
wXOAuthService.oauth(request, response);
}
return true;
}
@Override
@Transactional(readOnly = false)
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.warn("==============執行順序: 2、postHandle================");
// request.getSession().setAttribute("openid", "oJIGa0RLwXB8r5vxYphyKCOQGxz1"); // 設定 Session Openid
// // 獲取 seesion openid
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.warn("==============執行順序: 3、afterCompletion================");
}
}
3.授權介面服務類WXOauthService
注:WXOauthService中userInfo方法為請求授權介面,在請求授權獲取使用者資訊後需要將openid存進session裡去,這樣在攔截器中才可以取到粉絲的openid
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.app.entity.user.Follow;
import com.thinkgem.jeesite.modules.app.service.user.FollowService;
import com.thinkgem.jeesite.modules.app.service.user.MemberService;
import com.thinkgem.jeesite.modules.wechat.receiveVo.FansVo;
/**
* 網頁授權 服務
* @author caowencao
*
*/
@Service
@Transactional(readOnly = true)
public class WXOAuthService {
private static final Logger logger = LoggerFactory.getLogger(WXOAuthService.class);
@Autowired
private WxMpService wxMpService;
@Autowired
private FollowService followService;
@Autowired
private MemberService memberService;
/**
* 網頁授權
* @param request
* @param response
* @throws IOException
*/
public void oauth(HttpServletRequest request, HttpServletResponse response) throws Exception{
String backUrl = request.getRequestURL().toString(); //取得當前 URL
String redirectUri = wxMpService.oauth2buildAuthorizationUrl(backUrl, WxConsts.OAuth2Scope.SNSAPI_USERINFO,"1");
logger.info("redirectUri地址={}", redirectUri);// 日誌
response.sendRedirect(redirectUri);
}
/**
* 獲取使用者資訊
* @param request
* @param response
* @throws IOException
*/
@Transactional(readOnly = false)
public void userInfo(HttpServletRequest request, HttpServletResponse response) throws Exception{
String code = request.getParameter("code");
if(StringUtils.isBlank(code))
oauth(request, response); //繼續授權
// 通過code換取access token
WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
String openId = null;
try {
wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
openId = wxMpOAuth2AccessToken.getOpenId();
logger.info("openId={}", openId);
String lang = "zh_CN";
WxMpUser wxMpUser = this.wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, lang);
// TODO 操作儲存使用者資訊到資料庫
// 儲存通過授權拿到的使用者資訊
followService.saveOauthFollowInfo(wxMpUser);
// Follow follow = followService.findFollowByOpenId(openId);
// if (null == follow && null != wxMpUser) {
// // 儲存通過授權拿到的使用者資訊
// followService.saveOauthFollowInfo(wxMpUser);
// }
logger.info("網頁授權獲取使用者資訊 :" + wxMpUser.toString());
FansVo fans = new FansVo();
// 獲取粉絲賬號
String account = memberService.getAccountByOpenid(openId);
if (!StringUtils.isBlank(account)) {
fans.setAccount(account);
fans.setOpenid(openId);
}
request.getSession().setAttribute("fans", fans); // session中設定粉絲賬號和openid
request.getSession().setAttribute("openid", openId); //設定 Session Openid
}
catch (WxErrorException e) {
logger.error("【微信網頁授權】{}", e.getMessage());
oauth(request, response);
throw new RuntimeException("網頁授權失敗!");
}
}
}
好了,到這裡使用攔截器獲取微信openID、授權獲取使用者資訊就實現了,像這樣封裝複用性比較高;
相關文章
- 前端實現微信公眾號授權—獲取openid前端
- 微信公眾號獲取AccessToekn
- 如何在微信公眾號上傳附件給粉絲下載
- 【Java】微信公眾號開發筆記Java筆記
- 微信公眾號開發之坑(一)
- 微信公眾號開發
- php 獲取微信公眾號access_tokenPHP
- 微信公眾號開發之客服訊息
- Nodejs微信公眾號開發NodeJS
- .net開發微信公眾號
- 微信公眾號開發-分享
- 微信公眾號Java開發記錄(一)接入Java
- TNW-獲取微信公眾號的 access_tokenTNW
- 微信公眾號支付開發全過程(Java 版)Java
- 微信小程式獲取openid,unionid微信小程式
- 微信授權獲取使用者的openid
- 爬取微信公眾號文章工具
- Python+Tornado開發微信公眾號Python
- PHP微信公眾號開發——公共方法PHP
- Laravel+easywechat 開發微信公眾號Laravel
- 微信公眾號測試號開發小結
- Python 使用” 先知” 預測公眾號未來的粉絲量Python
- 微信公眾號自動回覆_JavaJava
- 微信公眾號讚賞功能開通方法 微信公眾號讚賞如何開通
- 微信公眾號開發推送事件排重事件
- 微信公眾號支付開發手記(node)
- 記一次微信公眾號開發
- 微信公眾號開發Django JSSDK授權DjangoJS
- 微信公眾號開發(一)基礎配置
- Spring Boot 開發微信公眾號後臺Spring Boot
- 微信公眾號開發 2 : weixin-JS-sdk 的使用JS
- 微信開發——同步粉絲、群發訊息
- 微信公眾號開發 —— 微信網頁授權小記網頁
- ASP.NET微信公眾號用於給指定OpenId使用者傳送紅包ASP.NET
- 微信公眾號開發5-自定義選單-微信開發phpPHP
- 微信公眾號開發——伺服器配置及token驗證伺服器
- 微信開發系列之一 - 微信公眾號開發的開發環境搭建開發環境
- NodeJS介紹以及開發微信公眾號ExampleNodeJS