直接上代码

constant.java为基础常量类

import com.douples.common.util.CommonUtil;
import com.douples.framework.util.PageData;
import java.text.SimpleDateFormat;/*** 常量* * @author lucky* @date 2019-02-12*/
public class Constant {public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMddHHmmsss");public static final String SUCCESS = "10000";//请求处理成功public static final String FAIL = "10001";//请求处理失败//微信部分的常量PageData pd = new PageData();//服务器域名public static final String DOMAIN = "http://88hyze.natappfree.cc";//public static final String DOMAIN = CommonUtil.getConfig("common","WEIXIN_DOMAIN");//微信配置的常量//微信的消息类型public static final String TEXT_MESSAGE = "text";public static final String NEWS_MESSAGE = "news";//用户回复的特定消息public static final String WX_KEY_WORD = CommonUtil.getConfig("common","WEIXIN_WX_KEY_WORD");//public static final String WX_KEY_WORD = "ceshi";public static final String TOKEN="weChat";public static final String APP_ID = "111122222333333";public static final String APP_SECRET = "6666uy7jkop778889";//获取公众号的全局唯一接口调用凭据的接口public static final String GLOBAL_ACCESS_TOKEN="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";//创建自定义菜单的接口public static final String MENU = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";//微信授权模块//1.微信网页授权接口public static final String AUTH = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";//2.通过code换取网页授权access_tokenpublic static final String GET_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";//3,刷新access_token(跟全局的不一样),如果有需要的话public static final String REFRESH_TOKEN = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";//4.拉取用户信息(需scope为 snsapi_userinfo)public static final String GET_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";//微信jdk jsApi的tokenpublic static final String JS_API_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";//微信消息模块//数据库存储的模板idpublic static final String Template_Id = CommonUtil.getConfig("common","WEIXIN_Template_Id");//public static final String Template_Id ="--hiFOOuQC207RPmYYUEmk592GM4_ihtaEM1-Vj1Lj8";//获取模板消息--get方式,测试号获取不到public static final String GET_TEMPLATE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=ACCESS_TOKEN";//发送模板消息---post方式发送有public static final String SEND_TEMPLATE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";//微信登录模块public static final String WX_LOGIN_SESSION = "wxSessionUser";}

WXEntry.java接口调用类

import com.alibaba.fastjson.JSONObject;
import com.douples.common.annotation.IgnoreAuth;
import com.douples.common.constant.Constant;
import com.douples.common.util.weChat.OAuthUtil;
import com.douples.common.util.weChat.ResponseProcessUtil;
import com.douples.common.util.weChat.SignUtil;
import com.douples.framework.core.impl.BaseController;
import com.douples.framework.util.PageData;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;@Controller
@RequestMapping(value = "weChat/wxEntry")
public class WXEntry extends BaseController {/*** 接收微信端消息的入口* @param request* @param response*/@RequestMapping(value = "/main", method = { RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic void getToken(HttpServletRequest request,HttpServletResponse response) throws Exception {boolean isGet = request.getMethod().toLowerCase().equals("get");boolean isPost = request.getMethod().toLowerCase().equals("post");PrintWriter print;if (isGet) {//接收get方法信息// 微信加密签名String signature = request.getParameter("signature");// 时间戳String timestamp = request.getParameter("timestamp");// 随机数String nonce = request.getParameter("nonce");// 随机字符串String echostr = request.getParameter("echostr");// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败if (signature != null&& SignUtil.checkSignature(signature, timestamp, nonce)) {try {print = response.getWriter();print.write(echostr);print.close();} catch (IOException e) {e.printStackTrace();}}isGet = false;}if(isPost) {//接收post信息//将请求、相应类型都设置为utf-8防止出现乱码request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");PageData imgMsg =null;//PageData imgMsg = wxFacade.findImgMsg();System.out.println("res测试1----------------");String res = ResponseProcessUtil.processRequest(request,imgMsg);System.out.println("res测试1----------------"+res);PrintWriter writer = response.getWriter();writer.print(res);writer.close();writer = null;isPost = false;}}/*** 网页授权入口,以snsapi_userinfo为scope发起的网页授权,能够获取能获取的所有信息* @param request* @param response* @throws IOException */@IgnoreAuth@RequestMapping(value = "/webAuthorize", method = { RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic void webAuthorize(HttpServletRequest request,HttpServletResponse response) throws IOException {PageData pageData = getPageData();String redicUrl =Constant.DOMAIN+"/weChat/wxEntry/webJumpPage?requestURI="+pageData.get("requestURI").toString();String appId = Constant.APP_ID;String scope = "snsapi_userinfo";String state = "1";//非必需//redicUURLEredicUrl = URLEncoder.encode(redicUrl,"UTF-8");System.out.println("这个是auth---1"+Constant.AUTH);String url = Constant.AUTH.replace("APPID", appId).replace("REDIRECT_URI", redicUrl).replace("SCOPE", scope).replace("STATE", state);response.sendRedirect(url);}/***  通过获取到code来查询登录的用户信息*/@IgnoreAuth@RequestMapping(value = "/webJumpPage", method = { RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic void webAuthorizes(HttpServletRequest request,HttpServletResponse response,String code) throws IOException {PageData pageData = getPageData();JSONObject authAccessToken = OAuthUtil.getAuthAccessToken(code);String openid = (String) authAccessToken.get("openid");String unionid = (String) authAccessToken.get("unionid");Subject currentUser = SecurityUtils.getSubject();Session session = currentUser.getSession();session.setAttribute("openId", openid);//session.setAttribute("unionId", unionid);session.setAttribute("unionId", "123456");response.getWriter().print("<script>top.location='"+Constant.DOMAIN+pageData.get("requestURI").toString()+ "';</script>");}}

ResponseProcessUtil.java 类

import com.douples.framework.util.PageData;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ResponseProcessUtil {//获取返回的微信消息public static String processRequest(HttpServletRequest request, PageData pd){//返回的消息String respMessage = null;try {//将xml解析成mapMap map = ResponseProcessUtil.parseXml(request);// 发送方帐号(open_id)String fromUserName = map.get("FromUserName").toString();// 公众帐号String toUserName = map.get("ToUserName").toString();// 消息类型String msgType = map.get("MsgType").toString();//消息内容String content = map.get("Content").toString();System.out.println("content值---------"+content);if(content!=null){//特定回复}} catch (Exception e) {e.printStackTrace();}return respMessage;}/*** 拓展xstream 将每个节点都加上cdata块*/private static XStream xStream = new XStream(new XppDriver(){@Overridepublic HierarchicalStreamWriter createWriter(Writer out) {return new PrettyPrintWriter(out){// 对所有xml节点的转换都增加CDATA标记boolean cdata = true;public void startNode(String name, Class clazz){super.startNode(name,clazz);}public void writeText(QuickWriter writer, String text){if (cdata){writer.write("<![CDATA[");writer.write(text);writer.write("]]>");}}};}});//解析微信发送过来的xml信息public static Map parseXml(HttpServletRequest request) throws Exception{Map res = new HashMap();InputStream inputStream = request.getInputStream();SAXReader reader = new SAXReader();Document document = reader.read(inputStream);Element root = document.getRootElement();List<Element> elements = root.elements();for (Element e:elements) {res.put(e.getName(),e.getText());}inputStream.close();inputStream = null;return res;}
}

SignUtil.java类

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import com.douples.common.constant.Constant;public class SignUtil {//与接口配置的token保持一致private static String token = Constant.TOKEN;/*** 验证签名* @param signature* @param timestamp* @param nonce* */public static boolean checkSignature(String signature, String timestamp, String nonce) {String[] arr = new String[] { token, timestamp, nonce };// 将token、timestamp、nonce三个参数进行字典序排序Arrays.sort(arr);StringBuilder content = new StringBuilder();for (int i = 0; i < arr.length; i++) {content.append(arr[i]);}MessageDigest md = null;String tmpStr = null;try {md = MessageDigest.getInstance("SHA-1");// 将三个参数字符串拼接成一个字符串进行sha1加密byte[] digest = md.digest(content.toString().getBytes());tmpStr = byteToStr(digest);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}content = null;// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;}/*** 将字节数组转换为十六进制字符串* @param byteArray* @return*/private static String byteToStr(byte[] byteArray) {String strDigest = "";for (int i = 0; i < byteArray.length; i++) {strDigest += byteToHexStr(byteArray[i]);}return strDigest;}/*** 将字节转换为十六进制字符串* @param mByte* @return*/private static String byteToHexStr(byte mByte) {char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };char[] tempArr = new char[2];tempArr[0] = Digit[(mByte >>> 4) & 0X0F];tempArr[1] = Digit[mByte & 0X0F];String s = new String(tempArr);return s;}
}

OAuthUtil为基础实现类

import java.net.ConnectException;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSONObject;
import com.douples.common.constant.Constant;/*** 授权登陆* @author lucky**/
public class OAuthUtil {private static Logger logger = Logger.getLogger(OAuthUtil.class);/*** 获取网页授权的accessToken* @param code* @return* @throws ConnectException*/public static JSONObject getAuthAccessToken(String code) throws ConnectException {//获取token的urlSystem.out.println("这个是GET_TOKEN---1"+Constant.GET_TOKEN);String url = Constant.GET_TOKEN.replace("APPID", Constant.APP_ID).replace("SECRET", Constant.APP_SECRET).replace("CODE", code);JSONObject res = HttpUtil.httpsConnect(url, "GET", null);return res;}/*** 获取微信用户信息详情* @param* @return* @throws ConnectException*/public static JSONObject getWxUserInfo(String token, String openid) throws ConnectException {//获取信息的urlSystem.out.println("这个是GET_USER_INFO---1"+Constant.GET_USER_INFO);String userInfoUrl = Constant.GET_USER_INFO.replace("ACCESS_TOKEN", token).replace("OPENID", openid);JSONObject info = HttpUtil.httpsConnect(userInfoUrl, "GET", null);return info;}}

WeChatLoginAuthInterceptor.java为微信接口拦截器类,所有路径访问都需要经过此拦截器进行拦截

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;public class WeChatLoginAuthInterceptor extends HandlerInterceptorAdapter{public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{HttpSession sesssion = request.getSession();String requestURI = request.getRequestURI();if(sesssion.getAttribute("unionId") == null){response.getWriter().print("<script>top.location='/weChat/wxEntry/webAuthorize?requestURI="+requestURI+ "';</script>");return false;}return true;}}

在 applicationContext-mvc.xml配置拦截器

     <mvc:interceptor><mvc:mapping path="/weChat/**/**"/><mvc:exclude-mapping path="/weChat/wxEntry/**"/><bean class="com.douples.framework.interceptor.WeChatLoginAuthInterceptor"></bean></mvc:interceptor>

【微信开发】WeChat公众号开发接口及完整过程相关推荐

  1. 微信小程序公众号开发

    微信小程序&公众号开发 一.什么是微信开发 二.微信开放平台 三.微信公众平台 四.小程序与公众号的区别 1. 用途不同 2. 运营方式不同 3. 操作方法不同 4. 用户体验不同(公众号操作 ...

  2. 微信商城开发:公众号平台接口配置及调试

    <微信商城开发系列教程第二讲> 公众号平台接口配置及调试 [本系列文章转载自:walkingmanc(作者:陈伟)] 在上一篇中,我们讲解了如何申请微信公众号,公众平台开发的基本原理以及服 ...

  3. python开发微信订阅号如何申请_基于Python的微信公众平台二次开发(Python常用框架、订阅号开发、公众号开发)...

    1.1.课程的背景 微信公众平台的火热程度已经不用多言,无论是个人还是企业,政府还是商家,都已经开始搭建微信公众平台,微信的作用已经被各界人士认可.微信公众平台的技术需求市场缺口巨大.同时python ...

  4. webpack代理 host文件 微信小程序公众号开发必配

    需求:在开发公众号的时候必然会遇到很多页面跳转,例如用户点击分享跳进来的问题,进入不同详情页的问题,域名回调的作问题, 如果想本地调试的话,需要以下配置. 本地host文件配置: 作用:当在浏览器输入 ...

  5. 微信H5、公众号开发,域名重定向

    一. 在公众号中绑定域名 二.本地host映射域名 文件地址:C:\Windows\System32\drivers\etc(vscode打开,地址.域名不可加端口号) 127.0.0.1 <域 ...

  6. “errcode“:40164,“errmsg“:“invalid ip ...微信公众号开发调用失败的解决办法

    问题概述 关于这个问题,博主是在进行微信公众号平台开发的过程中遇到的, 微信公众号平台的前后端代码开发完成后,在联调接口调用: " https://api.weixin.qq.com/cgi ...

  7. 公众号php支付接口开发,公众号支付接口的开发

    这次给大家带来公众号支付接口的开发,公众号支付接口开发的注意事项有哪些,下面就是实战案例,一起来看一下. 公众号支付就是在微信里面的H5页面唤起微信支付,不用扫码即可付款的功能.做这个功能首先要明确的 ...

  8. 开发好还是实施好_公众号开发 选择模板好还是选择定制发好

    微信公众号是很多企业和商家在微信上进行营销推广时会使用到的工具之一.但由于微信公众号的基础功能比较简单,往往无法满足企业运营的需求,因此很多企业表示要增加一些功能,也就是对公众号进行二次开发. 公众号 ...

  9. 微信公众号开发(—)接口与服务器关联

    微信公众号开发(-) 以下都是借鉴的微信公众平台的文档加老师指点和自行的理解. 1.一台有微信的手机.(别问我老人机可以不 有微信就可以!!!) 2.需要有一个微信公众平台的测试号(订阅号,服务号也可 ...

最新文章

  1. 【C语言学习】《C Primer Plus》第5章 运算符、表达式和语句
  2. nuxt 头部引入js文件 第一次进入页面不加载js文件的解决方法
  3. c打开指定路径文件_C++ 读取指定路径下所有的文件 (C++ get the list of files in a directory)...
  4. Spring配置形式之基于注解的方式
  5. js 中的[] {}是什么意思
  6. 图像处理直方图匹配-巴氏系数原理及实现
  7. 重新认识块级元素--DIV
  8. Behave用户自定义数据类型
  9. android java 调用js_Android Java/JS互相调用
  10. 3.第九章 树--9.3 二叉树结点类表示
  11. linux中文件带方块,JFreeChart图片里的中文在linux下显示为方块的解决办法
  12. PostgreSQ 存储过程 和 存储函数的区别
  13. 5个免费音效素材网站
  14. 常见的树以及树的应用场景
  15. 加速计算,加速智慧未来
  16. 查看mysql数据库所占内存,以及每个表所占内存
  17. Haar特征和级联分类器目标检测介绍及应用
  18. DQN、DDQN、Dueling DQN、PER DQN
  19. 磁编码器MT6835_SPI读取位置信息
  20. 视频教程-2019年人工智能热门案例精讲之P图美化照片-深度学习

热门文章

  1. 欧盟加密资产市场监管法案(Markets in Crypto Assets Regulation Bill,MiCAR法案)内容概览
  2. XMPP协议和asmack
  3. Linux基础之命令【ls】
  4. 374. 猜数字大小
  5. 主题:基于改进粒子群算法的含源配电网静态重构 利用IEEE-33节点系统进行仿真计算
  6. 解决Cfree [Error] g++.exe: 5\mingw\lib\: No such file or directory
  7. java 金额转换 元转分 分转元
  8. 传奇GeeM2引擎配置生成登陆器配置详细图文教程
  9. 高精度电子罗盘精确导航中的应用
  10. Sublime Text 超美丽主题配色