Struts 2 Проверка параметров запроса (Int и Strings)

Допустим, у меня есть этот URL здесь

<s:url action ="profile" var ="profile_url">
  <s:param name = "id">${user.userId}</s:param>
</s:url>
<s:a href = "%{profile_url}">My Profile</s:a>

Где идентификатор параметра будет иметь только значение int. Итак, внутри моего класса Action.

public class ViewProfileAction extends ActionSupport{

    public String execute(){
       //someServiceLayer.getUser(id);
       return "success";
    }

    public int getId() {
       return id;
    }

    public void setId(int id) {
       this.id = id;
    }

    private int id;
}

Кажется, все идет хорошо, пока пользователь нажимает на ссылку, поэтому, если пользователь нажмет на ссылку, URL-адрес будет примерно таким

localhost:8090/HelloStruts2/profile?id=1

но что, если пользователь напрямую манипулирует URL-адресом? он вручную набрал в браузере букву или символ? так

localhost:8090/HelloStruts2/profile?id=b

если пользователь сделал это, я уверен, что произойдет исключение или произойдет ошибка.

Мой вопрос, как мне проверить параметр URL? или если бы пользователь сделал такое (ввел букву или отрицательное число в параметре id) я бы перенаправил его на другую страницу.


person user962206    schedule 18.01.2013    source источник
comment
Если вы уверены, пожалуйста, сообщите нам, что такое исключение.   -  person Roman C    schedule 18.01.2013
comment
Лучше ограничить URL-адреса несанкционированного доступа в пользовательском перехватчике, прежде чем выполнять само действие, мы должны предотвратить проблему.   -  person MohanaRao SV    schedule 18.01.2013


Ответы (2)


У вас есть поле параметра как int, но вы установили его как String в URL-адресе. Чтобы устранить ошибки такого рода, вам нужно поставить какой-нибудь перехватчик перед (или после, не имеет значения) перехватчиком params, чтобы проверить это значение. Например вы ставите перехватчик validation.

@Action(value = "youraction", results = {
  @Result(location = "/path/to/page.jsp"),
}, interceptorRefs = {@InterceptorRef("validation"), @InterceptorRef("basicStack")})

тогда вам нужно реализовать метод validate() в своем действии

public void validate() {}

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

public void setId(String id) {
    try {
      this.id = Integer.parseInt(id);
    } catch (NumberFormatException nfe){}
} 

все, у вас больше нет исключения и в сеттере проверяется параметр типа String.

На ваш вопрос: если вы неправильно проанализировали параметр, у вас будет значение 0 в методе execute(). Итак, вы решаете, какой результат вернуть. Вы также можете проверить значение в методе validate(), если перехватчик validation, размещенный после перехватчика params, выполняет синтаксический анализ или GenericValidator.isInt после этого setFieldError() и показывает его в JSP или перенаправляет сразу после проверки.

person Roman C    schedule 18.01.2013
comment
Я сделал то, что вы предложили, но все равно OGNL все еще компанится, это ошибка ognl.MethodFailedException: Method setId failed for objectorg.hitplay.user.actions.ViewProfileAction.setId([Ljava.lang.String;)] - person user962206; 19.01.2013
comment
также, почему я должен добавить метод validate()? - person user962206; 19.01.2013
comment
нужны были оба перехватчика validation, setId, validate(). Последнее является своего рода магией. Это необходимо для правильной работы проверки. - person Roman C; 19.01.2013

ParametersInterceptor, используя XWorkConverter, вызовет исключение типа

ognl.MethodFailedException: java.lang.NoSuchMethodException setId(java.lang.String);

потому что он будет искать (посредством отражения) Setter для String вместо int.

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

Если у вас нет результата input, объявленного в вашем struts.xml, вы получите исключение типа

Не определен результат для действия your.package.your.Action и ввода результата

Если он у вас есть, то вы будете перенаправлены обратно к результату, объявленному в вашем struts.xml (тот же JSP, другой JSP или действие).

Вы можете справиться с этим, выводя ошибки поля через тег <s:fielderror /> в вашем JSP и, в конечном итоге, окрашивая красные границы полей с помощью javascript (не в вашем случае, потому что они являются параметрами URL).

Чтобы правильно проверить такие вещи (вместо того, чтобы запрашивать Struts2 для сбоя и выдачи ошибок для вас), вы можете использовать XML Validation, объявив файл XML в том же пакете действия с именем YourActionName-validation.xml

В вашем случае следует использовать Обязательный валидатор< /a> и Int Validator

(и укажите 0 как параметр min в вашем Int Validator, чтобы предотвратить отрицательные значения)

person Andrea Ligios    schedule 18.01.2013
comment
вы правы, он возвращает указанную ошибку, в частности ognl.MethodFailedException: java.lang.NoSuchMethodException setId(java.lang.String); он продолжает отображаться на моей консоли, можно ли его удалить? или не показывать? . Я просто хочу удалить его. также я забыл о том, что Validation.xml не знал, что он также будет работать для запроса на получение. - person user962206; 18.01.2013
comment
ЕСЛИ (и это не обязательно) вы хотите проверить ошибки, исходящие от людей, пытающихся взломать (или неправильно использовать) ваше веб-приложение, сделайте это. В противном случае не делайте этого. Но невозможно избежать отображения этой ошибки в консоли, если вы не напишете свой собственный Interceptor для выполнения тех же операций, что и ValidatorInterceptor, но без вывода ошибки... для меня это не имеет смысла. Просто объявите результат ввода и красиво обработайте его на странице, показывая сообщение вроде «ой, я обнаружил, что вы пытались взломать мои вещи... пожалуйста, дайте мне хорошие параметры». - person Andrea Ligios; 18.01.2013
comment
после прочтения вашего комментария я понял, что я думаю, что было бы хорошо показать эту ошибку в консоли или в регистраторе для будущего использования. В любом случае, я чувствую себя немного глупо, спасибо! - person user962206; 18.01.2013