- 1 访问注册页面
- 1.1 Controller
- 1.2 动态页面
- 1.2.1 处理首尾的静态资源
- 1.2.2 处理头部
- 2 提交注册数据
- 2.1 数据访问层
- 2.2 业务层
- 2.3 邮件修改为动态模板
- 2.4 视图层
- 2.5 动态模板
- 2.5.1 site/operate-result.html
- 2.5.2 site/register.html
- 前端传值给后端
- 后端传值给前端
- 3 激活注册账号
- 3.1 数据访问层
- 3.2 业务层
- 3.3 视图层
- 3.4 视图层里涉及到的动态页面
- 4 测试
- 5 优化:将注册错误信息异步显示
复杂的功能要拆成相对简单的功能,这样好开发
web项目可以按照请求拆分功能
点击注册按钮,跳到注册页面,这是一次请求;
将注册信息提交到服务器,服务器要发送激活邮件,这是一次请求;
点击激活邮件里的链接,服务器要将该用户的status改成已激活,这是一次请求
每一次请求都按照数据访问层、业务层和视图层开发
有的请求没有完整的三层
现在首页和注册按钮的链接都是静态链接,先把他俩改成动态链接
templates里的网页不能直接访问,只能利用Controller访问
首页由于之前写过Controller方法,现在已经可以点击了,注册还没写过,点击会
现在写注册的Controller方法
开发注册功能就重新用一个Controller吧
//访问注册页面
@RequestMapping(path = "/register",method = RequestMethod.GET)
public String getRegister(){
return "/site/register";
}
注意:第二行的path是注册页面的网址,要与引擎模板里的网址一致
第四行的网址是返回的templates里动态页面的路径名
把templates下site/register.html修改成动态页面
1.2.1 处理首尾的静态资源
头部复用index里的头部
index.html
register.html
提供插入用户、修改用户状态的方法
2.2 业务层1.返回各种出错信息
2.注册用户
3.发送激活邮件
coding…
【SpringBoot学习】01、SpringBoot发送电子邮件
【SpringBoot学习】02、用MD5对密码加密
//注册用户,发送激活邮件
public Map register(User user){
//错误信息用map封装
Map map = new HashMap<>();
//空值判断
if(user==null){
throw new IllegalArgumentException("用户不能为空!");
}
if(StringUtils.isBlank(user.getUsername())){
map.put("usernameMsg","用户名不能为空!");
return map;
}
if(StringUtils.isBlank(user.getPassword())){
map.put("passwordMsg","密码不能为空!");
return map;
}
if(StringUtils.isBlank(user.getEmail())){
map.put("emailMsg","邮箱不能为空!");
return map;
}
//验证用户名
User u = userMapper.selectByName(user.getUsername());
if(u!=null){
map.put("usernameMsg","该用户名已存在!");
return map;
}
//验证邮箱
u=userMapper.selectByEmail(user.getEmail());
if(u!=null){
map.put("emailMsg","该邮箱已被注册!");
return map;
}
//注册用户
user.setSalt(CommunityUtil.generateUUID().substring(0,5));
user.setPassword(CommunityUtil.md5(user.getPassword()+user.getSalt()));
user.setType(0);
user.setStatus(0);
user.setActivationCode(CommunityUtil.generateUUID());
user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png", new Random().nextInt(1000)));
user.setCreateTime(new Date());
userMapper.insertUser(user);
//发送激活邮件
Context context = new Context();
context.setVariable("email",user.getEmail());
// http://localhost:8080/community/activation/id/code
String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();
context.setVariable("url", url);
String content = templateEngine.process("/mail/activation", context);
mailClient.sendMail(user.getEmail(), "激活账号", content);
return map;
}
2.3 邮件修改为动态模板
2.4 视图层
//接收注册数据,发送激活邮件
@RequestMapping(path = "/register",method = RequestMethod.POST)
public String register(User user, Model model){
Map map = userService.register(user);
//没问题
if(map.isEmpty()||map==null){
model.addAttribute("Msg","注册成功,我们已经向您的邮箱发送了一封激活邮件,请尽快前往激活!");
model.addAttribute("target","/index");
return "site/operate-result";
}
//有问题
else{
model.addAttribute("usernameMsg",map.get("usernameMsg"));
model.addAttribute("passwordMsg",map.get("passwordMsg"));
model.addAttribute("emailMsg",map.get("emailMsg"));
return "site/register";
}
}
2.5 动态模板
视图层返回的页面都要改成静态模板
2.5.1 site/operate-result.html
action:提交表单时发送表单数据的目的地是/register,会被地址映射为/register的Controller方法处理
method="post" th:action="@{/register}"
前端传值给后端
困扰我很久的问题:前端以表单提交的数据怎么封装成类传给后端?
我猜想是:
请求提交后DispatcherServlet传给相应的Controller方法,该方法的输入参数有User,那就从表单提交的数据里匹配User类的属性,将数据封装成User类再传给Controller方法
这个需要看源码才能确认
可以肯定的是:前端上name值与Controller方法输入参数一致,DispatcherServlet就会将其赋给对应输入参数的值
1.传html页面
2.传JSON字符串
点击激活链接之后,服务器要将该用户的status从0改为1
3.1 数据访问层提供根据用户id修改status的功能
3.2 业务层提供激活用户的方法:传入的激活码与数据库中的激活码一致,就激活成功
将状态常量放在接口里,要用到状态常量的类去继承该接口
//激活用户
public int activation(int userId,String code){
User user = userMapper.selectById(userId);
if(user.getStatus()==1)
return ACTIVATION_REPEAT;
else{
if(user.getActivationCode().equals(code)){
userMapper.updateStatus(userId, 1);
return ACTIVATION_SUCCESS;
}
else
return ACTIVATION_FAIL;
}
}
3.3 视图层
//激活用户
// http://localhost:8080/community/activation/id/code
@RequestMapping(path = "/activation/{userId}/{activationCode}",method = RequestMethod.GET)
public String activation(Model model,@PathVariable("userId")int userId,@PathVariable("activationCode")String code){
int result = userService.activation(userId, code);
if(result==ACTIVATION_REPEAT){
model.addAttribute("Msg","无效操作,您已激活该账户,不需要重新激活。");
model.addAttribute("target", "/index");
}else if(result==ACTIVATION_SUCCESS){
model.addAttribute("Msg","激活成功,您的账号已经可以正常使用了!");
model.addAttribute("target", "/login");
}else{
model.addAttribute("Msg","激活失败,您提供的激活码不正确!");
model.addAttribute("target", "/index");
}
return "/site/operate-result";
}
3.4 视图层里涉及到的动态页面
4 测试
额,怎么不能异步请求服务器数据呢。。。。。
以后再说
改了一些bug,还有一个bug是怎么异步显示账户有没有被注册之类的?
哦,老师本来就没有实现异步显示,我琢磨一下怎么显示
效果:
Controller
//异步返回错误信息
@RequestMapping(path="/register/error",method = RequestMethod.POST)
@ResponseBody
public String registerError(User user){
//看用户名是否重复
String username=user.getUsername();
User u = userService.findUserByName(username);
if(u!=null){
return CommunityUtil.getJSONString(0,"该名称已被占用");
}else{
return CommunityUtil.getJSONString(1,"该名称尚未被使用");
}
}
register.httml
在register.httml最后加上jQuery代码



