使用dropwizard验证,我可以访问数据库以插入记录 [英] With dropwizard validation, can I access the DB to insert a record

查看:142
本文介绍了使用dropwizard验证,我可以访问数据库以插入记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题如下:

我正在使用dropwizard进行项目,到目前为止,我已经愉快地成功使用了验证框架。我的验证工作正常,它以标准方式使用。这就是我所拥有的:

I am using dropwizard for a project and I have used the validation framework happily and successfully so far. My validation works fine and it is used in the standard way. This is what I have:

请求类:

import javax.validation.constraints.NotNull;

import MandatoryFieldLengthCheck;

public class InitiatePaymentRequest implements PaymentRequest {

    @NotNull(message = "Mandatory input field missing")
    @MandatoryFieldLengthCheck(value = 32)
    protected String   transactionId;
}

然后是注释类:

@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = MandatoryFieldLengthCheckValidator.class)
@Documented
public @interface MandatoryFieldLengthCheck {

    String message() default "Invalid input data";

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

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

    long value();

}

然后验证器类:

public class MandatoryFieldLengthCheckValidator implements ConstraintValidator<MandatoryFieldLengthCheck, Object> {

    private static final Logger LOGGER = LoggerFactory.getLogger(MandatoryFieldLengthCheckValidator.class);

    private long                length;

    @Override
    public void initialize(final MandatoryFieldLengthCheck constraintAnnotation) {
        this.length = constraintAnnotation.value();
    }

    @Override
    public boolean isValid(final Object object, final ConstraintValidatorContext constraintContext) {
        LOGGER.debug("isValid [{}]", object);

        // fields with a MandatoryFieldLengthCheck will also have a NotNull annotation so
        // nulls will be handled there, to avoid returning an invalid field value return true here
        if (object == null) {
            return true;
        }

        if (object instanceof Long || object instanceof Integer || object instanceof Short) {
            return object.toString().length() <= this.length;
        } else if (object instanceof String) {
            return (((String) object).replace(" ", "").length() > 0) && (((String) object).length() <= this.length);
        } else {
            return false;
        }
    }
}

这是有效的,它是很好。

That is working and it is fine.

现在,从MandatoryFieldLengthCheckValidator,我想在数据库中插入一条记录(它必须是数据库),就像验证失败一样,用于审计目的。

Now, from MandatoryFieldLengthCheckValidator, I want to insert a record in the database (it has to be the database), like validation fail for auditing purposes.

我试图注入DAO但没有成功,不确定是否可能。验证器是动态创建的,所以我无法控制我传递的内容,除非有一些魔法注入dao。

I have tried to inject a DAO without success, not sure if it possible or not. The validator is created on the fly, so I cannot control what I pass or not unless there is some magic that inject the dao.

所以我的问题是我怎么办更具体地说:

So my question is how can I do that and more specifically:


  • 我可以注入DAO吗?

  • 访问是否有意义您的验证码中的数据库?

  • 我可以重新配置验证引擎以获得此功能吗?

  • 有没有其他框架可以让我这样做?

  • 还有其他方法吗? AOP?使用静态方法?

  • Can I inject the DAO?
  • Does it make sense to access your DB from your validation code?
  • Can I reconfigure the validation engine to get this functionality?
  • Is there any other framework that can let me do it?
  • Any other way to do this? AOP? using Static methods?

即使你没有确切地说,如果你指出我正确的方向,它会很感激。谢谢。

Even if you do not exactly, if you point me in the right direction, it will appreciate it. Thanks.

推荐答案

soz,我迟到了。有一种方法可以使这个工作(注入验证器)。请注意,验证器应该简单的注释仍然适用,但有时您只需注入一些其他对象进行正确的验证。所以这就是你如何做到这一点:

soz, I'm late to the party. There is a way to get this working as well (injecting into validators). Mind you, the comment that validators should be simple still holds true, however sometimes you just need to inject some other object for correct validation. So this is how you can achieve this:

首先,我假设你已经设置了DI。如果没有,请查看 https://github.com/xvik/dropwizard-guicey - 它集成了变成了一个蠢货,也做得很好。一旦你完成了这个设置,你几乎就在那里。

So first off, I assume you have DI set up. If not, look into https://github.com/xvik/dropwizard-guicey - it integrates guice into dropwizard and does a rather great job too. Once you have this set up, you're almost there.

验证适用于Validator类,它将动态创建验证器 - 你是正确的。这个创建将无法注入任何值,因为它并不意味着开箱即用。

Validation works on the Validator class which will create your validators on the fly - you are correct in that. This creation will NOT be able to inject any values as it's just not meant to do this out of the box.

您可以创建一个模块(由guice处理),为您创建验证器。这看起来像这样:

You can create a Module (handled by guice) that will create the validator for you. This can look like that:

public class ValidationModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(GuiceConstraintValidationFactory.class).in(Singleton.class);
    }

    @Provides
    public Validator validator(GuiceConstraintValidationFactory validatoFactory) {
        return Validation.byDefaultProvider().configure().constraintValidatorFactory(validatoFactory).buildValidatorFactory().getValidator();
    }

}

请注意,这会创建一个GuiceConstraintValidationFactory。这个工厂只是一个委托,它将返回正确的验证器。它是一个委托,以便旧的验证器仍然可以工作(NotNull和朋友)。下面是一些代码:

Note that this creates a GuiceConstraintValidationFactory. This factory is simply a delegate which will return the correct validator. It is a delegate so that old validators still work (NotNull and friends). Here's some code:

public class GuiceConstraintValidationFactory implements ConstraintValidatorFactory {

    private ConstraintValidatorFactory delegate;
    private Set<ConstraintValidator> validators;

    @Inject
    public GuiceConstraintValidationFactory(final Set<ConstraintValidator> validators) {
        this.validators = validators;
        delegate = new ConstraintValidatorFactoryImpl();
    }

    @Override
    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
        for(ConstraintValidator<?, ?> validator : validators) {
            if(validator.getClass() == key) {
                return (T) validator;
            }
        }
        return delegate.getInstance(key);
    }

    @Override
    public void releaseInstance(ConstraintValidator<?, ?> instance) {
        delegate.releaseInstance(instance);
    }

}

注意此类如何注入验证器。这些验证器是guice句柄,因此它们可以有注入字段。例如:

Note how this class gets injected validators. These validators are guice handles, hence they can have injected fields. For example:

@Plugin(ConstraintValidator.class)
public class ResourceValidator implements ConstraintValidator<ValidResource, String>{


    private static final Logger log = Logger.getLogger(ResourceValidator.class);

    @Inject
    private MyConfiguration conf;

    @Override
    public void initialize(ValidResource constraintAnnotation) {
        // nothing to do here
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if(value == null) {
            return true;
        }
        String fullPath = conf.getBasePath() + File.separator + value;
        return new File(fullPath).exists();
    }

}

这个验证器是guice处理的。 @Plugin注释启用了guicey dropwizard来创建实例,注入它然后将它们全部组合在一个集合中(使它更容易注入它们)请参阅GuiceConstraintValidationFactory,其中一组验证器被注入工厂。
此工厂现在将由默认验证器使用。在请求新验证器时,工厂会检查是否存在所需类型的guice托管验证器。如果没有,它将默认返回正常的验证器实现。如果是,它将返回guice托管验证器。这使您可以动态添加新的验证器,并且可以创建,管理和注入它们。

This validator is guice handled. The @Plugin annotation enabled guicey dropwizard to create the instance, inject it and then group all of them in a set (makes it easier to inject them) See the GuiceConstraintValidationFactory where a Set of validators is injected into the factory. This factory will now be used by the default Validator. When requesting a new validator, the factory checks if a guice managed validator exists for the required type. If not, it will default back to the normal validator implementation. If yes, it will return the guice managed validator. This enables you to add new validators on the fly and have guice create, manage and inject them.

我希望有所帮助。

- Artur

-- Artur

这篇关于使用dropwizard验证,我可以访问数据库以插入记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆