项目一:第八天 1、前台系统导入 实现客户注册 发验证码,邮件 springdata-redis存储数据 3、实现客户登陆
1 前台系统客户注册功能
页面:signup.html

1.1 验证手机号是否注册(邮箱同样)
1、 使用Jquery-validate插件进行相关校验,使用校验规则
<input type="text" id="telephone" value="" name="telephone" class="fn-tinput" placeholder="手机号" required data-rule-mobile="true" data-rule-remote="customerAction_validateTel.action" data-msg-required="请输入手机号" data-msg-mobile="请输入正确格式" data-msg-remote="手机号已经被注册!" />

1、 在CRM中扩展手机号是否存在方法

2、 重新生成代码,将生成接口拷贝到前台项目中
3、 搭建前台系统中CXF客户端环境,在spring配置文件中产生代理对象

4、 在前台客户action中注入远程调用代理对象,调用服务器端方法

客户注册页面验证码60秒倒计时效果实现并发送请求

校验手机号是否合法:

1.1 调用阿里云通信发送短信验证码
在bosutil项目中提供发送短信工具类

public class AliSMSUtil {
/**
* SMS_127167078 , ${username}
* SMS_119087143, ${code}
*/
public static boolean sendMessge(String tel, String templateCode, Map<String, Object> tempalteParams){
try {
//设置超时时间-可自行调整
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
// 初始化ascClient需要的几个参数
final String product = "Dysmsapi";//短信API产品名称(短信产品名固定,无需修改)
final String domain = "dysmsapi.aliyuncs.com";//短信API产品域名(接口地址固定,无需修改)
//TODO 替换成你的AK
final String accessKeyId = "LTAIbzuUhxVW8GDT";//你的accessKeyId,参考本文档步骤2
final String accessKeySecret = "SXEYEjZTnSa2uo2Pf77llrXt2XhvjC";//你的accessKeySecret,参考本文档步骤2
//初始化ascClient,暂时不支持多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();
//使用post提交
request.setMethod(MethodType.POST);
//必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
request.setPhoneNumbers(tel);
//TODO 必填:短信签名-可在短信控制台中找到
request.setSignName("速运");
//TODO 必填:短信模板-可在短信控制台中找到
request.setTemplateCode(templateCode);
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
// request.setTemplateParam("{\"name\":\"Tom\", \"code\":\"123\"}");
// String randomNumeric = RandomStringUtils.randomNumeric(4);
// HashMap<String, Object> map = new HashMap<>();
// map.put("code", randomNumeric);
String templateParam = JSONObject.fromObject(tempalteParams).toString();
request.setTemplateParam(templateParam);
//可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
//请求失败这里会抛ClientException异常
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
System.out.println(sendSmsResponse.getMessage());
if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
//请求成功
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

1.2 客户注册页面调整并提交表单
修改注册表单form的action地址。


改为异步方式提交:
//将表单中所有输入项(必须有name) 转为json对象形式 {"input的name","input中value"}
$.fn.serializeJson=function(){
var serializeObj={};
var array=this.serializeArray();
var str=this.serialize();
$(array).each(function(){
if(serializeObj[this.name]){
if($.isArray(serializeObj[this.name])){
serializeObj[this.name].push(this.value);
}else{
serializeObj[this.name]=[serializeObj[this.name],this.value];
}
}else{
serializeObj[this.name]=this.value;
}
});
return serializeObj;
};
表单调用方法:

服务器端:
/**
* @Description: 调用CRM注册客户信息
* @return 0:注册失败 1:注册成功 2:验证码不正确
* @throws Exception
*
*/
@Action("customerAction_regist")
public String regist() throws Exception {
try {
//获取正确验证码
String realChecode = (String) ServletActionContext.getRequest().getSession().getAttribute(model.getTelephone());
if(StringUtils.isNotBlank(realChecode)){
if(realChecode.equals(checkcode)){
//调用CRM完成注册
customerPRoxy.regist(model);
//TODO 发送短信
//生成激活码-将来手机号跟激活码一一对应
String activeCode = UUID.randomUUID().toString()+UUID.randomUUID().toString();
String content = "欢迎您注册速运快递,为了提供更好的服务,请您在24小时内激活账户!!</br>"
+ "<a href='"+MailUtils.activeUrl+"?telephone="+model.getTelephone()+"&activeCode="+activeCode +"'>点击激活账户</a>";
//TODO 给用户发送激活账户邮件
MailUtils.sendMail("欢迎注册快递", content, model.getEmail());
//将激活码存储--redis内存数据库中
redisTemplate.opsForValue().set(model.getTelephone(), activeCode, 24, TimeUnit.HOURS);
//将Session中验证码移除
ServletActionContext.getRequest().getSession().removeAttribute(model.getTelephone());
ServletActionContext.getResponse().getWriter().write("1");
}else{
//验证码不正确
ServletActionContext.getResponse().getWriter().write("2");
}
}
} catch (Exception e) {
e.printStackTrace();
ServletActionContext.getResponse().getWriter().write("0");
}
return NONE;
}
1.1 在CRM服务中提供客户注册方法

需要重新发布服务,生成本地调用代码。将生成本地调用代码(接口跟Customer实体类)拷贝到前台系统中。


将复制接口,配置spring配置文件:配置访问CRM系统的代理对象。
测试注意:现有客户表中已经数据,第一条记录查询序列值为1,跟现有数据id冲突,违反唯一约束。
在客户action中调用CRM完成客户保存:
@Autowired
private CustomerService customerProxy; //注入远程调用CRM服务代理对象
//接收页面提交验证码
private String checkcode;
public void setCheckcode(String checkcode) {
this.checkcode = checkcode;
}
/**
* @Description: 远程调用CRM保存客户记录
*/
@Action("customerAction_regist")
public String regist() throws Exception {
if(StringUtils.isNotBlank(checkcode)){
//判断验证码是否正确
//获取正确的验证码
String realCheckcode = (String) ServletActionContext.getRequest().getSession().getAttribute(model.getTelephone());
if(checkcode.equals(realCheckcode)){
//对用户密码进行加密
model.setPassword(Md5Util.encode(model.getPassword()));
customerProxy.save(model);
//发送短信通知用户:及时登录注册邮箱完成账户激活
//发送激活账户邮件
//将session中验证码清除
ServletActionContext.getRequest().getSession().removeAttribute(model.getTelephone());
return "signSuccess";
}
}
return "signError";
}
1 发送激活账户邮件
1 发送激活账户邮件
SMTP协议:Simple Mail Transfer Protocol 简单邮件传输协议----发送邮件协议
POP协议:Post Office Protocol:邮局协议 –接收邮件 v:pop3

1.1 Javamail发送邮件
导入工具类:

1.2 使用javamail发送激活账户邮件

String content = "欢迎您注册速运快递,为了提供更好的服务,请您在24小时内激活账户!!</br>"
+ "<a href='"+MailUtils.activeUrl+"?telephone="+model.getTelephone()+"&activeCode="+activeCode+"'>点击激活账户</a>";
MailUtils.sendMail("欢迎注册速运快递员", content, model.getEmail());
2 spring-data-redis使用
1.1 spring-data-redis操作数据库

Springdataredis通过配置连接池实现高效率操作数据库,提供模板redisTemplate简化操作数据库
1、 引入依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${springdataredis.version}</version>
</dependency>
2、 在spring配置文件中进行相关配置
<!-- jedis 连接池配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300" />
<property name="maxWaitMillis" value="3000" />
<!-- 从连接池中获取连接,先进行测试看连接是否可用,如果不能使用重新获取连接 -->
<property name="testOnBorrow" value="true" />
</bean>
<!-- jedis 连接工厂 -->
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost"/>
<property name="port" value="6379"/>
<property name="poolConfig" ref="poolConfig"/>
</bean>
<!-- spring data 提供 redis模板 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer">
</bean>
</property>
</bean>
3、 在项目中通过redisTemplate对象操作redis数据库

1.2 使用redisTemplate存储账户激活码
1、 在前台系统CustomerAction中注入redisTemplate
2、 通过末班对象操作redis数据库

1 完成账户邮箱激活


账户激活功能:验证在注册使用录入邮箱是否正确;
目的:前台系统远程调用CRM将数据库客户表中type值改为“1”;
1.1.1 在CRM中扩展方法
1、 查询客户账户状态:根据手机号查询账户状态(返回客户对象)
2、 根据客户Id更新type字段的值
Service:

Dao:

重新启动项目,生成前台系统调用的代码:
1.1.2 在前台系统中调用CRM方法
1、 注册用户会接收激活邮箱邮件,在邮件中有激活地址,点击

//激活链接中提交 url提交激活码
private String activeCode;
public void setActiveCode(String activeCode) {
this.activeCode = activeCode;
}
/**
* @Description: 激活邮件-确保邮箱是客户
*/
@Action("customerAction_activeMail")
public String activeMail() throws Exception {
ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
//1、查询客户激活状态
if(StringUtils.isNotBlank(model.getTelephone())&&StringUtils.isNotBlank(activeCode)){
Customer customer = customerPRoxy.findByType(model.getTelephone());
if(customer!=null){
if(customer.getType()==null){
//未激活状态
//2、判断激活码是否正确
String realActiveCode = redisTemplate.opsForValue().get(model.getTelephone());
if(StringUtils.isNotBlank(realActiveCode)){
if(activeCode.equals(realActiveCode)){
//3、调用CRM激活账户
customerPRoxy.activeAccount(customer.getId());
//清除redis数据库中激活码
redisTemplate.delete(model.getTelephone());
ServletActionContext.getResponse().getWriter().write("激活码成功,祝您使用愉快!");
}else{
//激活码错误
ServletActionContext.getResponse().getWriter().write("激活码错误");
}
}else{
//激活码失效
ServletActionContext.getResponse().getWriter().write("激活码失效");
}
}else{
//账户已经激活
ServletActionContext.getResponse().getWriter().write("账户已经激活");
}
}else{
//手机号不存在
ServletActionContext.getResponse().getWriter().write("手机号不存在");
}
}else{
//激活码或者手机为空
ServletActionContext.getResponse().getWriter().write("激活码或者手机为空");
}
return NONE;
}
1 MD5加密函数
2 实现前台系统登录功能
2.1 前台系统页面调整
1、将以下代码拷贝登陆form表单中,去后台管理系统中拷贝页面:validatecode.jsp
<div class="form-group">
<label for="inputvalidate" class="col-sm-3 control-label">验证码</label>
<div class="col-sm-4">
<input type="text" name=”checkCode” class="form-control" id="inputaccount" placeholder="请输入验证码">
</div>
<div class="col-sm-4">
<img id="loginform:vCode" src="validatecode.jsp" onclick="javascript:document.getElementById('loginform:vCode'). src='validatecode.jsp?'+Math.random();" />
</div>
</div>
1、 提交表单:使用工具方法将表单中的输入项序列化为json
//将表单中输入项序列为json对象
$.fn.serializeJson=function(){
var serializeObj={};
var array=this.serializeArray();
var str=this.serialize();
$(array).each(function(){
if(serializeObj[this.name]){
if($.isArray(serializeObj[this.name])){
serializeObj[this.name].push(this.value);
}else{
serializeObj[this.name]=[serializeObj[this.name],this.value];
}
}else{
serializeObj[this.name]=this.value;
}
});
return serializeObj;
};

注意:发送的是ajax请求。

Name:将来可能邮箱,可以是账户名
1、 在customerAction中添加方法
1.1 CRM中扩展登陆方法
Service:

Dao:

重新发布服务,生成本地调用代码:
1.1 前台实现登陆
//登陆:name可能是手机号可能是邮箱或者是账户名
private String name;
public void setName(String name) {
this.name = name;
}
/**
* @Description: 登陆
* @return
* @throws Exception
*
*/
@Action("customerAction_login")
public String login() throws Exception {
//获取真实验证码
String realCode = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
if(checkCode.equals(realCode)){
//调用CRM判断提交数据是否正确
Customer customer = crmProxy.login(name, model.getPassword());
if(customer!=null){
ServletActionContext.getResponse().getWriter().write("1");
ServletActionContext.getRequest().getSession().setAttribute("loginUser", customer);
return NONE;
}else{
//创建 json对象 设置消息具体信息
ServletActionContext.getResponse().getWriter().write("0");
return NONE;
}
}
return NONE;
}
在页面中判断回调的值,跳转页面

项目一:第八天 1、前台系统导入 实现客户注册 发验证码,邮件 springdata-redis存储数据 3、实现客户登陆的更多相关文章
- ZZJ_淘淘商城项目:day04(淘淘商城03 - 前台系统搭建、实现、内容管理系统实现)
1. 今日大纲 1. 实现商品的编辑 2. 实现商品的规格参数功能 3. 搭建前台系统 4. 实现首页商品类目的显示 2.2.4. 未实现TODO 编辑时图片回显: 思路: 1. 查 ...
- 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 项目-基于视频压缩的实时监控系统--tiny6410
项目-基于视频压缩的实时监控系统--tiny6410 @国嵌linux学习笔记. 1. 构造服务端结构体 server struct server { int epfd; //保存epoll指针 st ...
- JAVAEE——宜立方商城05:前台系统搭建、首页展示、Cms系统的实现
1. 学习计划 1.前台系统搭建 2.商城首页展示 3.Cms系统的实现 a) 内容分类管理 b) 内容管理 4.前台内容动态展示 2. 商城首页展示 系统架构: 页面位置: 2.1. 工程搭建 可以 ...
- 仿LOL项目开发第八天
仿LOL项目开发第八天 by 草帽 这节我们继续上节所讲的内容,上节我们初始化好了LoginWindow,当我们点击确认选择服务器按钮的时候,就发送服务器id给游戏服务器. 这里就开始涉及到客户端需要 ...
- 业务逻辑:完成客户下单后前台系统的数据处理并调用后台系统服务处理业务 webservice接口调用 有用
思路: 页面提交表单后,在Action类中将页面提交的参数进行组装,随后通过使用Webservice技术来远程调用后台系统的业务接口服务来进行订单的保存操作 操作步骤: 在前台系统的Action类中通 ...
- 初阶项目一-集成一套linux系统:红帽系统,LVM分区,Apache服务,MySQL服务,数据定时备份脚本
目录 一.项目目标 二.实施工具 三.项目实施计划 四.安装rhel7.5操作系统 4.1 配置虚拟机 4.2 安装操作系统 4.3 系统配置 4.3.1 网络配置 4.3.2 修改主机名 4.3.3 ...
- vue大型电商项目尚品汇(前台篇)day02
现在正式回归,开始好好做项目了,正好这一个项目也开始慢慢的开始起色了,前面的准备工作都做的差不多了. 而且我现在也开始慢慢了解到了一些项目才开始需要的一些什么东西了,vuex.router这些都是必备 ...
- 项目接入即时聊天客服系统(环信系统)PHP后端操作
环信工作原理: 一.由于环信没有直接的接口来主动调取本项目中的用户数据,所有用户信息必须在环信服务器上注册对应信息成为环信的用户:(这样才能当用户进入聊天时显示其基本信息,如:名称.昵称.电话.邮箱等 ...
随机推荐
- Git_学习_07_ 推送修改到远端
一.操作流程 多人协作时,若自己的本地代码有了修改,想提交自己的代码,就需要按照以下步骤操作: 1.确认修改正确 使用以下命令,查看有哪些是自己未提交的代码 git status 2.拉取远程最新代码 ...
- 在winform中给GridView加checkbox在按钮点击的时候获取选中的checkbox
dataGridView绑定后 bool[] mark = new bool[this.dataGridView1.Rows.Count]; ; i < mark.Length; i++) { ...
- 马拉车——Manacher一篇看上去很靠谱的理解(代码显然易懂)
由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以这里我们使用一个技巧,在字符间插入一个字符(前提这个字符未出现在串里).举个例子:s="a ...
- LeetCode Reverse Words in a String III
原题链接在这里:https://leetcode.com/problems/reverse-words-in-a-string-iii/#/description 题目: Given a string ...
- HIVE-利用ow_number() OVER(PARTITION BY)函数介绍求TOP-K
http://blog.csdn.net/631799/article/details/7419797 第一句话: select row_number() over (partition by mon ...
- Java 虚拟机-Java内存区域
简要介绍Java的内存区域: 运行时数据区域 HotSpot虚拟机对象 一.概览 二.运行时数据区域 2.1 程序计数器 Program Counter Register,代表当前线程所执行的字节码的 ...
- Oracle记录(一)Oracle简介与安装
Oracle笔记(一) Oracle简介及安装 一.轨迹 二.Oracle简介 Oracle是现在全世界最大的数据库提供商,编程语言提供商,应用软件提供商,它的地位等价于微软的地位. Oracle在古 ...
- unix下网络编程之I/O复用(二)
select函数 该函数允许进程指示内核等待多个事件中的任何一个发生,并仅在有一个或是多个事件发生或经历一段指定的时间后才唤醒它.我们调用select告知内核对哪些描述字(就读.写或异常条件)感兴趣以 ...
- ArcGis教程
91卫图助手帮助中心-如何导出ArcGIS Server瓦片格式并进行发布 http://help.91weitu.com/rhdcarcgis%20serverwpgsbjxfb.html ArcG ...
- DCloud-MUI:杂项
ylbtech-DCloud-MUI:杂项 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 7.返回顶部 8.返回顶部 9.返回 ...