Можно ли установить несколько сообщений с помощью овальной AbstractAnnotationCheck? - PullRequest
4 голосов
/ 30 ноября 2011

Я использую овальную структуру проверки для проверки полей, которые в полях HTML не могут содержать вредоносный код JavaScript. Для обнаружения вредоносного кода я использую внешнюю платформу, которая возвращает мне список ошибок, которые я хотел бы использовать в качестве сообщений об ошибках в поле. Проблема, с которой я сталкиваюсь, заключается в том, что я могу установить setMessage только в реализации проверки, в то время как я бы предпочел сделать что-то вроде 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;
            }
        }
    }
}

Модель класса

class Foo {

    @HtmlField
    public String bar;

}

Код контроллера

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
}

Ответы [ 2 ]

4 голосов
/ 20 октября 2012

Если setMessage(String message) - это метод, созданный суперклассом, вы можете переопределить его и, как только он получит данные, просто разбить строку на список и вызвать вторую функцию, в которую вы фактически поместите свой код. Кроме того, я бы рекомендовал изменить разделительную строку на нечто более уникальное, поскольку само сообщение об ошибке может содержать запятую.

Ваш вопрос не имеет особого смысла. Если вы «передаете их обратно» методу, реализованному в суперклассе, то это приводит к аннулированию всей сути вашего вопроса, поскольку суперкласс будет обрабатывать данные.

Я собираюсь предположить, что setError методы - это простой установщик, который устанавливает переменную 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
}

EDIT:

После того, как вы обновили свой код, я понимаю, что вы имеете в виду. Хотя я думаю, что это своего рода перебор, и было бы намного проще просто преобразовать строку в массив позже, вы могли бы сделать это, создав новый класс, расширяющий 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

0 голосов
/ 08 апреля 2016

Ситуация, в которой я хочу добиться этого, отличалась от вашей, однако в моем случае лучше всего было создать аннотацию для каждой ошибки (вместо того, чтобы иметь аннотацию, которая будет возвращать несколько ошибок).Я предполагаю, что это зависит от того, сколько ошибок вы, вероятно, будете производить, в моем случае это было всего две или три.

Этот метод также делает ваш код действительно простым для повторного использования, так как вы можете просто добавлять аннотации там, где они вам нужны, и комбинировать их по желанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...