【钉钉发送消息 上传文本 群主发送工具类】

钉钉发送消息 上传文本 群主发送工具类

package com.autoding.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkdrive_1_0.models.*;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;

@Slf4j
public class DingTalkUntil {

    /**
     * 测试数据
     */
    private final  static String appkey = "appkey";

    private final  static String appsecret = "appsecret";

    private final  static long AgentId = 1472988657L;

    private final  static String processCode = "PROC-C36472CE-19E6-4CAB-B3FE-27D6C709BEF0";

    private final  static String mobile = "mobile";


    /**
     * get请求
     * @param url
     * @return
     */
    public static JSONObject httpGet(String url){
        JSONObject jsonrResult = null;
        CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            CloseableHttpResponse response = closeableHttpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity, "UTF-8");
            jsonrResult = JSON.parseObject(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonrResult;
    }

    /**
     * POST请求
     * @param url
     * @param json
     * @return
     */
    public static JSONObject httpPost(String url, JSONObject json){
        CloseableHttpClient httpClient = HttpClients.createDefault();
        JSONObject jsonrResult = null;
        HttpPost httpPost = new HttpPost(url);
        try {
            if (null != json){
                StringEntity entity = new StringEntity(json.toString(),"utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
                CloseableHttpResponse response = httpClient.execute(httpPost);
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                    String result = EntityUtils.toString(response.getEntity(), "utf-8");
                    System.out.println("result:"+result);
                    jsonrResult = JSONObject.parseObject(result);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonrResult;
    }


   /* public static void main(String args[]){
        examine("11","22","33","55");
    }*/


    /**
     * 发起审批
     * @param spaceId
     * @param fileName
     * @param fileType
     * @param fileId
     * @return Boolean
     */
    public static boolean examine(String spaceId,String fileName,String fileType,String fileId){
        //文件上传盯盘 返回审批附件所需参数
        /*try {
            AddFileResponseBody result = upload("111", "222");
            System.out.println(result);
            spaceId = result.getSpaceId();
            fileName = result.getFileName();
            fileType = result.getFileType();
            fileId = result.getFileId();
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        //获取accessToken
        String access_tokenUrl = "https://oapi.dingtalk.com/gettoken?appkey="+appkey+"&appsecret="+appsecret;//在钉钉管理员后台中获取appkey和appsecret
        JSONObject access_token = DingTalkUntil.httpGet(access_tokenUrl);
        String accessToken = access_token.getString("access_token");
        //获取userid
        String getUseridurl = "https://oapi.dingtalk.com/user/get_by_mobile?access_token="+accessToken+"&mobile="+mobile;
        JSONObject useridJson = DingTalkUntil.httpGet(getUseridurl);
        String userid = useridJson.getString("userid");
        //发起审批
        String createApproval = "https://oapi.dingtalk.com/topapi/processinstance/create?access_token="+accessToken;
        //用JSONObject封装参数
        JSONObject jsonObject = new JSONObject();
        //封装userid
        jsonObject.put("originator_user_id",userid);
        //url中的process_code
        jsonObject.put("process_code",processCode);
        //所在部门根部门为-1
        //jsonObject.put("dept_id",deptId);
        jsonObject.put("dept_id",-1);
        jsonObject.put("title", "审批测试专用");
        //参数拼接
        JSONObject form_component_values2 = new JSONObject();
        //组件内容
        form_component_values2.put("name","标题");
        form_component_values2.put("value","梁浩测试审批666");
        //参数拼接
        JSONObject form_component_values3 = new JSONObject();
        //组件内容
        form_component_values3.put("name","日期");
        form_component_values3.put("value","2022-02-22");
        //参数拼接
        JSONObject form_component_values = new JSONObject();
        //组件内容
        form_component_values.put("name","内容");
        form_component_values.put("value","测试OA审批");
        //参数拼接
        JSONObject form_component_values4 = new JSONObject();
        //上传审批附件
        JSONObject jsonObjectFjian = new JSONObject();
        jsonObjectFjian.put("spaceId", spaceId);
        jsonObjectFjian.put("fileName", fileName);
        jsonObjectFjian.put("fileSize", "276297");
        //jsonObjectFjian.put("fileType", fileType);
        jsonObjectFjian.put("fileType", "xlsx");
        jsonObjectFjian.put("fileId", fileId);
        Object o[] = new Object[]{jsonObjectFjian};
        String strData = JSON.toJSONString(o);
        form_component_values4.put("name","附件");
        form_component_values4.put("value",strData);

        ArrayList<Object> list = new ArrayList<>();
        list.add(form_component_values);
        list.add(form_component_values2);
        list.add(form_component_values3);
        list.add(form_component_values4);

        jsonObject.put("form_component_values",list);
        System.out.println(jsonObject);
        JSONObject jsonObject1 = DingTalkUntil.httpPost(createApproval, jsonObject);

        System.out.println("返回结果=========="+jsonObject1);
        log.info("返回结果==========: {}", jsonObject1);
        if(jsonObject1.get("errcode").toString().equals("0")){
            //审批发起成功
            return true;
        }else{
            //审批发起失败
            return false;
        }

    }

    /**
     * 获取用户unionid
     * @param accessToken
     * @return
     */
    public static String getUnionid(String accessToken) {
        String unionid = null;
        try {
            //获取userid
            String getUseridurl = "https://oapi.dingtalk.com/user/get_by_mobile?access_token="+accessToken+"&mobile="+mobile;
            JSONObject useridJson = DingTalkUntil.httpGet(getUseridurl);
            String userid = useridJson.getString("userid");
            //获取用户UniID
            String createApproval = "https://oapi.dingtalk.com/topapi/v2/user/get?access_token="+accessToken;
            //用JSONObject封装参数
            JSONObject jsonObject = new JSONObject();
            //封装userid
            jsonObject.put("userid",userid);
            //组件内容
            JSONObject rsp = DingTalkUntil.httpPost(createApproval, jsonObject);
            System.out.println(rsp);
            log.info("rsp==========: {}", rsp);
            //json转MAP
            Map mapType = JSON.parseObject(String.valueOf(rsp),Map.class);
            Map resultMap = JSON.parseObject(String.valueOf(mapType.get("result")),Map.class);
            unionid = resultMap.get("unionid").toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return unionid;
    }


    /**
     * 使用 Token 初始化账号Client
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dingtalkdrive_1_0.Client createClient() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkdrive_1_0.Client(config);
    }

    public static String getSpaceId(String accessToken) throws Exception {

        String spaceId = null;
        com.aliyun.dingtalkdrive_1_0.Client client = Sample.createClient();
        ListSpacesHeaders listSpacesHeaders = new ListSpacesHeaders();

        listSpacesHeaders.xAcsDingtalkAccessToken = accessToken;
        String unionid = getUnionid(accessToken);
        ListSpacesRequest listSpacesRequest = new ListSpacesRequest()
                .setUnionId(unionid)
                .setSpaceType("org")
                .setMaxResults(50);
        try {
            ListSpacesResponse listSpacesResponse = client.listSpacesWithOptions(listSpacesRequest, listSpacesHeaders, new RuntimeOptions());
            System.out.println("listSpacesResponse=========="+listSpacesResponse.getBody().getSpaces().get(1).spaceId);
            log.info("listSpacesResponse==========: {}", listSpacesResponse.getBody().getSpaces().get(1).spaceId);
            spaceId = listSpacesResponse.getBody().getSpaces().get(1).spaceId;
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }
            log.info("listSpacesResponse err==========: {}", err);
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }
            log.info("listSpacesResponse err==========: {}", err);
        }

        return spaceId;
    }




    /**
     * 获取OSS临时凭证 获取文件上传信息
     * @param accessToken
     * @param unionid
     * @param fileName
     * @return
     * @throws Exception
     */
    public static GetUploadInfoResponseBody.GetUploadInfoResponseBodyStsUploadInfo  GetUploadInfo(String accessToken,String unionid,String fileName) throws Exception {

        com.aliyun.dingtalkdrive_1_0.Client client = Sample.createClient();
        GetUploadInfoHeaders getUploadInfoHeaders = new GetUploadInfoHeaders();
        getUploadInfoHeaders.xAcsDingtalkAccessToken = accessToken;
        String strMd5 = UUID.randomUUID().toString().replaceAll("-","").toUpperCase();
        GetUploadInfoRequest getUploadInfoRequest = new GetUploadInfoRequest()
                .setUnionId(unionid)
                .setFileName(fileName)
                .setFileSize(156L)
                .setMd5(strMd5);

        String spaceId = getSpaceId(accessToken);
        try {
            GetUploadInfoResponse uploadInfoWithOptions = client.getUploadInfoWithOptions(spaceId, "0", getUploadInfoRequest, getUploadInfoHeaders, new RuntimeOptions());
            log.info("uploadInfoWithOptions==========: {}", uploadInfoWithOptions.getBody().getStsUploadInfo());
            return uploadInfoWithOptions.getBody().getStsUploadInfo();
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }
            System.out.println(err);
            log.info("err==========: {}", err);

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }
            log.info("err==========: {}", err);
        }
        return null;
    }


     /**
     * 上传文件到钉钉网盘
     * @param fileName
     * @param filePath
     * @throws Exception
     */
    public static AddFileResponseBody upload(String fileName,String filePath) throws Exception {

        AddFileResponseBody addNewFileResponse = new AddFileResponseBody();

        com.aliyun.dingtalkdrive_1_0.Client client = Sample.createClient();
        AddFileHeaders addFileHeaders = new AddFileHeaders();

        fileName = "22222222入场模板template_1641967114820(1).xlsx";
        filePath = "C:/Users/Administrator/Desktop/22222222入场模板template_1641967114820(1).xlsx";

        String access_tokenUrl = "https://oapi.dingtalk.com/gettoken?appkey="+appkey+"&appsecret="+appsecret;//在钉钉管理员后台中获取appkey和appsecret
        JSONObject access_token = DingTalkUntil.httpGet(access_tokenUrl);
        String accessToken = access_token.getString("access_token");
        String unionid = getUnionid(accessToken);
        String spaceId = getSpaceId(accessToken);

        //1.调用获取文件上传信息接口,获取文件上传临时凭证。
        GetUploadInfoResponseBody.GetUploadInfoResponseBodyStsUploadInfo getUploadInfoResponseBodyStsUploadInfo = null;
        try {
            getUploadInfoResponseBodyStsUploadInfo = GetUploadInfo(accessToken,unionid,fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //2.根据返回的文件上传凭证,上传文件到钉盘空间。
        // 以下参数为步骤1返回的上传凭证
        // 阿里云账号的临时accessKeyId。
        String accessKeyId =  getUploadInfoResponseBodyStsUploadInfo.getAccessKeyId();
        // 阿里云账号的临时accessKeySecret。
        String accessKeySecret =  getUploadInfoResponseBodyStsUploadInfo.getAccessKeySecret();
        // 临时访问密钥。
        String securityToken = getUploadInfoResponseBodyStsUploadInfo.getAccessToken();
        // OSS访问域名。
        String endpoint = getUploadInfoResponseBodyStsUploadInfo.getEndPoint();
        // OSS存储空间。
        String bucket = getUploadInfoResponseBodyStsUploadInfo.getBucket();
        // 对应OSS Object Key,可用于刷新token以及调用添加文件(夹)接口添加文件记录。
        String ossKey = getUploadInfoResponseBodyStsUploadInfo.getMediaId();

        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret, securityToken);
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setProtocol(Protocol.HTTPS); // 注意, 需要是HTTPS
        OSSClient ossClient = new OSSClient(endpoint, credentialsProvider, clientConfiguration);
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, ossKey,new File(filePath));

        PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
        System.out.println("putObjectResult=========="+putObjectResult);
        log.info("putObjectResult==========: {}", putObjectResult);
        // 关闭OSSClient。
        ossClient.shutdown();


        //3.调用添加文件(夹)接口添加钉盘文件源信息。
        addFileHeaders.xAcsDingtalkAccessToken = accessToken;
        AddFileRequest addFileRequest = new AddFileRequest()
                .setParentId("0")
                .setFileType("file")
                .setFileName(fileName)
                .setMediaId(ossKey)
                .setAddConflictPolicy("autoRename")
                .setUnionId(unionid);
        try {

            AddFileResponse addFileResponse = client.addFileWithOptions(spaceId, addFileRequest, addFileHeaders, new RuntimeOptions());
            System.out.println("addFileResponse=========="+addFileResponse.getBody());
            log.info("addFileResponse==========: {}", addFileResponse.getBody());
            addNewFileResponse = addFileResponse.getBody();
            return addNewFileResponse;
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }
            log.info("err==========: {}", err);
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }
            log.info("err==========: {}", err);
        }
        return  addNewFileResponse;
    }


    /**
     * 钉钉发送信息
     * @param appkey
     * @param appsecret
     * @param title
     * @param content
     * @param mobiles
     * @return
     */
    public boolean sendDingTalk(String appkey,String appsecret,String title,String content,String mobiles) {

        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();

        String accessToken = getToken(appkey,appsecret);
        String[] dingMobiles = mobiles.split(",");
        String userid = null;
        StringBuffer sb = new StringBuffer();
        try{
            if(StringUtils.isNotEmpty(dingMobiles)){
                for(String info:dingMobiles){
                    //获取userid
                    String getUseridurl = "https://oapi.dingtalk.com/user/get_by_mobile?access_token="+accessToken+"&mobile="+info;
                    JSONObject useridJson = DingTalkUntil.httpGet(getUseridurl);
                    userid = useridJson.getString("userid");
                    sb.append(userid).append(",");
                }
            }
        }catch (Exception err){
            log.info("获取用户userId==========: {}", err);
            return false;
        }
        try{
            String userIds = sb.deleteCharAt(sb.length() - 1).toString();
            request.setAgentId(1472988657L);
            request.setUseridList(userIds);
            request.setToAllUser(false);
            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setMsgtype("markdown");
            msg.setMarkdown(new OapiMessageCorpconversationAsyncsendV2Request.Markdown());
            msg.getMarkdown().setTitle(title);
            msg.getMarkdown().setText(content);
            request.setMsg(msg);
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, accessToken);
            if(rsp.isSuccess()){
                log.info("发送请求response==========: {}", rsp.getBody());
                return true;
            }
            return false;
        }catch (Exception err){
            log.info("发送用户信息错误==========: {}", err);
            return false;
        }

    }


    /**
     * 获取token
     * @param appkey
     * @param appsecret
     * @return
     */
    public static String getToken (String appkey,String appsecret){
        Object object = LocalCacheClient.get("access_token");
        if(object != null){
            return object.toString();
        }
        DefaultDingTalkClient client = new
                DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(appkey);
        request.setAppsecret(appsecret);
        request.setHttpMethod("GET");
        try {
            //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的
            OapiGettokenResponse response = client.execute(request);
            LocalCacheClient.set("access_token", response.getAccessToken(),5200*1000);
            log.info("AccessToken==========: {}", response.getAccessToken());
            return response.getAccessToken();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;
    }
}



加密解密工具类

package com.autoding.common.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
* 钉钉开放平台加解密方法
* 在ORACLE官方网站下载JCE无限制权限策略文件
* JDK6的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
* JDK7的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
* JDK8的下载地址 https://www.oracle.com/java/technologies/javase-jce8-downloads.html
*/
public class DingCallbackCrypto {

private static final Charset CHARSET = Charset.forName("utf-8");
private static final Base64 base64 = new Base64();
private byte[] aesKey;
private String token;
private String corpId;
/**
* ask getPaddingBytes key固定长度
**/
private static final Integer AES_ENCODE_KEY_LENGTH = 43;
/**
* 加密随机字符串字节长度
**/
private static final Integer RANDOM_LENGTH = 16;

/**
* 构造函数
*
* @param token          钉钉开放平台上,开发者设置的token
* @param encodingAesKey 钉钉开放台上,开发者设置的EncodingAESKey
* @param corpId         企业自建应用-事件订阅, 使用appKey
*                       企业自建应用-注册回调地址, 使用corpId
*                       第三方企业应用, 使用suiteKey
*
* @throws DingTalkEncryptException 执行失败,请查看该异常的错误码和具体的错误信息
*/
public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException {
if (null == encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH) {
    throw new DingTalkEncryptException(DingTalkEncryptException.AES_KEY_ILLEGAL);
}
this.token = token;
this.corpId = corpId;
aesKey = Base64.decodeBase64(encodingAesKey + "=");
}

public Map<String, String> getEncryptedMap(String plaintext) throws DingTalkEncryptException {
return getEncryptedMap(plaintext, System.currentTimeMillis(), Utils.getRandomStr(16));
}

/**
* 将和钉钉开放平台同步的消息体加密,返回加密Map
*
* @param plaintext 传递的消息体明文
* @param timeStamp 时间戳
* @param nonce     随机字符串
* @return
* @throws DingTalkEncryptException
*/
public Map<String, String> getEncryptedMap(String plaintext, Long timeStamp, String nonce)
    throws DingTalkEncryptException {
if (null == plaintext) {
    throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL);
}
if (null == timeStamp) {
    throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_TIMESTAMP_ILLEGAL);
}
if (null == nonce) {
    throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL);
}
// 加密
String encrypt = encrypt(Utils.getRandomStr(RANDOM_LENGTH), plaintext);
String signature = getSignature(token, String.valueOf(timeStamp), nonce, encrypt);
Map<String, String> resultMap = new HashMap<String, String>();
resultMap.put("msg_signature", signature);
resultMap.put("encrypt", encrypt);
resultMap.put("timeStamp", String.valueOf(timeStamp));
resultMap.put("nonce", nonce);
return resultMap;
}

/**
* 密文解密
*
* @param msgSignature 签名串
* @param timeStamp    时间戳
* @param nonce        随机串
* @param encryptMsg   密文
* @return 解密后的原文
* @throws DingTalkEncryptException
*/
public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg)
    throws DingTalkEncryptException {
//校验签名
String signature = getSignature(token, timeStamp, nonce, encryptMsg);
if (!signature.equals(msgSignature)) {
    throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
// 解密
String result = decrypt(encryptMsg);
return result;
}

/*
* 对明文加密.
* @param text 需要加密的明文
* @return 加密后base64编码的字符串
*/
private String encrypt(String random, String plaintext) throws DingTalkEncryptException {
try {
    byte[] randomBytes = random.getBytes(CHARSET);
    byte[] plainTextBytes = plaintext.getBytes(CHARSET);
    byte[] lengthByte = Utils.int2Bytes(plainTextBytes.length);
    byte[] corpidBytes = corpId.getBytes(CHARSET);
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    byteStream.write(randomBytes);
    byteStream.write(lengthByte);
    byteStream.write(plainTextBytes);
    byteStream.write(corpidBytes);
    byte[] padBytes = PKCS7Padding.getPaddingBytes(byteStream.size());
    byteStream.write(padBytes);
    byte[] unencrypted = byteStream.toByteArray();
    byteStream.close();
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
    IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
    byte[] encrypted = cipher.doFinal(unencrypted);
    String result = base64.encodeToString(encrypted);
    return result;
} catch (Exception e) {
    throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR);
}
}

/*
* 对密文进行解密.
* @param text 需要解密的密文
* @return 解密得到的明文
*/
private String decrypt(String text) throws DingTalkEncryptException {
byte[] originalArr;
try {
    // 设置解密模式为AES的CBC模式
    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
    IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
    cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
    // 使用BASE64对密文进行解码
    byte[] encrypted = Base64.decodeBase64(text);
    // 解密
    originalArr = cipher.doFinal(encrypted);
} catch (Exception e) {
    throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR);
}

String plainText;
String fromCorpid;
try {
    // 去除补位字符
    byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr);
    // 分离16位随机字符串,网络字节序和corpId
    byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
    int plainTextLegth = Utils.bytes2int(networkOrder);
    plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
    fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
} catch (Exception e) {
    throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR);
}

// corpid不相同的情况
if (!fromCorpid.equals(corpId)) {
    throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR);
}
return plainText;
}

/**
* 数字签名
*
* @param token     isv token
* @param timestamp 时间戳
* @param nonce     随机串
* @param encrypt   加密文本
* @return
* @throws DingTalkEncryptException
*/
public String getSignature(String token, String timestamp, String nonce, String encrypt)
    throws DingTalkEncryptException {
try {
    String[] array = new String[] {token, timestamp, nonce, encrypt};
    Arrays.sort(array);
    System.out.println(JSON.toJSONString(array));
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < 4; i++) {
        sb.append(array[i]);
    }
    String str = sb.toString();
    System.out.println(str);
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    md.update(str.getBytes());
    byte[] digest = md.digest();

    StringBuffer hexstr = new StringBuffer();
    String shaHex = "";
    for (int i = 0; i < digest.length; i++) {
        shaHex = Integer.toHexString(digest[i] & 0xFF);
        if (shaHex.length() < 2) {
            hexstr.append(0);
        }
        hexstr.append(shaHex);
    }
    return hexstr.toString();
} catch (Exception e) {
    throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);
}
}

public static class Utils {
public Utils() {
}

public static String getRandomStr(int count) {
    String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    Random random = new Random();
    StringBuffer sb = new StringBuffer();

    for (int i = 0; i < count; ++i) {
        int number = random.nextInt(base.length());
        sb.append(base.charAt(number));
    }

    return sb.toString();
}

public static byte[] int2Bytes(int count) {
    byte[] byteArr = new byte[] {(byte)(count >> 24 & 255), (byte)(count >> 16 & 255), (byte)(count >> 8 & 255),
            (byte)(count & 255)};
    return byteArr;
}

public static int bytes2int(byte[] byteArr) {
    int count = 0;

    for (int i = 0; i < 4; ++i) {
        count <<= 8;
        count |= byteArr[i] & 255;
    }

    return count;
}
}

public static class PKCS7Padding {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final int BLOCK_SIZE = 32;

public PKCS7Padding() {
}

public static byte[] getPaddingBytes(int count) {
    int amountToPad = 32 - count % 32;
    if (amountToPad == 0) {
        amountToPad = 32;
    }

    char padChr = chr(amountToPad);
    String tmp = new String();

    for (int index = 0; index < amountToPad; ++index) {
        tmp = tmp + padChr;
    }

    return tmp.getBytes(CHARSET);
}

public static byte[] removePaddingBytes(byte[] decrypted) {
    int pad = decrypted[decrypted.length - 1];
    if (pad < 1 || pad > 32) {
        pad = 0;
    }

    return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}

private static char chr(int a) {
    byte target = (byte)(a & 255);
    return (char)target;
}
}

public static class DingTalkEncryptException extends Exception {
public static final int SUCCESS = 0;
public static final int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001;
public static final int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002;
public static final int ENCRYPTION_NONCE_ILLEGAL = 900003;
public static final int AES_KEY_ILLEGAL = 900004;
public static final int SIGNATURE_NOT_MATCH = 900005;
public static final int COMPUTE_SIGNATURE_ERROR = 900006;
public static final int COMPUTE_ENCRYPT_TEXT_ERROR = 900007;
public static final int COMPUTE_DECRYPT_TEXT_ERROR = 900008;
public static final int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009;
public static final int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010;
private static Map<Integer, String> msgMap = new HashMap();
private Integer code;

static {
    msgMap.put(0, "成功");
    msgMap.put(900001, "加密明文文本非法");
    msgMap.put(900002, "加密时间戳参数非法");
    msgMap.put(900003, "加密随机字符串参数非法");
    msgMap.put(900005, "签名不匹配");
    msgMap.put(900006, "签名计算失败");
    msgMap.put(900004, "不合法的aes key");
    msgMap.put(900007, "计算加密文字错误");
    msgMap.put(900008, "计算解密文字错误");
    msgMap.put(900009, "计算解密文字长度不匹配");
    msgMap.put(900010, "计算解密文字corpid不匹配");
}

public Integer getCode() {
    return this.code;
}

public DingTalkEncryptException(Integer exceptionCode) {
    super((String)msgMap.get(exceptionCode));
    this.code = exceptionCode;
}
}
static {
try {
    Security.setProperty("crypto.policy", "limited");
    RemoveCryptographyRestrictions();
} catch (Exception var1) {
}

}
private static void RemoveCryptographyRestrictions() throws Exception {
Class<?> jceSecurity = getClazz("javax.crypto.JceSecurity");
Class<?> cryptoPermissions = getClazz("javax.crypto.CryptoPermissions");
Class<?> cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission");
if (jceSecurity != null) {
    setFinalStaticValue(jceSecurity, "isRestricted", false);
    PermissionCollection defaultPolicy = (PermissionCollection)getFieldValue(jceSecurity, "defaultPolicy", (Object)null, PermissionCollection.class);
    if (cryptoPermissions != null) {
        Map<?, ?> map = (Map)getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class);
        map.clear();
    }

    if (cryptoAllPermission != null) {
        Permission permission = (Permission)getFieldValue(cryptoAllPermission, "INSTANCE", (Object)null, Permission.class);
        defaultPolicy.add(permission);
    }
}

}
private static Class<?> getClazz(String className) {
Class clazz = null;

try {
    clazz = Class.forName(className);
} catch (Exception var3) {
}

return clazz;
}
private static void setFinalStaticValue(Class<?> srcClazz, String fieldName, Object newValue) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & -17);
field.set((Object)null, newValue);
}
private static <T> T getFieldValue(Class<?> srcClazz, String fieldName, Object owner, Class<T> dstClazz) throws Exception {
Field field = srcClazz.getDeclaredField(fieldName);
field.setAccessible(true);
return dstClazz.cast(field.get(owner));
}

}

存储缓存工具类
package com.autoding.common.utils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class LocalCacheClient {
// 缓存map
private static Map<String, Object> cacheMap = new HashMap<String, Object>();
// 缓存有效期map
private static Map<String, Long> expireTimeMap = new HashMap<String, Long>();

/**
 * 获取指定的value,如果key不存在或者已过期,则返回null
 * @param key
 * @return
 */
public static Object get(String key) {
    if (!cacheMap.containsKey(key)) {
        return null;
    }
    if (expireTimeMap.containsKey(key)) {
        if (expireTimeMap.get(key) < System.currentTimeMillis()) { // 缓存失效,已过期
            return null;
        }
    }
    return cacheMap.get(key);
}

/**
 * @param key
 * @param <T>
 * @return
 */
public static <T> T getT(String key) {
    Object obj = get(key);
    return obj == null ? null : (T) obj;
}

/**
 * 设置value(不过期)
 * @param key
 * @param value
 */
public static void set(String key, Object value) {
    cacheMap.put(key, value);
}

/**
 * 设置value
 * @param key
 * @param value
 * @param millSeconds 过期时间(毫秒)
 */
public static void set(final String key, Object value, int millSeconds) {
    final long expireTime = System.currentTimeMillis() + millSeconds;
    cacheMap.put(key, value);
    expireTimeMap.put(key, expireTime);
    if (cacheMap.size() > 2) { // 清除过期数据
        new Thread(new Runnable() {
            public void run() {
                // 此处若使用foreach进行循环遍历,删除过期数据,会抛出java.util.ConcurrentModificationException异常
                Iterator<Map.Entry<String, Object>> iterator = cacheMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Object> entry = iterator.next();
                    if (expireTimeMap.containsKey(entry.getKey())) {
                        long expireTime = expireTimeMap.get(key);
                        if (System.currentTimeMillis() > expireTime) {
                            iterator.remove();
                            expireTimeMap.remove(entry.getKey());
                        }
                    }
                }
            }
        }).start();
    }
}

/**
 * key是否存在
 * @param key
 * @return
 */
public static boolean isExist(String key) {
    return cacheMap.containsKey(key);
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java发送HTTP请求的工具类是一种方便的编程工具,可以用于与Web服务器进行交互。这个工具类基于Java的网络编程API,可以发送不同类型的HTTP请求,如GET、POST等。 首先,我们需要使用Java中的URLConnection类来建立HTTP连接。使用URLConnection,我们可以指定请求的URL、请求的方法,以及其他相关的请求参数。然后,根据请求方法的不同,我们可以使用不同的方法来发送请求和接收响应。 对于GET请求,我们可以使用URLConnection的getInputStream()方法来获取服务器返回的响应数据。我们可以使用输入流来读取响应数据,并进行相应的处理操作。 对于POST请求,我们需要设置URLConnection的输出流,并将要发送的数据写入到输出流中。然后,我们可以使用URLConnection的getOutputStream()方法将数据发送给服务器。服务器收到数据后,可以进行相应的处理,并返回响应数据。我们可以使用URLConnection的getInputStream()方法来获取服务器返回的响应数据,并进行相应的处理操作。 此外,还可以通过设置请求头信息来发送特定类型的请求。可以通过URLConnection的setRequestProperty()方法来设置请求头信息,比如User-Agent、Content-Type等。这样,我们可以根据需求定制请求的特定信息。 最后,为了确保程序的稳定性和安全性,我们需要在代码中处理一些异常情况,比如网络连接超时、服务器错误等。可以使用try-catch语句来捕获异常,并进行相应的处理操作,比如重试、日志输出等。 综上所述,Java发送HTTP请求的工具类是一种方便的编程工具,可以用于与Web服务器进行交互。通过使用URLConnection类,我们可以发送不同类型的HTTP请求,并根据需求接收和处理服务器返回的响应数据。同时,我们还可以设置请求的特定信息,以满足不同的需求。在代码中,我们需要处理一些异常情况,以确保程序的稳定性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农汉子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值