微信分享链接自定义标题,内容,小图标.

注意:实现此功能需要准备一个认证过的微信公众号才可以.

  1. 在页面

微信分享链接自定义标题,内容,小图标._第1张图片


2.把下面js代码,放到页面中的


3.后台代码

@RequestMapping("/promote")
@Controller
//@ValidationLogin(isValidateLogin=false)//验证是否登录,
public class PromoteController {

    @RequestMapping("/getWXParam")
    @ResponseBody
    public Map getWXParam(String url){
        //ticket是公共的,所有用户进来用的都是一个ticket.微信官方规定ticket失效时间两小时,每天的获取次数也有限制,所以每次进入都先从redis中获取ticket,存取redis的方法需要根据自己项目修改.或者存到数据库中也可以.
        String ticket = RedisPoolTools.getRedis(RedisPoolTools.getDatabase(),"redis_ticket");
		//判断ticket是否失效
        if("".equals(ticket) || null == ticket){
            //微信公众号的appId和secret
            String appId =  "wx91fc8777e7516707";
            String secret= "254001781918a47a79643656226e8213";
			//请求微信官方接口,获取access_token
            String s = UrlTools.INSTANCE.httpURLConnection(null,null,"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+secret,"GET");
            JSONObject res1Json = JSONObject.parseObject(s);
            Map wxBack = (Map)res1Json;
            System.out.println("wxBack==="+wxBack);
            String access_token = wxBack.get("access_token").toString();
			
			//请求微信接口,获取ticket
            String url2 = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";
            System.out.println("获取jsapi_ticket的地址==="+url2);
            String res2 = UrlTools.INSTANCE.httpURLConnection(null, null, url2, "GET");
            System.out.println("获取jsapi_ticket的结果==="+res2);
            Map resMap2 = JsonUtil.parseJSON2Map(res2);
            try{
                ticket = resMap2.get("ticket").toString();
                //把取到的ticket存到redis中(ticket默认两小时失效),设置失效时间7140s,也就是119分钟
                RedisPoolTools.setRedis(RedisPoolTools.getDatabase(),"redis_ticket",ticket,7140);
            }catch (Exception e){
                throw new RuntimeException("获取jsapi_ticket失败!");
            }
        }
        //调用工具类
        return jsApiUtil.sign(ticket,url);
    }

}

注意:

  • 只有使用企业认证的公众号才能使用自定义图标,标题,内容的功能.代码中的appid和secret填写使用的公众号的.
  • 把线上服务器的ip地址和域名配置到公众号后台,把微信认证的一个.txt文件放到服务器的域名根目录下,我的项目springBoot项目,放在了服务器的static目录下了
    微信分享链接自定义标题,内容,小图标._第2张图片
  1. 1:使用的工具类1: jsApiUtil
public class jsApiUtil {

    public static Map sign(String jsapi_ticket, String url) {
        Map ret = new HashMap();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "×tamp=" + timestamp +
                "&url=" + url;
        System.out.println(string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        //Map wxInfo = WXInfoApplication.getWXInfo(CookieUtil.getWxRegion());
        //微信公众号的appid,使用时需要修改
        String appId =  "wx91fc8777e7516707";
        ret.put("url", url);
        ret.put("appId",appId);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

}

4.2:使用的工具类2,把json转成map

public class JsonUtil {

	
	/**
	 * json转map
	 * @param jsonStr
	 * @return
	 */
	public static Map parseJSON2Map(String jsonStr){  
		Map map = new HashMap();  
		if(jsonStr!=null && !jsonStr.equals("")){
			if(jsonStr.indexOf("[")==0){
				jsonStr=jsonStr.substring(1,jsonStr.length()-1);
			}
			//最外层解析  
			JSONObject json = JSONObject.fromObject(jsonStr);  
			for(Object k : json.keySet()){  
				 Object v = json.get(k);   
				 //如果内层还是数组的话,继续解析  
				 if(v instanceof JSONArray){  
					 List> list = new ArrayList>();  
					 Iterator it = ((JSONArray)v).iterator();
					 while(it.hasNext()){  
						 JSONObject json2 = it.next();  
						 list.add(parseJSON2Map(json2.toString()));  
					 }  
					 map.put(k.toString(), list);  
				 } else {  
					 if(v.equals(null)){
						 v=new String();
					 }
					 map.put(k.toString(), v);  
				 }  
			}  
		}
		return map;  
	} 
}

5.使用的工具类3:请求外部接口

public enum UrlTools {
	INSTANCE;
	/**
	 * lyc
	 * 接口调用  get/POST
	 */
	public String httpURLConnection (Map headers, String param, String url, String method) {

		String res = "";
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		HttpURLConnection connection = null;
		PrintWriter out = null;
		try {
			URL u = new URL(url);
			// 将url 以 open方法返回的urlConnection  连接强转为HttpURLConnection连接  (标识一个url所引用的远程对象连接)
			// 此时cnnection只是为一个连接对象,待连接中
			connection = (HttpURLConnection) u.openConnection();
			// 设置连接输出流为true,默认false (post 请求是以流的方式隐式的传递参数)
			connection.setDoOutput(true);
			// 设置连接输入流为true
			connection.setDoInput(true);
			// 设置请求方式为post
			connection.setRequestMethod(method);
			// post请求缓存设为false
			connection.setUseCaches(false);
			// 设置该HttpURLConnection实例是否自动执行重定向
			connection.setInstanceFollowRedirects(true);
			//addRequestProperty添加相同的key不会覆盖,如果相同,内容会以{name1,name2}
			connection.setRequestProperty("Accept", "*/*");
			connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
			if(null != headers){
				setProperty(headers,connection);
			}
			// 建立连接 (请求未开始,直到connection.getInputStream()方法调用时才发起,以上各个参数设置需在此方法之前进行)
			connection.setConnectTimeout(10000);
			connection.setReadTimeout(10000);

			if("POST".equals(method) || "PUT".equals(method) && null != param){
				out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(),"utf-8"));
				out.println(param);
				out.close();
			}
			if(connection.getResponseCode() == HttpURLConnection.HTTP_OK ||
					connection.getResponseCode() ==  HttpURLConnection.HTTP_CREATED ||
					connection.getResponseCode() ==  HttpURLConnection.HTTP_ACCEPTED){
				in = connection.getInputStream();
			}else{
				in = connection.getErrorStream();
			}

			isr = new InputStreamReader(in);
			br = new BufferedReader(isr);
			String line = "";
			StringBuilder content = new StringBuilder();
			while ((line = br.readLine()) != null) {
				content.append(line);
			}
			res = content.toString().trim();
			return res;
		} catch (Exception e) {
			//logger.error(" ** 接口访问失败 - "+url +"\r\n 错误信息:" + e.getClass()+" - "+e.getMessage());
			e.printStackTrace();
			throw new RuntimeException("接口访问失败");
		} finally {
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
				}
			}

			if (null != isr) {
				try {
					isr.close();
				} catch (IOException e) {
				}
			}
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
			if (null != out) {
				try {
					out.close();
				} catch (Exception e) {
				}
			}
			if(null != connection){
				try {
					connection.disconnect(); // 销毁连接
				} catch (Exception e) {
				}
			}
		}
	}
	//lyc
	private void setProperty(Map headers,HttpURLConnection connection){
		if(headers.containsKey("v")){
			connection.setRequestProperty("v",headers.get("v").toString());
		}
		if(headers.containsKey("p")){
			connection.setRequestProperty("p",headers.get("p").toString());
		}
		if(headers.containsKey("d")){
			connection.setRequestProperty("d",headers.get("d").toString());
		}
		if(headers.containsKey("t")){
			connection.setRequestProperty("t",headers.get("t").toString());
		}
		if(headers.containsKey("a")){
			connection.setRequestProperty("a",headers.get("a").toString());
		}
		if(headers.containsKey("Access-Control-Allow-Origin")){
			connection.setRequestProperty("Access-Control-Allow-Origin",headers.get("Access-Control-Allow-Origin").toString());
		}
        /*if(headers.containsKey("Content-Type")){
            connection.setRequestProperty("Content-Type",headers.get("Content-Type").toString());
        }*/
	}
}

注意:后台代码使用的时候需要修改的内容:

  • 存取redis的方式,改成自己的
  • 微信公众号的appid和secret改成你使用的公众号
  • 不要忘了把自己服务器的ip和项目域名配置公众号后台,进行认证.

前端代码使用注意:

  • 不要忘记引入使用微信的js文件jweixin-1.6.0.js
  • 修改后台请求路径
  • 修改js代码中的图标地址,编辑标题和内容文案.

6.成品
微信分享链接自定义标题,内容,小图标._第3张图片

你可能感兴趣的:(微信分享链接自定义标题,内容,小图标.)