赞
踩
1.用户注册时,在注册页填写手机号进行手机验证码的获取
2.后台收到验证码请求后,首先校验手机号是否已存在
3.若手机号存在,则提醒用户。
4.若不存在,生成验证码,调用短信接口进行验证码发送
5.判断验证码发送是否成功,成功后将用户手机号作为key,验证码作为value存到redis中,并设置redis的key的有效时间为15分钟。来使验证码只有15分钟内有效
6.成功后用户输入信息,判断用户名是否重复。
7.校验完成后提交表单,使用表单数据与redis中手机号对应的数值判断验证码是否正确,进行注册。
短信依赖
<!-- 阿里短信 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.6</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
redis依赖
<!-- redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.1.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.2.1.RELEASE</version> </dependency>
#redis\u4E2D\u5FC3 #\u7ED1\u5B9A\u7684\u4E3B\u673A\u5730\u5740 redis.host=192.168.25.100 #\u6307\u5B9ARedis\u76D1\u542C\u7AEF\u53E3\uFF0C\u9ED8\u8BA4\u7AEF\u53E3\u4E3A6379 redis.port=6379 #\u6388\u6743\u5BC6\u7801\uFF08\u53EF\u4EE5\u4E0D\u4F7F\u7528\uFF09 #redis.password=bjtu #\u6700\u5927\u7A7A\u95F2\u6570\uFF1A\u7A7A\u95F2\u94FE\u63A5\u6570\u5927\u4E8EmaxIdle\u65F6\uFF0C\u5C06\u8FDB\u884C\u56DE\u6536 redis.maxIdle=100 #\u6700\u5927\u8FDE\u63A5\u6570\uFF1A\u80FD\u591F\u540C\u65F6\u5EFA\u7ACB\u7684\u201C\u6700\u5927\u94FE\u63A5\u4E2A\u6570\u201D redis.maxTotal=200 #\u6700\u5927\u7B49\u5F85\u65F6\u95F4\uFF1A\u5355\u4F4Dms redis.maxWait=1000 #\u4F7F\u7528\u8FDE\u63A5\u65F6\uFF0C\u68C0\u6D4B\u8FDE\u63A5\u662F\u5426\u6210\u529F redis.testOnBorrow=false #\u5F53\u5BA2\u6237\u7AEF\u95F2\u7F6E\u591A\u957F\u65F6\u95F4\u540E\u5173\u95ED\u8FDE\u63A5\uFF0C\u5982\u679C\u6307\u5B9A\u4E3A0\uFF0C\u8868\u793A\u5173\u95ED\u8BE5\u529F\u80FD redis.timeout=10000 redis.prefix=redis:cache:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring" xmlns:redis="http://www.springframework.org/schema/redis" xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis-1.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd"> <context:component-scan base-package="com.li"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <context:property-placeholder location="classpath:redis.properties,classpath:db.properties" ignore-resource-not-found="true" ignore-unresolvable="true"/> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> <property name="maxTotal" value="${redis.maxTotal}" /> <property name="blockWhenExhausted" value="true" /> </bean> <!-- jedis连接工程的配置 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.host}" /> <property name="port" value="${redis.port}" /> <property name="poolConfig" ref="jedisPoolConfig" /> <!-- <property name="password" value="${redis.password}" /> --> <property name="usePool" value="true"/> <property name="timeout" value="${redis.timeout}"></property> </bean> <!-- redisTemplate配置 --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer"> <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="hashValueSerializer"> <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> </property> </bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="initialPoolSize" value="${connection_pools.initial_pool_size}" /> <property name="minPoolSize" value="${connection_pools.min_pool_size}" /> <property name="maxPoolSize" value="${connection_pools.max_pool_size}" /> <property name="maxIdleTime" value="${connection_pools.max_idle_time}" /> <property name="acquireIncrement" value="${connection_pools.acquire_increment}" /> <property name="checkoutTimeout" value="${connection_pools.checkout_timeout}" /> </bean> <!-- 配置MyBatis的sqlSession --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- <property name="configLocation" value="classpath:mybatis.xml"></property> --> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"></property> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- xml aop事物方式 --> <aop:config> <!-- 切入点 --> <aop:pointcut expression="execution (* com.li.service.*.*(..))" id="serviceMethodAOP"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethodAOP"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 方法名称 以 add加入事物处理 addGoods updateGoods--> <tx:method name="insert*" propagation="REQUIRED" rollback-for="RunTimeException"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="RunTimeException"/> <tx:method name="delete*" propagation="REQUIRED" rollback-for="RunTimeException"/> <tx:method name="get*" propagation="NOT_SUPPORTED" rollback-for="RunTimeException" read-only="true"/> <tx:method name="select*" propagation="NOT_SUPPORTED" rollback-for="RunTimeException" read-only="true"/> <tx:method name="find*" propagation="NOT_SUPPORTED" rollback-for="RunTimeException" read-only="true"/> </tx:attributes> </tx:advice> <!-- 映射Mapper目录 --> <!-- Mapper接口所在包名,Spring会自动查找其下的Mapper --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.li.mapper" /> </bean> <!-- <bean id="sessionUtils" class="com.oracle.utils.SessionUtils"></bean> --> </beans>
sms.product =Dysmsapi
sms.domain =dysmsapi.aliyuncs.com
sms.accessKeyId =xxx
sms.accessKeySecret =xxx
sms.templateCode =SMS_xxx
/** * Created on 17/6/7. * 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过 * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可) * 工程依赖了2个jar包(存放在工程的libs目录下) * 1:aliyun-java-sdk-core.jar * 2:aliyun-java-sdk-dysmsapi.jar * * 备注:Demo工程编码采用UTF-8 * 国际短信发送请勿参照此DEMO */ @Configuration @PropertySource("classpath:sms.properties") public class SmsConfig { @Value("${sms.product}") private String product; @Value("${sms.domain}") private String domain; @Value("${sms.accessKeyId}") private String accessKeyId; @Value("${sms.accessKeySecret}") private String accessKeySecret; @Value("${sms.templateCode}") private String templateCode; @Value("Poseidon管理中心") private String signName; public SendSmsResponse sendSms(String phone,String randomCode) throws ClientException { try { //可自助调整超时时间 System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "10000"); //初始化acsClient,暂不支持region化 IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); IAcsClient acsClient = new DefaultAcsClient(profile); //组装请求对象-具体描述见控制台-文档部分内容 SendSmsRequest request = new SendSmsRequest(); //必填:待发送手机号 request.setPhoneNumbers(phone); //必填:短信签名-可在短信控制台中找到 request.setSignName(signName); //必填:短信模板-可在短信控制台中找到 request.setTemplateCode(templateCode); //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为 request.setTemplateParam("{\"code\":"+randomCode+"}"); //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者 request.setOutId("yourOutId"); //hint 此处可能会抛出异常,注意catch SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); return sendSmsResponse; } catch (ClientException e) { throw e; } } public QuerySendDetailsResponse querySendDetails(String bizId) throws ClientException { //可自助调整超时时间 System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "10000"); //初始化acsClient,暂不支持region化 IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); IAcsClient acsClient = new DefaultAcsClient(profile); //组装请求对象 QuerySendDetailsRequest request = new QuerySendDetailsRequest(); //必填-号码 request.setPhoneNumber("138xxxxxxxx"); //可选-流水号 request.setBizId(bizId); //必填-发送日期 支持30天内记录查询,格式yyyyMMdd SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd"); request.setSendDate(ft.format(new Date())); //必填-页大小 request.setPageSize(10L); //必填-当前页码从1开始计数 request.setCurrentPage(1L); //hint 此处可能会抛出异常,注意catch QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request); return querySendDetailsResponse; } public static void main(String[] args) throws ClientException, InterruptedException { SmsConfig smsConfig = new SmsConfig(); //发短信 SendSmsResponse response = smsConfig.sendSms("xxxxxx","xxx"); System.out.println("短信接口返回的数据----------------"); System.out.println("Code=" + response.getCode()); System.out.println("Message=" + response.getMessage()); System.out.println("RequestId=" + response.getRequestId()); System.out.println("BizId=" + response.getBizId()); Thread.sleep(3000L); //查明细 if(response.getCode() != null && response.getCode().equals("OK")) { QuerySendDetailsResponse querySendDetailsResponse = smsConfig.querySendDetails(response.getBizId()); System.out.println("短信明细查询接口返回数据----------------"); System.out.println("Code=" + querySendDetailsResponse.getCode()); System.out.println("Message=" + querySendDetailsResponse.getMessage()); int i = 0; for(QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse.getSmsSendDetailDTOs()) { System.out.println("SmsSendDetailDTO["+i+"]:"); System.out.println("Content=" + smsSendDetailDTO.getContent()); System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode()); System.out.println("OutId=" + smsSendDetailDTO.getOutId()); System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum()); System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate()); System.out.println("SendDate=" + smsSendDetailDTO.getSendDate()); System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus()); System.out.println("Template=" + smsSendDetailDTO.getTemplateCode()); } System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount()); System.out.println("RequestId=" + querySendDetailsResponse.getRequestId()); } } }
@Service public class MemberService { @Autowired private RedisTemplate<String,String> redisTemplate; @Autowired private MemberMapper memberMapper; @Value("${redis.prefix}") private String redisCache; /** * 校验手机号是否重复 * @return */ public boolean checkPhone(String phone){ MemberExample memberExample = new MemberExample(); MemberExample.Criteria criteria = memberExample.createCriteria(); criteria.andPhoneEqualTo(phone); int count = memberMapper.countByExample(memberExample); return count==0; } /** * 存验证码到redis * @return */ public void cachePhone(String phone,String randomCode){ String redisKey = redisCache+"reg:member:"+phone; //存redis redisTemplate.boundValueOps(redisKey).set(randomCode,2, TimeUnit.MINUTES); } /** * 校验短信验证码 * @return */ public boolean checkSmsCode(String smsCode,String phone){ String redisKey = redisCache+"reg:member:"+phone; String code = redisTemplate.boundValueOps(redisKey).get(); if(code==null||!code.equals(smsCode)){ return false; } return true; } /** * 注册 */ public void memberReg(Member memberVo){ memberVo.setStatus(200); memberMapper.insertSelective(memberVo); } /** * 校验用户名 */ public boolean checkUsername(String username){ MemberExample memberExample = new MemberExample(); MemberExample.Criteria criteria = memberExample.createCriteria(); criteria.andUsernameEqualTo(username); int count = memberMapper.countByExample(memberExample); return count==0; } }
@Slf4j @Controller @RequestMapping("member") public class MemberController { @Autowired private MemberService memberService; @Autowired private SmsConfig smsConfig; @RequestMapping("/getMobileCode") @ResponseBody public R getMobilePhone(String phone) throws ClientException { log.info("获取手机验证码开始,手机号:{0}",phone); boolean flag = memberService.checkPhone(phone); if(flag){ //验证码 String code = RandomCodeUtils.createRegisterCode().toString(); SendSmsResponse response = null; try { //发送短信验证码 response = smsConfig.sendSms(phone, code); if(response.getCode() != null && response.getCode().equals("OK")) { //存redis memberService.cachePhone(phone,code); return new R(200,"验证码已发送",null); } } catch (Exception e) { QuerySendDetailsResponse querySendDetailsResponse = smsConfig.querySendDetails(response.getBizId()); System.out.println("短信明细查询接口返回数据----------------"); System.out.println("Code=" + querySendDetailsResponse.getCode()); System.out.println("Message=" + querySendDetailsResponse.getMessage()); e.printStackTrace(); return new R(400, querySendDetailsResponse.getMessage(), null); } } return new R(400,"手机号已存在",null); } /** * 用户注册 * @param smsCode * @return */ @RequestMapping("/register") public String memberReg(Member memberVo, String smsCode, Model model){ //校验短信验证码是否正确 boolean flag = memberService.checkSmsCode(smsCode, memberVo.getPhone()); if(flag){ //验证成功,进行注册 memberService.memberReg(memberVo); return "reg_success"; } model.addAttribute("info","手机验证码错误,注册失败"); return "reg"; } @RequestMapping("/checkUsername") @ResponseBody public R checkUsername(String username){ boolean flag = memberService.checkUsername(username); if(flag){ return new R(200,"用户名可用",null); } return new R(400,"用户名已存在",null); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。