钉钉提供的内网穿透之HTTP穿透:https://www.cnblogs.com/pxblog/p/13862376.html
网页分享到微信中如何显示标题图,如果自定义标题图,描述,显示效果如下
官网接口地址;https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
加入maven依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>[4.1.12,)</version>
</dependency> <dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20171018</version>
</dependency>
HttpClientUtil.java
package com.test.cms.share; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
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.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; public class HttpClientUtil { private static class SingletonHolder{
private final static HttpClientUtil INSTANCE=new HttpClientUtil();
} private HttpClientUtil(){} public static HttpClientUtil getInstance(){
return SingletonHolder.INSTANCE;
} public String get(String url){
CharsetHandler handler = new CharsetHandler("UTF-8");
CloseableHttpClient client = null;
try {
HttpGet httpget = new HttpGet(new URI(url));
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
client= httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
return client.execute(httpget, handler);
} catch (Exception e) {
//e.printStackTrace();
return "";
}finally {
try {
if(client!=null){
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} public static String post(String url, String params,String contentType)
{ //创建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client); HttpPost post = new HttpPost(url);
CloseableHttpResponse res = null;
try
{
StringEntity s = new StringEntity(params,"UTF-8");
if(StringUtils.isBlank(contentType)){
s.setContentType("application/json");
}
s.setContentType(contentType);
s.setContentEncoding("utf-8");
post.setEntity(s);
res = client.execute(post);
HttpEntity entity = res.getEntity();
return EntityUtils.toString(entity, "utf-8");
}
catch (Exception e)
{
e.printStackTrace();
} finally {
try {
res.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
} public static String post(String urlStr,String xmlInfo) {
String line1 = "";
try {
URL url = new URL(urlStr);
URLConnection con = url.openConnection();
con.setDoOutput(true);
//con.setRequestProperty("Pragma:", "no-cache");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml"); OutputStreamWriter out = new OutputStreamWriter(con
.getOutputStream());
out.write(new String(xmlInfo.getBytes("utf-8")));
out.flush();
out.close();
BufferedReader br = new BufferedReader(new InputStreamReader(con
.getInputStream()));
String line = "";
for (line = br.readLine(); line != null; line = br.readLine()) {
line1+=line;
}
return new String(line1.getBytes(),"utf-8");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} private class CharsetHandler implements ResponseHandler<String> {
private String charset; public CharsetHandler(String charset) {
this.charset = charset;
} public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity != null) {
if (!StringUtils.isBlank(charset)) {
return EntityUtils.toString(entity, charset);
} else {
return EntityUtils.toString(entity);
}
} else {
return null;
}
}
} private static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLSv1");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
return httpclient; } catch (Exception ex) {
return null;
}
} }
RandomStr.java
package com.test.cms.share; import java.util.Random; public class RandomStr { private static char ch[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '0', '1' };//最后又重复两个0和1,因为需要凑足数组长度为64 private static Random random = new Random(); //生成指定长度的随机字符串
public static String createRandomString(int length) {
if (length > 0) {
int index = 0;
char[] temp = new char[length];
int num = random.nextInt();
for (int i = 0; i < length % 5; i++) {
temp[index++] = ch[num & 63];//取后面六位,记得对应的二进制是以补码形式存在的。
num >>= 6;//63的二进制为:111111
// 为什么要右移6位?因为数组里面一共有64个有效字符。为什么要除5取余?因为一个int型要用4个字节表示,也就是32位。
}
for (int i = 0; i < length / 5; i++) {
num = random.nextInt();
for (int j = 0; j < 5; j++) {
temp[index++] = ch[num & 63];
num >>= 6;
}
}
return new String(temp, 0, length);
}
else if (length == 0) {
return "";
}
else {
throw new IllegalArgumentException();
}
} public static void main(String[] args) {
System.out.println(createRandomString(16));
}
}
Sha1.java
package com.test.cms.share; import java.security.MessageDigest; public class Sha1 { private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 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);
}
}
}
控制器类
ShareController.java
package com.test.cms.share; import cn.hutool.json.JSONUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URI;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map; @Controller
public class ShareController { /**
* 微信公众号的appid
*/
private String appid="wxd"; /**
* 微信公众号的appSecret
*/
private String secret="ebded33"; /**
* 这是跳转到分享的页面
* @return
*/
@RequestMapping(value = "/to_detail")
public String share(){
return "/index/share";
} /**
* 获取微信分享配置的请求 方法只写了主要方法,需要根据自己的要求 完善代码
* @param url 前台传过来的当前页面的请求地址
* @return
*/
@RequestMapping(value = "/get_wx_config")
@ResponseBody
public String share(String url){
long timestamp = System.currentTimeMillis() / 1000;
String noncestr = RandomStr.createRandomString(16);
String ticket =getJsapiTicket();
String str = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url;
System.out.println("签名str:" + str);
String signature = Sha1.encode(str); //这只是简单写法,没有做错误判断
Map map=new HashMap();
map.put("appId",appid);
map.put("timestamp",timestamp);
map.put("nonceStr",noncestr);
map.put("signature",signature); //这里使用了hutool工具将map转为String
String json = JSONUtil.toJsonStr(map); return json;
} /**
* 官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
*
* 获取jsapi_ticket
*
*
* 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。
* 正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。
* 由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
*
* 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):
* https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
*
* 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):
* https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
*
* @return
*/
public String getJsapiTicket() {
String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
tokenUrl = tokenUrl + "&appid=" + appid + "&secret=" + secret;
JSONObject tokenJson=new JSONObject();
tokenJson=getUrlResponse(tokenUrl);
System.out.println("tokenJson:"+tokenJson.toString());
String token="";
try {
token=tokenJson.getString("access_token");
} catch (JSONException e) {
e.printStackTrace();
System.out.println("报错了");
return null;
} String jsapiTicketUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
JSONObject jsapiTickeJson=new JSONObject();
System.out.println("getJsapiTicket:获取token:"+token);
if(StringUtils.isNotBlank(token)){
jsapiTicketUrl = jsapiTicketUrl.replace("ACCESS_TOKEN",token);
jsapiTickeJson=getUrlResponse(jsapiTicketUrl);
System.out.println("tokenJson:"+jsapiTickeJson.toString());
try {
return (String) jsapiTickeJson.get("ticket");
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}else{
return null;
}
} private JSONObject getUrlResponse(String url){
CharsetHandler handler = new CharsetHandler("UTF-8");
try {
HttpGet httpget = new HttpGet(new URI(url));
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
//HttpClient
CloseableHttpClient client = httpClientBuilder.build();
client = (CloseableHttpClient) wrapClient(client);
return new JSONObject(client.execute(httpget, handler));
} catch (Exception e) {
e.printStackTrace();
return null;
}
} private static HttpClient wrapClient(HttpClient base) {
try {
SSLContext ctx = SSLContext.getInstance("TLSv1");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
return httpclient; } catch (Exception ex) {
return null;
}
} private class CharsetHandler implements ResponseHandler<String> {
private String charset; public CharsetHandler(String charset) {
this.charset = charset;
} public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity != null) {
if (!StringUtils.isBlank(charset)) {
return EntityUtils.toString(entity, charset);
} else {
return EntityUtils.toString(entity);
}
} else {
return null;
}
}
} }
页面主要代码、这里展示的是分享给朋友、分享到朋友圈代码,其他分享可以具体看官方接口代码
share.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>分享页面给朋友,朋友圈</title>
</head> <body> </body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script type="text/javascript">
$(function () {
//当前页面的url地址
var currUrl = decodeURIComponent(location.href.split('#')[0]);
$.ajax({
url: "/get_wx_config",
dataType : "json",
data: {
'url': currUrl
},
error: function (res) {
console.log(res);
alert("发生错误");
},
success: function (res) {
console.log(res);
var appId = res.appId;
var nonceStr = res.nonceStr;
var timestamp = res.timestamp;
var signature = res.signature;
wx.config({
debug: false, //开启调试模式,开发阶段可以改成true,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appId, //必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, //必填,生成签名的随机串
signature: signature, // 必填,签名,见附录1
jsApiList: [ //必填,需要使用的JS接口列表,所有JS接口列表 见附录2
'updateAppMessageShareData',
'updateTimelineShareData'
]
}); wx.ready(function () { //需在用户可能点击分享按钮前就先调用
//分享给朋友”及“分享到QQ”
wx.updateAppMessageShareData({
title: '朋友我是标题', // 分享标题
desc: '朋友 我是描述', // 分享描述
link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
success: function (res) {
// 设置成功
}
}) //分享到朋友圈”及“分享到QQ空间
wx.updateTimelineShareData({
title: '朋友圈我是标题', // 分享标题
link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
success: function (res) {
// 设置成功
}
}) }); wx.error(function (res) { });
}
}); }); </script>
</html>
设置公众号的js安全域名
把域名放进去,不用加http的前缀,点击保存即可
保存之前要把文件下载下来放到项目根目录下,如果是开发环境的springboot项目可以参照这个教程做
https://www.cnblogs.com/pxblog/p/13445128.html
JAVA调用微信接口实现页面分享功能(分享到朋友圈显示图片,分享给朋友)的更多相关文章
-
[实例]JAVA调用微信接口发送图文消息,不用跳到详情页
package com.test; import java.io.IOException; import java.io.InputStream; import java.io.OutputStrea ...
-
C# 调用微信接口的代码
调用微信接口前需要准备的内容. 1.微信公众平台的appid 2.微信公众平台的secret 3..获取tokenid 4.获取ticket 5.生成签名的随机串 6.生成签名的时间戳 7.生成签名 ...
-
C# 关于调用微信接口的代码
调用微信接口前需要准备的内容. 1.微信公众平台的appid 2.微信公众平台的secret 3..获取tokenid 4.获取ticket 5.生成签名的随机串 6.生成签名的时间戳 7.生成签名 ...
-
Java 调用http接口(基于OkHttp的Http工具类方法示例)
目录 Java 调用http接口(基于OkHttp的Http工具类方法示例) OkHttp3 MAVEN依赖 Http get操作示例 Http Post操作示例 Http 超时控制 工具类示例 Ja ...
-
Java调用webservice接口方法
java调用webservice接口 webservice的 发布一般都是使用WSDL(web service descriptive langu ...
-
C# 调用微信接口上传素材和发送图文消息
using Common;using Newtonsoft.Json.Linq;using System;using System.IO;using System.Net;using System.T ...
-
(二)通过JAVA调用SAP接口 (增加一二级参数)
(二)通过JAVA调用SAP接口 (增加一二级参数) 一.建立sap连接 请参考我的上一篇博客 JAVA连接SAP 二.测试项目环境准备 在上一篇操作下已经建好的环境后,在上面的基础上新增类即可 三. ...
-
Java调用RestFul接口
使用Java调用RestFul接口,以POST请求为例,以下提供几种方法: 一.通过HttpURLConnection调用 1 public String postRequest(String url ...
-
Android 仿微信朋友圈发表图片拖拽和删除功能
朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...
随机推荐
-
salesforce 零基础学习(五十九)apex:param使用以及相关的疑惑
做web项目难免要从一个页面传参数,解析参数中的值进行相关处理以后跳转到其他页面,VF中也不例外.使用传参的标签为apex:param. apex:param标签不可以单独使用,需要作为子标签嵌套在相 ...
-
Java事务处理全解析(四)—— 成功的案例(自己实现一个线程安全的TransactionManager)
在本系列的上一篇文章中我们讲到,要实现在同一个事务中使用相同的Connection对象,我们可以通过传递Connection对象的方式达到共享的目的,但是这种做法是丑陋的.在本篇文章中,我们将引入另外 ...
-
python基础知识讲解——@classmethod和@staticmethod的作用
python基础知识讲解——@classmethod和@staticmethod的作用 在类的成员函数中,可以添加@classmethod和@staticmethod修饰符,这两者有一定的差异,简单来 ...
-
完整的堆栈JavaScript路(十五)HTML5 focus 扩大 (扩展点)
HTML5 加入辅助管理 focus 产品特点, 有办法获得焦点文档; 页面加载,用户输入(通常由tab债券).和 调用代码focus()功能. HTML5新的属性和方法,辅助管理的重点: docu ...
-
201521123084 《Java程序设计》第5周学习总结
第5周-继承.多态.抽象类与接口 1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1. 代码阅读:Child压缩包内源代码 1.1 com.parent包中C ...
-
用sed实现wc -c的功能
sed是所谓的流编辑器,我们经常用它来做一些文本替换的事情,这是sed最擅长的事情,如sed 's/Bob/Tom/g'就是把文章中所有的Bob改成Tom. sed是图灵完备的,作为sed的粉丝,喜欢 ...
-
SDL 在指定窗口中绘图
SDL默认会自动创建绘图窗口,可以通过设置环境变量,让其在指定窗口绘图.代码如下: [cpp] view plaincopyprint? char sdl_var[64]; sprintf(sdl_v ...
-
solr界面
1.1 界面功能介绍 1.1.1 Analysis
-
[Ubuntu 14.04] 创建可以用于Android的WIFI热点
Ubuntu的网络管理为创建Wifi热点提供了方便,可是因为它用了ad-hoc网络,所以其创建的Wifi又不能让Android系统使用.这篇文字就是为了解决这个问题 1.Install AP-Host ...
-
poj2531(深搜剪枝)
题意就是把节点分成A.B两组,节点间距C给了,要求解分组的方法,使得∑Cij (i∈A,j∈B)最大. 首先把所有节点都放在一组,然后采用深度优先搜索的方法,对每一个节点都做判断是否应该移到另一组去, ...