✅P215_商城业务-认证服务-一步一坑的注册页环境
注册接口
cfmall-auth-server/src/main/java/com/gyz/cfmall/controller/LoginController.java
@PostMapping("/register")
public String register() {
//注册成功返回到登录页
return "redirect:/login.html";
}
封装注册VO
cfmall-auth-server/src/main/java/com/gyz/cfmall/vo/UserRegisterVo.java
package com.gyz.cfmall.vo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
@Data
public class UserRegisterVo {
/**
* 用户名
*/
private String userName;
/**
* 密码
*/
private String password;
/**
* 手机号
*/
private String phone;
/**
* 短信验证码
*/
private String code;
}
使用JSR303进行数据校验
导入依赖,使@Valid注解生效
cfmall-auth-server/pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
修改注册VOcfmall-auth-server/src/main/java/com/gyz/cfmall/vo/UserRegisterVo.java
@Data
public class UserRegisterVo {
/**
* 用户名
*/
@NotEmpty(message = "用户名不能为空")
@Length(min = 6, max = 18, message = "用户名长度最小为6为,最大长度18位")
private String userName;
/**
* 密码
*/
@NotEmpty(message = "密码不能为空")
@Length(min = 6, max = 18, message = "密码长度最小为6位,最大长度18位")
private String password;
/**
* 手机号
*/
@NotEmpty(message = "手机号不能为空")
@Pattern(regexp = "^1[3456789]\d{9}$", message = "手机号格式不正确")
private String phone;
/**
* 短信验证码
*/
@NotEmpty(message = "短信验证码不能为空")
private String code;
}
修改注册接口
使用@Valid注解开启数据校验功能,将校验后的结果封装到BindingResult中
@PostMapping("/register")
public String register(@Valid UserRegisterVo registerVo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "forward:/reg.html";
}
//注册成功返回到登录页
return "redirect:/login.html";
}
编写注册页面
为每个input框设置name属性,值需要与UserRegisterVo的属性名一一对应
点击注册按钮没有发送请求,说明:为注册按钮绑定了单击事件,禁止了默认行为。将绑定的单击事件注释掉
为Model绑定校验错误信息
- 方法一
@PostMapping("/register")
public String register(@Valid UserRegisterVo registerVo, BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
Map<String, Object> errors = bindingResult.getFieldErrors().stream().collect(Collectors.toMap(item -> {
return item.getField();
}, item -> {
return item.getDefaultMessage();
}));
model.addAttribute("errors", errors);
return "forward:/reg.html";
}
//注册成功返回到登录页
return "redirect:/login.html";
}
- 方法二
@PostMapping("/register")
public String register(@Valid UserRegisterVo registerVo, BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
Map<String, Object> errors = bindingResult.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField,FieldError::getDefaultMessage));
model.addAttribute("errors", errors);
return "forward:/reg.html";
}
//注册成功返回到登录页
return "redirect:/login.html";
}
编写前端页面获取错误信息
cfmall-auth-server/src/main/resources/templates/reg.html
导入thymeleaf的名称空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">
封装错误信息
<div class="register-box">
<label class="username_label">用 户 名
<input name="userName" maxlength="20" type="text" placeholder="您的用户名和登录名">
</label>
<div class="tips" style="color: red" th:text="${errors != null ? (#maps.containsKey(errors, 'userName') ? errors.userName : '') : ''}">
</div>
</div>
出现问题: 转发失败,页面会打印字符串:redirect:http://auth.cfmall.com/reg.html
问题原因:
- controller层使用了@RestController注解会自动返回json数据
解决方案:
- 使用@Controller注解
- 删除方法上的@ResponseBody注解
出现问题: Request method 'POST' not supported
问题原因
- 表单的提交使用的是post请求,会原封不动的转发给
reg.html
,但是/reg.html(路径映射默认都是get方式访问)
解决方案
出现问题:刷新页面,会重复提交表单
问题原因:原封不动转发过去
解决方案:使用重定向
出现问题:转发,数据都封装在Model中,而重定向获取不到
**解决方案:使用 **RedirectAttributes
出现问题:重定向到服务端口地址
解决方案: 写完整的域名路径
@PostMapping("/register")
public String register(@Valid UserRegisterVo registerVo, BindingResult bindingResult, RedirectAttributes attributes) {
if (bindingResult.hasErrors()) {
Map<String, String> errors = bindingResult.getFieldErrors().stream().collect(Collectors.toMap(item -> {
return item.getField();
}, item -> {
return item.getDefaultMessage();
}));
attributes.addFlashAttribute("errors",errors);
return "redirect:http://auth.cfmall.com/reg.html";
}
//注册成功返回到登录页
return "redirect:/login.html";
}
说明: RedirectAttributes的addFlashAttribute()
方法是将errors保存在session中,刷新一次就没了
出现问题:分布式下重定向使用session存储数据会出现一些问题
解决方案:后续会说明