4.7、Lombok
lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码,尤其是针对pojo。
配置安装
导入依赖:
1. <!--简化代码的工具包--> 2. <dependency> 3. <groupId>org.projectlombok</groupId> 4. <artifactId>lombok</artifactId> 5. <optional>true</optional> 6. </dependency>
安装IDEA插件:
如果不安装插件,程序可以正常执行,但是看不到生成的一些代码,如:get、set方法。
常用注解
- @Data:注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
- @Setter:注解在属性上;为属性提供 setting 方法
- @Getter:注解在属性上;为属性提供 getting 方法
- @Slf4j:注解在类上;为类提供一个 属性名为log 的 slf4j日志对象
- @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
- @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
- @Builder:使用Builder模式构建对象
测试一:使用@Data注解
是不是很神奇?!
测试二:使用@Slf4j注解
测试:
测试三:@AllArgsConstructor、@NoArgsConstructor注解的使用
测试四:@Builder
测试结果:
5、注册登录需求分析
5.1、业务说明
用户通过手机验证码进行登录,如果是第一次登录则需要完善个人信息,在上传图片时,需要对上传的图片做人像的校验,防止用户上传非人像的图片作为头像。流程完成后,则登录成功。
- 已注册用户:
- 输入手机号发送验证码
- 输入验证码,进行比对完成登录
- 未注册用户:
- 输入手机号发送验证码
- 输入验证码,进行比对,自动注册(保存用户)
- 完善用户信息
5.2、需求分析
服务端接受客户端请求
Java代码调用第三方服务实现短信返送(发送短信需要运营资质,只能借助第三方实现)
5.3、数据库表
数据库使用的mysql:
1. CREATE TABLE `tb_user` ( 2. `id` bigint(20) NOT NULL AUTO_INCREMENT, 3. `mobile` varchar(11) DEFAULT NULL COMMENT '手机号', 4. `password` varchar(32) DEFAULT NULL COMMENT '密码,需要加密', 5. `created` datetime DEFAULT NULL, 6. `updated` datetime DEFAULT NULL, 7. PRIMARY KEY (`id`), 8. KEY `mobile` (`mobile`) USING BTREE 9. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表'; 10. 11. CREATE TABLE `tb_user_info` ( 12. `id` bigint(20) NOT NULL AUTO_INCREMENT, 13. `user_id` bigint(20) NOT NULL COMMENT '用户id', 14. `nick_name` varchar(50) DEFAULT NULL COMMENT '昵称', 15. `logo` varchar(100) DEFAULT NULL COMMENT '用户头像', 16. `tags` varchar(50) DEFAULT NULL COMMENT '用户标签:多个用逗号分隔', 17. `sex` int(1) DEFAULT '3' COMMENT '性别,1-男,2-女,3-未知', 18. `age` int(11) DEFAULT NULL COMMENT '用户年龄', 19. `edu` varchar(20) DEFAULT NULL COMMENT '学历', 20. `city` varchar(20) DEFAULT NULL COMMENT '居住城市', 21. `birthday` varchar(20) DEFAULT NULL COMMENT '生日', 22. `cover_pic` varchar(50) DEFAULT NULL COMMENT '封面图片', 23. `industry` varchar(20) DEFAULT NULL COMMENT '行业', 24. `income` varchar(20) DEFAULT NULL COMMENT '收入', 25. `marriage` varchar(20) DEFAULT NULL COMMENT '婚姻状态', 26. `created` datetime DEFAULT NULL, 27. `updated` datetime DEFAULT NULL, 28. PRIMARY KEY (`id`), 29. KEY `user_id` (`user_id`) 30. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';
5.4、实体类
User
1. @Data 2. @AllArgsConstructor //满参构造方法 3. @NoArgsConstructor //无参构造方法 4. public class User extends BasePojo { 5. 6. private Long id; 7. private String mobile; 8. private String password; 9. 10. //环信用户信息 11. private String hxUser; 12. private String hxPassword; 13. }
6、短信验证码
6.1、阿里云短信服务
6.1.1、申请签名与模板
使用阿里云短信服务非常简单,仅需要简单的申请和认证即可
说明:申请签名时,个人用户只能申请一个并且签名的名称必须为“ABC商城”,否则审核不通过。
申请模板:
审核时间需要1~2小时,请耐心等待~
6.1.2、示例代码
文档:调用SendSms发送短信_短信服务-阿里云帮助中心:
导入依赖:
1. <dependency> 2. <groupId>com.aliyun</groupId> 3. <artifactId>dysmsapi20170525</artifactId> 4. <version>2.0.1</version> 5. </dependency>
1. package com.tanhua.sso.service; 2. 3. import com.aliyun.dysmsapi20170525.models.SendSmsRequest; 4. import com.aliyun.dysmsapi20170525.models.SendSmsResponse; 5. import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody; 6. import com.aliyun.teaopenapi.models.Config; 7. 8. public class SendSms { 9. 10. /** 11. * 使用AK&SK初始化账号Client 12. * @param accessKeyId 13. * @param accessKeySecret 14. * @return Client 15. * @throws Exception 16. */ 17. public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception { 18. Config config = new Config() 19. // 您的AccessKey ID 20. .setAccessKeyId(accessKeyId) 21. // 您的AccessKey Secret 22. .setAccessKeySecret(accessKeySecret) 23. .setEndpoint("dysmsapi.aliyuncs.com"); 24. // 访问的域名 25. return new com.aliyun.dysmsapi20170525.Client(config); 26. } 27. 28. public static void main(String[] args_) throws Exception { 29. java.util.List<String> args = java.util.Arrays.asList(args_); 30. com.aliyun.dysmsapi20170525.Client client = SendSms 31. .createClient("**********", "**********"); 32. 33. SendSmsRequest sendSmsRequest = new SendSmsRequest() 34. .setPhoneNumbers( "158****7944") //目标手机号 35. .setSignName("ABC商城") //签名名称 36. .setTemplateCode("SMS_204756062") //短信模板code 37. .setTemplateParam("{\"code\":\"1111\"}"); //模板中变量替换 38. SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest); 39. 40. SendSmsResponseBody body = sendSmsResponse.getBody(); 41. 42. // code = OK 代表成功 43. System.out.println(body.getCode() + " " + body.getMessage()); 44. } 45. 46. }
3.6.1.4、实现发送短信方法
配置文件:aliyun.properties
1. aliyun.sms.accessKeyId = *********** 2. aliyun.sms.accessKeySecret = *********** 3. aliyun.sms.domain= dysmsapi.aliyuncs.com 4. aliyun.sms.signName= ABC商城 5. aliyun.sms.templateCode= SMS_204756062
需要注意中文编码问题:
读取配置:
1. package com.tanhua.sso.config; 2. 3. import lombok.Data; 4. import org.springframework.boot.context.properties.ConfigurationProperties; 5. import org.springframework.context.annotation.Configuration; 6. import org.springframework.context.annotation.PropertySource; 7. 8. @Configuration 9. @PropertySource("classpath:aliyun.properties") 10. @ConfigurationProperties(prefix = "aliyun.sms") 11. @Data 12. public class AliyunSMSConfig { 13. 14. private String accessKeyId; 15. private String accessKeySecret; 16. private String domain; 17. private String signName; 18. private String templateCode; 19. 20. }
代码实现:
1. package com.tanhua.sso.service; 2. 3. import cn.hutool.core.util.RandomUtil; 4. import cn.hutool.core.util.StrUtil; 5. import com.aliyun.dysmsapi20170525.Client; 6. import com.aliyun.dysmsapi20170525.models.SendSmsRequest; 7. import com.aliyun.dysmsapi20170525.models.SendSmsResponse; 8. import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody; 9. import com.aliyun.teaopenapi.models.Config; 10. import com.tanhua.sso.config.AliyunSMSConfig; 11. import lombok.extern.slf4j.Slf4j; 12. import org.springframework.beans.factory.annotation.Autowired; 13. import org.springframework.stereotype.Service; 14. 15. @Service 16. @Slf4j 17. public class SmsService { 18. 19. @Autowired 20. private AliyunSMSConfig aliyunSMSConfig; 21. 22. /** 23. * 发送短信验证码 24. * 25. * @param mobile 26. * @return 27. */ 28. public String sendSms(String mobile) { 29. //随机生成6位数字验证码 30. String code = RandomUtil.randomNumbers(6); 31. try { 32. Config config = new Config() 33. .setAccessKeyId(this.aliyunSMSConfig.getAccessKeyId()) 34. .setAccessKeySecret(this.aliyunSMSConfig.getAccessKeySecret()) 35. .setEndpoint(this.aliyunSMSConfig.getDomain()); 36. 37. Client client = new Client(config); 38. SendSmsRequest sendSmsRequest = new SendSmsRequest() 39. .setPhoneNumbers(mobile)//目标手机号 40. .setSignName(this.aliyunSMSConfig.getSignName()) //签名名称 41. .setTemplateCode(this.aliyunSMSConfig.getTemplateCode()) //短信模板code 42. .setTemplateParam("{\"code\":\"" + code + "\"}"); //模板中变量替换 43. SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest); 44. SendSmsResponseBody body = sendSmsResponse.getBody(); 45. if (StrUtil.equals("OK", body.getCode())) { 46. return code; 47. } 48. } catch (Exception e) { 49. log.error("发送短信验证码失败!" + mobile, e); 50. } 51. return null; 52. } 53. }
6.2、模板组件
企业开发中,往往将常见工具类封装抽取,以简洁便利的方式供其他工程模块使用。而SpringBoot的自动装配机制可以方便的实现组件抽取。SpringBoot执行流程如下
- 扫描依赖模块中META-INF/spring.factories
- 执行装配类中方法
- 对象存入容器中
- 核心工程注入对象,调用方法使用
6.2.1、配置类
tanhua-autoconfig创建配置信息类
1. @Data 2. @ConfigurationProperties(prefix = "tanhua.sms") 3. public class SmsProperties { 4. private String signName; 5. private String templateCode; 6. private String accessKey; 7. private String secret; 8. }
6.2.2、发送短信模板对象
tanhua-autoconfig创建模板对象对象发送信息
1. package com.tanhua.autoconfig.template; 2. 3. import com.aliyun.dysmsapi20170525.models.SendSmsRequest; 4. import com.aliyun.dysmsapi20170525.models.SendSmsResponse; 5. import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody; 6. import com.aliyun.teaopenapi.models.Config; 7. import com.tanhua.autoconfig.properties.SmsProperties; 8. 9. public class SmsTemplate { 10. 11. private SmsProperties properties; 12. 13. public SmsTemplate(SmsProperties properties) { 14. this.properties = properties; 15. } 16. 17. public void sendSms(String mobile,String code) { 18. 19. try { 20. //配置阿里云 21. Config config = new Config() 22. // 您的AccessKey ID 23. .setAccessKeyId(properties.getAccessKey()) 24. // 您的AccessKey Secret 25. .setAccessKeySecret(properties.getSecret()); 26. // 访问的域名 27. config.endpoint = "dysmsapi.aliyuncs.com"; 28. 29. com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); 30. 31. SendSmsRequest sendSmsRequest = new SendSmsRequest() 32. .setPhoneNumbers(mobile) 33. .setSignName(properties.getSignName()) 34. .setTemplateCode(properties.getTemplateCode()) 35. .setTemplateParam("{\"code\":\""+code+"\"}"); 36. // 复制代码运行请自行打印 API 的返回值 37. SendSmsResponse response = client.sendSms(sendSmsRequest); 38. 39. SendSmsResponseBody body = response.getBody(); 40. 41. System.out.println(body.getMessage()); 42. 43. }catch (Exception e) { 44. e.printStackTrace(); 45. } 46. 47. } 48. 49. }
6.2.3、自动装配类
tanhua-autoconfig创建自动装配的配置类
1. package com.tanhua.autoconfig; 2. 3. 4. import com.tanhua.autoconfig.properties.*; 5. import com.tanhua.autoconfig.template.*; 6. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7. import org.springframework.boot.context.properties.EnableConfigurationProperties; 8. import org.springframework.context.annotation.Bean; 9. 10. @EnableConfigurationProperties({ 11. SmsProperties.class 12. }) 13. public class TanhuaAutoConfiguration { 14. 15. @Bean 16. public SmsTemplate smsTemplate(SmsProperties properties) { 17. return new SmsTemplate(properties); 18. } 19. }
6.2.4、自动装配配置
根据自动装配原则,在tanhua-autoconfig工程创建 /META-INF/spring.factories文件
1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2. com.tanhua.autoconfig.TanhuaAutoConfiguration
6.2.5、测试
tanhua-app-server工程加入短信配置
1. tanhua: 2. sms: 3. signName: 物流云商 4. templateCode: SMS_106590012 5. accessKey: LTAI4GKgob9vZ53k2SZdyAC7 6. secret: LHLBvXmILRoyw0niRSBuXBZewQ30la
编写单元测试类
1. @RunWith(SpringRunner.class) 2. @SpringBootTest(classes = AppServerApplication.class) 3. public class SmsTemplateTest { 4. 5. //注入 6. @Autowired 7. private SmsTemplate smsTemplate; 8. 9. //测试 10. @Test 11. public void testSendSms() { 12. smsTemplate.sendSms("18618412321","4567"); 13. } 14. }