java微信公众号开发(零)
时间:2019-03-18
本文章向大家介绍java微信公众号开发(零),主要包括java微信公众号开发(零)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
ps:实现功能有微信公众号自定义菜单,文本自动回复,网页授权获取用户信息及openid等功能
(只贴代码,不写逻辑,有空再整理)
参考博客地址:
微信公众号开发系统入门教程(公众号注册、开发环境搭建、access_token管理、Demo实现、natapp外网穿透)
https://blog.csdn.net/a1786223749/article/details/80787379#_9
基于Springboot的微信公众号接入、通过网页授权机制获取用户信息
https://www.2cto.com/kf/201701/583038.html
1. WechatController
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.jinfei.core.HttpsUtils;
import com.jinfei.core.WechatMessageUtil;
@Controller
@RequestMapping("/wechatServer")
public class WechatController {
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/**
* Takes the raw bytes from the digest and formats them correct.
*
* @param bytes the raw bytes from the digest.
* @return the formatted bytes.
*/
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
public static String encode(String str) {
if (str == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
messageDigest.update(str.getBytes());
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 验证签名
*
* @param token 微信服务器token,在env.properties文件中配置的和在开发者中心配置的必须一致
* @param signature 微信服务器传过来sha1加密的证书签名
* @param timestamp 时间戳
* @param nonce 随机数
* @return
*/
public static boolean checkSignature(String token,String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
// 将三个参数字符串拼接成一个字符串进行sha1加密
String tmpStr = encode(arr[0] + arr[1] + arr[2]);
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
@RequestMapping(value = "/wx.do")
public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 将请求、响应的编码均设置为UTF-8(防止中文乱码)
request.setCharacterEncoding("UTF-8"); //微信服务器POST消息时用的是UTF-8编码,在接收时也要用同样的编码,否则中文会乱码;
response.setCharacterEncoding("UTF-8"); //在响应消息(回复消息给用户)时,也将编码方式设置为UTF-8,原理同上;boolean isGet = request.getMethod().toLowerCase().equals("get");
PrintWriter out = response.getWriter();
System.out.println("weMe+++++++==="+request.getMethod());
try {
if ("GET".equals(request.getMethod())) {
String signature = request.getParameter("signature");// 微信加密签名
String timestamp = request.getParameter("timestamp");// 时间戳
String nonce = request.getParameter("nonce");// 随机数
String echostr = request.getParameter("echostr");//随机字符串
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (checkSignature(WechatMessageUtil.WECHAT_TOKEN, signature, timestamp, nonce)) {
System.out.println("Connect the weixin server is successful.");
response.getWriter().write(echostr);
} else {
System.out.println("Failed to verify the signature!");
}
}else{
String respMessage = "异常消息!";
try {
respMessage = WechatMessageUtil.weixinPost(request);
out.write(respMessage);
System.out.println("The request completed successfully");
System.out.println("to weixin server "+respMessage);
} catch (Exception e) {
System.out.println("Failed to convert the message from weixin!");
}
}
} catch (Exception e) {
System.out.println("Connect the weixin server is error.");
}finally{
out.close();
}
}
@RequestMapping("/vote.do")
public ModelAndView listVote(String code, String state) {
System.out.println("-----------------------------收到请求,请求数据为:" + code + "-----------------------" + state);
String openId = "";
String nickName = "", sex = "", openid = "";
JSONObject userMessageJsonObject = null;
// 通过code换取网页授权web_access_token
if (code != null || !(code.equals(""))) {
String APPID = WechatMessageUtil.WECHAT_APPID;
String SECRET = WechatMessageUtil.WECHAT_APPSECRET;
String CODE = code;
String WebAccessToken = "";
String REDIRECT_URI = "http://www.jinfeismartcity.com/jinfeigw/wechatServer/vote.do";
String SCOPE = "snsapi_userinfo";
String getCodeUrl = WechatMessageUtil.getCode(APPID, REDIRECT_URI, SCOPE);
System.out.println("---------------getCodeUrl--------------" + getCodeUrl);
// 替换字符串,获得请求URL
String token = WechatMessageUtil.getWebAccess(APPID, SECRET, CODE);
System.out.println("----------------------------token为:" + token);
// 通过https方式请求获得web_access_token
String response = HttpsUtils.httpsRequestToString(token, "GET", null);
JSONObject jsonObject = JSON.parseObject(response);
System.out.println("jsonObject------" + jsonObject);
if (null != jsonObject) {
try {
WebAccessToken = jsonObject.getString("access_token");
openId = jsonObject.getString("openid");
System.out.println(
"获取access_token成功-------------------------" + WebAccessToken + "----------------" + openId);
// -----------------------拉取用户信息...替换字符串,获得请求URL
String userMessage = WechatMessageUtil.getUserMessage(WebAccessToken, openId);
System.out.println(" userMessage===" + userMessage);
// 通过https方式请求获得用户信息响应
String userMessageResponse = HttpsUtils.httpsRequestToString(userMessage, "GET", null);
userMessageJsonObject = JSON.parseObject(userMessageResponse);
System.out.println("userMessagejsonObject------" + userMessageJsonObject);
if (userMessageJsonObject != null) {
try {
// 用户昵称
nickName = userMessageJsonObject.getString("nickname");
// 用户性别
sex = userMessageJsonObject.getString("sex");
sex = (sex.equals("1")) ? "男" : "女";
// 用户唯一标识
openid = userMessageJsonObject.getString("openid");
} catch (JSONException e) {
System.out.println("获取userName失败");
}
}
} catch (JSONException e) {
WebAccessToken = null;// 获取code失败
System.out.println("获取WebAccessToken失败");
}
}
// ……………………业务代码,此处省略
ModelAndView mv = new ModelAndView();
mv.addObject("openId", openId);
mv.addObject("nickName", nickName);
mv.addObject("sex", sex);
mv.addObject("code", code);
mv.addObject("userMsg",userMessageJsonObject);
mv.setViewName("/welcome");
return mv;
}
return null;
}
}
2 WechatMessageUtil
package com.jinfei.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.alibaba.fastjson.JSONObject;
import com.jinfei.pojo.wechat.Button;
import com.jinfei.pojo.wechat.ClickButton;
import com.jinfei.pojo.wechat.Menu;
import com.jinfei.pojo.wechat.ViewButton;
public class WechatMessageUtil {
/**
* 返回消息类型:文本
*/
public static final String RESP_MESSAGE_TYPE_TEXT = "text";
/**
* 返回消息类型:音乐
*/
public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
/**
* 返回消息类型:图文
*/
public static final String RESP_MESSAGE_TYPE_NEWS = "news";
/**
* 请求消息类型:文本
*/
public static final String REQ_MESSAGE_TYPE_TEXT = "text";
/**
* 请求消息类型:图片
*/
public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
/**
* 请求消息类型:链接
*/
public static final String REQ_MESSAGE_TYPE_LINK = "link";
/**
* 请求消息类型:地理位置
*/
public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
/**
* 请求消息类型:音频
*/
public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
/**
* 请求消息类型:推送
*/
public static final String REQ_MESSAGE_TYPE_EVENT = "event";
/**
* 事件类型:subscribe(订阅)
*/
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
/**
* 事件类型:unsubscribe(取消订阅)
*/
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
/**
* 事件类型:CLICK(自定义菜单点击事件)
*/
public static final String EVENT_TYPE_CLICK = "CLICK";
/**
* 事件类型:CLICK(自定义菜单点击事件)
*/
public static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=";
/**
* 事件类型:CLICK(自定义菜单点击事件)
*/
public static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=";
public static String WECHAT_APPID = "wx186752ee65c0a***";
public static String WECHAT_APPSECRET = "5ba58fa3af3a56c1ad5a0e3d4304***";
public static String WECHAT_TOKEN = "wx_***";
public static String oauth2_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=APP_URL&response_type=code&scope=snsapi_userinfo&s%20tate=123&connect_redirect=1#wechat_redirect";
/**
* 处理微信发来的请求
*
* @param request
* @return
*/
public static String weixinPost(HttpServletRequest request) {
String respMessage = null;
try {
// xml请求解析
Map<String, String> requestMap = xmlToMap(request);
// 发送方帐号(open_id)
String fromUserName = requestMap.get("FromUserName");
// 公众帐号
String toUserName = requestMap.get("ToUserName");
// 消息类型
String msgType = requestMap.get("MsgType");
// 消息内容
String content = requestMap.get("Content");
System.out.println("FromUserName is:" + fromUserName + ", ToUserName is:" + toUserName + ", MsgType is:" + msgType);
// 文本消息
if (msgType.equals(REQ_MESSAGE_TYPE_TEXT)) {
//这里根据关键字执行相应的逻辑,只有你想不到的,没有做不到的
if(content.equals("xxx")){
}
//自动回复
// respMessage = java2Xml(TextMessage.class,text);
respMessage =
"<xml>"+
"<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>"+
"<FromUserName><![CDATA["+toUserName+"]]></FromUserName>"+
"<CreateTime>"+new Date().getTime()+"</CreateTime>"+
"<MsgType><![CDATA[text]]></MsgType>"+
"<Content><![CDATA["+content+"]]></Content>"+
"</xml>";
} /*else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {// 事件推送
String eventType = requestMap.get("Event");// 事件类型
if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {// 订阅
respContent = "欢迎关注xxx公众号!";
return MessageResponse.getTextMessage(fromUserName , toUserName , respContent);
} else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {// 自定义菜单点击事件
String eventKey = requestMap.get("EventKey");// 事件KEY值,与创建自定义菜单时指定的KEY值对应
logger.info("eventKey is:" +eventKey);
return xxx;
}
}
//开启微信声音识别测试 2015-3-30
else if(msgType.equals("voice"))
{
String recvMessage = requestMap.get("Recognition");
//respContent = "收到的语音解析结果:"+recvMessage;
if(recvMessage!=null){
respContent = TulingApiProcess.getTulingResult(recvMessage);
}else{
respContent = "您说的太模糊了,能不能重新说下呢?";
}
return MessageResponse.getTextMessage(fromUserName , toUserName , respContent);
}
//拍照功能
else if(msgType.equals("pic_sysphoto"))
{
}
else
{
return MessageResponse.getTextMessage(fromUserName , toUserName , "返回为空");
}*/
// 事件推送
else if (msgType.equals(REQ_MESSAGE_TYPE_EVENT)) {
String eventType = requestMap.get("Event");// 事件类型
// 订阅
if (eventType.equals(EVENT_TYPE_SUBSCRIBE)) {
// respMessage = java2Xml(TextMessage.class,text);
}
// TODO 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息
else if (eventType.equals(EVENT_TYPE_UNSUBSCRIBE)) {// 取消订阅
}
// 自定义菜单点击事件
else if (eventType.equals(EVENT_TYPE_CLICK)) {
String eventKey = requestMap.get("EventKey");// 事件KEY值,与创建自定义菜单时指定的KEY值对应
if (eventKey.equals("11")) {
String eventKeyContent = "click菜单被点击!";
respMessage =
"<xml>"+
"<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>"+
"<FromUserName><![CDATA["+toUserName+"]]></FromUserName>"+
"<CreateTime>"+new Date().getTime()+"</CreateTime>"+
"<MsgType><![CDATA[text]]></MsgType>"+
"<Content><![CDATA["+eventKeyContent+"]]></Content>"+
"</xml>";
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return respMessage;
}
/**
* xml转换为map
* @param request
* @return
* @throws IOException
*/
@SuppressWarnings("unchecked")
public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException{
Map<String, String> map = new HashMap<String, String>();
SAXReader reader = new SAXReader();
InputStream ins = null;
try {
ins = request.getInputStream();
} catch (IOException e1) {
e1.printStackTrace();
}
Document doc = null;
try {
doc = reader.read(ins);
Element root = doc.getRootElement();
List<Element> list = root.elements();
for (Element e : list) {
map.put(e.getName(), e.getText());
}
return map;
} catch (DocumentException e1) {
e1.printStackTrace();
}finally{
ins.close();
}
return null;
}
//获取AccessToken
public static String getAccessToken() throws Exception {
System.out.println("WechatController ---- getAccessToken");
Map<String, Object> params = new HashMap<>();
params.put("appid", WECHAT_APPID);
params.put("password", WECHAT_APPSECRET);
params.put("grant_type", "client_credential");
JSONObject rel = HttpsUtils.doGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WECHAT_APPID+"&secret="+WECHAT_APPSECRET+"");
System.out.println(rel.getString("access_token"));
return rel.getString("access_token");
}
public static int createMenu(String token,String menu) throws Exception {
int result = 0;
String url = CREATE_MENU_URL + token;
JSONObject jsonObject = HttpsUtils.doPost(url, menu);
if(jsonObject != null){
result = jsonObject.getIntValue("errcode");
}
return result;
}
/**
* 组装菜单
* @return
*/
public static String initMenu() throws Exception {
Menu menu = new Menu();
ClickButton button11 = new ClickButton();
button11.setName("click菜单");
button11.setType("click");
button11.setKey("11");
ViewButton button21 = new ViewButton();
button21.setName("imooc菜单");
button21.setType("view");
button21.setUrl("http://www.imooc.com");
ViewButton button22 = new ViewButton();
button22.setName("百度菜单");
button22.setType("view");
button22.setUrl("http://www.baidu.com");
ViewButton button23 = new ViewButton();
button23.setName("网页授权测试");
button23.setType("view");
button23.setUrl(oauth2_url);
Button button2 = new Button();
button2.setName("view菜单");
button2.setSub_button(new Button[] { button21, button22 ,button23});
ClickButton button31 = new ClickButton();
button31.setName("扫码事件");
button31.setType("scancode_push");
button31.setKey("31");
ClickButton button32 = new ClickButton();
button32.setName("地理位置");
button32.setType("location_select");
button32.setKey("32");
Button button3 = new Button();
button3.setName("菜单");
button3.setSub_button(new Button[] { button31, button32 });
menu.setButton(new Button[] { button11, button2, button3 });
return JSONObject.toJSON(menu).toString();
}
//获取code的请求地址
public static String Get_Code = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STAT#wechat_redirect";
//替换字符串
public static String getCode(String APPID, String REDIRECT_URI,String SCOPE) {
return String.format(Get_Code,APPID,REDIRECT_URI,SCOPE);
}
//获取Web_access_tokenhttps的请求地址
public static String Web_access_tokenhttps = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
//替换字符串
public static String getWebAccess(String APPID, String SECRET,String CODE) {
return String.format(Web_access_tokenhttps, APPID, SECRET,CODE);
}
//拉取用户信息的请求地址
public static String User_Message = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";
//替换字符串
public static String getUserMessage(String access_token, String openid) {
return String.format(User_Message, access_token,openid);
}
public static void main(String[] args) throws Exception {
String accessToken = getAccessToken() ;
// 删除菜单
/*String url = DELETE_MENU_URL+accessToken;
JSONObject jsonObject = HttpsUtils.doGet(url);
System.out.println(jsonObject);*/
String menu = initMenu();
int result = createMenu(accessToken, menu);
if(result==0){
System.out.println("菜单创建成功!");
}else{
System.out.println("菜单创建失败");
}
}
}
3 HttpsUtils
package com.jinfei.core;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jinfei.pojo.wechat.JEEWeiXinX509TrustManager;
public class HttpsUtils {
private static PoolingHttpClientConnectionManager connMgr;
private static RequestConfig requestConfig;
private static final int MAX_TIMEOUT = 7000;
private static final Logger logger = LoggerFactory.getLogger(HttpsUtils.class);
static {
// 设置连接池
connMgr = new PoolingHttpClientConnectionManager();
// 设置连接池大小
connMgr.setMaxTotal(100);
connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
// Validate connections after 1 sec of inactivity
connMgr.setValidateAfterInactivity(1000);
RequestConfig.Builder configBuilder = RequestConfig.custom();
// 设置连接超时
configBuilder.setConnectTimeout(MAX_TIMEOUT);
// 设置读取超时
configBuilder.setSocketTimeout(MAX_TIMEOUT);
// 设置从连接池获取连接实例的超时
configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
requestConfig = configBuilder.build();
}
/**
* 发送 GET 请求(HTTP),不带输入数据
*
* @param url
* @return
*/
public static JSONObject doGet(String url) {
return doGet(url, new HashMap<String, Object>());
}
/**
* 发送 GET 请求(HTTP),K-V形式
*
* @param url
* @param params
* @return
*/
public static JSONObject doGet(String url, Map<String, Object> params) {
String apiUrl = url;
StringBuffer param = new StringBuffer();
int i = 0;
for (String key : params.keySet()) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(params.get(key));
i++;
}
apiUrl += param;
String result = null;
HttpClient httpClient = null;
if (apiUrl.startsWith("https")) {
httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory())
.setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
} else {
httpClient = HttpClients.createDefault();
}
try {
HttpGet httpGet = new HttpGet(apiUrl);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = IOUtils.toString(instream, "UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
return JSON.parseObject(result);
}
/**
* 发送 POST 请求(HTTP),不带输入数据
*
* @param apiUrl
* @return
*/
public static JSONObject doPost(String apiUrl) {
return doPost(apiUrl, new HashMap<String, Object>());
}
/**
* 发送 POST 请求,K-V形式
*
* @param apiUrl
* API接口URL
* @param params
* 参数map
* @return
*/
public static JSONObject doPost(String apiUrl, Map<String, Object> params) {
CloseableHttpClient httpClient = null;
if (apiUrl.startsWith("https")) {
httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory())
.setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
} else {
httpClient = HttpClients.createDefault();
}
String httpStr = null;
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
try {
httpPost.setConfig(requestConfig);
List<NameValuePair> pairList = new ArrayList<>(params.size());
for (Map.Entry<String, Object> entry : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
pairList.add(pair);
}
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
httpStr = EntityUtils.toString(entity, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
EntityUtils.consume(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return JSON.parseObject(httpStr);
}
/**
* 发送 POST 请求,JSON形式
*
* @param apiUrl
* @param json
* json对象
* @return
*/
public static JSONObject doPost(String apiUrl, Object json) {
CloseableHttpClient httpClient = null;
if (apiUrl.startsWith("https")) {
httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory())
.setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
} else {
httpClient = HttpClients.createDefault();
}
String httpStr = null;
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
try {
httpPost.setConfig(requestConfig);
StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
httpStr = EntityUtils.toString(entity, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (response != null) {
try {
EntityUtils.consume(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return JSON.parseObject(httpStr);
}
/**
* 创建SSL安全连接
*
* @return
*/
private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
SSLConnectionSocketFactory sslsf = null;
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
sslsf = new SSLConnectionSocketFactory(sslContext, new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return sslsf;
}
/**
* 以https方式发送请求并将请求响应内容以String方式返回
*
* @param path 请求路径
* @param method 请求方法
* @param body 请求数据体
* @return 请求响应内容转换成字符串信息
*/
public static String httpsRequestToString(String path, String method, String body) {
if (path == null || method == null) {
return null;
}
String response = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
HttpsURLConnection conn = null;
try {
//创建SSLConrext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = {new JEEWeiXinX509TrustManager()};
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
//从上述对象中的到SSLSocketFactory
SSLSocketFactory ssf = sslContext.getSocketFactory();
System.out.println(path);
URL url = new URL(path);
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
//设置请求方式(git|post)
conn.setRequestMethod(method);
//有数据提交时
if (null != body) {
OutputStream outputStream = conn.getOutputStream();
outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
//将返回的输入流转换成字符串
inputStream = conn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
response = buffer.toString();
} catch (Exception e) {
} finally {
if (conn != null) {
conn.disconnect();
}
try {
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
} catch (IOException execption) {
}
}
return response;
}
}
4 用到的实体类(set,get方法没写)
4.1 Button
public class Button {
private String type;
private String name;
private Button[] sub_button;
}
4.2 ClickButton
public class ClickButton extends Button {
private String key;
}
4.3 ViewButton
public class ViewButton extends Button{
private Button[] button;
private String url;
}
4.4 Menu
public class Menu {
private Button[] button;
}
4.5 JEEWeiXinX509TrustManager (通过https方式请求获得用户信息响应用到的实体类)
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class JEEWeiXinX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
- 微信公众平台增加更多统计项 让你更了解运营数据
- 用OpenCV计算道路交通流量的一个直观教程
- WPF Button TextBox 圆角
- 设置WPF窗体全屏显示:
- winform 、WPF传值方式详解
- 你一定要知道!数据科学家提高工作效率的基本工具
- MySQL 大数据操作注意事项
- Winform窗口里的嵌入WPF的UserControl,关闭Winform父窗体的方法
- LINQ分页和排序,skip和Take 用法
- 这或许是对小白最友好的python入门了吧——21,导入模块
- opoa介绍
- 数据库记录安全解决方案
- 基于计算机视觉和OpenCV:创建一个能够计算道路交通流量的应用
- 这或许是对小白最友好的python入门了吧——20,定义函数简单应用
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- java学习之路:6.格式化输出字符串
- java学习之路:4.String类 连接字符串 获取字符串信息
- java学习之路:11.数组排序算法
- java学习之路:5.字符串操作
- [Skr-Shop]什么,秒杀系统也有这么多种!
- java学习之路:3.数据类型 变量 运算符 转换
- 状态变换 | 我的代码没有else
- java学习之路:2.我的第一个java程序
- 线性表--顺序队列 循环队列 双端队列(十三)
- 线性表--链队列(十二)
- 线性表--链栈(十一)
- 线性表--多栈共享技术(十)
- PostgreSQL TID及tuple slot
- 线性表--顺序栈(九)
- 线性表--顺序表--静态链表(八)