最近在弄微信支付,网站有好几种不同类型的"商品",去每个支付的页面都需要获取用户的OpenId,而且获取openid要在微信的浏览器去发送请求,如果有三个不同类型的付款页面就需要写三个一样获取openid的方法,这为了以后如果网站需要在其他的地方获取openid,为了扩展所以lz想了一个办法 把获取微信openId的方法抽取成了用注解和spring mvc的拦截器来实现。废话不多说下面直接上代码。

1.获取微信openid 网页授权代码

这里就不详细说啦,可以参照点击打开链接微信开发文档,下面也会体现到网页授权

注解代码实现

package com.workit.handler;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
*
* @Title: WeiXinGetOpenId.java
* @Description: 获取openId注解,needGetOpenId 为true时调用获取openid
* @date 2017年5月9日 下午4:12:02
* @version V1.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WeiXinGetOpenId { /**
*
* @Title: needGetOpenId
* @Description: 是否需要获取OpenId。
* @param @return
* @return boolean
*/
boolean needGetOpenId() default false; /**
*
* @Title: needGetUserInfo
* @Description: 是否需要获取用户信息。
* @param @return
* @return boolean
*/
boolean needGetUserInfo() default false; /**
*
* @Title: scopeType
* @Description: 授权方式
* @param @return
* @return String
*/
String scopeType() default "snsapi_base"; }

spring mvc配置文件加入下代码

<mvc:interceptors>
<!-- 获取OpenId注解 -->
<mvc:interceptor>
<!-- <mvc:mapping path="/**"/>这个地方时你要拦截得路径 我这个意思是拦截所有得URL -->
<mvc:mapping path="/**/*"/>
<mvc:exclude-mapping path="/**/fonts/*"/>
<mvc:exclude-mapping path="/**/*.css"/>
<mvc:exclude-mapping path="/**/*.js"/>
<mvc:exclude-mapping path="/**/*.png"/>
<mvc:exclude-mapping path="/**/*.gif"/>
<mvc:exclude-mapping path="/**/*.jpg"/>
<mvc:exclude-mapping path="/**/*.jpeg"/>
<bean class="com.jkinvest.sme.web.handler.WeixinGetOpenIdHandlerInterceptor"/><!--class文件路径改成你自己写得拦截器路径!! -->
</mvc:interceptor>
</mvc:interceptors>

拦截器代码实现类

package com.workit.handler;

import java.net.URLEncoder;
import java.util.Enumeration; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import com.alibaba.fastjson.JSONObject;
import com.workit.comm.util.GlobalConstant;
import com.workit.comm.util.String.StringUtil;
import com.workit.comm.util.weixin.WeiXinConstant;
import com.workit.comm.util.weixin.WeiXinUtil; /**
* @Title: WeixinGetOpenIdHandlerInterceptor.java
* @Description: TODO
* @date 2017年5月9日 上午10:56:45
* @version V1.0
*/
public class WeixinGetOpenIdHandlerInterceptor implements HandlerInterceptor { @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod) handler;
WeiXinGetOpenId annotation = method.getMethodAnnotation(WeiXinGetOpenId.class);
if(WeiXinUtil.checkWeiXinAgent(request)){
if (annotation != null) {
boolean needGetOpenId = annotation.needGetOpenId();
String scopeType= annotation.scopeType();
if (needGetOpenId) {
String url =request.getRequestURI();
String methodType = request.getMethod();
@SuppressWarnings("rawtypes")
Enumeration enu=request.getParameterNames();
JSONObject json = new JSONObject();
json.put("targetUrl",url);
json.put("submitMethodType",methodType);
while(enu.hasMoreElements()){
String paraName=(String)enu.nextElement();
json.put(paraName, request.getParameter(paraName));
}
//说明已经获取过OpenId
if(StringUtil.isNotEmpty(json.get("weiXinGetOpenIdFlag"))){
return true;
}else{
String jsonParams = json.toJSONString();
String returnUrl ="网站名字"+"/WeiXinCommGetOpenId.html?weixin_outh2_params="+jsonParams;
returnUrl=URLEncoder.encode(returnUrl,"UTF-8");
String scope =scopeType;
returnUrl = WeiXinConstant.WEIXIN_AUTH_URL.replace("APPID",GlobalConstant.SERVICE_APPID).replace("REDIRECT_URI", returnUrl).replace("SCOPE", scope);
response.sendRedirect(returnUrl);
return false;
}
}
}
}
}
return true;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub } @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub } }

获取OpenId的类

package com.workit.handler;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import com.workit.comm.util.weixin.WeiXinUtil; /**
* @Title: WeiXinCommGetOpenId.java
* @Description: TODO
* @date 2017年5月9日 下午1:45:30
* @version V1.0
*/
@Controller
public class WeiXinCommGetOpenId {
private static final Logger logger = LoggerFactory.getLogger(WeiXinCommGetOpenId.class); @RequestMapping("/WeiXinCommGetOpenId.html")
public void getWeiXinCommOpenId(HttpServletRequest request,HttpServletResponse response) throws IOException{
Map<String,Object> paramMap = new HashMap<String,Object>();
String postUrl ="";
try {
String code = request.getParameter("code");
String weixin_outh2_params = request.getParameter("weixin_outh2_params");
JSONObject json = new JSONObject(weixin_outh2_params);
String clickOpenId = WeiXinUtil.getUserInfoOpenId(code);
Iterator<?> it = json.keys();
postUrl = json.getString("targetUrl");
if(postUrl.contains("网站名字")){
postUrl = postUrl.replace("网站名字/","");
}
postUrl ="网站名字"+postUrl;
paramMap.put("weiXinOpenId", clickOpenId);
paramMap.put("weiXinGetOpenIdFlag","isTure");
while (it.hasNext()) {
String key = (String) it.next();
String value = json.getString(key);
paramMap.put(key, value);
}
} finally {
// TODO: handle finally clause
doReq(response, postUrl, paramMap);
} }
/**
*
* @param response
* @param postUrl
* @param paramMap
* @throws IOException
*/
public static void doReq(HttpServletResponse response,String postUrl,Map<String, ?> paramMap) throws IOException {
logger.debug("go into doReq method");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String type =(String) paramMap.get("submitMethodType");
out.println("<form name='postSubmit' method='"+type+"' target='_blank' action='"+postUrl+"' >");
for (String key : paramMap.keySet()) {
out.println("<input type='hidden' name='"+key+"' value='" + paramMap.get(key)+ "'>");
}
out.println("</form>");
out.println("<script>");
out.println("document.postSubmit.submit()");
out.println("</script>");
logger.debug("======doReq =====");
}
}

使用只要在获取需要获取OPenID的方法前面加上注解

@WeiXinGetOpenId(needGetOpenId=true)

在方法里通过request.getParams("weiXinOpenId")

基于注解的实现获取微信openId1的更多相关文章

  1. Spring事务的介绍,以及基于注解@Transactional的声明式事务

    前言 事务是一个非常重要的知识点,前面的文章已经有介绍了关于SpringAOP代理的实现过程:事务管理也是AOP的一个重要的功能. 事务的基本介绍 数据库事务特性: 原子性 一致性 隔离性 持久性 事 ...

  2. Spring7:基于注解的Spring MVC(下篇)

    Model 上一篇文章<Spring6:基于注解的Spring MVC(上篇)>,讲了Spring MVC环境搭建.@RequestMapping以及参数绑定,这是Spring MVC中最 ...

  3. 基于注解的Spring AOP入门、增强Advice实例

    这篇文章简单通过一个例子,介绍几种增强的基本配置,以方便spring框架初学者对aop的代码结构有个清楚的了解认识.首先,spring支持aop编程,支持aspectJ的语法格式来表示切入点,切面,增 ...

  4. Mybatis框架基于注解的方式,实对数据现增删改查

    编写Mybatis代码,与spring不一样,不需要导入插件,只需导入架包即可: 在lib下 导入mybatis架包:mybatis-3.1.1.jarmysql驱动架包:mysql-connecto ...

  5. 基于注解的Spring AOP的配置和使用

    摘要: 基于注解的Spring AOP的配置和使用 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不 ...

  6. springAOP实现基于注解的数据源动态切换

    需求 代码实现读写数据库分离 武器 spring3.0以上版本 实现思路 1.继承org.springframework.jdbc.datasource.lookup.AbstractRoutingD ...

  7. springMVC 基于注解的controller

    概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spring 2.5 又为 Spring MVC 引入了注解驱动功能.现在你无须让 Controller 继承任何接口,无需在 ...

  8. hibernate基于注解的维护权反转:@OneToMany(mappedBy=)

    背景说明:首先是SSH环境下,对象基于注解的方式映射到数据库: 昨天遇到一个比较纠结的问题,@OneToMany(mappedBy="xxx"), mappedBy属性有什么用,然 ...

  9. SpringMVC4 + Spring + MyBatis3 基于注解的最简配置

    本文使用最新版本(4.1.5)的springmvc+spring+mybatis,采用最间的配置方式来进行搭建. 1. web.xml 我们知道springmvc是基于Servlet: Dispatc ...

随机推荐

  1. 【DKNN】Distilling the Knowledge in a Neural Network 第一次提出神经网络的知识蒸馏概念

    原文链接 小样本学习与智能前沿 . 在这个公众号后台回复"DKNN",即可获得课件电子资源. 文章已经表明,对于将知识从整体模型或高度正则化的大型模型转换为较小的蒸馏模型,蒸馏非常 ...

  2. Docker实战 | 第二篇:IDEA集成Docker插件实现一键自动打包部署微服务项目,一劳永逸的技术手段值得一试

    一. 前言 大家在自己玩微服务项目的时候,动辄十几个服务,每次修改逐一部署繁琐不说也会浪费越来越多时间,所以本篇整理通过一次性配置实现一键部署微服务,实现真正所谓的一劳永逸. 二. 配置服务器 1. ...

  3. msql语句

    表相关语句: 创表相关 CREATE TABLE `Student`( `s_id` VARCHAR(20), `s_name` VARCHAR(20) NOT NULL DEFAULT '', `s ...

  4. requests请求高德地图api

    高德地图通过GET方式发送url请求数据.url里需要包含开发者key以及一些请求的具体参数.(详情可见高德官网)高德返回的数据默认为JSON格式,方便处理. 顺带来回忆一下requests模块的一些 ...

  5. 2017 Mid Central Regional F.Orderly Class(大水题)

    这两天刷了两道过去的原题,看看思维还是8太行. 这道题问给出两个字符串,要求只翻转一次,问有几种不同的方法使得a串变成b串 我一开始没看到只翻转一次,还以为是个计数 + 字符串dp大难题,心想当年的学 ...

  6. 第11.9节 Python正则表达式的贪婪模式和非贪婪模式

    在使用正则表达式时,匹配算法存在贪婪模式和非贪婪模式两种模式,在<第11.8节 Pytho正则表达式的重复匹配模式及元字符"?". "*". " ...

  7. Python中数字按位取反的方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Python中有个按位取反运算符:,但这个运算符并不是真正的按位取反,而是效果相当于原值乘以负一再减 ...

  8. PyQt学习随笔:使用QPropertyAnimation开发简单动画

    QPropertyAnimation是PyQt5.QtCore模块提供的动画设计类,使用该类可以针对PyQt的界面对象进行动画播放,如果要针对一个指定对象进行动画播放,包括如下步骤: 一.创建动画对象 ...

  9. C++编程指南(6-7)

    六.函数设计 函数是C++/C程序的基本功能单元,其重要性不言而喻.函数设计的细微缺点很容易导致该函数被错用,所以光使函数的功能正确是不够的.本章重点论述函数的接口设计和内部实现的一些规则. 函数接口 ...

  10. python xlrd读取excel常用方法

    最近学习了python操作excel,记录下常用方法. 需要安装xlrd模块, 打开cmd,输入命令:pip install xlrd  进行安装,若已安装显示如下: xlrd读取excel常用方法如 ...