在上一篇Day 15 - Spring Boot 注册与登入中,我们已经初步完成了注册与登入的基础功能,但我们要记得,Spring Boot 为了简化开发的流程,提供了许多开箱即用的依赖,这篇我们就要介绍Spring Boot 提供关於资料验证的依赖,也就是Day 07 - Spring Boot 常用依赖中提到spring-boot-starter-validation
,主要透过注释的方式进行,可以进一步简化我们的程序码,让我们更专注在业务逻辑上。
当然,不免俗的要先看一下它提供的注释,以下列出一些常用的注释,可以不用背下来,但要记得有关於资料验证的功能,可以先查一下它有没有提供相关的注释。
@Valid
: 注释在方法中要校验的参数上,用於启动校验,可搭配BindingResult 物件获取校验失败的讯息;也可以注释在成员属性上,用於进行嵌套验证。@Validated
: 对於@Valid 的封装,由Spring 提供的校验机制,比@Valid 多了分组功能,但必须配合@Valid 才能进行嵌套验证。@Email
: 被注释的属性必须是电子信箱格式。@Pattern
: 被注释的属性必须符合指定的正则表示法。@Null
: 被注释的属性必须为Null。@NotNull
: 被注释的属性必须不为Null。@NotEmpty
: 被注释的字串不可为空。@NotBlank
: 被注释的字串非null 且长度必须大於0。@Length
: 被注释的字串长度必须在指定的范围内。@Min(value)
: 被注释的属性必须为一个数字且大於或等於指定的最小值。@Max(value)
: 被注释的属性必须为一个数字且小於或等於指定的最大值。@DecimalMin(value)
: 被注释的属性必须为一个数字且大於或等於指定的最小值。@DecimalMax(value)
: 被注释的属性必须为一个数字且小於或等於指定的最大值。@Size(max, min)
: 被注释的属性必须为一个数字且在指定的范围内。@Digits(integer, fraction)
: 被注释的属性必须为一个数字且在可接收的范围内。@Range
: 被注释的属性必须在合适的范围内。@AssertTrue
: 被注释的属性必须为一个布林值且为true。@AssertFalse
: 被注释的属性必须为一个布林值且为false。@Past
: 被注释的属性必须为一个过去的日期。@Future
: 被注释的属性必须为一个未来的日期。<!-- Spring Validator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
package com.example.demo.entity;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class MemberAccount extends Base {
private String id;
@Email(message = "帐号必须是Email 格式")
@NotBlank(message = "帐号不可为空")
private String username;
@NotBlank(message = "密码不可为空")
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[\\w]{6,16}$",
message = "密码必须为长度6~16位码大小写英文加数字")
private String password;
private String salt;
}
@Controller
public class MemberAccountController {
// 略...
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String doLogin(
@Valid @ModelAttribute MemberAccount memberAccount,
HttpSession session,
RedirectAttributes redirectAttributes) {
MemberAccountVO memberAccountVO = memberAccountService.login(memberAccount);
if(memberAccountVO == null) {
redirectAttributes.addFlashAttribute("MESSAGE", "帐号或密码错误");
return "redirect:login";
}
session.setAttribute("member", memberAccountVO);
return "redirect:information";
}
// 略...
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String doRegister(
@Valid @ModelAttribute MemberAccountVO memberAccountVO,
RedirectAttributes redirectAttributes) {
Optional<String> optional = memberAccountService.register(memberAccountVO);
String message = optional.orElse("注册成功");
redirectAttributes.addFlashAttribute("MESSAGE", message);
return "redirect:login";
}
}
可以看到注册的业务逻辑,少了前面对帐号及密码格式的判断,别小看这边只少了两行,当专案越来越大,搭配@Validated
为验证逻辑进行分组,可以减少各处的验证判断。
@Service
public class MemberAccountServiceImpl implements MemberAccountService {
// 略...
@Override
public Optional<String> register(MemberAccountVO memberAccountVO) {
// TODO Auto-generated method stub
// 检查两次输入密是否相符
if(!memberAccountVO.getPassword().equals(memberAccountVO.getCheckPassword())) return Optional.of("两次输入密码不相符");
// 检查帐号是否重复注册
MemberAccount data = memberAccountDao.findMemberAccountByUsername(memberAccountVO.getUsername());
if(data != null) return Optional.of("该帐号已被使用");
// 产生盐值
String salt = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
// 密码加密
String md5Password = getMd5Password(memberAccountVO.getPassword(), salt);
// 新增MemberAccount 资料
MemberAccount memberAccount = new MemberAccount();
memberAccount.setUsername(memberAccountVO.getUsername());
memberAccount.setPassword(md5Password);
memberAccount.setSalt(salt);
memberAccount.setCreate_by(memberAccountVO.getUsername());
memberAccount.setUpdate_by(memberAccountVO.getUsername());
Integer id = memberAccountDao.insert(memberAccount);
if(id == 0) return Optional.of("新增会员帐号时发生错误");
// 新增Member 资料
Member member = new Member();
member.setMa_id(String.valueOf(id));
member.setName(memberAccountVO.getName());
member.setCreate_by(memberAccountVO.getUsername());
member.setUpdate_by(memberAccountVO.getUsername());
Integer result = memberService.insert(member);
if(result == 0) return Optional.of("新增会员资料时发生错误");
return Optional.empty();
}
// 略...
}
使用SpringBoot进行优雅的资料验证_部落格园精华区 - MdEditor
SpringBoot - 第二十章 | 资料验证(二)
<<: Day 19: Security Hub 单一帐号/启用Org.後的布建
>>: Day16 NiFi - 与 MongoDB 对接设定
与你分享的快乐,胜过独自拥有 现代人看到有趣的网页、新闻、消息等等时,最常做的事情就是分享到社群帐...
from Unsplash 写了三十天的技术文章,最後一篇想谈谈「职涯发展」,毕竟这才是非本科转职...
User story:用一个简短的句子,描述用户的需求价值,也是大家所熟知的,身为一个「角色」,我想...
建立订单 from shioaji.constant import * # 股票 order = ...
在专案过程中,透过 GitLab CI 建立流水线,让研发过程中如编译、测试、打包、部署等工作都得以...