Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从自定义验证注释将实体对象传递给控制器_Java_Spring_Spring Mvc_Spring Boot_Spring Security - Fatal编程技术网

Java 如何从自定义验证注释将实体对象传递给控制器

Java 如何从自定义验证注释将实体对象传递给控制器,java,spring,spring-mvc,spring-boot,spring-security,Java,Spring,Spring Mvc,Spring Boot,Spring Security,我有一个请求数据传输对象(DTO),用于接受API的POST主体。该DTO具有X实体的枚举键。我创建了一个自定义的验证注释,并通过其实体存储库验证枚举是否存在于我的系统中,该实体存储库根据枚举的存在返回entity或null 我想将该X验证实体传递给我的控制器。我不想在我的业务逻辑中再次通过ENUM获取X实体,因为我已经在验证中这样做了 我将该实体保存在annotation validator类中的一个静态变量中,并在以后需要在业务逻辑中访问该实体时访问它,但如果API同时被命中,则我的静态变量

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

我想将该
X
验证实体传递给我的控制器。我不想在我的业务逻辑中再次通过ENUM获取
X
实体,因为我已经在验证中这样做了

我将该实体保存在annotation validator类中的一个静态变量中,并在以后需要在业务逻辑中访问该实体时访问它,但如果API同时被命中,则我的静态变量将被第二个请求覆盖,并且当第一个请求的业务逻辑获取
X
实体时,它获取由于覆盖问题而导致的第二个请求的实体

我希望
X
实体对象在其自己的请求周期内确定范围,并像其他对象一样在请求完成后销毁或GC。我怎样才能做到这一点

我的自定义验证器:

@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{};
}
我的控制器:

@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
}
@RequestMapping(值='/x',方法=RequestMethod.POST)
公共@ResponseBody
映射createX(@Validated@RequestBody DTO到DTO,BindingResult错误){
//我想在这里的实体,我从数据库回购在我的验证器
}

我刚刚从
RequestContextHolder

解决方案代码:

验证程序实现

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);
    }
}
}
公共类validateImpl实现ConstraintValidator{
@自动连线
DBRepo-DBRepo;
@凌驾
公共void初始化(ValidateX注释){
}
@凌驾
公共布尔值有效(字符串值,ConstraintValidatorContext ctx){
试一试{
XEntity X=dbRepo.findByEnum(值);//我希望控制器中有这个实体
RequestContextHolder.getRequestAttributes().setAttribute(
“XEntity”,X,RequestAttributes.SCOPE\u请求
);//我将其保存在RequestContextHolder中
返回(!value.isEmpty()&&X!=null);
}捕获(例外情况除外){
抛出新的运行时异常(ex);
}
}
}
我的控制器

@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
}
@RequestMapping(值='/x',方法=RequestMethod.POST)
公共@ResponseBody
映射createX(@Validated@RequestBody DTO到DTO,BindingResult错误){
//我想在这里的实体,我从数据库回购在我的验证器
System.out.println(
RequestContextHolder.getRequestAttributes().getAttribute(
“至尊”,
RequestAttributes.SCOPE\u请求
)
);//我是从RequestContextHolder那里得到的
}

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

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

解决方案代码:

验证程序实现

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);
    }
}
}
公共类validateImpl实现ConstraintValidator{
@自动连线
DBRepo-DBRepo;
@凌驾
公共void初始化(ValidateX注释){
}
@凌驾
公共布尔值有效(字符串值,ConstraintValidatorContext ctx){
试一试{
XEntity X=dbRepo.findByEnum(值);//我希望控制器中有这个实体
RequestContextHolder.getRequestAttributes().setAttribute(
“XEntity”,X,RequestAttributes.SCOPE\u请求
);//我将其保存在RequestContextHolder中
返回(!value.isEmpty()&&X!=null);
}捕获(例外情况除外){
抛出新的运行时异常(ex);
}
}
}
我的控制器

@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
}
@RequestMapping(值='/x',方法=RequestMethod.POST)
公共@ResponseBody
映射createX(@Validated@RequestBody DTO到DTO,BindingResult错误){
//我想在这里的实体,我从数据库回购在我的验证器
System.out.println(
RequestContextHolder.getRequestAttributes().getAttribute(
“至尊”,
RequestAttributes.SCOPE\u请求
)
);//我是从RequestContextHolder那里得到的
}

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

如果使用表单对象接收请求参数,您可以验证该对象中的字段,并将其传递给controller方法。这是一个示例:否,我在自定义验证器中创建了另一个对象,我希望该对象在controller.hmm中传递。一种方法是只验证indata,然后在dto中的get方法中为该字段创建新对象。这样行吗?顺便说一句,一些代码会帮助你的项目清单使你的问题不可读。请重新措辞你的问题。不要使用项目符号列表,除非你真的在列出项目。对于一个问题,请使用普通的散文。如果使用表单对象接收请求参数,则可以验证该对象中的字段,并将其传递给控制器方法。这是一个示例:否,我在自定义验证器中创建了另一个对象,我希望该对象在controller.hmm中传递。好的。一种方法是只验证indata,然后在dto中的get方法中为该字段创建新对象。这样行吗?顺便说一句,一些代码会帮助你的项目清单使你的问题不可读。请重新措辞你的问题。不要使用项目符号列表,除非你真的在列出项目。对于一个问题,使用普通的散文。