Step1: 顺序运行EurekaServer及EurekaClient,输入网址: http://localhost:8989/registry,得到图4所示的页面:
# eureka server端口号 默认是8761
server.port=8761
# 指定服务名称 注意:服务名不能出现下划线 默认服务名不区分大小写 推荐服务名大写
spring.application.name = EUREKASERVER
# eureka server服务注册中心地址 暴露服务地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
# 关闭eureka client的立即注册
eureka.client.fetch-registry=false
# 让当前应用仅仅是一个服务注册中心
eureka.client.register-with-eureka=false
package com.salieri;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer // 开启当前应用是一个服务注册中心
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class,args);
}
}
<!-- springboot相关依赖 -->
<!-- 引入eureka client -->
<!-- 引入包含雪花算法的工具包 -->
<!-- 引入包含整合前端页面的依赖 -->
<!-- mail -->
<!-- ssm -->
3.2 写配置
# 指定服务端口
# 指定服务名称
# 指定服务注册中心地址
# 指定数据库连接
# 指定邮件连接
3.3 代码段
3.3.1 mapper文件
package com.salieri.mapper;
import com.salieri.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface UserMapper {
// 新增用户
@Insert("INSERT INTO userinfo ( email, password, salt, confirm_code , activation_time, is_valid )" +
"VALUES ( #{email}, #{password}, #{salt}, #{confirmCode}, #{activationTime}, #{isValid})" )
int insertUser(User user);
// 根据确认码查询用户
@Select("SELECT email, activation_time FROM userinfo WHERE confirm_code = #{confirmCode} AND is_valid = 0")
User selectUserByConfirmCode(@Param("confirmCode") String confirmCode);
// 根据确认码查询用户并修改状态值为1(可用)
@Update("UPDATE userinfo SET is_valid = 1 WHERE confirm_code = #{confirmCode}")
int updateUserByConfirmCode(@Param("confirmCode") String confirmCode);
// 根据邮箱查询用户
@Select("SELECT email, password, salt FROM userinfo WHERE email = #{email} AND is_valid = 1")
List<User> selectUserByEmail(@Param("email") String email);
}
3.3.2 service文件
3.3.2.1 UserService
package com.salieri.service;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.salieri.mapper.UserMapper;
import com.salieri.pojo.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class UserService {
@Resource
private UserMapper userMapper;
@Resource
private MailService mailService;
// 注册账号
@Transactional
public Map<String, Object> createAccount(User user) {
// 雪花算法生成确认码
String confirmCode = IdUtil.getSnowflake(1,1).nextIdStr();
// 盐(用于加密)
String salt = RandomUtil.randomString(6);
// 加密密码: 原始密码+盐
String md5Pwd = SecureUtil.md5(user.getPassword() + salt);
// 激活失效时间: 24小时
LocalDateTime ldt = LocalDateTime.now().plusDays(1);
// 初始化账号信息
user.setSalt(salt);
user.setPassword(md5Pwd);
user.setConfirmCode(confirmCode);
user.setActivationTime(ldt);
user.setIsValid((byte) 0);
// 新增账号
int result = userMapper.insertUser(user);
Map<String, Object> resultMap = new HashMap<>();
if ( result > 0 ) {
// 发送邮件
String activationUrl = "http://localhost:8989/user/activation?confirmCode=" + confirmCode;
mailService.sendMailForActivationAccount(activationUrl, user.getEmail());
resultMap.put("code",200);
resultMap.put("message","注册成功,请前往邮箱进行账号激活");
} else {
resultMap.put("code",400);
resultMap.put("message","注册失败");
}
return resultMap;
}
// 登录账号
@Transactional
public Map<String, Object> loginAccount(User user) {
Map<String, Object> resultMap = new HashMap<>();
// 根据邮箱查询用户
List<User> userList = userMapper.selectUserByEmail(user.getEmail());
// 查询不到结果,返回:该账户不存在或未激活
if ( userList == null || userList.isEmpty() ) {
resultMap.put("code",400);
resultMap.put("message","该账户不存在或未激活");
return resultMap;
}
// 查询到多个用户,返回;账号异常,请联系管理员
if ( userList.size() > 1 ) {
resultMap.put("code",400);
resultMap.put("message","账号异常,请联系系统管理员");
return resultMap;
}
// 查询到一个用户,进行密码比对
User us = userList.get(0);
// 用户输入的密码和盐进行加密
String md5Pwd = SecureUtil.md5(user.getPassword() + us.getSalt());
// 密码不一致,返回:用户名或密码错误
if ( !us.getPassword().equals(md5Pwd) ) {
resultMap.put("code",400);
resultMap.put("message","用户名或密码错误");
return resultMap;
}
resultMap.put("code",200);
resultMap.put("message","登录成功");
return resultMap;
}
// 激活账号
@Transactional
public Map<String,Object> activationAccount(String confirmCode) {
Map<String, Object> resultMap = new HashMap<>();
// 根据确认码查询用户
User user = userMapper.selectUserByConfirmCode(confirmCode);
// 判断激活时间是否超时
boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
if ( after ){
resultMap.put("code",400);
resultMap.put("message","链接已失效,请重新注册");
return resultMap;
}
// 根据确认码查询用户并修改状态值为1(可用)
int result = userMapper.updateUserByConfirmCode(confirmCode);
if ( result > 0 ) {
resultMap.put("code",200);
resultMap.put("message","激活成功");
} else {
resultMap.put("code",400);
resultMap.put("message","激活失败");
}
return resultMap;
}
}
3.3.2.2 MailService
package com.salieri.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
@Service
public class MailService {
@Value("${spring.mail.username}")
private String mailUsername;
@Resource
private JavaMailSender javaMailSender;
@Resource
private TemplateEngine templateEngine;
// 激活账号邮件发送
public void sendMailForActivationAccount(String activationUrl, String email) {
// 创建邮件对象
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);
// 设置邮件主题
message.setSubject("个人账号激活");
// 设置邮件发送者
message.setFrom(mailUsername);
// 设置邮件接收者,可以多个
message.setTo(email);
// 设置邮件抄送人,可以多个
// message.setCc();
// 设置隐秘抄送人,可以多个
// message.setBcc();
// 设置邮件发送日期
message.setSentDate(new Date());
// 创建上下文环境
Context context = new Context();
context.setVariable("activationUrl",activationUrl);
String text = templateEngine.process("activation-account.html",context);
// 邮件发送
// 设置邮件正文
message.setText(text,true);
} catch (MessagingException e) {
e.printStackTrace();
}
javaMailSender.send(mimeMessage);
}
}
3.4 Controller
3.4.1 SystemController
作用:两个页面的跳转显示
package com.salieri.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class SystemController {
/* 登录页面跳转 */
@GetMapping("login")
public String login() {
return "login";
}
/* 注册页面跳转 */
@GetMapping("registry")
public String registry() {
return "registry";
}
}
3.4.2 UserController
作用:调用service服务
package com.salieri.controller;
import com.salieri.pojo.User;
import com.salieri.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Map;
@RestController
@RequestMapping("user")
public class UserController {
@Resource
private UserService userService;
// 注册账号
@PostMapping("create")
public Map<String, Object> createAccount(User user) {
return userService.createAccount(user);
}
// 登录账号
@PostMapping("login")
public Map<String, Object> loginAccount(User user) {
return userService.loginAccount(user);
}
// 激活账号
@GetMapping("activation")
public Map<String, Object> activationAccount(String confirmCode) {
return userService.activationAccount(confirmCode);
}
}
3.5 templates
activation-account.html
注意:
registry.html