是否可以使用椭圆形 AbstractAnnotationCheck 设置多个消息?

发布于 2024-12-18 16:55:34 字数 1673 浏览 1 评论 0原文

我正在使用 Oval 验证框架来验证 HTML 字段不能包含恶意 JavaScript 代码的字段。对于恶意代码检测,我使用一个外部框架,它返回一个错误列表,我希望将其用作现场的错误消息。我遇到的问题是我只能在检查实现中设置消息,而我宁愿做类似 setMessages(List) 的事情。因此,虽然我目前只是用逗号连接错误,但我宁愿将它们作为列表传递回来。

注解

@Target({ ElementType.METHOD, ElementType.FIELD})
@Retention( RetentionPolicy.RUNTIME)
@Constraint(checkWith = HtmlFieldValidator.class)
public @interface HtmlField {
   String message() default "HTML could not be validated";
}

检查

public class HtmlFieldValidator  extends AbstractAnnotationCheck<HtmlDefaultValue> {
    public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
        if (o1 == null) {
            return true;
        } else {
            CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
            if (cleanResults.getErrorMessages().size() > 0) {
                String errors = StringUtils.join(cleanResults.getErrorMessages(), ", ");
                this.setMessage(errors);
                return false;
            } else {
                return true;
            }
        }
    }
}

Model类

class Foo {

    @HtmlField
    public String bar;

}

Controller代码

Validator validator = new Validator(); // use the OVal validator
Foo foo = new Foo();
foo.bar = "<script>hack()</script>";

List<ConstraintViolation> violations = validator.validate(bo);

if (violations.size() > 0) {
    // inform the user that I cannot accept the string because 
    // it contains invalid html, using error messages from OVal
}

I am using the Oval validation framework to validate fields that HTML fields cannot hold malicious javascript code. For the malicious code detection, I am using an external framework that returns me a list of errors that I would like to use as error messages on the field. The problem I am running into is that I can only setMessage in the check implementation, while I would rather do something like setMessages(List). So while I am currently just joining the errors with a comma, I would rather pass them back up as a list.

Annotation

@Target({ ElementType.METHOD, ElementType.FIELD})
@Retention( RetentionPolicy.RUNTIME)
@Constraint(checkWith = HtmlFieldValidator.class)
public @interface HtmlField {
   String message() default "HTML could not be validated";
}

Check

public class HtmlFieldValidator  extends AbstractAnnotationCheck<HtmlDefaultValue> {
    public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
        if (o1 == null) {
            return true;
        } else {
            CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
            if (cleanResults.getErrorMessages().size() > 0) {
                String errors = StringUtils.join(cleanResults.getErrorMessages(), ", ");
                this.setMessage(errors);
                return false;
            } else {
                return true;
            }
        }
    }
}

Model class

class Foo {

    @HtmlField
    public String bar;

}

Controller code

Validator validator = new Validator(); // use the OVal validator
Foo foo = new Foo();
foo.bar = "<script>hack()</script>";

List<ConstraintViolation> violations = validator.validate(bo);

if (violations.size() > 0) {
    // inform the user that I cannot accept the string because 
    // it contains invalid html, using error messages from OVal
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

行至春深 2024-12-25 16:55:34

如果 setMessage(String message) 是由超类创建的方法,您可以重写它,一旦它接收到数据,只需将字符串拆分为列表并调用您实际放置的第二个函数你的代码。另外,我还建议将分隔字符串更改为更独特的内容,因为错误消息本身可能包含逗号。

但你的问题并没有多大意义。如果您将它们“传递回”到超类中实现的方法,那么这将导致您问题的全部要点无效,因为超类将处理数据。

我假设 setError 方法是一个简单的 setter,它设置一个 String 变量来存储您计划在检查数据后访问的错误消息。由于您希望数据采用您喜欢的类型,因此只需在您的类中创建一个新的字符串数组并忽略超类即可。如果您愿意,您甚至可以同时使用两者。

public class HtmlFieldValidator  extends AbstractAnnotationCheck<HtmlDefaultValue> {
    public String[] errorMessages = null;

    public void setErrorMessages(String[] s) {
        this.errorMessages = s;
    }

    public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
        if (o1 == null) {
            return true;
        } else {
            CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
            if (cleanResults.getErrorMessages().size() > 0) {
                //String errors = StringUtils.join(cleanResults.getErrorMessages(), ", ");
                //this.setMessage(errors);
                this.setErrorMessages(cleanResults.getErrorMessages());
                return false;
            } else {
                return true;
            }
        }
    }
}

其他地方:

HtmlFieldValidator<DefaultValue> hfv = new HtmlFieldValidator<DefaultValue>();
boolean satisfied = hfv.isSatisfied(params);
if (!satisfied) {
    String[] errorMessages = hfv.errorMessages;
    //instead of using their error message

    satisfy(errorMessages);//or whatever you want to do
}

编辑:

更新代码后我明白你的意思了。虽然我认为这有点过头了,稍后将字符串转换为数组会更容易,但您可以通过创建一个扩展 Validator 其 的新类来实现这一点。 >setMessage 方法。在该方法中,您将调用 super.setMethod 以及拆分字符串并将其作为数组存储在其类中。

class ValidatorWithArray extends Validator {
    public String[] errors;
    public final static String SPLIT_REGEX = ";&spLit;";// Something unique so you wont accidentally have it in the error

    public void setMessage(String error) {
        super.setMessage(error);
        this.errors = String.split(error, SPLIT_REGEX);
    }
}

HtmlFieldValidator 中:

public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
            if (o1 == null) {
                return true;
            } else {
                CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
                if (cleanResults.getErrorMessages().size() > 0) {
                    String errors = StringUtils.join(cleanResults.getErrorMessages(), ValidatorWithArray.SPLIT_REGEX);
                    this.setMessage(errors);
                    return false;
                } else {
                    return true;
                }
            }
        }

现在只需使用 ValidatorWithArray 而不是 Validator

If setMessage(String message) is a method created by a superclass, you can override it and once it receives the data, simply split the string into a list and call a second function in which you would actually place your code. On a side note, I would also recommend changing the separating string to something more unique as the error message itself could include a comma.

Your question doesn't really make much sense though. If you are "passing them back up" to a method implemented in a superclass, then this voids the entire point of your question as the superclass will be handling the data.

I am going to assume the setError methods is a simple setter that sets a String variable to store an error message that you plan to access after checking the data. Since you want to have the data in your preferred type, just create a new array of strings in your class and ignore the superclass. You can even use both if you so desire.

public class HtmlFieldValidator  extends AbstractAnnotationCheck<HtmlDefaultValue> {
    public String[] errorMessages = null;

    public void setErrorMessages(String[] s) {
        this.errorMessages = s;
    }

    public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
        if (o1 == null) {
            return true;
        } else {
            CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
            if (cleanResults.getErrorMessages().size() > 0) {
                //String errors = StringUtils.join(cleanResults.getErrorMessages(), ", ");
                //this.setMessage(errors);
                this.setErrorMessages(cleanResults.getErrorMessages());
                return false;
            } else {
                return true;
            }
        }
    }
}

Elsewhere:

HtmlFieldValidator<DefaultValue> hfv = new HtmlFieldValidator<DefaultValue>();
boolean satisfied = hfv.isSatisfied(params);
if (!satisfied) {
    String[] errorMessages = hfv.errorMessages;
    //instead of using their error message

    satisfy(errorMessages);//or whatever you want to do
}

EDIT:

After you updated your code I see what you mean. While I think this is sort of overdoing it and it would be much easier to just convert the string into an array later, you might be able to do it by creating a new class that extends Validator its setMessage method. In the method, you would call super.setMethod as well as splitting and storing the string as an array in its class.

class ValidatorWithArray extends Validator {
    public String[] errors;
    public final static String SPLIT_REGEX = ";&spLit;";// Something unique so you wont accidentally have it in the error

    public void setMessage(String error) {
        super.setMessage(error);
        this.errors = String.split(error, SPLIT_REGEX);
    }
}

In HtmlFieldValidator:

public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
            if (o1 == null) {
                return true;
            } else {
                CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
                if (cleanResults.getErrorMessages().size() > 0) {
                    String errors = StringUtils.join(cleanResults.getErrorMessages(), ValidatorWithArray.SPLIT_REGEX);
                    this.setMessage(errors);
                    return false;
                } else {
                    return true;
                }
            }
        }

And now just use ValidatorWithArray instead of Validator

﹂绝世的画 2024-12-25 16:55:34

我想要实现这一目标的情况与您的情况不同,但是我发现在我的情况下最好的是为每个错误创建一个注释(而不是创建一个会返回多个错误的注释)。我想这取决于你可能会产生多少错误,在我的例子中只有两个或三个。

这种方法还使您的代码非常易于重用,因为您可以在需要的地方添加注释并随意组合它们。

The situation in which I want to achieve this was different from yours, however what I found was best in my case was to create an annotation for each error (rather than having one that would return multiple errors). I guess it depends on how many errors you are likely to be producing in my case it was only two or three.

This method makes also makes your code really easy to reuse as you can just add the annotations wherenever you need them and combine them at will.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文