博客项目目录: 请戳这里
准备
需求:实现用户注册功能,将用户注册的信息存入数据库,并且显示成功页面,注册之后跳转到登录页
1.新建auth目录,引入login.ftl与reg.ftl
- 将/fly-3.0/html/user目录下的login.html与reg.html引入到auth,修改后缀名为ftl
- 保留页面的container部分与带user信息的script,引入layout模板,自定义页面标题
- 修改header.ftl登录、注册按钮的链接,以及登录页、注册页对应的按钮链接
登录页:
注册页:
2.定义AuthController类,设计login与register的controller
@Controller
public class AuthController extends BaseController{
@GetMapping("/login")
public String login(){
return "/auth/login";
}
@GetMapping("/register")
public String register(){
return "auth/reg";
}
}
填写注册页默认表单信息:
运行项目,进行测试:
3.验证码设计
- 1.引入谷歌依赖包
<!--验证码-->
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>0.0.9</version>
</dependency>
- 2.验证码配置类
主要是设置验证码的边框、高度、宽度、颜色、字体等属性。
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha producer () {
Properties propertis = new Properties();
propertis.put("kaptcha.border", "no");
propertis.put("kaptcha.image.height", "38");
propertis.put("kaptcha.image.width", "150");
propertis.put("kaptcha.textproducer.font.color", "black");
propertis.put("kaptcha.textproducer.font.size", "32");
Config config = new Config(propertis);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
- 3.生成验证码
首先获取验证码的文本部分,然后将文本嵌入图片,resp设置对应的请求头和内容格式,创建流,利用IO工具,将图片放在流里。
@Autowired
Producer producer;
/**
* 生成验证码
*
* @param resp
* @throws IOException
*/
@GetMapping("/capthca.jpg")
public void kaptcha(HttpServletResponse resp) throws IOException {
//验证码
String text = producer.createText();
BufferedImage image = producer.createImage(text);
resp.setHeader("Cache-Control", "no-store, no-cache");
resp.setContentType("image/jpeg");
ServletOutputStream outputStream = resp.getOutputStream();
ImageIO.write(image, "jpg", outputStream);
}
- 4.测试
运行项目,浏览器输入http://localhost:8080/capthca.jpg
4.展示验证码到表单部分
修改reg.ftl对应部分:
运行项目,可以看到有验证码了
去掉验证码栏的类样式,就没有错位了
5.验证码点击事件
目标:点击验证码图片后,会刷新出一个新的验证码
-
引入jquery.min.js资源
-
layout.ftl引入jquery
-
对应位置写上点击函数
"#capthca"对应上面div标签的img的id。<script> layui.cache.page = 'user'; $("#capthca").click(function () { this.src = "/capthca.jpg"; }); </script>
-
测试
点击验证码,发现可以刷新了
6.封装返回结果类
- status表示状态码,为0表示成功,1表示失败
- msg表示返回信息
- data表示返回数据
- action表示返回结果之后的后续操作
@Data
public class Result implements Serializable {
//0成功,-1失败
private int status;
private String msg;
private Object data;
private String action;
public static Result success() {
return Result.success("操作成功", null);
}
public static Result success(Object data) {
return Result.success("操作成功", data);
}
public static Result success(String msg, Object data){
Result result=new Result();
result.status=0;
result.msg=msg;
result.data=data;
return result;
}
public static Result fail(String msg){
Result result=new Result();
result.status=-1;
result.msg=msg;
result.data=null;
return result;
}
public Result action(String action){
this.action = action;
return this;
}
}
7.在AuthController新建doregister类
在之前的验证码获取时,设置一个session,然后在doregister进行获取
private static final String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY";
@Autowired
Producer producer;
/**
* 生成验证码
*
* @param resp
* @throws IOException
*/
@GetMapping("/capthca.jpg")
public void kaptcha(HttpServletResponse resp) throws IOException {
//验证码
String text = producer.createText();
BufferedImage image = producer.createImage(text);
req.getSession().setAttribute(KAPTCHA_SESSION_KEY, text);
resp.setHeader("Cache-Control", "no-store, no-cache");
resp.setContentType("image/jpeg");
ServletOutputStream outputStream = resp.getOutputStream();
ImageIO.write(image, "jpg", outputStream);
}
@ResponseBody
@PostMapping("/register")
public Result doregister() {
String capthca = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);
return Result.success().action("/login");
}
注释掉index.js对应的代码:
在提交按钮处添加alert=“true”,运行程序进行测试:
发现有操作成功的弹窗。
点击确定:
跳转到登录页面
8.doregister类验证用户注册信息是否有问题,并保存
- 验证用户信息是否完整
- 验证密码
- 验证码是否填写正确
- 验证之后的动作,主要是将注册信息填到数据库
(注意:需要在util包引入ValidationUtil工具类)
@ResponseBody
@PostMapping("/register")
public Result doregister(User user, String repass, String vercode) {
//验证用户信息是否没填完整
ValidationUtil.ValidResult validResult = ValidationUtil.validateBean(user);
if(validResult.hasErrors()) {
return Result.fail(validResult.getErrors());
}
//验证两次密码是否不相同
if(!user.getPassword().equals(repass)) {
return Result.fail("两次输入密码不相同");
}
String capthca = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);
//验证码确定
if(vercode == null || !vercode.equalsIgnoreCase(capthca)) {
return Result.fail("验证码输入不正确");
}
//注册动作
Result result = userService.register(user);
return Result.success().action("/login");
}
9.注册接口
public interface UserService extends IService<User> {
Result register(User user);
}
10.注册动作实现
- 通过查询,判断用户名或邮箱是否被占用
- 如果被占用,返回错误信息;如果没有,将注册信息存到数据库
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public Result register(User user) {
//验证用户信息是否被占用
int count = this.count(new QueryWrapper<User>()
.eq("email", user.getEmail())
.or()
.eq("username", user.getUsername())
);
if(count > 0) return Result.fail("用户名或邮箱已被占用");
//将信息填到数据库
User temp = new User();
temp.setUsername(user.getUsername());
temp.setPassword(SecureUtil.md5(user.getPassword()));
temp.setEmail(user.getEmail());
temp.setAvatar("/res/images/avatar/default.png");
temp.setCreated(new Date());
temp.setPoint(0);
temp.setVipLevel(0);
temp.setCommentCount(0);
temp.setPostCount(0);
temp.setGender("0");
this.save(temp);
return Result.success();
}
}
11.测试
运行项目,填写正确验证码,点击注册,查看mysql对应表信息:
发现多了一条刚才注册的用户信息。
(注意:reg.ftl的密码部分,将"pass"改为"password")
参考资料:
https://github.com/MarkerHub/eblog