验证期间使用泛型

钱包

我正在使用apache CXF。

以下API用于发布联系人。

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
ResponseResult create(@Context HttpHeaders httpHeaders, @Context Request request, @Context UriInfo uriInfo,
        UserContact contact) throws MDMException;

这里的UserContact类包含有关用户的联系信息,该联系信息作为JSON传递到正文中。

我需要对此UserContact对象进行一些业务验证。但是我不喜欢在单个类中包含太多验证代码。

我想做类似以下的事情。但是我面对泛型的问题。

interface Rule<S>
{
    void applyRule(S s)throws Exception;
}

interface Validatable
{
    void validate() throws Exception;
}

public class MyValidator
{
    private HashMap<? extends Rule ,?> map = new HashMap<>();

    public void validate() throws Exception
    {
        for(Rule rule : map.keySet())
        {
            rule.applyRule(map.get(rule));
        }
    }

    public <S> void addRule(Rule<S> rule, S data)
    {
        this.map.put(rule, data);
    }
}   


class EMailValidationRule implements Rule<String>
{
    private static final Pattern emailPattern = Pattern.compile("email-regex");
    public void applyRule(String s) throws Exception
    {
        if(!emailPattern.matcher(s).matches())
            throw new Exception("Not a valid EMail");
    }
}

因此,UserContact必须执行以下操作以进行验证。这样可以使代码紧凑(IMO)。

class UserContact implements Validatable
{

    // some 
    // code
    // related to User Contact


    public void validate() throws Exception
    {
        MyValidator validator = new MyValidator();
        validator.addRule(new EMailValidationRule(), "[email protected]");
        validator.addRule(new PhoneValidationRule(), "+1234567890");
        validator.validate();
    }
}

我不断收到类似的错误:

HashMap类型的put(capture#5-of?扩展Rule,capture#6-of?)方法不适用于参数(Rule,S)

上述设计是否也适合进行验证?

乔恩·韦尔尼

问题是,尽管您的封装确保了这一点,但是编译器无法确保所检索Rule<...>的类型参数与所检索的数据具有相同的类型。

还有一个问题是无法插入Rule<T>带有的子类型的数据T如果您有Rule<S> rule, S data类型,则必须完全匹配。虽然aRule<S>可以处理一个S很好的子类型


虽然这MyValidator是一个很棒的小班,但我真的看不出有什么意义。特别是因为您每次调用都会创建一个新文件validate由于规则是静态的(对于类的每个实例都是相同的),并且数据来自各个实例(我会假设),因此也很难进行缓存。

您也可以这样做:

class UserContact implements Validatable
{

    // some 
    // code
    // related to User Contact

    // 1 rule instance for the entire class, not a new one per call to 'validate'
    private static EMailValidationRule emailRule = new EmailValidationRule();
    private static PhoneValidationRule phoneRule = new PhoneValidationRule();

    public void validate() throws Exception
    {
        emailRule.applyRule("[email protected]");
        phoneRule.applyRule("+1234567890");
    }
}

不管怎样,这是的工作版本MyValidator

class MyValidator {
    private Map<Rule<?>, RuleNode<?>> map = new HashMap<>();

    public void validate() throws Exception {
        for(RuleNode<?> node : map.values())
            node.apply();
    }

    public <T, D extends T> void addRule(Rule<T> rule, D data) {
        @SuppressWarnings("unchecked") // unchecked, but safe due to encapsulation
        RuleNode<T> r = (RuleNode<T>) map.get(rule);
        if(r == null) {
            r = new RuleNode<T>(rule);
            map.put(rule, r);
        }

        r.add(data);
    }

    private static class RuleNode<T> { // Maintains that the rule and data are compatible
        private final Rule<T> rule;
        private final List<T> list = new ArrayList<>();

        public RuleNode(Rule<T> rule) {
            this.rule = rule;
        }

        public void add(T data) {
            list.add(data);
        }

        public void apply() throws Exception {
            for(T data : list)
                rule.applyRule(data);
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Python继承期间使用__init__

来自分类Dev

在upsert期间使用$ set和$ setOnInsert

来自分类Dev

从磁盘读取文件期间使用中断

来自分类Dev

在循环期间使用函数的php数组

来自分类Dev

在赋值期间使用后删除变量

来自分类Dev

泛型执行请求,使用泛型

来自分类Dev

泛型类使用泛型参数

来自分类Dev

针对泛型类型的非泛型属性进行验证

来自分类Dev

是否使用泛型?

来自分类Dev

Java使用泛型

来自分类Dev

如何使用泛型

来自分类Dev

使用泛型与POJO

来自分类Dev

如何使用泛型?

来自分类Dev

如何使用泛型

来自分类Dev

Checkstyle 5.5是否验证泛型

来自分类Dev

Magento库存量更新期间使用“ FOR UPDATE”

来自分类Dev

在Heroku上的资产编译轨道期间使用Node

来自分类Dev

mongodb在文档更新期间使用if设置字段值

来自分类Dev

在游戏期间使用setVisibility(View.GONE)隐藏广告

来自分类Dev

在ADO.NET事务期间使用using()块

来自分类Dev

在列表理解期间使用append更改列表

来自分类Dev

在列表理解期间使用append更改列表

来自分类Dev

Java在内存分配期间使用多个线程

来自分类Dev

在实例化期间使用构造函数变量

来自分类Dev

在Git变基期间使用什么算法?

来自分类Dev

左移操作期间使用的寄存器

来自分类Dev

我如何在tkinter期间使用Work

来自分类Dev

从Dockerfile进行Docker构建期间使用STDIN

来自分类Dev

如何在安装程序期间使用SetupCopyOEMInf