发表于: 2018-01-22 22:14:58

3 644


今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了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点临时想去服务器尝试一下邮件,所以只能明天处理


收获:(通过今天的学习,学到了什么知识)

在写判断逻辑很多的代码的时候,思路一定要清晰, 要先理清楚需求(目的)是什么,再根据这个需求去思考逻辑,

才能比较顺畅的完成需求.


返回列表 返回列表
评论

    分享到