JAVA调用微信接口实现页面分享功能(分享到朋友圈显示图片,分享给朋友)

时间:2022-12-03 22:38:55

钉钉提供的内网穿透之HTTP穿透:https://www.cnblogs.com/pxblog/p/13862376.html

网页分享到微信中如何显示标题图,如果自定义标题图,描述,显示效果如下

JAVA调用微信接口实现页面分享功能(分享到朋友圈显示图片,分享给朋友)

官网接口地址;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 + "&timestamp=" + 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安全域名

JAVA调用微信接口实现页面分享功能(分享到朋友圈显示图片,分享给朋友)

JAVA调用微信接口实现页面分享功能(分享到朋友圈显示图片,分享给朋友)

JAVA调用微信接口实现页面分享功能(分享到朋友圈显示图片,分享给朋友)

把域名放进去,不用加http的前缀,点击保存即可

保存之前要把文件下载下来放到项目根目录下,如果是开发环境的springboot项目可以参照这个教程做

https://www.cnblogs.com/pxblog/p/13445128.html

JAVA调用微信接口实现页面分享功能(分享到朋友圈显示图片,分享给朋友)的更多相关文章

  1. &lbrack;实例&rsqb;JAVA调用微信接口发送图文消息,不用跳到详情页

    package com.test; import java.io.IOException; import java.io.InputStream; import java.io.OutputStrea ...

  2. C&num; 调用微信接口的代码

    调用微信接口前需要准备的内容. 1.微信公众平台的appid 2.微信公众平台的secret 3..获取tokenid 4.获取ticket 5.生成签名的随机串 6.生成签名的时间戳 7.生成签名 ...

  3. C&num; 关于调用微信接口的代码

    调用微信接口前需要准备的内容. 1.微信公众平台的appid 2.微信公众平台的secret 3..获取tokenid 4.获取ticket 5.生成签名的随机串 6.生成签名的时间戳 7.生成签名 ...

  4. Java 调用http接口(基于OkHttp的Http工具类方法示例)

    目录 Java 调用http接口(基于OkHttp的Http工具类方法示例) OkHttp3 MAVEN依赖 Http get操作示例 Http Post操作示例 Http 超时控制 工具类示例 Ja ...

  5. Java调用webservice接口方法

                             java调用webservice接口   webservice的 发布一般都是使用WSDL(web service descriptive langu ...

  6. C&num; 调用微信接口上传素材和发送图文消息

    using Common;using Newtonsoft.Json.Linq;using System;using System.IO;using System.Net;using System.T ...

  7. &lpar;二&rpar;通过JAVA调用SAP接口 &lpar;增加一二级参数&rpar;

    (二)通过JAVA调用SAP接口 (增加一二级参数) 一.建立sap连接 请参考我的上一篇博客 JAVA连接SAP 二.测试项目环境准备 在上一篇操作下已经建好的环境后,在上面的基础上新增类即可 三. ...

  8. Java调用RestFul接口

    使用Java调用RestFul接口,以POST请求为例,以下提供几种方法: 一.通过HttpURLConnection调用 1 public String postRequest(String url ...

  9. Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

随机推荐

  1. salesforce 零基础学习(五十九)apex&colon;param使用以及相关的疑惑

    做web项目难免要从一个页面传参数,解析参数中的值进行相关处理以后跳转到其他页面,VF中也不例外.使用传参的标签为apex:param. apex:param标签不可以单独使用,需要作为子标签嵌套在相 ...

  2. Java事务处理全解析(四)—— 成功的案例&lpar;自己实现一个线程安全的TransactionManager&rpar;

    在本系列的上一篇文章中我们讲到,要实现在同一个事务中使用相同的Connection对象,我们可以通过传递Connection对象的方式达到共享的目的,但是这种做法是丑陋的.在本篇文章中,我们将引入另外 ...

  3. python基础知识讲解——&commat;classmethod和&commat;staticmethod的作用

    python基础知识讲解——@classmethod和@staticmethod的作用 在类的成员函数中,可以添加@classmethod和@staticmethod修饰符,这两者有一定的差异,简单来 ...

  4. 完整的堆栈JavaScript路(十五)HTML5 focus 扩大 &lpar;扩展点&rpar;

    HTML5 加入辅助管理 focus 产品特点,  有办法获得焦点文档; 页面加载,用户输入(通常由tab债券).和 调用代码focus()功能. HTML5新的属性和方法,辅助管理的重点: docu ...

  5. 201521123084 《Java程序设计》第5周学习总结

    第5周-继承.多态.抽象类与接口 1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1. 代码阅读:Child压缩包内源代码 1.1 com.parent包中C ...

  6. 用sed实现wc -c的功能

    sed是所谓的流编辑器,我们经常用它来做一些文本替换的事情,这是sed最擅长的事情,如sed 's/Bob/Tom/g'就是把文章中所有的Bob改成Tom. sed是图灵完备的,作为sed的粉丝,喜欢 ...

  7. SDL 在指定窗口中绘图

    SDL默认会自动创建绘图窗口,可以通过设置环境变量,让其在指定窗口绘图.代码如下: [cpp] view plaincopyprint? char sdl_var[64]; sprintf(sdl_v ...

  8. solr界面

    1.1 界面功能介绍 1.1.1 Analysis

  9. &lbrack;Ubuntu 14&period;04&rsqb; 创建可以用于Android的WIFI热点

    Ubuntu的网络管理为创建Wifi热点提供了方便,可是因为它用了ad-hoc网络,所以其创建的Wifi又不能让Android系统使用.这篇文字就是为了解决这个问题 1.Install AP-Host ...

  10. poj2531&lpar;深搜剪枝&rpar;

    题意就是把节点分成A.B两组,节点间距C给了,要求解分组的方法,使得∑Cij (i∈A,j∈B)最大. 首先把所有节点都放在一组,然后采用深度优先搜索的方法,对每一个节点都做判断是否应该移到另一组去, ...