Java 集成企业微信消息推送功能

1. 自己注册企业微信公司和应用

这个地方可以参考https://blog.csdn.net/zxl782340680/article/details/79876502
这篇文章把前面注册写的很详细,后面代码也有借鉴价值

2. 获取 token

token 是关键码 在企业微信的开发文档中说明每次获取的 token 的有效期是 7200s(2h), 而且获取 token 在一天中还受次数限制所以在开发过程中要使用 redis 缓存进行处理
这个 bo 是发送给企业微信的对象

package com.bo;

public class WeChatDataBO {
	 //发送微信消息的URLString sendMsgUrl="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";
    /**
     * 成员账号
     */
    private String touser;
    /**
     * 消息类型
     */
    private String msgtype;
    /**
     * 企业应用的agentID
     */
    private int agentid;
    /**
     * 实际接收Map类型数据
     */
    private Object text;
    
    private Object file;
 
    public Object getText() {
        return text;
    }
    public void setText(Object text) {
        this.text = text;
    }
    public String getMsgtype() {
        return msgtype;
    }
    public void setMsgtype(String msgtype) {
        this.msgtype = msgtype;
    }
    public int getAgentid() {
        return agentid;
    }
    public void setAgentid(int agentid) {
        this.agentid = agentid;
    }
    public String getTouser() {
        return touser;
    }
    public void setTouser(String touser) {
        this.touser = touser;
    }
	public Object getFile() {
		return file;
	}
	public void setFile(Object file) {
		this.file = file;
	}
}

这个 bo 是一些企业微信地址

package com.bo;

public class WeChatUrlDataBO {

    String corpid;
    String corpsecret;
    String Get_Token_Url;
    String SendMessage_Url;

    public String getCorpid() {
        return corpid;
    }
    public void setCorpid(String corpid) {
        this.corpid = corpid;
    }
    public String getCorpsecret() {
        return corpsecret;
    }
    public void setCorpsecret(String corpsecret) {
        this.corpsecret = corpsecret;
    }
    public void setGet_Token_Url(String corpid,String corpsecret) {
        this.Get_Token_Url ="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+corpid+"&corpsecret="+corpsecret;
    }
    public String getGet_Token_Url() {
        return Get_Token_Url;
    }
    public String getSendMessage_Url(){
        SendMessage_Url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";
        return SendMessage_Url;
    }

} 

获取企业微信 token

	//获取企业微信token
	//获取企业微信token
	public String getToken(){

		String token ="";
		//判断redis缓存里面的是否失效
		 Jedis redis=new Jedis("127.0.0.1");		 
		 if(redis.exists("qywxToken")){
			 token= redis.get("qywxToken");
		 }else{
			 String qyId = iSysParamManager.getClientParamValByCode("QYWX_QY");
			 if(qyId==null||"".equals(qyId))
			 {
				throw new MestarException("请在客户端参数维护企业微信企业Id信息QYWX_QY!");
			 }
			 String yyId = iSysParamManager.getClientParamValByCode("QYWX_YY");
			 if(yyId==null||"".equals(yyId))
			 {
				throw new MestarException("请在客户端参数维护企业微信应用Id信息QYWX_YY!");
			 }
	        WeChatUrlDataBO uData = new WeChatUrlDataBO();
	        uData.setGet_Token_Url(qyId,yyId);    
	        try {
	        	token = toAuth(uData.getGet_Token_Url());
	            try{
	                Map<String, Object> map = gson.fromJson(token,new TypeToken<Map<String, Object>>() {}.getType());
	                token = map.get("access_token").toString();
	                }catch (Exception e) {      
	            }
	        	//更新缓存
	        	redis.set("qywxToken",token);
	        	redis.expire("qywxToken", 3600);
			} catch (IOException e) {
				e.printStackTrace();
			}
		 }		
	return token;
	}

Jedis 是 redis 的工具类,直接下载 jar 包使用即可
Jedis 学习可以参考https://www.cnblogs.com/tengfly/p/9307373.html

3. 企业微信发送文件

这个是先把文件上传到企业微信的服务器上,服务器返回一个文件 Id,然后我们发送信息的时候把 id 带上即可

public JSONObject UploadMeida(String fileType, String filePath,String token) throws Exception {
		// 返回结果
		String result = null;
		File file = new File(filePath);
		if (!file.exists() || !file.isFile()) {

			throw new IOException("文件不存在");
		}
		String uploadTempMaterial_url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
		uploadTempMaterial_url = uploadTempMaterial_url.replace("ACCESS_TOKEN", token).replace("TYPE", fileType);
		URL url = new URL(uploadTempMaterial_url);
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.setRequestMethod("POST");// 以POST方式提交表单
		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setUseCaches(false);// POST方式不能使用缓存
        // 设置请求头信息
		conn.setRequestProperty("Connection", "Keep-Alive");
		conn.setRequestProperty("Charset", "UTF-8");
        // 设置边界
		String BOUNDARY = "----------" + System.currentTimeMillis();
		conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
        // 请求正文信息
        // 第一部分
		StringBuilder sb = new StringBuilder();
		sb.append("--");// 必须多两条道
		sb.append(BOUNDARY);
		sb.append("\r\n");
		sb.append("Content-Disposition: form-data;name=\"media\"; filename=\"" + file.getName() + "\"\r\n");
		sb.append("Content-Type:application/octet-stream\r\n\r\n");

         // 获得输出流
		OutputStream out = new DataOutputStream(conn.getOutputStream());
        // 输出表头
		out.write(sb.toString().getBytes("UTF-8"));
        // 文件正文部分
       	// 把文件以流的方式 推送道URL中
		DataInputStream din = new DataInputStream(new FileInputStream(file));
		int bytes = 0;
		byte[] buffer = new byte[1024];
		while ((bytes = din.read(buffer)) != -1) {
			out.write(buffer, 0, bytes);
		}
		din.close();
       // 结尾部分
		byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");// 定义数据最后分割线
		out.write(foot);
		out.flush();
		out.close();
		if (HttpsURLConnection.HTTP_OK == conn.getResponseCode()) {

			StringBuffer strbuffer = null;
			BufferedReader reader = null;
			try {
				strbuffer = new StringBuffer();
				reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				String lineString = null;
				while ((lineString = reader.readLine()) != null) {
					strbuffer.append(lineString);

				}
				if (result == null) {
					result = strbuffer.toString();

				}
			} catch (IOException e) {

				e.printStackTrace();
			} finally {
				if (reader != null) {
					reader.close();
				}
			}

		}
		JSONObject jsonObject = JSONObject.parseObject(result);
		return jsonObject;

	} 

4. 发送数据的方法

 public String createpostdata(String touser, String msgtype,
        int application_id, String contentKey ,String contentValue) {
		WeChatDataBO wcd = new WeChatDataBO();
		wcd.setTouser(touser);
		wcd.setAgentid(application_id);
		wcd.setMsgtype(msgtype);
		Map<Object, Object> content = new HashMap<Object, Object>();
		content.put(contentKey,contentValue);
		if("content".equals(contentKey)){
			wcd.setText(content);
		}else{
			wcd.setFile(content);
		}
		return gson.toJson(wcd);
    }
    
    
    /**
     * @Title  创建微信发送请求post实体
     * charset消息编码    ,contentType消息体内容类型,
     * url微信消息发送请求地址,data为post数据,token鉴权token
     * @return String
     */
    public String post(String charset, String contentType, String url,
                       String data,String token) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        httpPost = new HttpPost(url+token);
        httpPost.setHeader(CONTENT_TYPE, contentType);
        httpPost.setHeader("charset", "utf-8");
        httpPost.setEntity(new StringEntity(data,charset));

        CloseableHttpResponse response = httpclient.execute(httpPost);
        String resp="";
        try {
            HttpEntity entity = response.getEntity();
            try {
				resp = EntityUtils.toString(entity, charset);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            EntityUtils.consume(entity);
        } finally {
            response.close();
        return resp;
    }
   }

5. 总方法

    public void sendQywxData(){

		 int yyNum =xxxx;//企业微信应用编码
    	 //1.查询需要发送的信息
    	String hql=" from  Qywx t where t.sendQty<5 and t.state <>2";
    	List<Qywx> sendList=this.dao.getCurrentSession().createQuery(hql).list();
    	if(sendList.size()>0){
    		//获取token
    		String token=getToken();
    		for(MesToQywx wx:sendList){
    		//对于要发送的数据进行处理
    		String toUser=wx.getTouser();
    		int type=wx.getMsgtype();
    		String msgtype="text";
    		String data=wx.getContent();
    		String temp="content";
    		if(type==1){
    			msgtype="file";
    			temp="media_id";
    			try {
					data=UploadMeida(msgtype, wx.getContent(),token).get("media_id").toString();
				} catch (Exception e) {
					e.printStackTrace();
				}
    		}	
    		String sendDate=createpostdata(toUser,msgtype,yyNum,temp,data);
    		String resp="";
    		//开始发送数据
    		try {
				 resp=post("utf-8",CONTENT_TYPE,(new WeChatUrlDataBO()).getSendMessage_Url(),sendDate,token);
			} catch (IOException e) {

				e.printStackTrace();
			}
    		if(resp!=null&&!"".equals(resp)){
    			 Map<String, Object> map = new HashMap<String, Object>();
    			 map = gson.fromJson(resp, map.getClass());
    			 //对发送结果进行处理
    			 String errcode = map.get("errcode") == null ? null : map.get("errcode").toString();
    			 String errmsg = map.get("errmsg") == null ? null : map.get("errmsg").toString();
    			 wx.setSendQty(wx.getSendQty()+1);	 
    			 wx.setMessage(errmsg);
    			 if("0.0".equals(errcode)){
    				 wx.setState(2);
    			 }else{
    				 wx.setState(1);
    			 }
    		}
    	  }
    	}
    	if(sendList.size()>0){
    		this.dao.saveAll(sendList);
    	}
    }

企业微信对象

package com.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

import com.epichust.mestar.domain.BaseEntity;
@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true)
@Table(name = "QYWX")
public class Qywx {
    
	private static final long serialVersionUID = 1L;

	private String touser;//成员账号
    
    private Integer msgtype;//信息类型(1.file,0.text)
    
    private String content;//发送内容
    
    private Integer state;// 状态  发送状态(0未发送  1 已发送发送失败  2 已发送发送成功)
    
	private String message;// 消息
	
	private Integer sendQty;// 发送次数
	@Column(name = "USER_CODE")
	public String getTouser() {
		return touser;
	}

	public void setTouser(String touser) {
		this.touser = touser;
	}
	@Column(name = "MSG_TYPE")
	public Integer getMsgtype() {
		return msgtype;
	}

	public void setMsgtype(Integer msgtype) {
		this.msgtype = msgtype;
	}
	@Column(name = "SEND_CONTENT")
	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	@Column(name = "STATE")
	public Integer getState() {
		return state;
	}

	public void setState(Integer state) {
		this.state = state;
	}

	@Column(name = "MESSAGE")
	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	@Column(name = "SEND_QTY")
	public Integer getSendQty() {
		return sendQty;
	}

	public void setSendQty(Integer sendQty) {
		this.sendQty = sendQty;
	}
	
	
	
	
	
    
}