我确认电子邮件是唯一的。这是注册期间的工作。但当我试图更改用户配置文件中的电子邮件时,我出现了一个错误。
我检查电子邮件以运行userRepository。findByEmail。如果找到用户,则电子邮件不是唯一的。但当用户在profile中更改其电子邮件时,findByEmail将返回此用户。验证失败。
我需要检查用户是由findByUser返回的不是更改电子邮件的同一用户。为此,我需要传递在验证器中更改电子邮件的用户。
这是我的代码。
实体:
@Data
@Table(name = "users")
@NoArgsConstructor
@CheckPasswordConfirm(message = "Password not equal!")
@Entity
public class User implements UserDetails{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotBlank(message = "Username is empty!")
@UniqueUsername(message = "Username isn't unique")
private String username;
@NotBlank(message = "Password is empty!")
private String password;
@Transient
@NotBlank(message = "Password confirm is empty!")
private String passwordconfirm;
private boolean active;
@Email(message = "E-mail!")
@NotBlank(message = "E-mail is empty!")
@UniqueEmail(message = "Email isn't unique!")
private String email;
private String activationCode;
@ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
@CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
private Set<Role> roles;
public boolean isAdmin()
{
return roles.contains(Role.ADMIN);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
注释:电子邮件:
@Constraint(validatedBy = UniqueEmailValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface UniqueEmail {
public String message();
public Class<?>[] groups() default {};
public Class<? extends Payload>[] payload() default{};
}
验证器:
package ru.watchlist.domain.validation.validators;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import ru.watchlist.domain.validation.annotations.UniqueEmail;
import ru.watchlist.service.UserService;
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
@Autowired
private UserService userService;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && !userService.isEmailAlredyUse(value);
}
}
用户服务。isEmailAlredyUse:
public boolean isEmailAlredyUse(String value) {
User user = userRepository.findByEmail(value);
if(user != null) {
return true;
}
return false;
}
这里我需要检查一下:
User userFromDB = userRepository.findByEmail(value);
if(userFromDB != null && user != userFromDB) {
return true;
}
我该如何解决这个问题?
另外,如果我要使用跨字段对类进行验证,我不能在Thymeleaf中显示其字段的错误。因此,我需要字段的验证器。
请注意我的控制器:
@Controller
@RequestMapping("/profile")
public class ProfileController {
@Autowired
UserService userService;
@GetMapping
public String profile(@AuthenticationPrincipal User user, Model model) {
model.addAttribute(user);
return "profile";
}
@PostMapping("/update")
public String saveChanges(@Valid User user, Errors errors) {
if(errors.hasErrors()) {
return "profile";
}
userService.addUser(user);
return "redirect:/profile";
}
}
用户存储库:
public interface UserRepository extends JpaRepository<User, Long>{
User findByUsername(String username);
User findByActivationCode(String code);
User findByEmail(String email);
}
User userFromDB = userRepository.findByEmail(value);
if(userFromDB != null && user != userFromDB) {
return true;
}
在这种情况下,user和userFromDB总是不同的,因为这些对象可以有不同的hashCodes。你能在返回user
的地方添加存储库和类的实现吗?我假设您没有使用JPA规范,但是如果您使用它,请尝试用这个附件替换您自己的验证@Coliv(独特=真实)
如果您想在控制器中验证您的对象,您可以使用@Valid
注释,其中控制器侧的代码可以如下所示:
@PostMapping
public String saveObject(@Valid @ModelAttribute("email") Object object, BindingResult bindingResult) {
if(bindingResult.hasErrors()){
return view_with_form;
}
repository.save(object)
return "redirect:path";
}
从Thymeleaf表格:
<div class="col-md-6 mt-2 form-group">
<label>Recipe Description:</label>
<input type="text" class="form-control" th:field="*{email}" th:errorclass="is-invalid"/>
<span class="invalid-feedback" th:if="${#fields.hasErrors('email')}">
<ul>
<li th:each="error : ${#fields.errors('email')}" th:text="${error}"></li>
</ul>
</span>
</div>
此示例适用于引导程序4。
我们不建议使用Hibernate Validator来检查数据库约束。
但是,如果您想这样做,可以使用约束验证器负载:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#constraint-验证器有效负载。它们是为这种需求而创建的。
示例6.7是您正在寻找的,因为您不想每次都构建一个完整的ValidatorFactory
,只是一个特定的上下文。
现在,这是针对Hibernate验证器端的,但是您需要一种方法来正确配置由Spring创建的验证器
,以便将登录用户注入其中。我帮不了你。
问题内容: 我使用passportJS,我想提供的不仅仅是更多的和我的身份验证策略(护照本地)。 我有3个表单字段:,,和 我如何从本地策略访问,该策略如下所示: 我在我的路由(而不是路由中间件)中称呼它,像这样: 问题答案: 您可以启用一个选项,如下所示: 何时,set 成为verify回调的第一个参数,您可以根据需要对其进行检查。
问题内容: 该文档讨论了使用numba的作为的参数。我需要带有附加参数的相同内容。 我基本上是想做这样的事情: 但是,它不起作用,因为应该是/并且不能将它们转换为。我收到以下错误消息: 我没有找到有关如何从Numba中提取值的任何信息。在C语言中,应该类似于—在Numba中可以做同样的事情吗? 问题答案: 1.通过传递额外的参数 该文件说: 如果用户希望改善集成性能,则可以使用以下签名之一: 该是
我想使自定义验证器除了必需的_之外,如果所有字段都已填充,也不会失败。 现行规则: 将导致: Foo、Bar和Baz都是空的(错误) 一个Foo/Bar已填充,另一个为空(错误) Foo和Bar已满,Baz为空(OK) Foo和Bar是空的,Baz是满的(OK) Foo-Bar和Baz已填充(OK)← 我希望这变成一个错误 所以我使用扩展创建自定义验证器,并希望像这样使用它: AppService
我写了一个代码来管理一个咖啡馆,所以在框架中我添加了一个JTable,每次我从JComboBox中选择一个项目,它都应该显示在JTable中。为此,我添加了一个按钮,对于它的操作,我确保每次单击它时,它都将从JComboBox中单击的项存储在数据库中,然后将从数据库中获取的项存储在JTable中。但问题是JTable有两列,而JComboBox中的选择只有一列。因此,另一列必须从其他数据库调用,这
问题内容: 我正在使用一个存储过程,在其中发送数据库中其类型为的存储过程,并且还声明parameter 。 当我将列名传递为float时,它给出了错误: 消息8114,将数据类型nvarchar转换为float时出错。 这是我的测试查询 当我将参数类型更改为时,它给了我这个错误: 消息8117,操作数数据类型varchar对avg运算符无效。 我该如何解决? 更新 : 这是我的存储过程: 问题答案
问题内容: 为了解释这个问题,请考虑我有2个詹金斯工作。 职位1:PARAM_TEST1 它接受称为“ MYPARAM”的参数化值 职位2:PARAM_TEST2 它还接受称为“ MYPARAM”的参数化值 有时我需要按顺序运行这两个作业-因此我创建了一个单独的管道作业,如下所示。它工作正常。 它还接受名为“ MYPARAM”的参数化值,以将其简单地传递到构建作业步骤。 我的问题: 这个例子很简单