Intershop: проверка на ненулевое значение в шаблоне .isml

Я не нахожу функцию для проверки существования значения в коде шаблона ISML. Есть «isDefined», но не «isNull».

isDefined возвращает true для нулевых значений:

      <isset name="woot" value="" scope="request">

       <isif condition="#isDefined(woot)#">
           <h1>woot</h1>
       </isif>

На данный момент я использую:

 <isif condition="#woot EQ null#">

or

 <isif condition="#woot EQ ''#">

Я не знаю, будет ли это работать для логических значений.


person nullsteph    schedule 31.08.2017    source источник
comment
обновите ответ, надеюсь, это прояснит для вас ситуацию.   -  person Willem Evertse    schedule 10.09.2017


Ответы (1)


isDefined - это то, как вы будете проверять нулевое значение. В AbstractTemplate у вас есть вызываемый метод isDefined(Object anObject). Проверьте скомпилированные версии jsp и java вашего шаблона isml.

In AbstractШаблон

public Boolean isDefined(Object anObject){
    ...
    return anObject != null ? Boolean.TRUE : Boolean.FALSE;
}

Код в вашем примере немного вводит в заблуждение, он фактически не проверяет нулевую ссылку. Потерпите меня.

Первое утверждение:

<isset name="woot" value="" scope="request">

Компилируется в:

Object temp_obj = (""); 
getPipelineDictionary().put("woot", temp_obj);

Это просто устанавливает переменную woot в пустую строку. Если вы добавите следующий скриптлет в свой isml, вы увидите, что он действительно не нулевой.

Отказ от ответственности: не используйте скриптлеты в производственном коде, это только для демонстрации точки зрения

<%
    Object woot = getPipelineDictionary().get("woot");
    out.print(woot == null); //print false
%>

Вторая линия:

<isif condition="#isDefined(woot)#">

Оценивает, существует ли переменная и существует ли она. В качестве значения он имеет пустую строку, а не null, как вы могли бы подумать.

Так что же происходит здесь тогда?

<isif condition="#woot EQ null#">

Глядя на скомпилированную версию:

context.getFormattedValue(getObject("woot"),null).equals(context.getFormattedValue(getObject("null"),null))

context.getFormattedValue(getObject("null"),null) здесь важный бит. Он пытается получить переменную с именем null, она не существует, поэтому возвращает null. Затем метод getFormattedValue возвращает пустую строку для нулевого аргумента (см. TemplateExecutionConfig::getFormattedValue). Затем все утверждение становится истинным. Не потому, что woot имеет значение null, а потому, что вы сравниваете его с несуществующей переменной, поэтому вы непреднамеренно оцениваете две пустые строки. Это поведение согласуется с оператором EQ, поскольку он используется для сравнить строки.

Вы бы получили тот же результат, если бы использовали это утверждение.

<isif condition="#woot EQ iDontExistButImAlsoNotNull#"> //true

Третий оператор сравнивает переменную woot с пустым строковым значением, которое возвращает true.

<isif condition="#woot EQ ''#">

Скомпилированная версия:

context.getFormattedValue(getObject("woot"),null).equals(context.getFormattedValue("",null))

Итак, настоящая проблема в том, что woot не имеет буквального значения null. См. следующий код:

<isset name="foo" value="#IDontExitPrettySureAboutThat#" scope="request">
<%
    Object foo = getPipelineDictionary().get("foo");
    out.print("foo is null? ");
    out.print(foo == null);
    //prints : foo is null? true
%>
<isif condition="#isDefined(foo)#">
    <h1>foo1</h1> //is never printed
</isif>

Я злоупотребляю тем фактом, что IDontExitPrettySureAboutThat не существует, чтобы установить нулевое значение для foo. Затем isDefined начинает работать так, как вы ожидаете. Это до тех пор, пока кто-то не инициализирует мою переменную чем-то отличным от нуля.

Однако я бы не рекомендовал вам использовать этот метод. Я думаю, что лучший совет — не использовать null для представления отсутствующего значения или недопустимого состояния. В этой ветке подробно рассматриваются некоторые детали этой темы.

person Willem Evertse    schedule 01.09.2017
comment
Я обновляю ОП. isDefined проверяет, только если он существует (был объявлен). Он не проверяет ценность или правдивость. - person nullsteph; 02.09.2017