最近在弄微信支付,网站有好几种不同类型的"商品",去每个支付的页面都需要获取用户的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")