Javaweb 短信接口

reg.ftl

<div class="formRow">
     <input type="text" id="random" name="random" placeholder="短信验证码">
     <button type="button" id="getCode" class="btn_code">获取验证码</button>
</div>


JS

/* ---------------- 验证用户名为手机号 ---------------- */
<span style="white-space:pre">			</span>function validation(tel){
<span style="white-space:pre">			</span>  reg=/^1[3|4|5|7|8]\d{9}$/;
        <span style="white-space:pre">	</span>  return reg.test(tel);
<span style="white-space:pre">			</span>}
/* ---------------- jquery init ---------------- */
			$(function(){
				//点击获取验证码
				$('.btn_code').on('click',function(){
					$.ajax({
						type:"post",
						url:"${path}/reg/chickout",
						data:$("#validation-form").serialize(),
						success:function(data){
							// 验证电话号码
							var tel = $('#username').val();
							if(tel=="" || !validation(tel)){
								common.alert({content:'请输入正确的手机号码'});
								return false;
							}
							if(data.code==500){
								common.alert({content:data.msg});
								return false;
							}else{
								<span style="color:#ff6666;">//获取验证码
								getCode(tel);</span>
								//启动计时器
								timeOut();
							}
		               	<span style="white-space:pre">	</span>}
	            	<span style="white-space:pre">	</span>})
			});
/* ---------------- 获取验证码 ---------------- */
<span style="white-space:pre">			</span>function getCode(tel){
<span style="white-space:pre">				</span>$.ajax({
<span style="white-space:pre">					</span>type:"post",
<span style="white-space:pre">					</span>dataType:"json",
<span style="white-space:pre">					</span>data:{
<span style="white-space:pre">						</span>"username":tel
<span style="white-space:pre">					</span>},
<span style="white-space:pre">					</span><span style="color:#ff6666;">url:"${path}/message/reg",</span>
<span style="white-space:pre">					</span>success:function(data){
<span style="white-space:pre">						</span>if('200' == data.code){
<span style="white-space:pre">							</span>common.alert({content:'验证码已发送,请注意查收'});
<span style="white-space:pre">						</span>}else if('300' == data.code){
<span style="white-space:pre">							</span>$('#random').val(data.result);
<span style="white-space:pre">							</span>//common.alert({content:'短信接口被停用'});
<span style="white-space:pre">						</span>}else{
<span style="white-space:pre">							</span>common.alert({content:data.msg});
<span style="white-space:pre">						</span>}
<span style="white-space:pre">					</span>},error: function(XMLHttpRequest, textStatus, errorThrown) {
<span style="white-space:pre">						</span>common.alert({content:'网络异常'});
                    <span style="white-space:pre">		</span>}
<span style="white-space:pre">				</span>})
<span style="white-space:pre">			</span>}

RegController

/** 
 * 电脑端注册
 * @author CHAN
 */
@Controller
@RequestMapping(value="/reg")
public class RegController extends BaseController {
	
	Logger logger = Logger.getLogger(RegController.class);
	
	@Autowired
	private IMemberService memberService;
	@Autowired
	private IMemberLocationRecordService recordService;  
	@Autowired
	private RedisService redisService;
	
	/**
	 * 注册页面
	 */
	@RequestMapping(method = RequestMethod.GET)
	public String reg(){
		return "reg";
	}
	
	/**
	 * 注册
	 */
	@RequestMapping(method=RequestMethod.POST)
	@ResponseBody
	public ResultObject doReg(Member member,String random,RedirectAttributes redirectAttributes,HttpServletRequest request){
		try {
			/** -------- redis获取验证码 -------- **/
			String randomInRedis = redisService.get("redis_login_"+member.getUsername());
			if(!randomInRedis.equals(random)){
				return new ResultObject("500", "短信验证码错误", null);
			}
			
			/** -------- 会员注册-------- **/
			ResultObject rs = memberService.register(member);
			
			/** -------- 会员登陆-------- **/
			SSOToken st = new SSOToken(request);
			st.setId(member.getId());
			st.setType(1);
			st.setData(member.getUsername());
			//记住密码,设置 cookie 时长 1 周 = 604800 秒 【动态设置 maxAge 实现记住密码功能】
			if ( "on".equals(request.getParameter("rememberMe")) ) {
				request.setAttribute(SSOConfig.SSO_COOKIE_MAXAGE, 604800); 
			}
			SSOHelper.setSSOCookie(request, response, st, true);
			
			//记录地理位置
			recordService.saveMemberLocationRecord(member,new Corporation(corpid),request);
		    
		    
			return rs;
		} catch (Exception e) {
			logger.error("注册出错", e);
			return new ResultObject("500", "注册出错", null);
		}
	}
	
	@RequestMapping(value="/chickout",method=RequestMethod.POST)
	@ResponseBody
	public ResultObject chickout(Member member,String random,RedirectAttributes redirectAttributes,HttpServletRequest request,HttpSession session){
		try {
			/** -------- 检查用户名-------- **/
			Member temp = memberService.findMemberByUsername(member.getUsername());
			if(temp!=null){
				return new ResultObject("500", "该手机号码已被注册", null);
			}
			
			//判断验证码
			String code = (String) session.getAttribute("captcha");
			String summitCode = request.getParameter("captcha");
			if(StringUtils.isBlank(summitCode) || !StringUtils.equals(code.toLowerCase(), summitCode.toLowerCase())){
				 return new ResultObject("500", "验证码错误", "");
			}
			return new ResultObject("200", "手机号和图像验证码确认无误", null);	
		} catch (Exception e) {
			logger.error("注册出错", e);
			return new ResultObject("500", "注册出错", null);
		}
	}
	
	/**
	 * 判断账号是否唯一 
	 * true表示唯一
	 */
	@RequestMapping(value="/unique/username",method = RequestMethod.POST)
	@ResponseBody
	public boolean unique(String username){
		try{
			return memberService.unique(username);
		}catch(Exception e){
			logger.error("判断账号是否唯一,username="+username, e);
			return false;
		}
	}
	
	
}

MessageController

/** 
 * 短消息控制器
 * 
 * @author CHAN
 *  
 */
@Controller
@RequestMapping(value="/message")

public class MessageController extends BaseController {
	
	Logger logger = LoggerFactory.getLogger(MessageController.class);
	
	@Autowired
	private IMessageChannelService messageChannelService;
	
	@Autowired
	private RedisService redisService;
	
	<span style="color:#ff6666;">/**
	 * v1.0 注册验证码 2015-12-24 CHAN
	 */
	@RequestMapping(value="/reg",method=RequestMethod.POST)
	@ResponseBody
	public ResultObject sendMessage(@RequestParam String username){
			
		try {
			/** -------- 验证码生成 -------- **/
			String random = RandomStringUtils.random(6, "0123456789");
			
			/** -------- 将手机号,验证码存储到redis -------- **/
			redisService.set("redis_login_"+username, random, 1200);//60s 20min
			
			/** -------- 发送消息 -------- **/
			Map<String, String> map = new HashMap<String, String>();
			map.put("code", random);
			ResultObject rs = messageChannelService.send(corpid, MessageTemplateEnum.VERIFYCODE.getValue(), 
					username, map);
			
			return rs;
		} catch (Exception e) {
			logger.error("发送登陆验证码失败", e);
			return new ResultObject("500", "发送登陆验证码失败", null);
		}
	}</span>
	
	
	/**
	 * v1.0 修改密码验证码 2015-12-24 CHAN
	 */
	@RequestMapping(value="/forgetPassword",method=RequestMethod.POST)
	@ResponseBody
	public ResultObject sendMessageP(@RequestParam String username){
			
		try {
			/** -------- 验证码生成 -------- **/
			String random = RandomStringUtils.random(6, "0123456789");
			
			/** -------- 将手机号,验证码存储到redis -------- **/
			redisService.set("redis_login_"+username, random, 300);//60s 5min
			
			/** -------- 发送消息 -------- **/
			Map<String, String> map = new HashMap<String, String>();
			map.put("code", random);
			ResultObject rs = messageChannelService.send(corpid, MessageTemplateEnum.VERIFYCODE.getValue(), 
					username, map);
			return rs;
		} catch (Exception e) {
			logger.error("发送修改密码验证码失败", e);
			return new ResultObject("500", "发送修改密码验证码失败", null);
		}
	}
}


IMessageChannelService

@SuppressWarnings(value="all")
public interface IMessageChannelService extends IBaseService<MessageChannel>{
	
	<span style="color:#cc33cc;">/** 查询当前企业的短信通道 */
	public MessageChannel findMessageChannelByCorpId(Long corpid) throws Exception;</span>

	<span style="color:#6633ff;">/** 短信接口请求 */
	public ResultObject request(Long corpid,Integer templateTypeId,String action,String mobile,Map map) throws Exception;</span>
	
	<span style="color:#ff6666;">/** 短信接口发送 */
	public ResultObject send(Long corpid,Integer templateTypeId,String mobile,Map map) throws Exception;</span>
}


MessageChannelServiceImpl


@SuppressWarnings(value="all")
@Component
public class MessageChannelServiceImpl extends BaseServiceImpl<MessageChannel> implements IMessageChannelService {

	Logger logger = Logger.getLogger(MessageChannelServiceImpl.class);
	
	@Autowired
	private MessageChannelDao messageChannelDao;
	@Autowired
	private MessageRecordDao messageRecordDao;
	@Autowired
	private MessageTemplateDao messageTemplateDao;
	
	@Autowired
	private IMessageRecordService messageRecordService;

	<span style="color:#cc33cc;">/** 查询当前企业的短信通道 */
	@Override
	public MessageChannel findMessageChannelByCorpId(Long corpid) throws Exception {
		return messageChannelDao.findByCorpId(corpid);
	}</span>

	<span style="color:#3366ff;">/**
	 * 功能:短信请求
	 * create by chan on 2016-08-16
	 * @param corpid  		    	企业id
	 * @param templateTypeId	短信模板类型
	 * @param action		        	动作
	 * @param mobile		    	手机号码
	 * @param map					短信模板参数
	 * @return
	 */
	@Override
	public ResultObject request(Long corpid, Integer templateTypeId, String action, String mobile, Map map) throws Exception {
	
			</span><span style="color:#cc33cc;">/** -------- 判断短信通道情况  --------*/
			MessageChannel channel = findMessageChannelByCorpId(corpid); 
			if(channel.getStatus()==StatusEnum.STOP.getValue()){
				return new ResultObject("300", "短信接口已停用",map.get("code"));
			}
			boolean isMinimumInterval = messageRecordService.isMinimumInterval(corpid, mobile);
			if(isMinimumInterval){
				return new ResultObject("301", "您发送短信过于频繁,请稍后点击发送",null);
			}
			boolean isReachWaringLine = messageRecordService.isReachWaringLine(corpid);
			if(isReachWaringLine){
				return new ResultObject("302", "超出日均最大短信数量",null);
			}</span><span style="color:#3366ff;">
			
			/** -------- 组织参数  --------*/
			String url = channel.getUrl();
			String userid = channel.getUserid();
			String account = channel.getAccount();
			String password = channel.getPassword();
			String extno = channel.getExtno();
			</span><span style="color:#999900;">//根据短信类型,查询出短信模板
			String templateContent = messageTemplateDao.findByCorpIdAndType(corpid,templateTypeId).getContent();
			StringBuffer cnt = new StringBuffer();
			//根据短信模板,生成对应的短信记录
			cnt.append("【").append(channel.getSign()).append("】").append(replaceTemplate(templateContent, map));
</span><span style="color:#3366ff;">
			/** -------- 使用Httpclient发送请求参数 --------*/
			HttpClient client = new HttpClient();
			PostMethod post = new PostMethod(url);
			try {	
				
				/*-------- 设置请求接口和参数 -------- */
				post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");// 在头文件中设置转码
				NameValuePair[] data = {
						new NameValuePair("action", action),
						new NameValuePair("userid", userid),
						new NameValuePair("account", account),
						new NameValuePair("password", password),
						new NameValuePair("mobile", mobile),
						new NameValuePair("content", cnt.toString()),
						new NameValuePair("extno", extno) 
				};
				post.setRequestBody(data);
				
				/* -------- 发送请求 -------- **/
				client.executeMethod(post);

				/* -------- 返回状态 -------- **/
				// 返回状态
				int statusCode = post.getStatusCode();
				System.out.println("statusCode:" + statusCode);

				// 返回头信息
//				Header[] headers = post.getResponseHeaders();
//				for (Header h : headers) {
//					System.out.println(h.toString());
//				}

				/** -------- 处理结果--------*/
				// 返回信息 {"smsid":"9EF0A9EC94139CDC57F812D0CFB314DA","code":"0"} 表示成功
				//xml string->map
				String result = new String(post.getResponseBody(),"UTF-8");
				System.out.println(result);
				Map<String,String> xmlobj = parseXml(result);
				String returnstatus = xmlobj.get("returnstatus");
				String message = xmlobj.get("message");
				String remainpoint = xmlobj.get("remainpoint");

				
				if (!returnstatus.equals("Success")){
					return new ResultObject("500", "短信http通讯错误", null);
				}
				if(!message.equals("ok")){
					return new ResultObject("500", "短信接口错误 :"+message, null);
				}
				
				//新增短信记录
				MessageRecord record = new MessageRecord(mobile, cnt.toString());
				record.setCorp(channel.getCorp());
				record.setCreateTime(new Date());
				record.setReturnstatus(returnstatus);
				record.setMessage(message);
				messageRecordDao.save(record);
				//修改短信通道剩余条数
				channel.setRemainpoint(Integer.parseInt(remainpoint));
				messageChannelDao.save(channel);
				
				return new ResultObject("200", "短信发送成功,注意查收", null);
				
			} catch (Exception e) {
				logger.error("短信接口错误", e);
				return new ResultObject("500", "短信接口错误", null);
			} finally {
				// 释放链接
				post.releaseConnection();
			}
	}</span>
	
	
	
	
	<span style="color:#ff6666;">/** 短信接口发送 */
	@Override
	public ResultObject send(Long corpid,Integer templateTypeId,String mobile,Map map) throws Exception{
		return request(corpid, templateTypeId, "send", mobile, map);
	}
	
	
</span>	public static Map<String,String> parseXml(String text) throws Exception{
		
		Map<String,String> map = new HashMap<String, String>();
		
		Document document = DocumentHelper.parseText(text);
		//得到xml根元素
		Element root = document.getRootElement();
		List<Element> elements = root.elements();
		for (Element element : elements) {
			map.put(element.getName(), element.getText());
		}
		return map;
	}
	
	public static String generateString(String str,List<Object> list){
	      StringBuilder sb  = new StringBuilder();
	      int i=0;
	      for(String temp : str.split("_")){
	          sb.append(temp);
	          if(i<list.size())
	              sb.append(list.get(i));
	          	  i++;
	      }
	      return sb.toString();
	}
	
	public static String replaceTemplate(String template,Map<String,String> map){
		for (String key:map.keySet()) {
			System.out.println("#"+key+"#");
			template = template.replace("#"+key+"#", map.get(key));
		}
		return template;
	}
	
	public static Double formatString(String str){
		Double db = Double.valueOf(str);
		db=((int)(db*100))/100.0;
	    return db;
	}
	
	
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String, String>();
		map.put("code1", "aaa");
		map.put("code2", "bbb");
		String template= "#code1#,wcnm,#code2#";
		template = replaceTemplate(template, map);
		System.out.println(template);
	}
	
//	public static void main(String[] args) {
//		//String result = "{\"smsid\":\"9EF0A9EC94139CDC57F812D0CFB314DA\",\"code\":\"0\"}";
//		String result = "{\"code\":\"-1000\"}";
//		JSONObject jsonobj = JSON.parseObject(result);
//		int code = jsonobj.getInteger("code");
//		String smsid = jsonobj.getString("smsid");
//		System.out.println(code);
//		System.out.println(smsid==null);
//		
//		String str = "尊敬的客户,您的账户_于_年_月_日成功充值,人民币_元。 回T退订.";
		String str1 = "您的手机验证码为:_,请在5分钟内完有效。如非本人操作请忽略本短信。回T退订.";
//		List<Object> list = new ArrayList<Object>();
//		list.add("account");
//		list.add("year");
//		list.add("month");
//		list.add("day");
//		list.add(874198);
//		System.out.println(generateString(str, list));
//	}
}



IMessageRecordService


public interface IMessageRecordService extends IBaseService<MessageRecord> {
	
	
	
	//计算当前时间和最新一条短信记录的时间差,单位是秒
	public int calculateInterval(Long corpid, String mobile) throws Exception;
	
	<span style="color:#cc33cc;">//判断是否,在发送最小间隔内
	public boolean isMinimumInterval(Long corpid, String mobile) throws Exception;
	
	//判断是否,达到预警线
	public boolean isReachWaringLine(Long corpid) throws Exception;</span>
	
}



MessageRecordServiceImpl


@Component
public class MessageRecordServiceImpl extends BaseServiceImpl<MessageRecord> implements IMessageRecordService {

	@Autowired
	private MessageRecordDao recordDao;
	@Autowired
	private MessageChannelDao messageChannelDao;
	
	/** ------------------------------- 扩展  ------------------------------*/
	
	/**
	 * 计算当前时间和最新一条短信记录的时间差
	 * -1 表示没有任何一条记录
	 */
	public int calculateInterval(Long corpid, String mobile) throws Exception{
		MessageRecord latestRecord = recordDao.findTopByCorpIdAndMobileOrderByCreateTimeDesc(corpid, mobile);
		if(latestRecord==null){
			return -1;
		}
		DateTime start = new DateTime(latestRecord.getCreateTime());
		DateTime end = new DateTime();
		int diff = Seconds.secondsBetween(start,end).getSeconds();
		return diff;
	}

	<span style="color:#cc33cc;">/**
	 * 判断是否在发送最小间隔内 60s
	 * ps:短信通道是否停用,交给控制器处理
	 */
	@Override
	public boolean isMinimumInterval(Long corpid, String mobile) throws Exception{
		//短信通道
		MessageChannel channel = messageChannelDao.findByCorpId(corpid); 
		//获得发送最小间隔时间,当前时间和最新一条短信记录的时间差
		int minimumInterval = channel.getMinimumInterval();
		int diff = calculateInterval(corpid, mobile);
		System.out.println("最小间隔diff="+diff);
		return (diff>=0 && diff<=minimumInterval)?true:false;
	}</span>
	
	<span style="color:#cc33cc;">/**
	 * 判断是否,达到预警线
	 */
	@Override
	public boolean isReachWaringLine(Long corpid) throws Exception{
		//获取警戒线,每日最大发送短信数量
		MessageChannel channel = messageChannelDao.findByCorpId(corpid); 
		long warningLine = channel.getWarningLine().longValue();
		
		Collection<SearchFilter> filters = new ArrayList<SearchFilter>();
		filters.add(new SearchFilter("corp.id", Operator.EQ, corpid));
		filters.add(new SearchFilter("createTime", Operator.GE, new DateTime().toString("yyyy-MM-dd")));
		filters.add(new SearchFilter("createTime", Operator.LE, new DateTime().toString("yyyy-MM-dd")));
		Specification<MessageRecord> spec = DynamicSpecifications.bySearchFilter(filters, MessageRecord.class);
		long sendCount = recordDao.count(spec);
		
		return (sendCount>warningLine)?true:false;
	}</span>
}


MessageChannelDao


@Repository
public interface MessageChannelDao extends BaseRepository<MessageChannel, Long>, JpaSpecificationExecutor<MessageChannel> {

	<span style="color:#cc33cc;">MessageChannel findByCorpId(Long corpid);</span>
	
}

MessageTemplateDao

@Repository
public interface MessageTemplateDao extends BaseRepository<MessageTemplate, Long>, JpaSpecificationExecutor<MessageTemplate>{
	
	<span style="color:#009900;">MessageTemplate findByCorpIdAndType(Long corpid,Integer type);</span>

}

MessageTemplateEnum


public enum MessageTemplateEnum {
VERIFYCODE(1,"发送验证码"),ORDER_SUCCESS(2,"下单成功"),PAY_SUCCESS(3,"订单支付"),DELIVERY_SUCCESS(4,"订单发货");
private int value;
private String comment;


private MessageTemplateEnum(int value, String comment) {
this.value = value;
this.comment = comment;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}

public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public static MessageTemplateEnum get(int value){
for (MessageTemplateEnum o:MessageTemplateEnum.values()) {
if(o.value ==value){
return o;
}
}
return null;
}

}



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
短信验证码登录是一种通过发送短信验证码来验证用户身份的登录方式。具体实现的思路如下: 1. 用户在登录页面输入手机号码,并点击发送验证码按钮。 2. 后台接收到手机号码后,生成一个随机的验证码,并将验证码发送到用户的手机上。 3. 后台将生成的验证码存储在session中,以便后续验证使用。 4. 用户在手机上收到验证码后,输入验证码并点击登录按钮。 5. 后台接收到用户输入的验证码后,与session中存储的验证码进行比较。 6. 如果验证码匹配成功,则认为用户身份验证通过,可以进行登录操作。 7. 如果验证码匹配失败,则返回错误信息,要求用户重新输入验证码。 在具体的代码实现中,可以使用第三方短信服务提供商的API来发送短信验证码,比如榛子云。发送短信验证码的代码可以参考引用[2]中的示例代码。而验证码的验证可以参考引用[3]中的示例代码。 需要注意的是,为了保证安全性,验证码应该有一定的有效期限,并且在验证成功后应该立即从session中删除,以防止被恶意利用。此外,还可以考虑添加一些额外的安全措施,比如限制验证码的发送频率、添加图形验证码等。 总结起来,短信验证码登录是一种安全、方便的登录方式,通过发送短信验证码来验证用户身份,可以有效防止恶意登录和账号被盗用的风险。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值