技术上:
1、 httpClient远程调用技术
2、 使用Java代码发短信
3、 调用阿里云通信(阿里大于)发送短信
业务:完成用户注册
1 HttpClient的使用
1.1 常用的远程调用技术:
1、socket 套接字 效率特别高 开发特麻烦,
2、Webservice xml 传统公司使用比较多,比较稳定效率相对快一点
3、hessian
4、httpClient json 多用于互联网公司 稍微稍微简洁点
5、dubbo
1.2 httpClient 的demo
需要的依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
1.2.1 Get请求不带参数
public static void main(String[] args) throws Exception {
// https://www.baidu.com/s?ie=UTF-8&wd=httpClient
// 1:相当于打开浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
// 2:创建一个get的请求方式
HttpGet httpGet = new HttpGet("http://www.baidu.com/");
// 3:执行了ge t请求
CloseableHttpResponse response = httpClient.execute(httpGet);
// 4:获取返回的数据
// 200:正常
// 404:找不到资源
// 500:服务器内部错误
// 400:参数问题
// 302:重定向
// 304:缓存
// 403:Forbidden
if( response.getStatusLine().getStatusCode()==200){// 如果状态码是200 表示正常返回了
// 把返回的内容转成字符串
String content = EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println(content);
}
}
1.2.2 Get请求带参数:
1.2.3 Post请求不带参数
1.2.4 Post请求带参数
1.2.5 使用工具类
public static void main(String[] args) throws Exception {
HttpClient httpClient = new HttpClient("http://localhost:8081/brand/findPage");
// int pageNo, int pageSize
httpClient.addParameter("pageNo","1");
httpClient.addParameter("pageSize","3");
httpClient.post();
String content = httpClient.getContent();
System.out.println(content);
}
2 阿里云通信的使用
www.aliyun.com
需要申请账号,但是阿里云通信目前关闭了个人账号的申请
注意阿里云通信中需要申请签名和模板
3 创建一个发送短信的网关
3.1 创建项目拷贝配置文件
3.2 配置文件的内容
Web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Springmvc.xml文件
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:config/application.properties" />
<context:component-scan base-package="com.pyg.sms"/>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
<property name="features">
<array>
<value>WriteMapNullValue</value>
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--放行静态资源-->
<mvc:default-servlet-handler/>
</beans>
Pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>pyg_parent</artifactId>
<groupId>com.pyg</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<artifactId>pyg_sms</artifactId>
<dependencies>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 指定端口 -->
<port>7788</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.3 参考阿里云通信的代码创建SMSController
@RestController
@RequestMapping("/sms")
public class SmsController {
//产品名称:云通信短信API产品,开发者无需替换
static final String product = "Dysmsapi";
//产品域名,开发者无需替换
static final String domain = "dysmsapi.aliyuncs.com";
@Value("${accessKeyId}")
private String accessKeyId;
@Value("${accessKeySecret}")
private String accessKeySecret;
@RequestMapping("/sendSms")
public Map sendSms(String phoneNumbers,String signName,String templateCode,String templateParam){
SendSmsResponse response = null;
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("18703448120");
request.setPhoneNumbers(phoneNumbers);
//必填:短信签名-可在短信控制台中找到
// request.setSignName("品位优雅购物");
request.setSignName(signName);
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(templateCode);
// request.setTemplateCode("SMS_130926832");
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// 您的验证码为:${code},该验证码 5 分钟内有效,请勿泄漏于他人
request.setTemplateParam(templateParam);
// request.setTemplateParam("{\"code\":\"3234\"}");
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
//hint 此处可能会抛出异常,注意catch
response = acsClient.getAcsResponse(request);
Map map = new HashMap();
map.put("code",response.getCode());
map.put("message",response.getMessage());
map.put("requestid",response.getRequestId());
map.put("bizid",response.getBizId());
return map;
} catch (ClientException e) {
e.printStackTrace();
return null;
}
}
3.4 使用httpClient工具类测试
public static void main(String[] args) throws Exception {
HttpClient httpClient = new HttpClient("http://127.0.0.1:7788/sms/sendSms");
// (String phoneNumbers,String signName,String templateCode,String templateParam)
httpClient.addParameter("phoneNumbers","XXXXXXXXXXX");
httpClient.addParameter("signName","品位优雅购物");
httpClient.addParameter("templateCode","SMS_130926832");
String numeric = RandomStringUtils.randomNumeric(4);
System.out.println(numeric);
httpClient.addParameter("templateParam","{\"code\":\""+numeric+"\"}");
httpClient.post();
System.out.println(httpClient.getContent());
}
4 完成用户的注册
4.1 分析
4.2 创建项目
发送短信验证码的service代码
@Autowired
private RedisTemplate redisTemplate;
@Override
public void sendSms(String phone) throws Exception {
// 使用httpClient发送短信
HttpClient httpClient = new HttpClient("http://127.0.0.1:7788/sms/sendSms");
// (String phoneNumbers,String signName,String templateCode,String templateParam)
httpClient.addParameter("phoneNumbers",phone);
httpClient.addParameter("signName","品位优雅购物");
httpClient.addParameter("templateCode","SMS_130926832");
String numeric = RandomStringUtils.randomNumeric(4);
System.out.println(numeric);
httpClient.addParameter("templateParam","{\"code\":\""+numeric+"\"}");
httpClient.post();
System.out.println(httpClient.getContent());
// redisTemplate.boundValueOps("sms_"+phone).set(numeric,5, TimeUnit.MINUTES);
// 把验证码放入到redis中
redisTemplate.boundValueOps("sms_"+phone).set(numeric,30, TimeUnit.SECONDS);
}
注册时的service代码:
@Override
public void add(TbUser user, String code) {
String numeric = (String) redisTemplate.boundValueOps("sms_" + user.getPhone()).get();
if(numeric==null){
throw new RuntimeException("验证码已失效");
}
if(!numeric.equals(code)){
throw new RuntimeException("验证码输入有误");
}
// 处理默认值
String password = user.getPassword(); //明文
password = DigestUtils.md5Hex(password); //通过MD5加密
user.setPassword(password);
user.setCreated(new Date());
user.setUpdated(new Date());
//`password` varchar(32) NOT NULL COMMENT '密码,加密存储',
// `created` datetime NOT NULL COMMENT '创建时间',
// `updated` datetime NOT NULL,
//`source_type` varchar(1) DEFAULT NULL COMMENT '会员来源:1:PC,2:H5,3:Android,4:IOS,5:WeChat',
userMapper.insert(user);
// 验证码使用后就可以清除了
redisTemplate.delete("sms_" + user.getPhone());
}