微信小程序开发(一)系统对接微信UGC类小程序内容安全接口JAVA版

系统对接内容安全接口JAVA版



前言

写小程序的时候如果设计到发布文章内容和上传图片,类似微博,社区讨论时,就需要对用户的言论和发布图片进行审核,如果自己没有做校验审核,就要调用微信提供的内容安全接口,本文主要介绍文本和图片安全。


一、微信中UGC类小程序是什么?

微信说:小程序中的功能或服务中,涉及用户将自己自定义编辑的文字、图片、音频、视频等内容通过小程序进行展示或提供给其他用户的,属于UGC小程序。

二、微信内容安全接口是什么?

微信官方链接:https://developers.weixin.qq.com/miniprogram/dev/framework/msg_security.html

简单介绍:就是微信针对UGC类小程序发布的内容进行审核的接口,供开发者调用。

三、微信内容安全接口能干什么?

  1. (1)图片内容安全检测
  2. (2)文本内容安全检测
  3. (3)音频内容安全检测
  4. (4)图片内容安全检测

四、微信内容安全接口怎么使用?

微信官方开发文档:
图片检测接口(点击查看文档)
文本检测接口(点击查看文档)

1.准备工作

  • 引入Httpclient

代码如下(示例):

		<!--httpclient 依赖  通过httpclient进行接口调用 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>

		 <!--redis依赖  通过redis 实现缓存微信access_token-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2.编写所需代码

  • 创建业务Service
package com.ruoyi.apicampus.service;
import org.springframework.web.multipart.MultipartFile;
public interface WeixinCommonService {
    //获取小程序的accesstoken
    String getWeixinMiniprogramAccessToken(String wx_appid);
    //文本内容检测
    void weiXinCheckContent(String access_token,String content);
    //图片检测接口
    void weiXinCheckImg(String access_token, MultipartFile multipartFile);

}
  • 获取微信access_token(简单说就是调用凭证,你有了令牌才能调人家接口)
    微信官方介绍access_token:微信access_token介绍
  • 进行内容安全检测
  • 进行图片安全检测

代码如下(示例):

package com.ruoyi.apicampus.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.apicampus.config.SchoolCommonConfig;
import com.ruoyi.apicampus.mapper.SchoolMiniprogramApiMapper;
import com.ruoyi.apicampus.service.WeixinCommonService;
import com.ruoyi.apicampus.vo.SchoolMiniprogramVo;
import com.ruoyi.apicampus.wxcrypt.WeiXinUrlParam;
import com.ruoyi.apicampus.wxcrypt.WeixinCommonConfig;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.redis.RedisUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @description: 微信通用业务实现层
 * @author: Sun
 * @create: 2020-11-23 15:43
 **/

@Service
public class WeixinCommonServiceImpl implements WeixinCommonService {

    //log日志 本文不做解释  不需要可以删除
    private static final Logger log = LoggerFactory.getLogger(WeixinCommonServiceImpl.class);

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    SchoolMiniprogramApiMapper miniprogramApiMapper;

    @Override
    public String getWeixinMiniprogramAccessToken(String wx_appid) {
         //检验参数是否有误
        if ( StringUtils.isEmpty(wx_appid)){
            throw  new BusinessException("小程序配置信息有误~,请完善小程序配置信息,CODE:1000");
        }
        //获取小程序的api 密钥,我是存在数据库了  
        SchoolMiniprogramVo schoolMiniprogramVo = miniprogramApiMapper.querySchoolMiniprogramByWxAppid(wx_appid);
		//二次检测参数
        if (StringUtils.isNull(schoolMiniprogramVo)){
            throw  new BusinessException("小程序配置信息有误~,请完善小程序配置信息,CODE:1001");
        }
        //三次检测参数
        String wx_app_secret=schoolMiniprogramVo.getMiniprogramAPISecret();
        if ( StringUtils.isEmpty(wx_app_secret)){
            throw  new BusinessException("小程序配置信息有误~,请完善小程序配置信息,CODE:1002");
        }


        //redis 键名称(我是用appid + accessToken  作为键名)
        String token_key=wx_appid+"_accessToken";
        //如果redis 存在token 直接返回
        if (redisUtil.exists(token_key)){
            return redisUtil.get(token_key).toString();
        }else {
            //请求微信获取token URL
            String xcxGetAccessTokenUrl= WeiXinUrlParam.GET_MINIPROGRAM_ACCESS_TOKEN;
            //组装参数
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("grant_type", "client_credential");
            map.put("appid", wx_appid);
            map.put("secret", wx_app_secret);
            //获取session_key
            //注意:一般的接口用自己封装的http请求就行了
            String wx_token_info = HttpUtils.sendGet(xcxGetAccessTokenUrl,map);
            JSONObject tokenInfo = JSONObject.parseObject(wx_token_info);
            //用于测试
            //System.out.println("token对象="+tokenInfo);
            //请求成功  errcode = 0 时请求成功
            if (StringUtils.isNotEmpty(tokenInfo.getString("access_token")) ){
                String wx_access_token = tokenInfo.getString("access_token");
                redisUtil.set(token_key, wx_access_token, WeixinCommonConfig.WEIXIN_ACCESS_TOKEN_EXPIRED, TimeUnit.SECONDS);
                return wx_access_token;
            }else {
                String errcode = tokenInfo.getString("errcode");
                String errmsg = tokenInfo.getString("errmsg");
                //请求失败
                log.error("获取微信accesstoken出错,错误详情"+errmsg+",错误code:"+errcode);
                throw  new BusinessException("小程序配置信息有误~,错误详情:"+errmsg);
            }
        }
    }


    @Override
    public void weiXinCheckContent(String access_token, String content) {
        if ( StringUtils.isEmpty(access_token) || StringUtils.isEmpty(content)){
            throw  new BusinessException("小程序配置信息有误~,请完善小程序配置信息,CODE:1000");
        }
        //请求微信URL
        String MSG_CHECK_URL= WeiXinUrlParam.MSG_SEC_CHECK;
        try {
        	//创建http 请求
            CloseableHttpClient httpclient = HttpClients.createDefault();
            CloseableHttpResponse response = null;
            HttpPost request = new HttpPost(MSG_CHECK_URL+"?access_token=" + access_token);
            //设置响应头
            request.addHeader("Content-Type", "application/json");
			//组装参数
            Map<String, String> map = new HashMap<>();
            map.put("content",content);
            String body = JSONObject.toJSONString(map);
            request.setEntity(new StringEntity(body, ContentType.create("text/json", "UTF-8")));
            response = httpclient.execute(request);
            HttpEntity httpEntity = response.getEntity();
            String result = EntityUtils.toString(httpEntity, "UTF-8");// 转成string
            JSONObject msgInfo = JSONObject.parseObject(result);
            Object errcode = msgInfo.get("errcode");
            Object errmsg = msgInfo.get("errmsg");
            int errCode = (int) errcode;
            //SchoolCommonConfig是我自己写的通用参数
            //errcode 只有等于O 才是正常的
            if (errCode != SchoolCommonConfig.ZERO){
                log.error("发布内容调用微信接口出错,错误详情"+errmsg+",错误code:"+errcode);
                //此处是自定义异常  改成自己的就行
                throw  new BusinessException("发布内容含有违法违规内容,请修改内容后重新发布");
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw  new BusinessException("发布内容含有违法违规内容,请修改内容后重新发布");
        }
    }

    @Override
    public void weiXinCheckImg(String access_token, MultipartFile multipartFile) {
        if ( StringUtils.isEmpty(access_token) || StringUtils.isNull(multipartFile)){
            throw  new BusinessException("小程序配置信息有误~,请完善小程序配置信息,CODE:1000");
        }
        //请求微信URL
        String IMG_CHECK_URL= WeiXinUrlParam.IMG_SEC_CHECK;
        String contentType = multipartFile.getContentType();
        try {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            CloseableHttpResponse response = null;
            HttpPost request = new HttpPost(IMG_CHECK_URL+"?access_token=" + access_token);
            request.addHeader("Content-Type", "application/octet-stream");
            InputStream inputStream = multipartFile.getInputStream();
            byte[] byt = new byte[inputStream.available()];
            inputStream.read(byt);
            request.setEntity(new ByteArrayEntity(byt, ContentType.create(contentType)));
            response = httpclient.execute(request);
            HttpEntity httpEntity = response.getEntity();
            String result = EntityUtils.toString(httpEntity, "UTF-8");// 转成string
            JSONObject imgInfo = JSONObject.parseObject(result);
            String errmsg = imgInfo.getString("errmsg");
            String errcode = imgInfo.getString("errcode");
            //errcode 只有等于O 才是正常的
            if (!errcode.equals(SchoolCommonConfig.ZERO.toString())){
                log.error("上传图片调用微信接口出错,错误详情"+errmsg+",错误code:"+errcode);
                //此处是自定义异常  改成自己的就行
                throw  new BusinessException("上传的图片含有违法违规内容,请修改内容后重新发布");
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw  new BusinessException("上传的图片含有违法违规内容,请修改内容后重新发布");
        }
    }
}

3.可能用到的代码

  • 模拟Http请求工具类
package com.ruoyi.common.utils.http;

import java.io.*;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Set;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants;

/**
 * 通用http发送方法
 * 
 * @author sun
 */
public class HttpUtils
{
    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);


    /**
     * 将Map<String, String>转换为name=value&name=value形式的字符串
     * @param map
     * @return
     */
    public static String mapToParam(Map<String, Object> map){
        StringBuilder str = new StringBuilder();
        Set<String> set = map.keySet();
        for (String key : set) {
            str.append(key).append("=")
                    .append(map.get(key).toString()).append("&");
        }
        return str.toString().substring(0, str.lastIndexOf("&"));
    }




    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url 发送请求的 URL
     * @param paramMap 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, Map<String, Object> paramMap)
    {
        return sendGet(url, paramMap, Constants.UTF8);
    }

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url 发送请求的 URL
     * @param paramMap 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @param contentType 编码类型
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, Map<String, Object> paramMap, String contentType)
    {

        //map 转成参数
        String  param= mapToParam(paramMap);

        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try
        {
            String urlNameString = url + "?" + param;
            log.info("sendGet - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
            try
            {
                if (in != null)
                {
                    in.close();
                }
            }
            catch (Exception ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
     * @param paramMap 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, Map<String, Object> paramMap)
    {
        //map 转成参数
        String  param= mapToParam(paramMap);
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try
        {
            String urlNameString = url;
            log.info("sendPost - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
            }
            catch (IOException ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }



    public static String sendPost2(String url,String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
//      conn.setRequestProperty("Pragma:", "no-cache");
//      conn.setRequestProperty("Cache-Control", "no-cache");
//      conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }


    /**
     * json参数方式POST提交
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, JSONObject params){
        String strResult = "";
        // 1. 获取默认的client实例
        CloseableHttpClient client = HttpClients.createDefault();
        // 2. 创建httppost实例
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Content-Type", "application/json;charset=utf-8"); //添加请求头
        try {
            httpPost.setEntity(new StringEntity(params.toJSONString(),"utf-8"));
            CloseableHttpResponse resp = client.execute(httpPost);
            try {
                // 7. 获取响应entity
                HttpEntity respEntity = resp.getEntity();
                strResult = EntityUtils.toString(respEntity, "UTF-8");
            } finally {
                resp.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return strResult;
    }




    public static String sendSSLPost(String url, String param)
    {
        StringBuilder result = new StringBuilder();
        String urlNameString = url + "?" + param;
        try
        {
            log.info("sendSSLPost - {}", urlNameString);
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
            URL console = new URL(urlNameString);
            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);

            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String ret = "";
            while ((ret = br.readLine()) != null)
            {
                if (ret != null && !ret.trim().equals(""))
                {
                    result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
                }
            }
            log.info("recv - {}", result);
            conn.disconnect();
            br.close();
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
        }
        return result.toString();
    }

    private static class TrustAnyTrustManager implements X509TrustManager
    {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
        {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
        {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[] {};
        }
    }

    private static class TrustAnyHostnameVerifier implements HostnameVerifier
    {
        @Override
        public boolean verify(String hostname, SSLSession session)
        {
            return true;
        }
    }
}
  • Redis常用工具类
package com.ruoyi.common.utils.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @description: Redis常用工具类
 * @author: Sun
 * @create: 2020-11-23 15:31
 **/

@Component
public class RedisUtil {

    @Autowired
    RedisTemplate redisTemplate;
    /**
     * 写入缓存
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 写入缓存设置时效时间
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime , TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 批量删除对应的value
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }
    /**
     * 批量删除key
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0){
            redisTemplate.delete(keys);
        }
    }
    /**
     * 删除对应的value
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    /**
     * 判断缓存中是否有对应的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    /**
     * 读取缓存
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }
    /**
     * 哈希 添加
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value){
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
    }
    /**
     * 哈希获取数据
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey){
        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
        return hash.get(key,hashKey);
    }
    /**
     * 列表添加
     * @param k
     * @param v
     */
    public void lPush(String k,Object v){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k,v);
    }
    /**
     * 列表获取
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k,l,l1);
    }
    /**
     * 集合添加
     * @param key
     * @param value
     */
    public void add(String key,Object value){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key,value);
    }
    /**
     * 集合获取
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }
    /**
     * 有序集合添加
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key,Object value,double scoure){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key,value,scoure);
    }
    /**
     * 有序集合获取
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key,double scoure,double scoure1){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}
  • 字符串工具类
package com.ruoyi.common.utils;

import java.util.Collection;
import java.util.Map;
import com.ruoyi.common.core.text.StrFormatter;

/**
 * 字符串工具类
 *
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
    /** 空字符串 */
    private static final String NULLSTR = "";

    /** 下划线 */
    private static final char SEPARATOR = '_';

    /**
     * 获取参数不为空值
     * 
     * @param value defaultValue 要判断的value
     * @return value 返回值
     */
    public static <T> T nvl(T value, T defaultValue)
    {
        return value != null ? value : defaultValue;
    }

    /**
     * * 判断一个Collection是否为空, 包含List,Set,Queue
     * 
     * @param coll 要判断的Collection
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(Collection<?> coll)
    {
        return isNull(coll) || coll.isEmpty();
    }

    /**
     * * 判断一个Collection是否非空,包含List,Set,Queue
     * 
     * @param coll 要判断的Collection
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Collection<?> coll)
    {
        return !isEmpty(coll);
    }

    /**
     * * 判断一个对象数组是否为空
     * 
     * @param objects 要判断的对象数组
     ** @return true:为空 false:非空
     */
    public static boolean isEmpty(Object[] objects)
    {
        return isNull(objects) || (objects.length == 0);
    }

    /**
     * * 判断一个对象数组是否非空
     * 
     * @param objects 要判断的对象数组
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Object[] objects)
    {
        return !isEmpty(objects);
    }

    /**
     * * 判断一个Map是否为空
     * 
     * @param map 要判断的Map
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(Map<?, ?> map)
    {
        return isNull(map) || map.isEmpty();
    }

    /**
     * * 判断一个Map是否为空
     * 
     * @param map 要判断的Map
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Map<?, ?> map)
    {
        return !isEmpty(map);
    }

    /**
     * * 判断一个字符串是否为空串
     * 
     * @param str String
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(String str)
    {
        return isNull(str) || NULLSTR.equals(str.trim());
    }

    /**
     * * 判断一个字符串是否为非空串
     * 
     * @param str String
     * @return true:非空串 false:空串
     */
    public static boolean isNotEmpty(String str)
    {
        return !isEmpty(str);
    }

    /**
     * * 判断一个对象是否为空
     * 
     * @param object Object
     * @return true:为空 false:非空
     */
    public static boolean isNull(Object object)
    {
        return object == null;
    }

    /**
     * * 判断一个对象是否非空
     * 
     * @param object Object
     * @return true:非空 false:空
     */
    public static boolean isNotNull(Object object)
    {
        return !isNull(object);
    }

    /**
     * * 判断一个对象是否是数组类型(Java基本型别的数组)
     * 
     * @param object 对象
     * @return true:是数组 false:不是数组
     */
    public static boolean isArray(Object object)
    {
        return isNotNull(object) && object.getClass().isArray();
    }

    /**
     * 去空格
     */
    public static String trim(String str)
    {
        return (str == null ? "" : str.trim());
    }

    /**
     * 截取字符串
     * 
     * @param str 字符串
     * @param start 开始
     * @return 结果
     */
    public static String substring(final String str, int start)
    {
        if (str == null)
        {
            return NULLSTR;
        }

        if (start < 0)
        {
            start = str.length() + start;
        }

        if (start < 0)
        {
            start = 0;
        }
        if (start > str.length())
        {
            return NULLSTR;
        }

        return str.substring(start);
    }

    /**
     * 截取字符串
     * 
     * @param str 字符串
     * @param start 开始
     * @param end 结束
     * @return 结果
     */
    public static String substring(final String str, int start, int end)
    {
        if (str == null)
        {
            return NULLSTR;
        }

        if (end < 0)
        {
            end = str.length() + end;
        }
        if (start < 0)
        {
            start = str.length() + start;
        }

        if (end > str.length())
        {
            end = str.length();
        }

        if (start > end)
        {
            return NULLSTR;
        }

        if (start < 0)
        {
            start = 0;
        }
        if (end < 0)
        {
            end = 0;
        }

        return str.substring(start, end);
    }

    /**
     * 格式化文本, {} 表示占位符<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例:<br>
     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     * 
     * @param template 文本模板,被替换的部分用 {} 表示
     * @param params 参数值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... params)
    {
        if (isEmpty(params) || isEmpty(template))
        {
            return template;
        }
        return StrFormatter.format(template, params);
    }

    /**
     * 下划线转驼峰命名
     */
    public static String toUnderScoreCase(String str)
    {
        if (str == null)
        {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // 前置字符是否大写
        boolean preCharIsUpperCase = true;
        // 当前字符是否大写
        boolean curreCharIsUpperCase = true;
        // 下一字符是否大写
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++)
        {
            char c = str.charAt(i);
            if (i > 0)
            {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            }
            else
            {
                preCharIsUpperCase = false;
            }

            curreCharIsUpperCase = Character.isUpperCase(c);

            if (i < (str.length() - 1))
            {
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            }

            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
            {
                sb.append(SEPARATOR);
            }
            else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
            {
                sb.append(SEPARATOR);
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 是否包含字符串
     * 
     * @param str 验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inStringIgnoreCase(String str, String... strs)
    {
        if (str != null && strs != null)
        {
            for (String s : strs)
            {
                if (str.equalsIgnoreCase(trim(s)))
                {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
     * 
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String convertToCamelCase(String name)
    {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty())
        {
            // 没必要转换
            return "";
        }
        else if (!name.contains("_"))
        {
            // 不含下划线,仅将首字母大写
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String[] camels = name.split("_");
        for (String camel : camels)
        {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty())
            {
                continue;
            }
            // 首字母大写
            result.append(camel.substring(0, 1).toUpperCase());
            result.append(camel.substring(1).toLowerCase());
        }
        return result.toString();
    }

    /**
     * 驼峰式命名法
     * 例如:user_name->userName
     */
    public static String toCamelCase(String s)
    {
        if (s == null)
        {
            return null;
        }
        if (s.indexOf(SEPARATOR) == -1)
        {
            return s;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++)
        {
            char c = s.charAt(i);

            if (c == SEPARATOR)
            {
                upperCase = true;
            }
            else if (upperCase)
            {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            }
            else
            {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    @SuppressWarnings("unchecked")
    public static <T> T cast(Object obj)
    {
        return (T) obj;
    }
}

  • 小程序官方接口URL集合
package com.ruoyi.apicampus.wxcrypt;
/**
 * @description: 小程序官方接口URL集合
 * @author: Sun
 * @create: 2020-11-16 10:53
 **/
public class WeiXinUrlParam {
    /**
     *
     * 方法名称:获取小程序全局唯一后台接口调用凭据(access_token)。
     *
     * 功能描述:
     * 〈
     * 请求参数
     * 属性	类型	默认值	必填	说明
     * grant_type	string		是	填写 client_credential
     * appid	string		是	小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态)
     * secret	string		是	小程序唯一凭证密钥,即 AppSecret,获取方式同 appid
     * 返回值
     * Object
     * 返回的 JSON 数据包
     *
     * 属性	类型	说明
     * access_token	string	获取到的凭证
     * expires_in	number	凭证有效时间,单位:秒。目前是7200秒之内的值。
     * errcode	number	错误码
     * errmsg	string	错误信息
     *  〉
     *
     * @param null 1
     * @return :
     * @author : Sun
     * @date : 2020/11/23
     */
    public final static String GET_MINIPROGRAM_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token";

    /**
     * 方法名称:检查一段文本是否含有违法违规内容。
     * @author : Sun
     * @date : 2020/11/23
     */
    public final static String MSG_SEC_CHECK = "https://api.weixin.qq.com/wxa/msg_sec_check";

    /**
     * 
     * 方法名称:校验一张图片是否含有违法违规内容。
     * @author : Sun
     * @date : 2020/11/23
     */
    public final static String IMG_SEC_CHECK = "https://api.weixin.qq.com/wxa/img_sec_check";


  • 通用信息配置类
package com.ruoyi.apicampus.config;
/**
 * @description: 通用信息配置类
 * @author: Sun
 * @create:
 **/
public class SchoolCommonConfig {
    //返回类型为Integer, -1为错时使用
    public final static Integer  MINUS_ONE = -1;
    //Boolean
    public final static Boolean  TRUE = true;
    public final static Boolean  FALSE = false;
    //判断操作数据是否大于0,一到十
    public final static Integer  ZERO = 0;
    public final static Integer  ONE = 1;
    public final static Integer  TWO = 2;
    public final static Integer  THREE = 3;
    public final static Integer  FOUR = 4;
    public final static Integer  FIVE = 5;
    public final static Integer  SIX = 6;
    public final static Integer  SEVEN = 7;
    public final static Integer  EIGHT = 8;
    public final static Integer  NINE = 9;
    public final static Integer  TEN = 10;
}

总结

本文就是对微信小程序安全接口的总结,希望能对大家有所帮助,喜欢的可以点个赞~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜良配情深

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值