最近在弄微信支付,网站有好几种不同类型的"商品",去每个支付的页面都需要获取用户的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. 腾讯云 CHDFS — 云端大数据存算分离的基石

    随着网络性能提升,云端计算架构逐步向存算分离转变,AWS Aurora 率先在数据库领域实现了这个转变,大数据计算领域也迅速朝此方向演化. 存算分离在云端有明显优势,不但可以充分发挥弹性计算的灵活,同 ...

  2. Event Loop - 事件队列

    Event Loop 定义: event - 事件 loop - 循环,既然叫事件循环,那么循环的点在哪? 循环的是一个又一个的任务队列,这些任务队列由宏任务和微任务构成 两条原则 一次处理一个任务 ...

  3. 微软最强 Python 自动化工具开源了!不用写一行代码!

    1. 前言 最近,微软开源了一款非常强大的 Python 自动化依赖库:playwright-python 它支持主流的浏览器,包含:Chrome.Firefox.Safari.Microsoft E ...

  4. kafka 消费组功能验证以及消费者数据重复数据丢失问题说明 3

    原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 背景 上一篇文章记录了kafka的副本机制和容错功能的说明,本篇则主要在上一篇文章的基础上 ...

  5. 你说说对Java中SPI的理解吧

    前言 最近在面试的时候被问到SPI了,没回答上来,主要也是自己的原因,把自己给带沟里去了,因为讲到了类加载器的双亲委派模型,后面就被问到了有哪些是破坏了双亲委派模型的场景,然后我就说到了SPI,JND ...

  6. PyQt(Python+Qt)学习随笔:复选框状态枚举类Qt.CheckState取值及含义

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 老猿Python,跟老猿学Python! 老猿Python博文目录 专栏:使用PyQt开发图形界面P ...

  7. secret_key伪造session来进行越权

    从swpuctf里面的一道ctf题目来讲解secret_key伪造session来进行越权. 以前没有遇到过这种题目,这次遇到了之后查了一些资料把它做了出来,记录一下知识点. 参考资料 http:// ...

  8. Web前端-按钮点击效果(水波纹)

    这种效果可以由元素内嵌套canves实现,也可以由css3实现. Canves实现 网上摘了一份canves实现的代码,略微去掉了些重复定义的样式并且给出js注释,代码如下 第一种方法: html骨架 ...

  9. Symbol类型是不可枚举的

    const info = { [Symbol('a')]: 'b' } console.log(info)//{Symbol('a'): 'b'} console.log(Object.keys(in ...

  10. NOI2020网上同步赛 游记

    Day1 预计得分:\(32pts\)(我裂开了--) T1 美食家 表示考试的时候想到了关于矩阵快速幂的想法,甚至连分段后怎么处理都想好了,但是没有想到拆点,还有不知道怎么处理重边(这个考虑是多余的 ...