发表于: 2017-07-17 21:14:36

2 1051


今天完成了任务7的内容:



1.学员报名系统加上手机,邮箱,头像的字段,接口中添加对应的字段。
2.去容联申请免费的短信通道(或者是收钱的我不知道),SendCloud申请邮箱的,去金山云或者是七牛云去申请图片存储的。所有的账号和密码都只能通过Spring的配置文件完成。
3.分别按照Demo,测试短信,邮件,图片能否正常上传,账号是否可以正常使用,再去集成到自己的学员报名系统中。
4.分别做好异常处理,要知道第三方Api是很容易出问题的,最常见的方式就是当出现异常的时候,记录错误日志,然后每天晚上跑脚本,看看当天的邮件,短信,图片上传的失败率有多少。

5.编写图片迁移程序:假设是从金山云迁到七牛云,以及从七牛云迁到金山云。



部分代码:


控制器增加两个方法,一个注册,一个获取验证码。


注册控制器中,有6个参数,分别是,一个new 的用户对象,密码,验证码,头像图片的文件,用户选择的储存服务,Request。先校验验证码,再上传图片,再将用户数据插入数据库,再发送欢迎邮件,最后返回成功JSP页面。


验证码控制器中,使用SessionId和SessionLastAccessTime防止恶意发送验证码(本来应该使用定时运行功能,但配置起来过于麻烦,就暂时这样实现了),同一个Session半个小时不能超过三次取得验证码。


@PostMapping("/register")
public String registerHandler(User user,
                              @RequestParam("password") String password,
                              @RequestParam("code") String code,
                              @RequestParam("file") MultipartFile file,
                              @RequestParam(value = "service", required = false) Integer serviceNum,
                              HttpServletRequest request) throws Throwable {
    //首先校验短信验证码
    if (!smsCodeService.checkSmsCode(user.getPhone(), Integer.parseInt(code))){
        request.setAttribute("message", "验证码错误!");
        return "register";
    }
    //上传图片到七牛(或阿里)
    if(serviceNum == 1){
        storageService = aliService;
    }else{
        storageService = qiniuService;
    }
    if (!file.isEmpty()) {
        byte[] bytes = file.getBytes();
        storageService.upload(bytes, user.getUsername());
    }
    //将密码转为token
    String token = md5Cipher.MD5(password);
    user.setPasswordToken(token);
    //数据库中加入用户
    userService.insertUser(user);
    //发送确认邮件
    emailService.sendWelcome(user);
    request.setAttribute("user", user);
    return "success";
}
@PostMapping("/getcode")
public String smscodeHandler(@RequestParam("phone") String phone, HttpServletRequest request){
    String session = request.getRequestedSessionId();
    if(!sessionMap.containsKey(session)){
        sessionMap.put(session, 1);
        sessionTimeMap.put(session, request.getSession().getLastAccessedTime());
        smsCodeService.sendSmsCode(phone);
        return "register";
    }
    if(isExpired(30, sessionTimeMap.get(session))){
        sessionTimeMap.remove(session);
        sessionMap.remove(session);
        smsCodeService.sendSmsCode(phone);
        return "register";
    }
    if(sessionMap.get(session) <= 2){
        sessionMap.put(session, sessionMap.get(session) + 1);
        smsCodeService.sendSmsCode(phone);
        return "register";
    }
    else {
        return "redirect:/smscode.jsp";
    }


下面是使用的第三方SDK写的服务类:


阿里对象储存:


@Service
public class AliService implements StorageService{
    @Autowired
    private OSSClient ossClient;
    public boolean upload(byte [] bytes, String key){
        ossClient.putObject("zt1106", key, new ByteArrayInputStream(bytes));
        return true;
    }
    public byte [] download(String key) throws IOException {
        OSSObject ossObject = ossClient.getObject("zt1106", key);
        InputStream content = ossObject.getObjectContent();
        if (content != null) {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            copy(content, output);
            byte [] bytes = output.toByteArray();
            content.close();
            return bytes;
        }
        return null;
    }
}

七牛对象储存:


public class QiniuService implements StorageService{
    @Autowired
    private Logger logger;
    private String accessKey;
    private String secretKey;
    private String bucket;
    //private String key = "file key";
    //构造一个带指定Zone对象的配置类
    //zone1代表华北地区
    private Configuration cfg;
    //...其他参数参考类注释
    private UploadManager uploadManager;
    //...生成上传凭证,然后准备上传
    private Auth auth;
    public QiniuService(){
        cfg = new Configuration(Zone.zone1());
        uploadManager = new UploadManager(cfg);
    }
    public QiniuService(String accessKey, String secretKey, String bucket) {
        this();
        this.accessKey = accessKey;
        this.secretKey = secretKey;
        this.bucket = bucket;
        auth = Auth.create(accessKey, secretKey);
    }
    public boolean upload(byte [] bytes, String key){
        String upToken = auth.uploadToken(bucket, key);
        try {
            Response response = uploadManager.put(bytes, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            //System.out.println(putRet.key);
            //System.out.println(putRet.hash);
            return  true;
        } catch (QiniuException ex) {
            Response r = ex.response;
            logger.error("picture upload failed" + r.toString());
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
        }
        return false;
    }
    public byte [] download(String key) throws UnsupportedEncodingException, MalformedURLException {
        String domainOfBucket = "http://ot36zr42o.bkt.clouddn.com/";
        String encodedFileName = URLEncoder.encode(key, "utf-8");
        String finalUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
        URL url = new URL(finalUrl);
        try {
            URLConnection conn = url.openConnection();
            InputStream inStream = conn.getInputStream();
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            copy(inStream, output);
            byte [] bytes = output.toByteArray();
            return bytes;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}


邮件服务方法(SendCloud):

public void sendWelcome(User user) throws Throwable {
    MailAddressReceiver receiver = new MailAddressReceiver();
    receiver.addTo(user.getEmail());
    MailBody body = new MailBody();
    body.setFrom("zt1106@zt1106.com");
    body.setFromName("zt1106");
    body.setReplyTo("reply@sendcloud.org");
    body.setSubject("注册成功!!");
    TextContent content = new TextContent();
    content.setContent_type(TextContent.ScContentType.html);
    content.setText("<html><p>" + user.getUsername() + " 您已注册成功</p></html>");
    SendCloudMail mail = new SendCloudMail();
    mail.setTo(receiver);
    mail.setBody(body);
    mail.setContent(content);
    SendCloud sc = null;
    try {
        sc = SendCloudBuilder.build();
    } catch (Exception e) {
        logger.error("send email failed, unknown error " + e.getMessage());
    }
    ResponseData res = sc.sendMail(mail);
    if(res.getStatusCode() != 200){
        logger.error("send email failed, " + res.getInfo());
    }


短信验证码方法(一家不知名网站的):


public void sendSmsCode(String phone){
    HttpClient client = new HttpClient();
    PostMethod method = new PostMethod(Url);
    client.getParams().setContentCharset("UTF-8");
    method.setRequestHeader("ContentType","application/x-www-form-urlencoded;charset=UTF-8");
    int mobile_code = (int)((Math.random()*9+1)*100000);
    map.put(phone, mobile_code);
    String content = "您的验证码是:" + mobile_code + "。请不要把验证码泄露给其他人。";
    NameValuePair[] data = {
            new NameValuePair("account", account),//APIID
            new NameValuePair("password", password)//APIKEY
            new NameValuePair("mobile", phone),
            new NameValuePair("content", content),
    };
    method.setRequestBody(data);
    try {
        client.executeMethod(method);
        //String SubmitResult =method.getResponseBodyAsString();
    }
    catch (HttpException e) {
        logger.error("sms code http failed " + e.getMessage());
    } catch (IOException e) {
        logger.error("sms code io failed " + e.getMessage());
    }



阿里云和七牛云互相迁移方法:


@Autowired
public PictureTransfer(UserService userService, AliService aliService, QiniuService qiniuService) {
    this.userService = userService;
    this.aliService = aliService;
    this.qiniuService = qiniuService;
}
public void transferToAli() throws Exception {
    transfer(qiniuService, aliService);
}
public void transferToQiniu() throws Exception {
    transfer(aliService, qiniuService);
}
public void transfer(StorageService from, StorageService to) throws Exception {
    List<User> userList = userService.getAllUsers();
    for (User user : userList){
        if (user.getUsername() != null) {
            to.upload(from.download(user.getUsername()), user.getUsername());
        }
    }


所有的第三方Service类都在Spring容器中进行配置,使用同一的config.properties配置文件配置用户名密码URL等属性。


在成功页面JSP显示刚注册好的用户的信息,和他在七牛云的照片:


<body>
用户信息:<br>
user information <%= request.getAttribute("user") %>
<br>
<%
    User user = (User) request.getAttribute("user");
    String link = "http://ot36zr42o.bkt.clouddn.com/" + user.getUsername();
%>
<img src="<%=link%>"/>
</body>


明天:开始学习任务8的新内容。


问题:

1. 对于控制器返回值的写法还是比较乱,总是搞混视图和路径,也搞不清楚路径和视图的名字的命名规范是什么。

2. 基础还是不牢,很多东西现查,然后查完了还记不住。

3. 项目越来越大,依赖的问题越来越频繁,在加载第三方SDK时,需要更多乱七八糟的jar包,导致maven里臃肿不堪。


总结:任务中的易容联和SendCloud的短信服务都不能用了,一个要企业认证,一个要充500块钱,建议找一些小网站,管的没那么严;对象储存很便宜,阿里云100GB一年才4块钱。


返回列表 返回列表
评论

    分享到