최근 WeChat 서비스 계정 개발에 대해 조사한 결과 jfinal에서 패키지로 제공하는 SDK가 꽤 좋다는 것을 발견하고 이를 사용하기로 결정했습니다.
질문은 이렇습니다. git에 데모가 있는데 이를 자신의 프로젝트에 어떻게 통합합니까? 그냥 공부하고 공부하세요. 우리 프레임워크는 springmvc를 사용합니다. 통합 방법과 발생한 몇 가지 문제를 기록해 보겠습니다.
1. 프로젝트에서 먼저 jfinal WeChat에 필요한 jar 패키지와 jfinal의 SDK 패키지를 참조해야 합니다.
2. web.xml에서 구성하고 jfinal 관련 구성을 시작합니다(모든 인터셉터 위에 배치해야 함)
<filter> <filter-name>jfinal</filter-name> <filter-class>com.jfinal.core.JFinalFilter</filter-class> <init-param> <param-name>configClass</param-name> <param-value>com.jfinal.weixin.demo.WeixinConfig</param-value> </init-param> </filter> <filter-mapping> <filter-name>jfinal</filter-name> <url-pattern>/weixin/*</url-pattern> </filter-mapping>
3. WeixinMsgController 클래스를 상속하고 메시지 수신 기능을 구현하는 메서드를 다시 작성합니다.
4. 여기서 주요 주제는
WeChat 요청을 가로채는 인터셉터를 직접 작성
<bean id="methodInvokerIntercepterManager" class="org.springframework.web.servlet.mvc.annotation.MethodInvokerIntercepterManager"> <property name="intercepters"> <list> <bean class="com.xtwl.reporter.weixin.NeedOpenId"></bean><!-- 处理是否微信认证 --> <bean class="com.xtwl.framework.security.utils.MethodPrivilegeIntercepter"> <property name="loginPage" value="/workspace/login" /> <property name="noauthPage" value="global/error/401.ftl" /> <property name="rejectMessage" value="您无权访问" /> <property name="loginPrompt" value="请先登录" /> </bean> </list> </property> </bean>
주석용 Openid 클래스를 작성하고 사용하세요
package com.xtwl.reporter.weixin; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //检查是否需要登录 @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface Openid { }
NeedOpenId에 로그인했는지 확인하세요(메서드에 위의 주석이 있는지 확인하고, 있으면 WeChat 확인을 수행하세요)
package com.xtwl.reporter.weixin;import java.lang.reflect.Method;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.ui.Model;import org.springframework.web.servlet.mvc.annotation.IMethodIntercepterHolder;import org.springframework.web.servlet.mvc.annotation.IMethodInvokerIntercepter;import com.jfinal.kit.PropKit;import com.jfinal.weixin.sdk.api.ApiConfig;import com.jfinal.weixin.sdk.api.ApiConfigKit;import com.jfinal.weixin.sdk.api.SnsAccessToken;import com.jfinal.weixin.sdk.api.SnsAccessTokenApi;import com.xtwl.reporter.business.StudentService;import com.xtwl.reporter.domain.Student;import com.xtwl.water.business.AdminInfoService;import com.xtwl.water.domain.AdminInfo;@Componentpublic class NeedOpenId implements IMethodInvokerIntercepter { @Autowired private AdminInfoService adminInfoService; @Autowired private StudentService studentService; @Override public Object invokeHandlerMethod(Method handlerMethod, Object handler, HttpServletRequest request, HttpServletResponse response, Model model, IMethodIntercepterHolder chain) throws Exception { if (handlerMethod.isAnnotationPresent(Openid.class)) { ApiConfigKit.setThreadLocalApiConfig(getApiConfig()); Openid access = handlerMethod.getAnnotation(Openid.class); if (access != null) {// 如果有标签 System.out.println("需要检查openid"); //String openid = WeiXinSession.getOpenid(); String openid="oWDxdt8F5UTP8L3XV-KcmZdLmP2Q";//测试用的 System.out.println("session中的openid 为:" + openid); System.out.println(request.getRequestURL()+"=======request.getRequestURL()2"); if (openid != null && openid.length() > 5) {// session中已经有了。放行 return todo(chain, handlerMethod, handler, request, response, model, openid); } if (openid == null || openid.length() < 5) {// 没有openid 需要重新获取 String url = SnsAccessTokenApi.getAuthorizeURL(ApiConfigKit .getApiConfig().getAppId(), request.getRequestURL().toString(), true); String code = (String) request.getParameter("code"); System.out.println("code为:" + code + " 这是微信返回的请求"); if (code != null && code.length() > 1) {// 是请求微信之后返回来的 // 带着openid SnsAccessToken sn = SnsAccessTokenApi .getSnsAccessToken(ApiConfigKit.getApiConfig().getAppId(),ApiConfigKit.getApiConfig().getAppSecret(), code); System.out.println("微信返回的openid:" + sn.getOpenid()); WeiXinSession.setOpenid(sn.getOpenid()); return todo(chain, handlerMethod, handler, request, response, model, sn.getOpenid()); } else { System.out.println("重定向到微信获取openid:" + url); return "redirect:" + url; } } } } return chain.doChain(handlerMethod, handler, request, response, model); } private Object todo(IMethodIntercepterHolder chain, Method handlerMethod, Object handler, HttpServletRequest request, HttpServletResponse response, Model model, String openid) throws Exception { try { System.out.println(request.getRequestURL()+"=======request.getRequestURL()1"); if(request.getRequestURL().toString().indexOf("/mobile/post_bind/")>0){//绑定页面 放行 return chain.doChain(handlerMethod, handler, request, response, model); } // 根据openid获取用户信息 本地的 AdminInfo admin = adminInfoService.getItemByOpenid(openid); System.out.println(admin + "========数据库中的admin"); if (admin == null || admin.getId() == null) {// 未绑定 System.out.println("redirect:/mobile/bind_phone"); return "redirect:/mobile/bind_phone"; } else { Student s = studentService.getItemById(admin.getOtherid()); WeiXinSession.setWeiXinAdminInfo(admin); WeiXinSession.setWeiXinStudent(s); } return chain.doChain(handlerMethod, handler, request, response, model); } catch (Exception e) { e.printStackTrace(); return chain.doChain(handlerMethod, handler, request, response, model); } } public ApiConfig getApiConfig() { ApiConfig ac = new ApiConfig(); // 配置微信 API 相关常量 ac.setToken(PropKit.get("token")); ac.setAppId(PropKit.get("appId")); ac.setAppSecret(PropKit.get("appSecret")); /** * 是否对消息进行加密,对应于微信平台的消息加解密方式: * 1:true进行加密且必须配置 encodingAesKey * 2:false采用明文模式,同时也支持混合模式 */ ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false)); ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file")); return ac; } }
다음 단계는
@RequestMapping("/mobile/myself")@Openidpublic String toIndex(Map<String, Object>model, Principal principal,HttpServletRequest request){ model.put("principal", principal); try { AdminInfo admin = WeiXinSession.getWeiXinAdminInfo();; Student s = WeiXinSession.getWeiXinStudent(); model.put("classes", classes); model.put("admin", admin); model.put("student", s); } catch (Exception e) { e.printStackTrace(); } return "mobile/person.ftl"; }