另外一种实现方式,更加简单,代码粘下来就可以用:【Java用法】拿来即用--使用Java开发连接钉钉H5微应用实现钉钉通知提醒的功能(方式二)
项目背景
springboot + maven + mybatis-plus + jdk1.8
步骤一、添加依赖
<!--钉钉通知使用--> <dependency> <groupId>com.aliyun</groupId> <artifactId>taobao-dingding</artifactId> <version>1.0.0</version> </dependency>
步骤二、添加使用的工具类
参考本文拓展里的内容
步骤三、添加配置文件config.properties
步骤四、在业务中添加发送钉钉通知的代码
/** * 保存考试人员或者部门后,如果开启钉钉通知,则开始开启另一条线程执行钉钉通知 * * @param dingUserIdList 人员列表 * @param deptList 部门列表 * @param exam 考试实例 */ private void executeDingDingInform(List<String> dingUserIdList, List<String> deptList, Exam exam) { ThreadUtil.excAsync(new Runnable() { @Override public void run() { StringBuilder sb = new StringBuilder(); if (dingUserIdList != null && dingUserIdList.size() > 0) { for (String dingUserId : dingUserIdList) { sb.append(dingUserId).append(","); } } if (deptList != null && deptList.size() > 0) { sb = getDeptAllDingUserId(deptList); } if (StrUtil.isNotBlank(sb)) { // 删除最后一个逗号 sb.deleteCharAt(sb.lastIndexOf(",")); List<Map<String, Object>> mapList = this.getDingDingInformContent(exam); DingTalkUtil.sendDingMsg("考试通知", sb.toString(), "", mapList, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); } } private List<Map<String, Object>> getDingDingInformContent(Exam exam) { List<Map<String, Object>> collectList = new ArrayList<>(); Date startTime = exam.getStartTime(); Date endTime = exam.getEndTime(); String title = exam.getTitle(); Integer totalTime = exam.getTotalTime(); String content = exam.getContent(); if (startTime != null && endTime != null) { collectList = DingDingMsg.create("考试名称:", title) .builder("考试时长:", totalTime.toString() + "分钟") .builder("开始时间:", DateUtil.format(startTime, "yyyy-MM-dd")) .builder("结束时间:", DateUtil.format(endTime, "yyyy-MM-dd")) .builder("考试描述:", content) .collect(); } else { collectList = DingDingMsg.create("考试名称:", title) .builder("考试时长:", totalTime.toString() + "分钟") .builder("考试描述:", content) .collect(); } return collectList; } }, true); }
拓展:
步骤二中使用的工具类有以下几个(Util.class,Properties.class,JsonUtils.class,DingTalkUtil.class,DingDingMsg.class)
package com.soft.exam.utility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.math.BigDecimal; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.DecimalFormat; import java.util.*; /** * <p>Util.java此类用于工具组件</p> * <p>@author:hhh</p> * <p>@date:2012-2-23</p> * <p>@remark:提供一些常用的时间和字符串方法</p> */ public class Util implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private final static Logger log = LoggerFactory.getLogger(Util.class); /** * 向HttpServletResponse中写数据,设置ContentType为html/txt;charset=utf-8 * @param response * @param text 要写入的数据 */ public static void writeUtf8Text(HttpServletResponse response, String text){ //response 相关处理 response.setContentType("html/text;charset=utf-8"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache, must-revalidate"); response.setHeader("Pragma", "no-cache"); try { response.getWriter().write(text); response.getWriter().flush(); response.getWriter().close(); } catch (IOException e) { log.error("修改数据流编码格式出错", e); } } /** * 向HttpServletResponse中写数据,设置ContentType为html/txt;charset=utf-8 * @param response * @param text 要写入的数据 */ public static void writeUtf8Html(HttpServletResponse response, String text){ //response 相关处理 response.setContentType("text/html;charset=utf-8"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache, must-revalidate"); response.setHeader("Pragma", "no-cache"); try { response.getWriter().write(text); response.getWriter().flush(); response.getWriter().close(); } catch (IOException e) { log.error("修改数据流编码格式出错", e); } } /** * 向HttpServletResponse中写数据,设置ContentType为application/json;charset=utf-8 * @param response * @param text 要写入的数据 */ public static void writeUtf8Json(HttpServletResponse response, String text){ //response 相关处理 response.setContentType("application/json;charset=utf-8"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache, must-revalidate"); response.setHeader("Pragma", "no-cache"); try { response.getWriter().write(text); response.getWriter().flush(); response.getWriter().close(); } catch (IOException e) { log.error("修改数据流编码格式出错", e); } } /** * 从输入流中获取数据 * @param inStream 输入流 * @return 读取输入流的byte数组结果 * @throws Exception */ public static byte[] readInputStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while( (len=inStream.read(buffer)) != -1 ){ outStream.write(buffer, 0, len); } inStream.close(); return outStream.toByteArray(); } /** * 安全分隔字符串方法 * @param s 字符串 * @param regex 分隔正则表达式 * @return 分割后的字符数组 */ public static String[] split(String s, String regex) { return split(s, regex, -1); } /** * 在第几位分隔字符串方法 * @param s 字符串 * @param regex 分隔正则表达式 * @param limit 限定起始下标 * @return 分割后字符数组 */ public static String[] split(String s, String regex, int limit) { if (null == s) { return null; } else { return s.split(regex, limit); } } /** * 处理字符串空指针 * @param s 字符串 */ public static String varFormat(String s) { if(s == null) { s = ""; } return s; } public static String varFormat(Object s) { if(s == null) { s = ""; } return s.toString(); } /** * 获取主机唯一标示,返回的格式为:H_123 ,123为主机的主键 * @param regSnId 主机主键Id * @return 返回处理后的主机主键格式 */ public static String getHostUq(Object regSnId){ return "H_"+varFormat(regSnId); } public static String getVoicUq(Object voicBxoId){ return "V_"+varFormat(voicBxoId); } /** * 获取主机名称 格式:SHCS_HOST_NAME_123,123为主机主键 * @param regSnId 主机主键Id * @return 返回处理后的主机名称 */ public static String getHostName(String regSnId){ return "SHCS_HOST_NAME_"+regSnId; } /** * 转换字符串为大写 * @param s 处理后字符串 */ public static String toUpperCase(String s) { return varFormat(s).toUpperCase(); } /** * 转换字符串为小写 * @param s 处理后的字符串 */ public static String toLowerCase(String s) { return varFormat(s).toLowerCase(); } /** * 获取固定长度字符串 * @param s 字符串 * @param len 长度 * @return 截取后的字符 */ public static String limitFormat(String s, int len) { return limitFormat(s, len, true, ""); } /** * 获取固定长度字符串 * @param s 字符串 * @param len 长度 * @param c 后缀 * @return 截取后的字符 */ public static String limitFormat(String s, int len, String c) { return limitFormat(s, len, true, c); } /** * 获取固定长度字符串 * @param s 字符串 * @param len 长度 * @param b 方向 * @return 截取后字符串 */ public static String limitFormat(String s, int len, boolean b) { return limitFormat(s, len, b, ""); } /** * 获取固定长度字符串 * @param s 字符串 * @param len 长度 * @param b 方向 * @param c 前/后缀 * @return 截取后字符串 */ public static String limitFormat(String s, int len, boolean b, String c) { s = varFormat(s); c = varFormat(c); if(s.length() > len) { //需要截取 if(b) { //从前向后截取 if("".equals(c)) { return (s.substring(0, len)); } else { //加后缀 return (s.substring(0, len)+c); } } else { //从后向前截取 if("".equals(c)) { return (s.substring(s.length()-len, s.length())); } else { //加前缀 return (c+s.substring(s.length()-len, s.length())); } } } else { //不需要截取 return (s); } } /** * 处理字符串符合URL格式 * @param s 字符串 * @return 处理后字符串 */ public static String urlFormat(String s) { return varFormat(s).replaceAll("&", "%26"); } /** * 处理字符串符合XML格式 * @param s 字符串 * @param c 需要编码字符 * @return 处理后字符串 */ public static String xmlFormat(String s, String c) { s = varFormat(s); c = varFormat(c); if (c.indexOf("&") != -1) { s = s.replaceAll("&", "&"); } if (c.indexOf("<") != -1) { s = s.replaceAll("<", "<"); } if (c.indexOf(">") != -1) { s = s.replaceAll(">", ">"); } if (c.indexOf("\"") != -1) { s = s.replaceAll("\"", """); } if (c.indexOf("'") != -1) { s = s.replaceAll("'", "'"); } if (c.indexOf(" ") != -1) { s = s.replaceAll(" ", " "); } return s; } /** * 处理字符串符合XML格式 * @param s 字符串 * @return 处理后字符串 */ public static String xmlFormat(String s) { return xmlFormat(s, "<'&\">"); } /** * 处理字符串符合XML格式且不生成空字符串 * @param s 字符串 * @param c 需要编码字符 * @return 处理后字符串 */ public static String xmlSpanFormat(String s, String c) { s = xmlFormat(s, c); if("".equals(s)) { s = " "; } return s; } /** * 处理字符串符合XML格式且不生成空字符串 * @param s 字符串 * @return 处理后字符串 */ public static String xmlSpanFormat(String s) { s = xmlFormat(s); if("".equals(s)) { s = " "; } return s; } /** * 处理字符串符合JavaScript的字符串格式 * @param s 字符串 * @return 处理后字符串 */ public static String jsStringFormat(String s) { if(s == null) { s = ""; } else { s = s.trim(); s = s.replaceAll("\\\\", "\\\\\\\\"); s = s.replaceAll("\b", "\\\\b"); s = s.replaceAll("\f", "\\\\f"); s = s.replaceAll("\n", "\\\\n"); s = s.replaceAll("\r", "\\\\r"); s = s.replaceAll("\t", "\\\\t"); s = s.replaceAll("'", "\\\\'"); s = s.replaceAll("\"", "\\\\\""); } return s; } /** * 处理符合SQL字符格式由12,33转变为:'12','34' * @param s * @return 处理后字符串 */ public static String sqlStrFormat(String s) { if ("".equals(varFormat(s))) { return null; } String str[] = s.split(","); StringBuffer sql = new StringBuffer(); for(int i=0;i<str.length;i++){ sql.append("'"); sql.append(str[i]); sql.append("'"); //最后一个不在添加"," if(i!=(str.length-1)){ sql.append(","); } } return sql.toString(); } /** * 获取当前年份 * @return 返回年份 */ public static String getYear(){ Calendar cal = Calendar.getInstance(); int year = cal.get(Calendar.YEAR)+1; return year+""; } /** * 将十六进制字符串转行成字节 * @param hexString 十六进制字符串 * @return 处理后的字节数组 */ public static byte[] hexStringToBytes(String hexString) { if (hexString == null || "".equals(hexString)) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } /** * char 转换byte字节 * @param c char类型 * @return 处理后的字节 */ public static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } /** * 将字节转行成十六进制字符串 * @param src 字节数组 * @return 处理后的十六进制字符串 */ public static String bytesToHexString(byte[] src){ StringBuffer stringBuilder = new StringBuffer(500); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } /** * 16进制转换10进制 * @param str16 十六进制字符串 * @return 处理后的十进制类型 */ public static Integer getFrom16ToData(String str16){ return Integer.valueOf(str16.trim(),16); } /** * 将字符串转换字节 * @param str 字符串 * @return 处理后的byte数组 */ public static byte[] stringToBytes(String str){ byte[] buf = null; if("".equals(varFormat(str))){ buf = new byte[0]; return buf; } try { buf = str.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return buf; } /** * 将字节转换字符串 * @param data 字节数组 * @param charset 转换字符串格式 utf-8 、gbk等等 * @return 转换后的字符串 */ public static String byteToString(byte[] data, String charset){ if(isEmpty(data)){ return ""; } if(isEmpty(charset)){ return new String(data); } try { return new String(data, charset); } catch (UnsupportedEncodingException e) { System.out.println("byteToString:"+e); return new String(data); } } /** * 判断输入的字节数组是否为空 * * @param bytes 字节数组 * @return boolean 空则返回true,非空则flase */ public static boolean isEmpty(byte[] bytes){ return null==bytes || 0==bytes.length; } /** * 判断输入的字符串参数是否为空 * * @param input 字符串 * @return boolean 空则返回true,非空则flase */ public static boolean isEmpty(String input) { return null==input || 0==input.length() || 0==input.replaceAll("\\s", "").length(); } /** * 保留几位小数 * @param number * @param formNum 要保留的个数 * @return 返回doble类型 */ public static double getDobuleNumber(double number, int formNum){ BigDecimal T = new BigDecimal(number); double formartNumber = T.setScale(formNum,BigDecimal.ROUND_HALF_UP).doubleValue(); return formartNumber; } /** * 字节转换bite * @param b * @return byte转换字符串 */ public static String byteToBit(byte b) { return "" +(byte)((b >> 7) & 0x1) + (byte)((b >> 6) & 0x1) + (byte)((b >> 5) & 0x1) + (byte)((b >> 4) & 0x1) + (byte)((b >> 3) & 0x1) + (byte)((b >> 2) & 0x1) + (byte)((b >> 1) & 0x1) + (byte)((b >> 0) & 0x1); } /** * short 类型转换byte数组 * @param s * @return 返回byte数组 */ public static byte[] shortToByteArray(short s) { /* byte[] targets = new byte[2]; for (int i = 0; i < 2; i++) { int offset = (targets.length - 1 - i) * 8; targets[i] = (byte) ((s >>> offset) & 0xff); } */ //小端 byte[] targets = new byte[2]; targets[0] = (byte) (0xff & s); targets[1] = (byte) ((0xff00 & s) >> 8); return targets; } /** * 根据short类型转换btye数组 * @param number * @return 返回byte数组 */ public static byte[] shortToByte(short number) { int temp = number; byte[] b = new byte[2]; for (int i = 0; i < b.length; i++) { b[i] = new Integer(temp & 0xff).byteValue();// 将最低位保存在最低位 temp = temp >> 8; // 向右移8位 } return b; } /** * int 类型转换byte数组 * @param intValue * @return 返回btye数组 */ public static byte[] int2Byte(int intValue) { byte[] b = new byte[4]; /* for (int i = 0; i < 4; i++) { b[i] = (byte) (intValue >> 8 * (3 - i) & 0xFF); //System.out.print(Integer.toBinaryString(b[i])+" "); //System.out.print((b[i] & 0xFF) + " "); }*/ b[0] = (byte) (intValue & 0xff); b[1] = (byte) (intValue >> 8 & 0xff); b[2] = (byte) (intValue >> 16 & 0xff); b[3] = (byte) (intValue >> 24 & 0xff); return b; } /** * 4位字节数组转换为整型 * @param b * @return 返回int类型 */ public static int byte2Int(byte[] b) { /* int intValue = 0; for (int i = 0; i < b.length; i++) { intValue += (b[i] & 0xFF) << (8 * (3 - i)); } return intValue;*/ int resInt = 0;//结合变量 byte btemp; for (int i = 0; i < 4; i++) { btemp = b[i]; resInt += (btemp & 0xFF) << (8 * i); } return resInt; } /** * 转换为short类型 * @param b * @return 返回short类型 */ public static short byte2Short(byte[] b) { return (short) (((b[0 + 1] << 8) | b[0 + 0] & 0xff)); // return (short) (((b[0] << 8) | b[0 + 1] & 0xff)); // 大端 /*short res; res = (short) (b[0] & 0xff); res |= ((b[1] << 8) & 0xff); return res;*/ } /** * 根据传过来5个int参数转换成short类型 ,此方法适合前导数据,数据标示类型转换成short * @param dataType 数据类型 * @param protocolType 协议类性 * @param senderType 发送类型 * @param enType 是否加密 * @param coType 是否压缩 * @return 根据移位返回short类型 */ public static short buildShort(int dataType, int protocolType, int senderType, int enType, int coType) { short type = 0;//数据类型 //移位操作 左移n int 左侧高位丢丢失几位,右侧高位就 补几个0 type |= (dataType << 0); type |= (protocolType << 4); type |= (senderType << 8); type |= (enType << 12); type |= (coType << 14); return type; } /** * 把ip地址存入到4个字节里面,如:192.168.1.123 * @param IP1 如第一位192 * @param IP2 如ip第二位168 * @param IP3 1 * @param IP4 如123 * @return 根据移为把ip地址存储4个字节里面 */ public static int buildIPAddr(int IP1, int IP2, int IP3, int IP4) { int type = 0;//数据类型 //移位操作 左移n int 左侧高位丢丢失几位,右侧高位就 补几个0 type |= (IP1 << 0); type |= (IP2 << 8); type |= (IP3 << 16); type |= (IP4 << 24); return type; } /** * 骆驼峰结构: 比如gmt_modify ==> gmtModify * @param columName * @return 返回骆驼峰结构字符串 */ public static String camelName(String columName) { columName = columName.toLowerCase(); char[] chars = columName.toCharArray(); char[] result = new char[chars.length]; int curpos = 0; boolean upperCaseNext = false; for(char ch:chars){ if(ch == '_'){ upperCaseNext = true; }else if(upperCaseNext){ result[curpos++] = Character.toUpperCase(ch); upperCaseNext = false; }else{ result[curpos++] = ch; } } return new String(result,0,curpos); } /** * 除去数组中的空值和签名参数 * @param sArray 签名参数组 * @return 去掉空值与签名参数后的新签名参数组 */ public static Map<String, Object> paraFilter(Map<String, Object> sArray) { Map<String, Object> result = new HashMap<String, Object>(); if (sArray == null || sArray.size() <= 0) { return result; } for (String key : sArray.keySet()) { String value = Util.varFormat(sArray.get(key)); if (value == null || "".equals(value)) { continue; } result.put(key, value); } return result; } /** * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串 * @param params 需要排序并参与字符拼接的参数组 * @return 拼接后字符串 */ public static String createLinkString(Map<String, Object> params) { List<String> keys = new ArrayList<String>(params.keySet()); Collections.sort(keys); String prestr = ""; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = Util.varFormat(params.get(key)); if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符 prestr = prestr + key + "=" + value; } else { prestr = prestr + key + "=" + value + "&"; } } return prestr; } /** * MD5加密,可返回32位、16位根据需要调整 * @param sourceStr * @return 返回32位的md5值 */ public static String strToMd5(String sourceStr) { String result = ""; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.update(sourceStr.getBytes()); byte b[] = md.digest(); int i; StringBuffer buf = new StringBuffer(100); for (int offset = 0; offset < b.length; offset++) { i = b[offset]; if (i < 0) { i += 256; } if (i < 16) { buf.append("0"); } buf.append(Integer.toHexString(i)); } result = buf.toString(); System.out.println("MD5(" + sourceStr + ",32) = " + result); System.out.println("MD5(" + sourceStr + ",16) = " + buf.toString().substring(8, 24)); } catch (NoSuchAlgorithmException e) { System.out.println(e); } return result; } /** * 将指定字符串src,以每两个字符分割转换为16进制形式 如:"2B44EFD9" –> byte[]{0x2B, 0×44, 0xEF, * 0xD9} * @param src * String * @return byte[] */ public static byte[] HexString2Bytes(String src) { if (null == src || 0 == src.length()) { return null; } byte[] ret = new byte[src.length() / 2]; byte[] tmp = src.getBytes(); for (int i = 0; i < (tmp.length / 2); i++) { ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]); } return ret; } /** * 将两个ASCII字符合成一个字节; 如:"EF"–> 0xEF * @param src0 * byte * @param src1 * byte * @return byte */ public static byte uniteBytes(byte src0, byte src1) { byte _b0 = Byte.decode("0x" + new String(new byte[] {src0})).byteValue(); _b0 = (byte) (_b0 << 4); byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 })).byteValue(); byte ret = (byte) (_b0 ^ _b1); return ret; } /** * * 保留2位有效数据 * @param data * @return 获取保留2位的字符串 */ public static String getTwoDoble(double data){ DecimalFormat df = new DecimalFormat("######0.00"); return df.format(data); } //implements Serializable /* private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException,IOException { ois.defaultReadObject(); }*/ /** * 拼接日志字符串 * @param fieldsMap * @param map * @param valueMap * @return */ public static String jointLogContent(Map fieldsMap,Map<String, String> map,Map<String, String> valueMap){ StringBuilder content = new StringBuilder(); if (map.size() > 0) { for (Map.Entry<String, String> entry : map.entrySet()) { if (null != fieldsMap.get(entry.getKey())) { content.append(fieldsMap.get(entry.getKey())); content.append(entry.getValue()); content.append(valueMap.get(entry.getKey())); content.append(";"); } } } return content.toString(); } }
package com.soft.exam.utility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.Properties; /** * <p>PropertiesUtil.java此类用于加载系统属性文件</p> * <p>@author:hhh</p> * <p>@date:2015年11月23日</p> * <p>@remark:</p> */ public class PropertiesUtil { public static final Logger logger = LoggerFactory.getLogger(PropertiesUtil.class); static Properties prop = new Properties(); static{ try { // path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获 prop.load(PropertiesUtil.class.getResourceAsStream("/config.properties")); } catch (IOException e) { logger.error("加载系统属性文件失败", e); } } public static String getValue(String key){ String str = prop.getProperty(key); if (str == null) { str = ""; } return str; } }
package com.soft.exam.utility; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author <a href="https://github.com/binarywang">Binary Wang</a> */ public class JsonUtils { private static Logger logger = LogManager.getLogger(JsonUtil.class); private static ObjectMapper objectMapper = new ObjectMapper(); public static String objectTojson(Object object) { return JSON.toJSONString(object, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteDateUseDateFormat); } public static String listTojson(List list) { return JSON.toJSONString(list, SerializerFeature.WriteDateUseDateFormat); } /** * 把json数据转换成类 T * * @param json * @param clazz * @return */ public static <T> T fromJson(String json, Class<T> clazz) { return JSON.parseObject(json, clazz); } /** * 把json数据转换成 list<T> 类型 * * @param json * @param clazz * @return */ public static <T> List<T> fromJsonToList(String json, Class<T> clazz) { return JSON.parseArray(json, clazz); } /** * 字符串Json格式转换为对象Map * * @param strJson {"username":"sxb"} * @return */ public static Map<String, Object> jsonToMap(String strJson) { Map<String, Object> jsoMap = new HashMap<String, Object>(); try { jsoMap = JSONObject.parseObject(strJson, Map.class); //jsoMap = JSONArray.parseObject(strJson,Map.class); } catch (JSONException e) { logger.error("Json格式转换为对象Map入参strJson打印:{}", strJson); logger.error("Json格式转换为对象Map异常", e); } return jsoMap; } /** * 字符串Json 转换为对象List * * @param strJson [{"username":"sxb"}] * @return */ public static List<Map<String, Object>> jsonToList(String strJson) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); try { list = JSONObject.parseObject(strJson, List.class); } catch (JSONException e) { logger.error("Json转换为对象List入参strJson打印:{}", strJson); logger.error("Json转换为对象List异常", e); } return list; } /** * Json字符数组 转换为对象list * * @param * @return */ public static List<Map<String, Object>> jsonarrToList(String strJson) { List<Map<String, Object>> listObjectSec = new ArrayList<Map<String, Object>>(); try { listObjectSec = JSONArray.parseObject(strJson, List.class); } catch (JSONException e) { logger.error("Json转换为对象List入参strJson打印:{}", strJson); logger.error("Json转换为对象List异常", e); } System.out.println(listObjectSec); return listObjectSec; } /** * 将json转换成对象Class * * @param src * @param clazz * @param <T> * @return */ public static <T> T jsonToObject(String src, Class<T> clazz) { if (src == null || src == "" || clazz == null) { return null; } try { return clazz.equals(String.class) ? (T) src : objectMapper.readValue(src, clazz); } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) { String strArr = "[{\"0\":\"zhangsan\",\"1\":\"lisi\",\"2\":\"wangwu\",\"3\":\"maliu\"}," + "{\"00\":\"zhangsan\",\"11\":\"lisi\",\"22\":\"wangwu\",\"33\":\"maliu\"}]"; //jsonarrToList(strArr); jsonarrToList(strArr); } }
package com.soft.exam.utility; import cn.hutool.core.util.StrUtil; import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.request.CorpMessageCorpconversationAsyncsendRequest; import com.dingtalk.api.response.CorpMessageCorpconversationAsyncsendResponse; import com.taobao.api.ApiException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.List; import java.util.Map; /** * <p>DingTalkUtil.java此类用于钉钉自定义机器人</p> * <p>@author:hhh</p> * <p>@date:2018年8月20日</p> * <p>@remark:</p> */ public class DingTalkUtil { private final static Logger log = LoggerFactory.getLogger(DingTalkUtil.class); private static long agentId; private static String corpId; private static String corpSecret; private static String serverUrl; static { agentId = Long.parseLong(PropertiesUtil.getValue("dingtalk.agentid")); corpId = PropertiesUtil.getValue("dingtalk.corpid"); corpSecret = PropertiesUtil.getValue("dingtalk.corpsecret"); serverUrl = PropertiesUtil.getValue("dingtalk.serverurl"); } /** * 向钉钉发送消息 * * @param title 标题 * @param userList 用户Id 多个人用逗号隔开 333,444 * @param connect 内容 * @param author 发送的作者,如果无 可为空"" */ public static void sendDingMsg(String title, String userList, String connect, List<Map<String, Object>> fromList, String author) { DingTalkClient client = new DefaultDingTalkClient(serverUrl); CorpMessageCorpconversationAsyncsendRequest req = new CorpMessageCorpconversationAsyncsendRequest(); req.setMsgtype("oa"); // 188915017L req.setAgentId(agentId); req.setUseridList(userList); req.setToAllUser(false); Map<String, Object> msgMap = new HashMap<>(); msgMap.put("message_url", ""); Map<String, Object> headMap = new HashMap<>(); headMap.put("bgcolor", "FFBBBBBB"); headMap.put("text", title); msgMap.put("head", headMap); Map<String, Object> bodyMap = new HashMap<>(); bodyMap.put("title", title); bodyMap.put("form", fromList); bodyMap.put("content", connect); bodyMap.put("author", author); msgMap.put("body", bodyMap); req.setMsgcontentString(JsonUtils.objectTojson(msgMap)); CorpMessageCorpconversationAsyncsendResponse rsp; try { // 是否开启钉钉提醒 String isOpen = PropertiesUtil.getValue("dingtalk.isopen"); if (StrUtil.isNotBlank(isOpen) && "true".equals(isOpen)) { rsp = client.execute(req, getDingToken()); log.info(rsp.getBody()); } } catch (ApiException e) { // TODO Auto-generated catch block e.printStackTrace(); log.error("sendDingMsg=-", e); } } /** * 向钉钉发送消息 * * @param title 标题 * @param userList 用户Id 多个人用逗号隔开 333,444 * @param connect 内容 * @param author 发送的作者,如果无 可为空"" * @param token 令牌,减少令牌调用次数 */ public static void sendDingMsg(String title, String userList, String connect, List<Map<String, Object>> fromList, String author, String token) { DingTalkClient client = new DefaultDingTalkClient(serverUrl); CorpMessageCorpconversationAsyncsendRequest req = new CorpMessageCorpconversationAsyncsendRequest(); req.setMsgtype("oa"); req.setAgentId(agentId); req.setUseridList(userList); req.setToAllUser(false); Map<String, Object> msgMap = new HashMap<>(); msgMap.put("message_url", ""); Map<String, Object> headMap = new HashMap<>(); headMap.put("bgcolor", "FFBBBBBB"); headMap.put("text", title); msgMap.put("head", headMap); Map<String, Object> bodyMap = new HashMap<>(); bodyMap.put("title", title); bodyMap.put("form", fromList); bodyMap.put("content", connect); bodyMap.put("author", author); msgMap.put("body", bodyMap); req.setMsgcontentString(JsonUtils.objectTojson(msgMap)); CorpMessageCorpconversationAsyncsendResponse rsp; try { // 是否开启钉钉提醒 String isOpen = PropertiesUtil.getValue("dingtalk.isopen"); if (StrUtil.isNotBlank(isOpen) && "true".equals(isOpen)) { rsp = client.execute(req, token); log.info(rsp.getBody()); } } catch (ApiException e) { // TODO Auto-generated catch block e.printStackTrace(); log.error("sendDingMsg=-", e); } } /** * 获取叮叮令牌 * * @return */ public static String getDingToken() { String result = ""; String line; StringBuffer sb = new StringBuffer(); BufferedReader in = null; Map<String, Object> rMap = new HashMap<>(); try { String url = "https://oapi.dingtalk.com/gettoken?corpid=" + corpId + "&corpsecret=" + corpSecret; URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 设置请求格式 conn.setRequestProperty("contentType", "utf-8"); conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); //设置超时时间 conn.setConnectTimeout(6000); conn.setReadTimeout(6000); // 建立实际的连接 conn.connect(); // 定义 BufferedReader输入流来读取URL的响应,设置接收格式 in = new BufferedReader(new InputStreamReader( conn.getInputStream(), "utf-8")); while ((line = in.readLine()) != null) { sb.append(line); } result = sb.toString(); rMap = JsonUtils.jsonToMap(result); } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return Util.varFormat(rMap.get("access_token")); } public static void main(String[] args) { DingTalkUtil dingTalkUtil = new DingTalkUtil(); // System.out.println(dingTalkUtil.getDingToken()); } }
package com.soft.exam.utility; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 构建钉钉发送消息 * * @author hhh * @date 2019-04-24 */ public class DingDingMsg { private List<Map<String, Object>> mapList = new ArrayList<>(); private DingDingMsg() { } public static DingDingMsg create(String key, String value) { return (new DingDingMsg()).builder(key, value); } public DingDingMsg builder(String key, String value) { Map<String, Object> map = new HashMap<>(); map.put("key", key); map.put("value", value); mapList.add(map); return this; } public List<Map<String, Object>> collect() { return this.mapList; } }