最近研究微信服务号开发,发现jfinal家封装的SDK还是不错的,于是就定下来用它了。
那么问题来了:git上有demo,那么如何集成到自己的项目中呢?研究研究呗。我们框架使用的是springmvc,下面记录一下整合方法,以及遇到的一些问题:
1.自己项目中首先需要引用jfinal微信需要的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.这里主要讲的是
自己写一个拦截器,拦截微信请求
<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(检查方法是否有上方注解 如果有 就进行微信验证)
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"; }