发表于: 2018-01-22 22:14:58
3 643
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
完成了邮件的发送以及验证,头像图片的上传.东西有点多..另外因为短信需要照相认证,没法做,只能放到明天完成.
邮箱验证这块儿的整体逻辑是这样的:
在用户点击获取验证邮件之后,将一个带有两个参数的get请求的url发送给用户,并且将这两个参数存储到缓存中,用以进行比对.
看一下代码:
//发送验证邮件
@RequestMapping(value = "/u/email", method = RequestMethod.GET)
public String email(HttpServletRequest request, HttpSession session) throws IOException {
//这两句代码是为了获取请求URL
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
User user = userServiceImpl.selectUser((String) session.getAttribute("name"));
//获取点击链接的密钥,以及密钥ID
String verifyCode = UUID.randomUUID().toString();
String verifyCodeKey = user.getId().toString();
//将密钥存储进redis缓存中用于等待激活验证,存活时间为15分钟
redisUtil.put("mail", verifyCodeKey, verifyCode, 60 * 15L);
//统计邮件发送条数,发送1封之后给用户显示已发送.
session.setAttribute("mailCount", 1);
Mail mail = new Mail();
mail.setAddress(user.getEmail());
mail.setName(user.getUserName());
//进行验证url的拼接,使用get请求的方式将验证密钥和ID携带在URL中发送给用户邮件
mail.setUrl(basePath + "/verify?verifyCode=" + verifyCode+"&verifyCodeKey="+verifyCodeKey);
//调用邮件发送接口
SendCloudAPIV2_44.send_template(mail);
return "redirect:/u/user";
}
//用户url验证
@RequestMapping(value = "/verify", method = RequestMethod.GET)
public String verify(String verifyCode,String verifyCodeKey, HttpSession session) {
//判断用户通过URL get访问过来的数据是否能和redis中数据配对.
if (verifyCode.equals(redisUtil.get("mail", verifyCodeKey))) {
//配对成功更新数据库中的验证字段
userServiceImpl.upEmail(new Long(verifyCodeKey));
//成功之后删除对应的缓存以及Session字段.
redisUtil.del("mail", "verifyCode");
session.removeAttribute("mailCount");
}
return "redirect:/u/user";
}
}
页面做的一些判断
<div>
<span>${email}<span/>
<span>
<c:if test="${emailConf==0}">
<c:if test="${mailCount==1}">邮件已发送,请到邮箱验证</c:if>
<c:if test="${mailCount==null}"><a href="${pageContext.request.contextPath}/u/email">点击验证邮箱</a> </c:if>
</c:if>
<c:if test="${emailConf==1}">
邮箱已验证 </c:if>
<span/>
</div>
看一下测试效果:
点击获取邮件之后.这里我做了一个判断,15分种类未验证的话才允许冲洗发送邮件
进入邮箱查看:
可以看到我们的UR里面包含了2个信息,一个是我们的密钥ID,另外一个是密钥的值.
立即激活的按妞和这个链接是同样的功能.点击即可激活.
我在数据库中给了1个字段用以判断是否激活,未激活默认值为0,激活之后为1
页面上用于判断是否激活也是根据数据库这个字段来的.
具体逻辑其实更多,不过日报里不好表现,大致思路就是这样了.
头像上传,我使用的是阿里云的OSS,使用还是比较简单,OSS给的依赖和接口.
<!--阿里云OSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.2</version>
</dependency>
package com.util;
import com.aliyun.oss.OSSClient;
import com.dao.UserDao;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
/**
* @author Arike
* Create_at 2018/1/22 10:20
*/
public class Oss {
/**
* 图片上传
* @param is 输入的流文件
* @param end 截取的文件后缀名
* @return 返回图片地址
*/
public static String fileUp(InputStream is, String end) {
// endpoint以杭州为例,其它region请按实际情况填写
String endpoint = "http://oss-cn-beijing.aliyuncs.com";
// 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
String accessKeyId = "xxxxxxxxxx";
String accessKeySecret = "xxxxxxxxxx";
// 创建OSSClient实例
OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
String key = "task7/"+UUID.randomUUID()+"."+end;
// 使用访问OSS
// 上传文件流
client.putObject("head-file", key, is);
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
// 关闭client
client.shutdown();
return "http://head-file.oss-cn-beijing.aliyuncs.com/"+key;
}
}
对用的controller
//上传头像
@RequestMapping(value = "/u/file", method = RequestMethod.POST)
public String fileup(MultipartFile file, HttpSession session) throws IOException {
//获取到输入流
InputStream is = file.getInputStream();
//通过split方法用.分割文件名,并获取到最大索引位置的字符串(肯定就是后缀名了,不管他有多少个.)
String[] name = file.getOriginalFilename().split("\\.");
String end = name[name.length - 1];
User user = new User();
user.setUserName((String) session.getAttribute("name"));
user.setHead(Oss.fileUp(is, end));
userServiceImpl.upHead(user);
return "redirect:/u/user";
}
对应的页面:
<form action="${pageContext.request.contextPath}/u/file" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" name="提交">
</form>
<img src="${head}">
对应的数据库字段:
演示一下:
未上传任何图片
图片上传之后:
明天计划的事情:(一定要写非常细致的内容)
把短信验证做了, 顺便再回顾一波反射.
遇到的问题:(遇到什么困难,怎么解决的)
首先问题有几个,我提一下就是做验证邮件的时候会出现的问题.
第一个问题:
我一开始是把验证信息存储在Session中,意在降低数据库的压力,然而这有一个问题,session里我同时存放了验证登录状态的东西,以及用户信息,这个邮件验证的生命周期我就不好设置了.
第二个问题:
如果用户是在手机或者在申请邮件之后没有及时进行验证,用户到另外一台电脑就验证不了了,因为这个用户的连接的Session和他之前的那个session是不同的了,就导致无法定位到之前那个Session里进行验证.
解决思路也就是我上面的代码,使用缓存来做这些东西.缓存就可以脱离连接而存在,并且具有独立的声明周期,这个是比较好的.
在远程能连接服务器的Redis缓存, 项目打包到服务器上反而连接不上缓存了.有点迷.
这个问题因为我是晚上11点临时想去服务器尝试一下邮件,所以只能明天处理
收获:(通过今天的学习,学到了什么知识)
在写判断逻辑很多的代码的时候,思路一定要清晰, 要先理清楚需求(目的)是什么,再根据这个需求去思考逻辑,
才能比较顺畅的完成需求.
评论