1

前言

因为疫情相信最近一段时间很多同学都在准备线上答辩,博主也是一样,从答辩前紧张到无法呼吸,到答辩后一身轻松感谢各位老师的指导,整个过程就像坐过山车一样充满刺激。再见了我的青春,我的学生时代。在答辩过程中经常会被问到说:你觉得你的项目有什么亮点?今天就来给大家分享一下可以用哪些简单的技术来增加自己毕设的一个亮点。

发送邮件

其实Spring已经帮我们封装好了邮件发送的功能,只需要直接拿来用就可以了,在我的项目里就通过Spring Mail实现了邮件注册、忘记密码以及给用户留言等功能

首先第一步肯定是引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

接着就是我们的MailService工具类

@Service
public class MailService {

    @Autowired
    private JavaMailSender mailSender;//Spring封装好的类

    private String from=xxx@163.com;

    /**
    * 发送邮件
    */
    @Async
    public void sendMail(String title, String url, String email) {
        SimpleMailMessage message = new SimpleMailMessage();//也是Spring封装好的
        message.setFrom(from);//邮件发送者
        message.setSubject(title);//邮件标题
        message.setTo(email);//邮件接收者
        message.setText(url);//邮件内容
        mailSender.send(message);//发送
    }
}

代码中的JavaMailSender以及SimpleMailMessage都是Spring已经封装好的类,可以直接拿来使用。
核心代码已经写好了,但是这个时候还不能使用,你需要去获取授权,这里以163邮箱为例

勾选后安装提示会叫你设置授权密码之类的:记住授权的密码

之后只需要在application.properties文件配置一下就可以了

#spring-mail
spring.mail.host=smtp.163.com
spring.mail.username=xxx@163.com  //这里换成自己的邮箱
spring.mail.password=xxxx  //授权密码
spring.mail.properties.mail.smtp.auth=truehouse
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

接下来就可以去测试一下

sendMail("激活邮件", "你好,我是超大只乌龟!", "13415038974@163.com");

效果如下:

image.png

可以看到非常简单就可以实现发送邮件的功能,当然这只是简单的发送邮件功能,在我的系统里面会要求用户在15分钟之内打开链接才能成功激活,否则链接就会失效,那我们来看下是如何实现的:

其实就是通过com.google.common的一个Cache类实现的,具体代码如下:

import com.google.common.cache.Cache;


//缓存key-email键值对,当超过15分钟有效期后,若用户还未激活则从数据库删除用户信息
private final Cache<String, String> registerCache =
            CacheBuilder.newBuilder().maximumSize(100).expireAfterAccess(15, TimeUnit.MINUTES)
            .removalListener(new RemovalListener<String, String>() {
            @Override
           public void onRemoval(RemovalNotification<String, String> notification) {
                String email = notification.getValue();
                User user = new User();
                user.setEmail(email);
                List<User> targetUser = userMapper.selectUsersByQuery(user);
                if (!targetUser.isEmpty() && Objects.equal(targetUser.get(0).getEnable(), 0)) {
                    userMapper.delete(email);// 代码优化: 在删除前首先判断用户是否已经被激活,对于未激活的用户进行移除操作
            }

        }
    }).build();

我在Cache里面放的就是key-email,这个key就是发送给用户的激活链接所带的key,比如下面这个就是用户点击注册后会发送到用户邮箱的内容,后面的sukERsSHbe就是随机生成的一个key

http://127.0.0.1:8090/accounts/verify?key=sukERsSHbe

通过配置一些API方法去设置一个15分钟的有效期,当15分钟后就会去调用RemovalListener监听器,也就是说会去执行onRemoval方法,在该方法里面就可以判断用户是否已经激活,若没有则删除用户数据。

上面代码如果看一遍不懂可以多看几遍。

关于这个key如何生成可以自己定义,我用的是org.apache.commons.lang3中的RandomStringUtils类:

String randomKey = RandomStringUtils.randomAlphabetic(10);

排行榜

上面介绍了发送邮件的功能,接下来看看一个排行榜的功能。

在我系统里面实现的效果就是可以根据用户的点击量去做一个实时的排行,一开始我是想在数据库添加一个字段来表示点击量的,但是觉得这样频繁访问数据库性能会比较低,因此我使用Redis来实现排行榜的功能。

我们就是通过Redis中一个叫做Sort Set的数据结构来完成该功能的,所以你最好先了解一下相关知识
菜鸟教程 Redis SortSet
代码如下:

//对redis有序集合中指定id的分数加上1
redisService.zincrby(HOT_HOUSE_KEY, 1.0D, id + "");
//0代表第一个元素,-1代表最后一个元素,因为要保留热度最高的10位,所以删除第1位到倒数第11位的元素,
//剩下10位热度最高的
redisService.zremrangeByRank(HOT_HOUSE_KEY, 0, -11);

本项目是一个房产交易系统,做的是热门房产排行,因此当用户点击之后就会调用redis的zincrby去给房产ID加分,redis会根据评分做一个排行,下面是封装好的reids类:

/**
     * 对有序集合中指定成员加分
     */
    public void zincrby(String key, double sorce, String id) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.zincrby(key, sorce, id);
        } finally {
            closePool(jedis);
        }
    }

    /**
     * 移除有序集中,指定排名(rank)区间内的所有成员
     */
    public void zremrangeByRank(String key, long start, long end) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.zremrangeByRank(key, start, end);
        } finally {
            closePool(jedis);
        }
    }

redis中默认是按照从低到高去做一个排行,之后通过zrevrange方法做一个倒序取出数据即可,如下:

Set<String> idSet =redisService.zrevrange(HOT_HOUSE_KEY, 0, -1);


/**
* 返回有序集中,指定区间内的成员。其中成员的位置按分数值递减(从大到小)来排列
*/
public Set<String> zrevrange(String key, long start, long end) {
    Jedis jedis = null;
    try {
        jedis = jedisPool.getResource();
        Set<String> set = jedis.zrevrange(key, start, end);
        return set;
    } finally {
        closePool(jedis);
    }
}

总结

以上两个功能可以算是系统的几个亮点,这两个功能在很多系统中都很常用,希望本篇文章能帮到你们,如果有什么不对的地方请多多指教!


超大只乌龟
882 声望1.4k 粉丝

区区码农


« 上一篇
死磕Synchronized
下一篇 »
初识Redis