天天看点

springboot接入华为云短信

#记一次接入华为云短信

几个月前,也就是公司网站第一个版本上线的时候,当时有业务需要短信验证,于是购买了华为云的短信业务.在此简单的记录一下华为云短信api的接入,比较简单,拿来就可以用

这里我首先定义了一个实体类,方便参数注入
           
public class SmsConfig {

	//短信发送apiURI
	private String url;
	
	//APP_Key
	private String appKey; 
	
	//APP_Secret
    private String appSecret ; 
    
    //国内短信签名通道号或国际/港澳台短信通道号
    private String sender ; 
    
    //模板ID
    private String templateId ; 
    
    //签名名称
    private String signature;
    
    //返回信息回调URI
    //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
    private String statusCallBack;
	
}
           

这是首先要定义的两个方法,从华为云短信官方文档中找到,主要作用建立短信发送的请求头和请求体

直接从文档中拿取
private static final String WSSE_HEADER_FORMAT = "UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"";
    //无需修改,用于格式化鉴权头域,给"Authorization"参数赋值
private static final String AUTH_HEADER_VALUE = "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"";

public String buildRequestBody(String sender,String receiver,String templateId,String templateParas,String statusCallbackUrl,String signature) {
		if (null == sender || null == receiver || null == templateId || sender.isEmpty() || receiver.isEmpty()
		|| templateId.isEmpty()) {
			System.out.println("buildRequestBody(): sender, receiver or templateId is null.");
			return null;
		}
		List<NameValuePair> keyValues = new ArrayList<NameValuePair>();
		
		keyValues.add(new BasicNameValuePair("from", sender));
		keyValues.add(new BasicNameValuePair("to", receiver));
		keyValues.add(new BasicNameValuePair("templateId", templateId));
		if (null != templateParas && !templateParas.isEmpty()) {
			keyValues.add(new BasicNameValuePair("templateParas", templateParas));
		}
		if (null != statusCallbackUrl && !statusCallbackUrl.isEmpty()) {
			keyValues.add(new BasicNameValuePair("statusCallback", statusCallbackUrl));
		}
		if (null != signature && !signature.isEmpty()) {
			keyValues.add(new BasicNameValuePair("signature", signature));
		}
		
		return URLEncodedUtils.format(keyValues, Charset.forName("UTF-8"));
	}
    
    public String buildWsseHeader(String appKey, String appSecret) {
        if (null == appKey || null == appSecret || appKey.isEmpty() || appSecret.isEmpty()) {
            System.out.println("buildWsseHeader(): appKey or appSecret is null.");
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        String time = sdf.format(new Date()); //Created
        String nonce = UUID.randomUUID().toString().replace("-", ""); //Nonce

        byte[] passwordDigest = DigestUtils.sha256(nonce + time + appSecret);
        String hexDigest = Hex.encodeHexString(passwordDigest);
        String passwordDigestBase64Str = Base64.getEncoder().encodeToString(hexDigest.getBytes()); //PasswordDigest

        return String.format(WSSE_HEADER_FORMAT, appKey, passwordDigestBase64Str, nonce, time);
    }
           

最后这个就是发送功能的主要代码

@Autowired
private SmsConfig smsConfig;

public void sendMsg(String receiver,String templateParas) {
    	 String body = this.buildRequestBody(smsConfig.getSender(), receiver, smsConfig.getTemplateId(), templateParas, smsConfig.getStatusCallBack(), smsConfig.getSignature());
    	 if (null == body || body.isEmpty()) {
    	        System.out.println("body is null.");
    	        return;
    	 }
    	 String wsseHeader = this.buildWsseHeader(smsConfig.getAppKey(), smsConfig.getAppSecret());
         if (null == wsseHeader || wsseHeader.isEmpty()) {
             System.out.println("wsse header is null.");
             return;
         }
         try {
         CloseableHttpClient client = HttpClients.custom()
                 .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null,
                         (x509CertChain, authType) -> true).build())
                 .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                 .build();

	     HttpResponse response = client.execute(RequestBuilder.create("POST")//请求方法POST
	                 .setUri(smsConfig.getUrl())
	                 .addHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded")
	                 .addHeader(HttpHeaders.AUTHORIZATION, AUTH_HEADER_VALUE)
	                 .addHeader("X-WSSE", wsseHeader)
	                 .setEntity(new StringEntity(body)).build());

	     System.out.println(response.toString()); //打印响应头域信息
	     System.out.println(EntityUtils.toString(response.getEntity()));//打印响应消息实体
         }catch(Exception e) {
        	 log.error("[发送消息接口调用错误");
         }
    }
           

继续阅读