1.maven引入相關jar包
<dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.0.0</version> </dependency>
2.前端代碼
<%--
tips:
1.請注意”keycode=“后的都要進行UrlEncode轉碼(此處還未轉碼),不然后台request.getParamter(”key“)方法獲取的數據會丟失。
2.由於我只要獲取用戶openid,故scope=snsapi_base,若想獲取更多用戶信息,可將scope賦值為snsapi_userinfo。
--%>
<div > <img alt="二維碼" src="${pageContext.request.contextPath}/qrCode?keycode=
https://open.weixin.qq.com/connect/oauth2/authorize?
appid=公眾號的appid&redirect_uri=你要跳轉的方法
&response_type=code&scope=snsapi_base&state=1&connect_redirect=1#wechat_redirect"></img> </div>
3.web.xml配置
<!--我想實現一進入頁面就生成好了二維碼,此處映射到相關后台方法-->
<servlet> <servlet-name>qrCode</servlet-name> <servlet-class>com.daidao.controller.BarCode2DServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>qrCode</servlet-name> <url-pattern>/qrCode</url-pattern> </servlet-mapping>
4.后台代碼
BarCode2DServlet.java
import com.google.zxing.BarcodeFormat; import com.google.zxing.WriterException; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class BarCode2DServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final String KEY = "keycode"; private static final String SIZE = "msize"; private static final String IMAGETYPE = "JPEG"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String keycode = req.getParameter(KEY); if (keycode != null && !"".equals(keycode)) { ServletOutputStream stream = null; try { int size=129; String msize = req.getParameter(SIZE); if (msize != null && !"".equals(msize.trim())) { try{ size=Integer.valueOf(msize); } catch (NumberFormatException e) { //TODO output to log } } stream = resp.getOutputStream(); QRCodeWriter writer = new QRCodeWriter(); BitMatrix m = writer.encode(keycode, BarcodeFormat.QR_CODE, size, size); MatrixToImageWriter.writeToStream(m, IMAGETYPE, stream); } catch (WriterException e) { e.printStackTrace(); } finally { if (stream != null) { stream.flush(); stream.close(); } } } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
掃碼跳轉方法如下
@RequestMapping(params = "doBind") @ResponseBody public String doScan(HttpServletRequest request) { message = "掃碼成功"; String openid = ""; //1 .獲取參數code String code = request.getParameter("code"); //2. 根據code獲取向微信官方api發請求,獲取當前微信用戶的json數據 String url = "https://api.weixin.qq.com/sns/oauth2/access_token?
appid=公眾號的appid&secret=公眾號的appsecret&code="+ code + "&grant_type=authorization_code"; net.sf.json.JSONObject wxUser= WeixinUtil.httpRequest(url, "POST",""); //3. 獲取json數據中的openid openid = wxUser.getString("openid");return null; }
相關java代碼
WeixinUtil.java
import net.sf.json.JSONObject; import org.apache.commons.httpclient.util.DateUtil; import org.daidao.core.util.oConvertUtils; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.URL; import java.util.Date; public class WeixinUtil { // 獲取access_token的接口地址(GET) 限200(次/天) public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; // 菜單創建(POST) 限100(次/天) public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; //客服接口地址 public static String send_message_url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN"; //創建二維碼ticket請求 public static String qrcode_ticket_url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; //通過ticket換取二維碼 public static String get_qrcode_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET"; //微信網頁授權獲取CODE public static String web_oauth_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect"; //微信網頁授權獲取網頁accesstoken和OPENID public static String web_oauth_accesstoken_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; //微信網頁授權獲取用戶信息 public static String web_oauth_userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID"; //--驗證token是否有效------------------------------------------------------------------------ //獲取微信服務器IP地址 public static String get_callbackip_url = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN"; //--驗證token是否有效------------------------------------------------------------------------ // jsapi調用接口臨時憑證的接口地址(GET) 限200(次/天) public final static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; /** * 發起https請求並獲取結果 * * @param requestUrl 請求地址 * @param requestMethod 請求方式(GET、POST) * @param outputStr 提交的數據 * @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值) */ public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 創建SSLContext對象,並使用我們指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 從上述SSLContext對象中得到SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 設置請求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 當有數據需要提交時 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意編碼格式,防止中文亂碼 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 將返回的輸入流轉換成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 釋放資源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.fromObject(buffer.toString()); //jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { } catch (Exception e) { } return jsonObject; } /** * 發起https請求並獲取結果 * * @param requestUrl 請求地址 * @param requestMethod 請求方式(GET、POST) * @param outputStr 提交的數據 * @return JSONObject(通過JSONObject.get(key)的方式獲取json對象的屬性值) */ public static String httpCommonRequest(String requestUrl, String requestMethod, String outputStr) { StringBuffer buffer = new StringBuffer(); try { // 創建SSLContext對象,並使用我們指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 從上述SSLContext對象中得到SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection(); //HttpURLConnection設置網絡超時 httpUrlConn.setConnectTimeout(4500); httpUrlConn.setReadTimeout(4500); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 設置請求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 當有數據需要提交時 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意編碼格式,防止中文亂碼 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 將返回的輸入流轉換成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { if(oConvertUtils.isNotEmpty(str) && oConvertUtils.isNotEmpty(str.trim()) && !" ".equals(str)){ str = str.trim() + "\n"; buffer.append(str); } } bufferedReader.close(); inputStreamReader.close(); // 釋放資源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); ; //jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { } catch (Exception e) { } return buffer.toString().trim(); } /** * 保存HTTP獲取的圖片文件 * @param requestUrl http地址 * @param requestMethod * @param outputStr * @param target 存儲路徑 */ public static void saveHttpImage(String requestUrl, String requestMethod, String outputStr,File target) { //new一個URL對象 try { URL url = new URL(requestUrl); //打開鏈接 HttpURLConnection conn = (HttpURLConnection)url.openConnection(); //設置請求方式為"GET" conn.setRequestMethod(requestMethod); //超時響應時間為5秒 conn.setConnectTimeout(5 * 1000); //通過輸入流獲取圖片數據 InputStream inStream = conn.getInputStream(); //得到圖片的二進制數據,以二進制封裝得到數據,具有通用性 byte[] data = readInputStream(inStream); //創建輸出流 FileOutputStream outStream = new FileOutputStream(target); //寫入數據 outStream.write(data); //關閉輸出流 outStream.close(); } catch (Exception e) { // TODO: handle exception } } /** * 編碼 * @param bstr * @return String */ public static String encode(byte[] bstr){ return new sun.misc.BASE64Encoder().encode(bstr); } /** * 解碼 * @param str * @return string */ public static byte[] decode(String str){ byte[] bt = null; try { sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder(); bt = decoder.decodeBuffer( str ); } catch (IOException e) { e.printStackTrace(); } return bt; } /** * 上傳多媒體文件 * @param fileType * @param filePath * @param token * @return */ public static JSONObject sendMedia(String fileType,String filePath,String token) { String result = null; JSONObject jsonobject = new JSONObject(); jsonobject = null; File file = new File(filePath); if(!file.exists()||!file.isFile()){ jsonobject = null; }else{ try{ String requestUrl="http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token="+ token + "&type="+fileType; URL urlObj = new URL(requestUrl); HttpURLConnection con = (HttpURLConnection) urlObj.openConnection(); con.setRequestMethod("POST"); // 以Post方式提交表單,默認get方式 con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // post方式不能使用緩存 con.setRequestProperty("Connection", "Keep-Alive");// 設置請求頭信息 con.setRequestProperty("Charset", "UTF-8"); String BOUNDARY = "----------" + System.currentTimeMillis();// 設置邊界 con.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ BOUNDARY); // 請求正文信息 // 第一部分: StringBuilder sb = new StringBuilder(); sb.append("--"); // 必須多兩道線 sb.append(BOUNDARY); sb.append("\r\n"); sb.append("Content-Disposition: form-data;name=\"file\";filename=\""+ file.getName() + "\"\r\n"); sb.append("Content-Type:application/octet-stream\r\n\r\n"); byte[] head = sb.toString().getBytes("utf-8"); // 獲得輸出流 OutputStream out = new DataOutputStream(con.getOutputStream()); // 輸出表頭 out.write(head); // 文件正文部分 // 把文件已流文件的方式 推入到url中 DataInputStream in = new DataInputStream(new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while ((bytes = in.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } in.close(); // 結尾部分 byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定義最后數據分隔線 out.write(foot); out.flush(); out.close(); StringBuffer buffer = new StringBuffer(); BufferedReader reader = null; try { // 定義BufferedReader輸入流來讀取URL的響應 reader = new BufferedReader(new InputStreamReader(con.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { buffer.append(line); } if(result==null){ result = buffer.toString(); } } catch (IOException e) { e.printStackTrace(); throw new IOException("數據讀取異常"); } finally { if(reader!=null){ reader.close(); } } jsonobject = JSONObject.fromObject(result); }catch(Exception e){ e.printStackTrace(); } } return jsonobject; } /** * 上傳多媒體文件(永久) * @param fileType * @param filePath * @param token * @return */ public static JSONObject sendPermanentMedia(String fileType, String filePath, String token) { String result = null; JSONObject jsonobject = new JSONObject(); jsonobject = null; File file = new File(filePath); if(!file.exists()||!file.isFile()){ jsonobject = null; }else{ try{ String requestUrl="https://api.weixin.qq.com/cgi-bin/material/add_material?access_token="+ token+"&type="+fileType; URL urlObj = new URL(requestUrl); HttpURLConnection con = (HttpURLConnection) urlObj.openConnection(); con.setRequestMethod("POST"); // 以Post方式提交表單,默認get方式 con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // post方式不能使用緩存 con.setRequestProperty("Connection", "Keep-Alive");// 設置請求頭信息 con.setRequestProperty("Charset", "UTF-8"); String BOUNDARY = "----------" + System.currentTimeMillis();// 設置邊界 con.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ BOUNDARY); // 請求正文信息 // 第一部分: StringBuilder sb = new StringBuilder(); sb.append("--"); // 必須多兩道線 sb.append(BOUNDARY); sb.append("\r\n"); sb.append("Content-Disposition: form-data;name=\"media\";filename=\""+ file.getName() + "\"\r\n"); sb.append("Content-Type:application/octet-stream\r\n\r\n"); byte[] head = sb.toString().getBytes("utf-8"); // 獲得輸出流 OutputStream out = new DataOutputStream(con.getOutputStream()); // 輸出表頭 out.write(head); // 文件正文部分 // 把文件已流文件的方式 推入到url中 DataInputStream in = new DataInputStream(new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while ((bytes = in.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } in.close(); // 結尾部分 byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定義最后數據分隔線 out.write(foot); out.flush(); out.close(); StringBuffer buffer = new StringBuffer(); BufferedReader reader = null; try { // 定義BufferedReader輸入流來讀取URL的響應 reader = new BufferedReader(new InputStreamReader(con.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { buffer.append(line); } if(result==null){ result = buffer.toString(); } } catch (IOException e) { e.printStackTrace(); throw new IOException("數據讀取異常"); } finally { if(reader!=null){ reader.close(); } } jsonobject = JSONObject.fromObject(result); jsonobject.put("created_at", DateUtil.formatDate(new Date())); }catch(Exception e){ e.printStackTrace(); } } return jsonobject; } private static byte[] readInputStream(InputStream inStream) throws Exception { ByteArrayOutputStream outstream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; // 用數據裝 int len = -1; while ((len = inStream.read(buffer)) != -1) { outstream.write(buffer, 0, len); } outstream.close(); inStream.close(); // 關閉流一定要記得。 return outstream.toByteArray(); } /** * 獲取Request請求的路徑信息 帶參數 * @param request * @return */ public static String getRequestUrlWithParams(HttpServletRequest request){ String backurl = request.getScheme()+"://"+request.getServerName()+request.getRequestURI()+"?"+request.getQueryString(); return backurl; } }
oConvertUtils.java
public class oConvertUtils { public static boolean isEmpty(Object object) { if (object == null) { return (true); } if (object.equals("")) { return (true); } if (object.equals("null")) { return (true); } return (false); } public static boolean isNotEmpty(Object object) { if (object != null && !object.equals("") && !object.equals("null")) { return (true); } return (false); } public static String decode(String strIn, String sourceCode, String targetCode) { String temp = code2code(strIn, sourceCode, targetCode); return temp; } public static String StrToUTF(String strIn, String sourceCode, String targetCode) { strIn = ""; try { strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return strIn; } }
參考鏈接:https://my.oschina.net/jawava/blog/345887