微信扫码登录小dome
pom.xml jar包
4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.1.RELEASE com.example weixindemo 0.0.1-SNAPSHOT weixindemo Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-tomcat provided org.springframework.boot spring-boot-starter-test test org.apache.httpcomponents httpclient 4.5.6 com.alibaba fastjson 1.2.40 org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok

Constanst文件
package com.cskt.wxlogin.constanst;public class Constanst {/*** 自定义加密措施*/public static final String PWD_MD5 = "Cao#@Feng";
}
WeiXinController文件
package com.cskt.wxlogin.controller;import com.cskt.wxlogin.constanst.Constanst;
import com.cskt.wxlogin.entity.AccessToken;
import com.cskt.wxlogin.entity.WechatUserUnionID;
import com.cskt.wxlogin.service.impl.WeixinLoginServiceImpl;
import com.cskt.wxlogin.util.AesUtil;
import com.cskt.wxlogin.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;@Controller
public class WeiXinController {@Autowiredprivate WeixinLoginServiceImpl weixinLoginService;@RequestMapping("/weixinLogin")public String getWeixinUrl(){String url= weixinLoginService.getLoginUrl();//httpreturn "redirect:"+url;}/*** 回调地址处理* @param code* @param state* @return*/@GetMapping(value = "/weixinconnect")public ModelAndView callback(String code, String state) {String access_token=null;String openid=null;ModelAndView mav=new ModelAndView();if (code != null && state != null) {// 验证state为了用于防止跨站请求伪造攻击String decrypt = AesUtil.decrypt(AesUtil.parseHexStr2Byte(state), AesUtil.PASSWORD_SECRET_KEY, 16);if (!decrypt.equals(Constanst.PWD_MD5 + DateUtil.getYYYYMMdd())) {mav.addObject("error","登录失败,请联系管理员!");mav.setViewName("loginError");return mav;}AccessToken access = weixinLoginService.getAccessToken(code);if (access != null) {// 把获取到的access_token和openId赋值给变量access_token=access.getAccess_token();openid=access.getOpenid();// 存在则把当前账号信息授权给扫码用户WechatUserUnionID userUnionID = weixinLoginService.getUserUnionID(access_token,openid);mav.addObject("userInfo",userUnionID);mav.setViewName("main");return mav;}}return null;}}
AccessToken文件
package com.cskt.wxlogin.entity;/*** 通过code获取access_token*/
public class AccessToken {/*** 接口调用凭证*/private String access_token;/*** access_token接口调用凭证超时时间,单位(秒)*/private Integer expires_in;/*** 用户刷新access_token*/private String refresh_token;/*** 授权用户唯一标识*/private String openid;/*** 用户授权的作用域,使用逗号(,)分隔*/private String scope;/*** 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。*/private String unionid;public String getAccess_token() {return access_token;}public void setAccess_token(String access_token) {this.access_token = access_token;}public Integer getExpires_in() {return expires_in;}public void setExpires_in(Integer expires_in) {this.expires_in = expires_in;}public String getRefresh_token() {return refresh_token;}public void setRefresh_token(String refresh_token) {this.refresh_token = refresh_token;}public String getOpenid() {return openid;}public void setOpenid(String openid) {this.openid = openid;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}public String getUnionid() {return unionid;}public void setUnionid(String unionid) {this.unionid = unionid;}}
HttpParame文件
package com.cskt.wxlogin.entity;/*** HttpParame Description: 请求参数*/
public class HttpParame {// 应用唯一标识public static final String APPID = "appid";// 密匙public static final String SECRET = "secret";// 微信用户唯一标识public static final String OPENID = "openid";// 接口调用凭证public static final String ACCESS_TOKEN = "access_token";// 回调地址public static final String REDIRECT_URI = "redirect_uri";// 网页授权回调地址public static final String AUTHORIZATION_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";// 通过code获取access_tokenpublic static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";// 此接口用于获取用户个人信息 UnionID机制public static final String GET_UNIONID_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";}
Result文件
package com.cskt.wxlogin.entity;/*** 返回结果包装对象使用*/
public class Result {/*** 状态*/private Object status;/*** 结果*/private Object result;/*** 消息*/private String message;public Result() {}public Result(Object status, String message) {this.status = status;this.message = message;}public Result(Object status, Object result) {this.status = status;this.result = result;}public Result(Object status, Object result, String message) {this.status = status;this.result = result;this.message = message;}public Object getStatus() {return status;}public void setStatus(Object status) {this.status = status;}public Object getResult() {return result;}public void setResult(Object result) {this.result = result;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}
WechatUserUnionID文件
package com.cskt.wxlogin.entity;import java.util.List;/*** 获取用户个人信息(UnionID机制)*/
public class WechatUserUnionID {/*** 普通用户的标识,对当前开发者帐号唯一*/private String openid;/*** 普通用户昵称*/private String nickname;/*** 普通用户性别,1为男性,2为女性*/private Integer sex;/*** 普通用户个人资料填写的省份*/private String province;/*** 普通用户个人资料填写的城市*/private String city;/*** 国家,如中国为CN*/private String country;/*** 用户头像,最后一个数值代表正方形头像大小 (有0、46、64、96、132数值可选,0代表640*640正方形头像) 用户没有头像时该项为空*/private String headimgurl;/*** 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)*/private List privilege;/*** 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。*/private String unionid;public String getOpenid() {return openid;}public void setOpenid(String openid) {this.openid = openid;}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname = nickname;}public Integer getSex() {return sex;}public void setSex(Integer sex) {this.sex = sex;}public String getSexStr(){if (getSex() != null) return getSex() == 1 ? "男" : "女";return "";}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getCountry() {return country;}public void setCountry(String country) {this.country = country;}public String getHeadimgurl() {return headimgurl;}public void setHeadimgurl(String headimgurl) {this.headimgurl = headimgurl;}public List getPrivilege() {return privilege;}public void setPrivilege(List privilege) {this.privilege = privilege;}public String getUnionid() {return unionid;}public void setUnionid(String unionid) {this.unionid = unionid;}}
WeixinLoginService文件
package com.cskt.wxlogin.service;public interface WeixinLoginService {String getLoginUrl();}
WeixinLoginServiceImpl文件
package com.cskt.wxlogin.service.impl;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cskt.wxlogin.constanst.Constanst;
import com.cskt.wxlogin.entity.AccessToken;
import com.cskt.wxlogin.entity.HttpParame;
import com.cskt.wxlogin.entity.WechatUserUnionID;
import com.cskt.wxlogin.service.WeixinLoginService;
import com.cskt.wxlogin.util.AesUtil;
import com.cskt.wxlogin.util.DateUtil;
import com.cskt.wxlogin.util.HttpClientUtil;
import com.cskt.wxlogin.util.PropertiesUtil;
import org.springframework.stereotype.Service;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;@Service
public class WeixinLoginServiceImpl implements WeixinLoginService {@Overridepublic String getLoginUrl() {//第一步 加密String content = Constanst.PWD_MD5 + DateUtil.getYYYYMMdd();//第二步 加密密钥byte[] encrypt = AesUtil.encrypt(content, AesUtil.PASSWORD_SECRET_KEY, 16);//把密钥装成二进制String parseByte2HexStr = AesUtil.parseByte2HexStr(encrypt);//调取接口String url = HttpParame.AUTHORIZATION_URL;//输送参数url = url.replaceAll("APPID", PropertiesUtil.getValue(HttpParame.APPID));try {//调用回调地址 参数一定要用utf-8url = url.replaceAll("REDIRECT_URI", URLEncoder.encode(PropertiesUtil.getValue(HttpParame.REDIRECT_URI), "UTF-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}url = url.replaceAll("SCOPE", "snsapi_login");url = url.replace("STATE", parseByte2HexStr);return url;}public AccessToken getAccessToken(String code) {// 调器Code 获取 AccessTokenString accessTokenUrl = HttpParame.ACCESS_TOKEN_URL;//带入 appid 和密钥还有codeaccessTokenUrl = accessTokenUrl.replaceAll("APPID", PropertiesUtil.getValue(HttpParame.APPID));accessTokenUrl = accessTokenUrl.replaceAll("SECRET", PropertiesUtil.getValue(HttpParame.SECRET));accessTokenUrl = accessTokenUrl.replaceAll("CODE", code);String responseContent = HttpClientUtil.getInstance().sendHttpGet(accessTokenUrl);if (responseContent == null || responseContent == ""){return null;}JSONObject parseObject = JSONObject.parseObject(responseContent);AccessToken accessToken = JSONObject.toJavaObject(parseObject, AccessToken.class);return accessToken ;}public WechatUserUnionID getUserUnionID(String access_token, String openid) {//获取用户信息String unionIDUrl = HttpParame.GET_UNIONID_URL;//根据token获取 用户信息unionIDUrl = unionIDUrl.replace("ACCESS_TOKEN",access_token);//传入openidunionIDUrl = unionIDUrl.replace("OPENID",openid);//unionIDUrl = unionIDUrl.replace("CITY","上海");//发送请求String responseContent = HttpClientUtil.getInstance().sendHttpGet(unionIDUrl);//获取回调参数System.out.println("responseContent" + responseContent);if (responseContent == null || responseContent == "") {return null;}JSONObject parseObject = JSONObject.parseObject(responseContent);WechatUserUnionID userUnionID = JSONObject.toJavaObject(parseObject, WechatUserUnionID.class);return userUnionID;}
}
AesUtil文件
package com.cskt.wxlogin.util;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;/*** AES加密解密*/
public class AesUtil {public static void main(String[] args) {UUID uuid = UUID.randomUUID();String content = "token_"+ DateUtil.getYYYYMMdd()+"_"+uuid;System.out.println("内容:"+content);byte[] encrypt = AesUtil.encrypt(content, PASSWORD_SECRET_KEY, 16);//加密String parseByte2HexStr = AesUtil.parseByte2HexStr(encrypt);//转换为16进制字符串System.out.println("加密后:"+parseByte2HexStr);byte[] parseHexStr2Byte = AesUtil.parseHexStr2Byte(parseByte2HexStr);String decrypt = AesUtil.decrypt(parseHexStr2Byte, PASSWORD_SECRET_KEY, 16);System.out.println("解密后:"+decrypt);System.out.println("UUID:"+uuid);}/*** 秘钥*/public static final String PASSWORD_SECRET_KEY = "EasyRailEveryday";/*** 初始向量*/public static final String INITIAL_VECTOR = "EasyRailEasyRail";/*** 加密* @param content 需要加密的内容* @param password 加密密码* @param keySize 密钥长度16,24,32(密码长度为24和32时需要将local_policy.jar/US_export_policy.jar两个jar包放到JRE目录%jre%/lib/security下)* @return*/public static byte[] encrypt(String content, String password, int keySize){try {//密钥长度不够用0补齐。SecretKeySpec key = new SecretKeySpec(ZeroPadding(password.getBytes(Base64Util.DEFAULT_CHARSET), keySize), "AES");//定义加密算法AES、算法模式ECB、补码方式PKCS5Padding//Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//定义加密算法AES 算法模式CBC、补码方式PKCS5PaddingCipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//CBC模式模式下初始向量 不足16位用0补齐IvParameterSpec iv = new IvParameterSpec(ZeroPadding(INITIAL_VECTOR.getBytes(Base64Util.DEFAULT_CHARSET),16));byte[] byteContent = content.getBytes();//初始化加密//ECB//cipher.init(Cipher.ENCRYPT_MODE, key);//CBCcipher.init(Cipher.ENCRYPT_MODE, key,iv);byte[] result = cipher.doFinal(byteContent);return result;} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (InvalidAlgorithmParameterException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}return null;}/**解密* @param content 待解密内容* @param password 解密密钥* @param keySize 密钥长度16,24,32(密码长度为24和32时需要将local_policy.jar/US_export_policy.jar两个jar包放到JRE目录%jre%/lib/security下)* @return*/public static String decrypt(byte[] content, String password, int keySize) {try {//密钥长度不够用0补齐。SecretKeySpec key = new SecretKeySpec(ZeroPadding(password.getBytes(), keySize), "AES");//定义加密算法AES、算法模式ECB、补码方式PKCS5Padding//Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//定义加密算法AES 算法模式CBC、补码方式PKCS5PaddingCipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//CBC模式模式下初始向量 不足16位用0补齐IvParameterSpec iv = new IvParameterSpec(ZeroPadding(INITIAL_VECTOR.getBytes(Base64Util.DEFAULT_CHARSET),16));// 初始化解密//ECB//cipher.init(Cipher.DECRYPT_MODE, key);//CBCcipher.init(Cipher.DECRYPT_MODE, key,iv);byte[] result = cipher.doFinal(content);return new String(result,Base64Util.DEFAULT_CHARSET);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();} catch (InvalidAlgorithmParameterException e){e.printStackTrace();} catch (Exception e){e.printStackTrace();}return null;}/**将二进制转换成16进制* @param buf* @return*/public static String parseByte2HexStr(byte buf[]) {StringBuilder sb = new StringBuilder();for (int i = 0; i < buf.length; i++) {String hex = Integer.toHexString(buf[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}sb.append(hex.toUpperCase());}return sb.toString();}/**将16进制转换为二进制* @param hexStr* @return*/public static byte[] parseHexStr2Byte(String hexStr) {if (hexStr.length() < 1){return null;}byte[] result = new byte[hexStr.length()/2];for (int i = 0;i< hexStr.length()/2; i++) {int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);result[i] = (byte) (high * 16 + low);}return result;}/*** 字符达不到指定长度补0* @param in 字符数组* @param blockSize 长度* @return*/public static byte[] ZeroPadding(byte[] in,Integer blockSize){Integer copyLen = in.length;if (copyLen > blockSize) {copyLen = blockSize;}byte[] out = new byte[blockSize];System.arraycopy(in, 0, out, 0, copyLen);return out;}}
Base64Util文件
package com.cskt.wxlogin.util;import org.apache.tomcat.util.codec.binary.Base64;import java.nio.charset.Charset;/*** Base64Util工具类 --- 加密和解密*/
public class Base64Util {public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");/*** 解密* @param str* @return*/public static String decodeStr(String str){if (str == null) {return null;}if (str.length() == 0) {return "";}return new String(Base64.decodeBase64(new String(str).getBytes(DEFAULT_CHARSET)),DEFAULT_CHARSET).trim();}/*** 加密** @param str* @return*/public static String encodeStr(String str){if (str == null) {return null;}if (str.length() == 0) {return "";}return new String(Base64.encodeBase64Chunked(str.getBytes(DEFAULT_CHARSET)),DEFAULT_CHARSET).trim();}}
DateUtil文件
package com.cskt.wxlogin.util;import org.springframework.stereotype.Component;import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;/*** 日期工具类*/
@Component // 加此注解是把此类实例化spring容器中
public class DateUtil {/*** 默认日期格式*/public static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";/*** 如2018 0901 232211(年月日时分秒)** @return*/public String yyyyMMddHHmmss() {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");return sdf.format(Calendar.getInstance().getTime());}/*** 如20180901** @return*/public static String getYYYYMMdd() {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");return sdf.format(Calendar.getInstance().getTime());}/*** 如180901* @return*/public String getYYMMdd() {SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");return sdf.format(Calendar.getInstance().getTime());}/*** 如201809* @return*/public String getYYYYMM() {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");return sdf.format(Calendar.getInstance().getTime());}/*** 如 2018/02/11* @return*/public String getQueryEndDate() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");return sdf.format(Calendar.getInstance().getTime());}/*** 如 2018/02/11* @return*/public String getQueryStartDate() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Calendar cal = Calendar.getInstance();cal.add(Calendar.DAY_OF_YEAR, -30);return sdf.format(cal.getTime());}/*** 如 2018/02/11 12:30:00* @return*/public static String getQueryEndTime() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return sdf.format(Calendar.getInstance().getTime());}/*** 如 2018/02/11* @return*/public String getQueryStartTime() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Calendar cal = Calendar.getInstance();cal.add(Calendar.DAY_OF_YEAR, -30);return sdf.format(cal.getTime());}public String getQueryTwoAgoDate() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Calendar cal = Calendar.getInstance();cal.add(Calendar.DAY_OF_YEAR, -2);return sdf.format(cal.getTime());}/*** 字符串转换成日期** @param str 字符串* @param format 日期格式* @return 日期*/public static Date str2Date(String str, String format) {if (null == str || "".equals(str)) {return null;}// 如果没有指定字符串转换的格式,则用默认格式进行转换if (null == format || "".equals(format)) {format = DEFAULT_FORMAT;}SimpleDateFormat sdf = new SimpleDateFormat(format);Date date = null;try {date = sdf.parse(str);return date;} catch (ParseException e) {}return null;}/*** @param date 日期* @param format 日期格式* @return 字符串*/public static String date2Str(Date date, String format) {if (null == date) {return null;}SimpleDateFormat sdf = new SimpleDateFormat(format);return sdf.format(date);}/*** 时间戳转换为字符串* @param time* @return*/public static String timestamp2Str(Timestamp time) {Date date = new Date(time.getTime());return date2Str(date, DEFAULT_FORMAT);}/*** 字符串转换为时间* @param str* @return*/public static Timestamp str2Timestamp(String str) {Date date = str2Date(str, DEFAULT_FORMAT);return new Timestamp(date.getTime());}/*** 字符串转换为时间* @param str* @return*/public static Timestamp str2Timestamp(String str, String formatStr) {if (null == str) {return null;}Date date = str2Date(str, formatStr);return new Timestamp(date.getTime());}/*** 获取某年第一天日期* @param year 年份* @return Date*/public static Date getYearFirst(int year) {Calendar calendar = Calendar.getInstance();calendar.clear();calendar.set(Calendar.YEAR, year);Date currYearFirst = calendar.getTime();return currYearFirst;}/*** 获取某年最后一天日期* @param year 年份* @return Date*/public static Date getYearLast(int year) {Calendar calendar = Calendar.getInstance();calendar.clear();calendar.set(Calendar.YEAR, year);calendar.roll(Calendar.DAY_OF_YEAR, -1);Date currYearLast = calendar.getTime();return currYearLast;}@SuppressWarnings("static-access")public static Date getnextLast(String datetime, int year) {Calendar calendar = new GregorianCalendar();Date date = null;if (datetime.length() > 7) {date = str2Date(datetime, "yyyy-MM-dd");} else {date = str2Date(datetime, "yyyy-MM");}calendar.setTime(date);calendar.add(calendar.YEAR, year);// 把日期往后增加一年.整数往后推,负数往前移动date = calendar.getTime();return date;}public static String getrightDate(String datetime, int year) {String date = "";String years = datetime.substring(0, 4);String dates = datetime.substring(4, datetime.length());Integer s = new Integer(years) + year;date = s + dates;return date;}public static void main(String[] args) {System.out.println(getrightDate("2018-09", 4));System.out.println(date2Str(getnextLast("2018-09", 4), "yyyy-MM"));}}
HttpClientUtil文件
package com.cskt.wxlogin.util;import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** httpClient 工具类*/
public class HttpClientUtil {/*** 默认参数设置* setConnectTimeout:设置连接超时时间,单位毫秒。* setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。* setSocketTimeout:请求获取数据的超时时间,单位毫秒。访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。 暂时定义15分钟*/private RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(600000).setConnectTimeout(600000).setConnectionRequestTimeout(600000).build();/*** 静态内部类---作用:单例产生类的实例* @author Administrator**/private static class LazyHolder {private static final HttpClientUtil INSTANCE = new HttpClientUtil();}private HttpClientUtil(){}public static HttpClientUtil getInstance(){return LazyHolder.INSTANCE;}/*** 发送 post请求* @param httpUrl 地址*/public String sendHttpPost(String httpUrl) {HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPostreturn sendHttpPost(httpPost);}/*** 发送 post请求* @param httpUrl 地址* @param params 参数(格式:key1=value1&key2=value2)*/public String sendHttpPost(String httpUrl, String params) {HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPosttry {//设置参数StringEntity stringEntity = new StringEntity(params, "UTF-8");stringEntity.setContentType("application/x-www-form-urlencoded");httpPost.setEntity(stringEntity);} catch (Exception e) {e.printStackTrace();}return sendHttpPost(httpPost);}/*** 发送 post请求* @param httpUrl 地址* @param maps 参数*/public String sendHttpPost(String httpUrl, Map maps) {HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost// 创建参数队列List nameValuePairs = new ArrayList();for (String key : maps.keySet()) {nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));}try {httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));} catch (Exception e) {e.printStackTrace();}return sendHttpPost(httpPost);}/*** 发送Post请求* @param httpPost* @return*/private String sendHttpPost(HttpPost httpPost) {CloseableHttpClient httpClient = null;CloseableHttpResponse response = null;HttpEntity entity = null;String responseContent = null;try {// 创建默认的httpClient实例httpClient = HttpClients.createDefault();httpPost.setConfig(requestConfig);// 执行请求long execStart = System.currentTimeMillis();response = httpClient.execute(httpPost);long execEnd = System.currentTimeMillis();System.out.println("=================执行post请求耗时:"+(execEnd-execStart)+"ms");long getStart = System.currentTimeMillis();entity = response.getEntity();responseContent = EntityUtils.toString(entity, "UTF-8");long getEnd = System.currentTimeMillis();System.out.println("=================获取响应结果耗时:"+(getEnd-getStart)+"ms");} catch (Exception e) {e.printStackTrace();} finally {try {// 关闭连接,释放资源if (response != null) {response.close();}if (httpClient != null) {httpClient.close();}} catch (IOException e) {e.printStackTrace();}}return responseContent;}/*** 发送 get请求* @param httpUrl*/public String sendHttpGet(String httpUrl) {HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求return sendHttpGet(httpGet);}/*** 发送 get请求Https* @param httpUrl*/public String sendHttpsGet(String httpUrl) {HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求return sendHttpsGet(httpGet);}/*** 发送Get请求* @param httpPost* @return*/private String sendHttpGet(HttpGet httpGet) {CloseableHttpClient httpClient = null;CloseableHttpResponse response = null;HttpEntity entity = null;String responseContent = null;try {// 创建默认的httpClient实例.httpClient = HttpClients.createDefault();httpGet.setConfig(requestConfig);// 执行请求response = httpClient.execute(httpGet);entity = response.getEntity();responseContent = EntityUtils.toString(entity, "UTF-8");} catch (Exception e) {e.printStackTrace();} finally {try {// 关闭连接,释放资源if (response != null) {response.close();}if (httpClient != null) {httpClient.close();}} catch (IOException e) {e.printStackTrace();}}return responseContent;}/*** 发送Get请求Https* @param httpPost* @return*/private String sendHttpsGet(HttpGet httpGet) {CloseableHttpClient httpClient = null;CloseableHttpResponse response = null;HttpEntity entity = null;String responseContent = null;try {// 创建默认的httpClient实例.PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpGet.getURI().toString()));DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build();httpGet.setConfig(requestConfig);// 执行请求response = httpClient.execute(httpGet);entity = response.getEntity();responseContent = EntityUtils.toString(entity, "UTF-8");} catch (Exception e) {e.printStackTrace();} finally {try {// 关闭连接,释放资源if (response != null) {response.close();}if (httpClient != null) {httpClient.close();}} catch (IOException e) {e.printStackTrace();}}return responseContent;}}
PropertiesUtil文件
package com.cskt.wxlogin.util;import java.io.*;
import java.net.URI;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;/*** properties资源文件解析工具*/
public class PropertiesUtil {private static Properties props = null;private static URI uri;private static String fileName = "/weixinconnectconfig.properties";private static InputStream in = null;static {try {props = new Properties();InputStream fis = PropertiesUtil.class.getResourceAsStream(fileName);props.load(fis);uri = PropertiesUtil.class.getResource(fileName).toURI();} catch (Exception e) {e.printStackTrace();}}/*** 获取某个属性*/public static String getProperty(String key) {try {props.load(PropertiesUtil.class.getResourceAsStream(fileName));} catch (IOException e) {e.printStackTrace();}return props.getProperty(key);}/*** 获取所有属性,返回一个map,不常用 可以试试props.putAll(t)*/@SuppressWarnings("rawtypes")public static Map getAllProperty() {Map map = new HashMap();Enumeration enu = props.propertyNames();while (enu.hasMoreElements()) {String key = (String) enu.nextElement();String value = props.getProperty(key);map.put(key, value);}return map;}/*** 在控制台上打印出所有属性,调试时用。*/public static void printProperties() {props.list(System.out);}/*** 写入properties信息*/public static void writeProperties(String key, String value) {try {OutputStream fos = new FileOutputStream(new File(uri));props.setProperty(key, value);// 将此 Properties 表中的属性列表(键和元素对)写入输出流props.store(fos, "『comments』Update key:" + key);} catch (Exception e) {e.printStackTrace();}}/*** 取默认key的value* */public static String getValue(String key){String value = null;props = new Properties();in = PropertiesUtil.class.getResourceAsStream(fileName);try {props.load(in);} catch (IOException e) {
// e.printStackTrace();}value = (String) props.get(key);return value;}}
application.yml配置文件
server:port: 80 spring:thymeleaf:mode: HTML5prefix: classpath:/templates/suffix: .htmlcache: false
weixinconnectconfig.properties配置文件
appid=wx9dbc36f6430dc621
secret=11f48317f08fe2afbdf5cb80dcc4e99d
redirect_uri=http://www.csktedu.com/weixinconnect
templates文件夹
index.html
微信扫码登录测试 ![]()
main
主页 微信唯一标识OpenId:
昵称:
性别:
ooxx
整体目录如下:

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

