最近做的这个项目是一个类似于众筹的网站,众所周知,现在主流的网站都会涉及到注册验证码的发送以及验证,购买商品以及送礼这些都可能会有短信的提醒,那么这些短信都是怎么实现的呢?这个项目中需要实现验证码以及购买商品的短信提醒,最近研究了一下,下面把学习成果简略记录一下,以防以后忘记:
一、首先需要在云片网注册一个号码,网站链接:猛戳这里,当然这个网站是要收费的,在这个网站上可以定义模板,也就是你需要发的短信的样式,如下图:
二、有个云片网的模板后,就需要在项目中写接口了,下面上代码:
首先需要引入云片网的API,这些代码可以上云片网中API文档中找,如下代码:
import java.io.IOException; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpMethodParams; /** * 短信http接口的java代码调用示例 * @author jacky * @since 2013-12-1 */ public class JavaSmsApi { /** * 服务http地址 */ private static String BASE_URI = "http://yunpian.com"; /** * 服务版本号 */ private static String VERSION = "v1"; /** * 编码格式 */ private static String ENCODING = "UTF-8"; /** * 查账户信息的http地址 */ private static String URI_GET_USER_INFO = BASE_URI + "/" + VERSION + "/user/get.json"; /** * 通用发送接口的http地址 */ private static String URI_SEND_SMS = BASE_URI + "/" + VERSION + "/sms/send.json"; /** * 模板发送接口的http地址 */ private static String URI_TPL_SEND_SMS = BASE_URI + "/" + VERSION + "/sms/tpl_send.json"; /** * 取账户信息 * @return json格式字符串 * @throws IOException */ public static String getUserInfo(String apikey) throws IOException{ HttpClient client = new HttpClient(); HttpMethod method = new GetMethod(URI_GET_USER_INFO+"?apikey="+apikey); HttpMethodParams param = method.getParams(); param.setContentCharset(ENCODING); client.executeMethod(method); return method.getResponseBodyAsString(); } /** * 发短信 * @param apikey apikey * @param text 短信内容 * @param mobile 接受的手机号 * @return json格式字符串 * @throws IOException */ public static String sendSms(String apikey, String text, String mobile) throws IOException{ HttpClient client = new HttpClient(); NameValuePair[] nameValuePairs = new NameValuePair[3]; nameValuePairs[0] = new NameValuePair("apikey", apikey); nameValuePairs[1] = new NameValuePair("text", text); nameValuePairs[2] = new NameValuePair("mobile", mobile); PostMethod method = new PostMethod(URI_SEND_SMS); method.setRequestBody(nameValuePairs); HttpMethodParams param = method.getParams(); param.setContentCharset(ENCODING); client.executeMethod(method); return method.getResponseBodyAsString(); } /** * 通过模板发送短信 * @param apikey apikey * @param tpl_id 模板id * @param tpl_value 模板变量值 * @param mobile 接受的手机号 * @return json格式字符串 * @throws IOException */ public static String tplSendSms(String apikey, long tpl_id, String tpl_value, String mobile) throws IOException{ HttpClient client = new HttpClient(); NameValuePair[] nameValuePairs = new NameValuePair[4]; nameValuePairs[0] = new NameValuePair("apikey", apikey); nameValuePairs[1] = new NameValuePair("tpl_id", String.valueOf(tpl_id)); nameValuePairs[2] = new NameValuePair("tpl_value", tpl_value); nameValuePairs[3] = new NameValuePair("mobile", mobile); PostMethod method = new PostMethod(URI_TPL_SEND_SMS); method.setRequestBody(nameValuePairs); HttpMethodParams param = method.getParams(); param.setContentCharset(ENCODING); client.executeMethod(method); return method.getResponseBodyAsString(); } public static void main(String[] args) throws IOException { //修改为您的apikey String apikey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; //修改为您要发送的手机号 String mobile = "188xxxxxxxx"; /**************** 查账户信息调用示例 *****************/ System.out.println(JavaSmsApi.getUserInfo(apikey)); /**************** 使用通用接口发短信 *****************/ //设置您要发送的内容 String text = "您的验证码是1234【云片网】"; //发短信调用示例 System.out.println(JavaSmsApi.sendSms(apikey, text, mobile)); /**************** 使用模板接口发短信 *****************/ //设置模板ID,如使用1号模板:您的验证码是#code#【#company#】 long tpl_id=1; //设置对应的模板变量值 String tpl_value="#code#=1234&#company#=云片网"; //模板发送的调用示例 System.out.println(JavaSmsApi.tplSendSms(apikey, tpl_id, tpl_value, mobile)); } }然后就是在自己的接口中调用短信接API,如下面发送验证码的接口:
@RequestMapping(value = "/text/send", method = RequestMethod.GET) public ResponseEntity<?> registSendMobile(@RequestParam(value = "loginName", required = true)String loginName) throws IOException { Map<String, Object> map = Maps.newHashMap(); String text = String.valueOf(Math.random()).substring(2,8); String value = "#code#="+text; String res = textMessageService.tplSendSms(value, loginName, TextMessageService.SEND_VERIFICATION_CODE); text = MD5Util.MD5(text);//MD5加密 map.put("code", text); return new ResponseEntity(map, HttpStatus.OK); }这里用到的tplSendSms()方法就是调用的短信API中的方法,其中value是需要传的参数,这里如果有两个及以上的参数,需要用&隔开,如下:
String value = "#user#="+coupon.getUser().getName()+"#msg#="+coupon.getMemo()+","+coupon.getCouponNo();loginName|其实就是所发短信的电话号码,然后最后一个参数是云片网的模板参数。
这是直接在接口中直接调用短信接口和模板,还有一种方法是在接口中写一个触发方法,当我们监测到执行了触发方法后就开始调用短信接口和模板,继续上代码:
首先是接口代码:
//发送短信,用于短信发送的触发 presentService.sendMail(projectSupport, oldUser,newUser);
然后,调用发送短信API的代码,这里面要获取所要传的参数,其中参数要中#括起来,如#code#:
@AfterReturning("execution(* com.thon.service.user.PresentService.sendMail(..))") public void sendPresentTextAndMessage(JoinPoint jp) throws IOException { ProjectSupport ps = (ProjectSupport)jp.getArgs()[0]; User user = (User)jp.getArgs()[1]; User newUser = (User)jp.getArgs()[2]; ps = projectSupportService.getProjectSupport(ps.getId()); // Project projectSupport = project User from = userService.getUserByEmail(Global.getConfig("service.user")); User to = userService.getUser(user.getId()); String text = "亲爱的"+to.getName()+","+newUser.getName()+"向您赠送了"+ps.getProduct().getName(); messageService.sendMessage(from, to, text); //String value = "#user1#="+ps.getUserName()+"&"+"#user2#="+to.getName()+"&"+"#goods=#"+ps.getProduct().getName(); String text2 = String.valueOf(Math.random()).substring(2,8); String value = "#code#="+text2; String loginName = user.getLoginName(); textMessageService.tplSendSms(value, loginName, TextMessageService.SEND_VERIFICATION_CODE); //textMessageService.tplSendSms(value, to.getLoginName(), TextMessageService.SEND_PRESENT_MESSAGE); }其中的第一行代码就是监测sendMali()方法是否执行,如果执行,就是进入下面的接口。
总结:以上就是项目中实现短信的发送的一个简略流程,短信模板的好处就在于把短信发送与开发者分开了,我们只需要写接口传入所需正确的参数,调用模板就可以实现短信的发送了。