03 注册功能开发

注册register

在开发注册功能是有一下几个功能需要实现:

  • 前端传递User数据需要更新到user表里面
  • 参数检查

难点在于怎么实现UserService里面的内容,我们可以把需求来拆分一下。

发送邮件验证

在注册时要填入自己的邮箱,这里我们需要使用Springbootemail邮件服务。

这里我使用qq邮箱的smtp服务进行开发,开通邮箱smtp服务的教程网上有很多,这里就不去写了。

配置信息

1
2
3
4
5
6
7
spring.mail.host=smtp.qq.com
spring.mail.port=465
spring.mail.username=xxxxx@qq.com
spring.mail.from=xxxxxx@qq.com
spring.mail.password=xxxxxx # 这里是生成的邮箱校验码,不是邮箱的登录密码
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.enable=true

在配置好后,我们还要使用mail服务,下面是mail服务的maven坐标

1
2
3
4
5
<!-- 邮箱服务       -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

可以将这个服务封装为util

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Component
public class EmailSendService {

    private static final Logger log = LoggerFactory.getLogger(EmailSendService.class);
    // 发送的客户端
    @Autowired
    private JavaMailSender mailSender;

    // 发送的邮件信息
    @Value("${spring.mail.from}")
    private String from;

    /**
     *
     * @param to
     * @param subject
     * @param content
     */
    public void sendSimpleMail(String to, String subject, String content) {
        // 创建发送信息
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
        try {
            mimeMessageHelper.setFrom(from);
            log.info("from: " + from);
            mimeMessageHelper.setTo(to);
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(content, true); // true表示支持html的内容
            mailSender.send(mimeMessage);
            log.info("发送成功");
        } catch (Exception e) {
            log.error("发送失败{}", e.getMessage());
        }

    }
}

其实这些都是固定写法,不必要去纠结,能看懂即可。

AOP字段封装

discuss_postuser等其它实体类里面经常有create_time这个字段,如果我们每次都去在创建这些对象的时候其实不太好管理,因此我们可以使用aop来实现这些公共方法

自定义注解

根据AOP的知识,我们以可以自定义注解+Aspect类的方式来实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package com.zxp.nowcodercommunity.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AutoCreateTime {
}

自定义Aspect

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.zxp.nowcodercommunity.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.time.LocalDateTime;


@Aspect
@Component
public class CreateTimeAspect {

    private static final Logger log = LoggerFactory.getLogger(CreateTimeAspect.class);

    @Around("@annotation(com.zxp.nowcodercommunity.annotation.AutoCreateTime)")
    public Object createTime(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("开始createTime字段填充");
        // 通过反射来获取运行时对象
        Object[] args = joinPoint.getArgs();
        if (args.length > 0) {
            // 获取第一个参数
            Object entity = args[0];
            Field[] fields = entity.getClass().getDeclaredFields();
            for (Field field : fields) {
                if ("createTime".equals(field.getName())) { // 只处理 createTime 字段
                    field.setAccessible(true);
                    if (field.get(entity) == null) { // 只有 createTime 为空时才赋值
                        field.set(entity, LocalDateTime.now());
                    }
                    break;
                }
            }
        }
        return joinPoint.proceed();
    }
}

然后在需要填充这些公共字段的方法上加上我们的注解,例如,可以在用户注册成功后加上该注解

1
2
@AutoCreateTime
void insertUser(User user);

总结

开发注册功能的难点就是以上几点!

Licensed under CC BY-NC-SA 4.0
花有重开日,人无再少年
使用 Hugo 构建
主题 StackJimmy 设计