gpt4 book ai didi

java - 如何从自定义验证注释将实体对象传递到 Controller

转载 作者:行者123 更新时间:2023-12-02 02:15:49 25 4
gpt4 key购买 nike

我有一个请求数据传输对象(DTO),用于接受 API 的 POST 正文。该 DTO 有一个 X 实体的 ENUM 键。我创建了一个自定义验证注释,并通过其实体存储库验证 ENUM 是否存在于我的系统中,该实体存储库根据其存在返回实体或 null。

我想将 X 验证的实体传递给我的 Controller 。我不想在业务逻辑中再次通过 ENUM 获取 X 实体,因为我已经在验证中完成了该操作。

我将该实体保存在注释 validator 类的静态变量中,稍后当我需要在业务逻辑中使用它时访问它,但是如果 API 同时被命中,我的静态变量会被第二个请求覆盖,并且当我的第一个请求的业务逻辑被覆盖时请求获取 X 实体,由于覆盖问题,它获取第二个请求的实体。

我希望该 X 实体对象的作用域位于其自己的请求周期内,并像其他对象一样在请求完成后销毁或 GC。我怎样才能实现这个目标?

我的自定义 validator :

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidateXimpl.class)
@Documented
public @interface ValidateX {
String message() default "Message";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default{};
}

自定义 validator 实现:

public class ValidateXimpl implements ConstraintValidator<ValidateX, String> {

@Autowired
DBRepo dbRepo;

@Override
public void initialize(ValidateX annotation) {
}

@Override
public boolean isValid(String value, ConstraintValidatorContext ctx) {
try {
XEntity X = dbRepo.findByEnum(value); // I want this entity in my controller
return (!value.isEmpty() && X != null);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}

我放置验证的 DTO:

public class DTO{
....
@ValidateX
String xEntityEnum
....
}

我的 Controller :

@RequestMapping(value = '/x', method = RequestMethod.POST)
public @ResponseBody
Map<String, Object> createX(@Validated @RequestBody DTO dto, BindingResult errors) {
// I want that entity here which I get from db repo in my validator
}

最佳答案

我刚刚从 RequestContextHolder 解决了这个问题

解决方案代码:

validator 实现

public class ValidateXimpl implements ConstraintValidator<ValidateX, String> {

@Autowired
DBRepo dbRepo;

@Override
public void initialize(ValidateX annotation) {
}

@Override
public boolean isValid(String value, ConstraintValidatorContext ctx) {
try {
XEntity X = dbRepo.findByEnum(value); // I want this entity in my controller
RequestContextHolder.getRequestAttributes().setAttribute(
"XEntity", X, RequestAttributes.SCOPE_REQUEST
); // I saved it in RequestContextHolder
return (!value.isEmpty() && X != null);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}

我的 Controller

@RequestMapping(value = '/x', method = RequestMethod.POST)
public @ResponseBody
Map<String, Object> createX(@Validated @RequestBody DTO dto, BindingResult errors) {
// I want that entity here which I get from db repo in my validator
System.out.println(
RequestContextHolder.getRequestAttributes().getAttribute(
"XEntity",
RequestAttributes.SCOPE_REQUEST
)
); // I get that from RequestContextHolder
}

这才是我真正需要的。 RequestContextHolder 在请求完成时变得清晰,并且由于 setAttribute 函数中的请求范围设置,也仅在其自己的请求线程中可用。

关于java - 如何从自定义验证注释将实体对象传递到 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49319327/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com