系统对接内容安全接口JAVA版
文章目录
前言
写小程序的时候如果设计到发布文章内容和上传图片,类似微博,社区讨论时,就需要对用户的言论和发布图片进行审核,如果自己没有做校验审核,就要调用微信提供的内容安全接口,本文主要介绍文本和图片安全。
一、微信中UGC类小程序是什么?
微信说:小程序中的功能或服务中,涉及用户将自己自定义编辑的文字、图片、音频、视频等内容通过小程序进行展示或提供给其他用户的,属于UGC小程序。
-
简单总结:内容安全接口的前提,是用于UGC类小程序,UGC小程序就是咱们开发的小程序带有自定义发布内容(包含图片,内容,视频)的小程序都是。
二、微信内容安全接口是什么?
微信官方链接:https://developers.weixin.qq.com/miniprogram/dev/framework/msg_security.html
简单介绍:就是微信针对UGC类小程序发布的内容进行审核的接口,供开发者调用。
三、微信内容安全接口能干什么?
- (1)图片内容安全检测
- (2)文本内容安全检测
- (3)音频内容安全检测
- (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;
}
总结
本文就是对微信小程序安全接口的总结,希望能对大家有所帮助,喜欢的可以点个赞~