【Servlet】对基于Jsp的微信Oauth2认证的改进

上次写出来的《【Servlet】基于Jsp的微信Oauth2认证》(点击打开链接)相当地不好,浪费了许多页面,而且类的安排与布置非常地不明确,如果多个微信公众平台的程序需要调用到Oauth2认证,必须整段整段代码复制拷贝,这次,对其进行了改进,认证过程也封装到一个类里面,可以多次复用。


一、基本准备

首先,我们要到微信的开发者中心,修改“OAuth2.0网页授权”的接口,如下图:

【Servlet】对基于Jsp的微信Oauth2认证的改进

这里的“授权回调页面域名”是应该填写你服务器的总域名,而不是下面的一个个工程名,比如我的服务器IP是192.168.0.1,域名是http://a.b.com,里面的微信工程是wechattest,你就应该填写192.168.0.1或者http://a.b.com,而不是192.168.0.1/wechattest,或者a.b.com/wechattest,这样即使通过了,后面也是无法进行微信Oauth认证的。

之后,才于eclipse写代码,与上次一样,我们要在java中解析json,因为微信送过来的信息都是json,而且我们用到Servlet,自然而然地需要在Eclipse中新建的工程的lib文件夹中放入如下两包:

【Servlet】对基于Jsp的微信Oauth2认证的改进


二、基本思想

对于上次写出来的《【Servlet】基于Jsp的微信Oauth2认证》(点击打开链接)的思想,此次大幅度减少了jsp页面,甚至就把jsp页面的数目减到0,一切都在Servlet的java文件中进行,安全问题也得到了提升,但微信要求如何拿到用户信息,这里就不再赘述了,在上文已经说得比较详细了。

整个工程目录的布置如下:

【Servlet】对基于Jsp的微信Oauth2认证的改进

其实这里最关键还是那个Oauth.java文件,这里Scanhandle.java是由于我拿到的用户信息之后,还要进行其它的操作,所以才命名成这个名字的。


三、制作过程

首先同样与上次一样,在Servlet的web.xml于<web-app>之间的写入你要跳转的链接,比如我要到wx.loginqrcode.Scanhandle这个类而且指明域名是/scanhandle进行Oauth认证,则与web.xml中写入:

<servlet>
	<servlet-name>scanhandle</servlet-name>
	<servlet-class>wx.loginqrcode.Scanhandle</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>scanhandle</servlet-name>
	<url-pattern>/scanhandle</url-pattern>
</servlet-mapping>
【Servlet】对基于Jsp的微信Oauth2认证的改进

如果还不明白可以再参考我之前的《【Servlet】最简单的Servlet JavaWeb程序》(点击打开链接

然后就是两个java文件:

1、Scanhandle.java

请忽略这个文件的命名~>_<!

package com.scholat.wx.loginqrcode;

//首先由于oauth.java在其他的包里面,所以我们要引入这个包
import com.scholat.wx.oauth.*;

//io异常需要
import java.io.*;

//servlet需要
import javax.servlet.*;
import javax.servlet.http.*;

public class Scanhandle extends HttpServlet {
	//没有下面这句eclipse会出警告
	private static final long serialVersionUID = 1L;
	//微信Oauth认证用到了get方法
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		/*
		 * @param code 这是微信提供的东西code
		 * @param jsonstring 用户信息json字符串
		 */
		String code = request.getParameter("code");
		String jsonstring = null;
		//如果没有code,就向微信提供的网址请求
		//state里面还可以带上你需要拿到用户信息之后进一步处理的参数
		if (code == null) {
			/*
			 * @param appid 微信提供给你的appid
			 * @param redirect_uri 你自己的服务器地址/工程名/本页的Servelt名字
			 * @param state 你还需要带上的参数
			 */
			response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=http://192.168.0.1/wechattest/scanhandle&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect");
		} else {
			//在后续需要进一步处理的参数,取出
			String param = request.getParameter("state");
			//向oauth.java拿到了用户信息之后,存到Session
			jsonstring = new Oauth().getUserinfo(code);
			request.getSession().setAttribute("jsonstring", jsonstring);
			//这里可以再写,你需要进一步处理的代码
		}
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

	}
}

2、Oauth.java

这个文件就是《【Servlet】最简单的Servlet JavaWeb程序》(点击打开链接)一文的Loading.java被封装而已,具体的过程可以看上次那篇文章的流程图。由于微信Oauth2认证只是用到get方法,所以整个文件用到了《【Java】读取网页中的内容》(点击打开链接)的思想

package com.scholat.wx.oauth;

import java.io.*;
import java.net.*;

import com.alibaba.fastjson.*;

public class Oauth {
	public String getUserinfo(String code) throws IOException{
		StringBuilder json = new StringBuilder();
		String url = null;
		BufferedReader in = null;
		String inputLine = null;
		String jsonstring = null;
		JSONObject jobject = null;
		// 这里的appid与secret换成你自己的appid与secret
		url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code="
				+ code + "&grant_type=authorization_code";
		in = new BufferedReader(new InputStreamReader(new URL(url)
				.openConnection().getInputStream(), "utf-8"));
		while ((inputLine = in.readLine()) != null) {
			json.append(inputLine);
		}
		in.close();
		
		jsonstring = json.toString();
		jobject = JSON.parseObject(jsonstring);
		json = new StringBuilder();

		url = "https://api.weixin.qq.com/sns/userinfo?access_token="
				+ jobject.getString("access_token") + "&openid="
				+ jobject.getString("openid");
		in = new BufferedReader(new InputStreamReader(new URL(url)
				.openConnection().getInputStream(), "utf-8"));
		inputLine = null;
		while ((inputLine = in.readLine()) != null) {
			json.append(inputLine);
		}
		in.close();
		jsonstring = json.toString();
		return jsonstring;
	}

}

至此,这个微信Oauth2认证就完成了,你可以在Scanhandle.java那里进行进一步操作,而下次又有其他微信公众平台需要调用微信Oauth2认证获取用户的微信信息进行下一步的操作,可以像Scanhandle.java进行一个简单的过程就可以了,因为获取code之后的过程,在Oauth.java这个类里面封装好了。

【Servlet】对基于Jsp的微信Oauth2认证的改进

上一篇:我新买的红米手机,新浪和360浏览器都能进,也能看电视,就是不能上手机QQ和微信


下一篇:微信公开课发布微信官方教程:教你用好微信JS-SDK接口