package com.wechat.common; import java.io.UnsupportedEncodingException; import java.util.Calendar; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTCreationException; import com.wechat.activerequests.responses.MessageIdResponse; import com.wechat.common.utils.AESUtil; import com.wechat.common.utils.JacksonUtils; import com.wechat.common.utils.MessageUtils; import com.wechat.common.utils.NetworkUtils; import com.wechat.common.utils.NumberUtils; import com.wechat.common.utils.StringsUtils; import com.wechat.model.dbEntity.MdeLoginHis; import com.wechat.model.requestDto.TMsgSendBaseReq; import com.wechat.service.WeiXinService; import nl.basjes.parse.useragent.UserAgent; import nl.basjes.parse.useragent.UserAgentAnalyzer; /** * The common method shared in all project * * @author Administrator */ @Component public class CommonHelper { // url根目录 @Value("#{configProperties['hostPort']}") private String urlBase; // 模板消息发送用url @Value("#{configProperties['weixin.tmsg.send']}") private String tmsgSendUrl; // token过期时间 @Value("#{configProperties['token.expire.minute']}") private String tokenExpireTime; private static final Log log = LogFactory.getLog(CommonHelper.class); public String getIRealIPAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } // 如果通过多级反向代理,X-Forwarded-For的值不止一个,而是一串用逗号分隔的IP值,此时取X-Forwarded-For中第一个非unknown的有效IP字符串 if ((ip.indexOf(",") > -1)) { ip = ip.split(",")[0]; } return ip; } /** * 验证是否是手机号码 * * @param mobile * @return */ public boolean isMobile(String mobile) { Pattern p = null; Matcher m = null; p = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$"); // 验证手机号 m = p.matcher(mobile); return m.matches(); } /** * 取得完整的图片访问url * * @param mobile * @return */ public String getImgUrl(String urlChild) { return urlBase + urlChild; } /** * 模板消息推送 * * @param keyWord * 用户发送的信息 * @return */ public String send(TMsgSendBaseReq req) { String url = MessageUtils.getText(tmsgSendUrl, WeiXinService.getInstance().getAccessToken()); MessageIdResponse response = NetworkUtils.getRemoteResponseAsJson(url, req, MessageIdResponse.class); log.debug("Responded: " + JacksonUtils.beautifulSerialize(response)); // 模板消息推送出错 if (!StringsUtils.isEqual(Constants.STR_OK, Long.toString(response.getErrorCode()))) { log.error("模板消息推送异常:ErrorMsg=" + response.getErrorMsg() + "; ErrorCode=" + response.getErrorCode() + "; MessageId=" + response.getMessageId()); // 40001 的情况下强制重取token if (StringsUtils.isEqual(Constants.STR_TOKEN_ERO, Long.toString(response.getErrorCode()))) { WeiXinService.getInstance().updAccessTokenInfo(); url = MessageUtils.getText(tmsgSendUrl, WeiXinService.getInstance().getAccessToken()); } // 重新发送 response = NetworkUtils.getRemoteResponseAsJson(url, req, MessageIdResponse.class); log.error("模板消息重发:ErrorMsg=" + response.getErrorMsg() + "; ErrorCode=" + response.getErrorCode() + "; MessageId=" + response.getMessageId()); } return response.getErrorCode().toString(); } /** * token生成 * * @param userCode 用户code * @param req * @param identityFlag 个人企业区分 * @param creatDate 用户注册日期 * @return * @throws IllegalArgumentException * @throws JWTCreationException * @throws UnsupportedEncodingException */ public String getToken(String userCode, String identityFlag, String creatDate) throws IllegalArgumentException, JWTCreationException, UnsupportedEncodingException { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MINUTE, NumberUtils.stringToInt(tokenExpireTime, 120)); // 生成token 用户code拼上随机字符串进行md5加密 String token = JWT.create().withClaim(Constants.TOKEN_USER_ID, userCode).withClaim(Constants.TOKEN_IDENTITY_FLAG, identityFlag).withClaim(Constants.TOKEN_CREATDATE, creatDate).withExpiresAt(calendar.getTime()) .sign(Algorithm.HMAC512(Constants.TOKEN_KEY)); return token; } /** * ActivationToken生成 邮箱激活token * * @param userCode * 用户code * @return token * @throws UnsupportedEncodingException * @throws JWTCreationException * @throws IllegalArgumentException */ public String getActivationToken(String userCode) throws IllegalArgumentException, JWTCreationException, UnsupportedEncodingException { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, 5); // 生成token 用户code拼上随机字符串进行md5加密 String token = JWT.create().withClaim(Constants.ACTIVATION_TOKEN, userCode).withExpiresAt(calendar.getTime()) .sign(Algorithm.HMAC512(Constants.TOKEN_KEY)); return token; } /** * 获取客户端信息 * @param request * @return */ public MdeLoginHis getDeviceType(HttpServletRequest request) { MdeLoginHis his = new MdeLoginHis(); String agentString = request.getHeader("User-Agent"); UserAgentAnalyzer a = UserAgentAnalyzer.newBuilder().hideMatcherLoadStats().delayInitialization().build(); UserAgent userAgent = a.parse(agentString); // 浏览器信息 his.setBrowser(userAgent.getValue(UserAgent.AGENT_NAME)); his.setBrowserVersion(userAgent.getValue(UserAgent.AGENT_NAME_VERSION)); his.setIp(getIRealIPAddr(request)); // 设备信息 String deviceName = userAgent.getValue(UserAgent.DEVICE_NAME); String lower = agentString.toLowerCase(); if(lower.contains("devtool") || lower.contains("postman") || lower.contains("request") || lower.contains("debug") || lower.contains("api")) { deviceName = "IT人员!"; } his.setOperating(deviceName); // 设备类型 his.setDeviceClass(userAgent.getValue(UserAgent.DEVICE_CLASS)); // 操作系统信息 his.setSystem(userAgent.getValue(UserAgent.OPERATING_SYSTEM_NAME_VERSION)); his.setRemarks(agentString); return his; } /** * 根据shareJob 获取jobid * @param request * @return */ public int getJobId(String shareJob) { String jobId = shareJob.substring(10); return NumberUtils.stringToInt(jobId, 0); } /** * 获取分享用-用户code * Aes加密 * @param request * @return */ public String getShareCodeAes(String userCode, Date creatTime) { String shareCode = AESUtil.encrypt(userCode+Constants.UNDER_LINE+String.valueOf(creatTime.getTime()), Constants.AES_PASSWORD); return shareCode; } /** * 获取分享用-用户code * Aes解密 * @param request * @return */ public String[] getUserCodeAes(String shareCode) { /* * try { shareCode = URLDecoder.decode(shareCode,"utf-8"); } catch * (UnsupportedEncodingException e) { // TODO Auto-generated catch block * e.printStackTrace(); } */ String shareCodeStr = AESUtil.decryptStr(shareCode, Constants.AES_PASSWORD); return shareCodeStr.split(Constants.UNDER_LINE); } }