Есть ли способ настроить Struts для привязки нулевого значения вместо пустой строки? - PullRequest
4 голосов
/ 01 июня 2011

Когда пользователь решает оставить поле в форме пустым, Apache Struts связывает пустое значение String как значение для свойств в ActionForm. Есть ли способ изменить поведение глобально и выбрать null вместо пустого String?

Я знаю, что Spring MVC делает то же самое, но есть также StringTrimmerEditor , который можно зарегистрировать как редактор свойств для обрезки строк до null.

Ответы [ 8 ]

3 голосов
/ 02 июня 2011

Возможное решение - одно, которое позволит использовать единую точку входа для всех ваших полей String, - это зарегистрировать пользовательский преобразователь, но не в Struts, а в BeanUtils .

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

Упрощенный поток будет похож на Struts: RequestUtils > BeanUtils > BeanUtilsBean > ConvertUtils > ConvertUtilsBean > Конвертер .

Интересно то, что есть также StringConverter , который преобразует из String в ... aaaaaa ... String!

Класс ConvertUtils имеет метод register , который вы можете использовать для регистрации преобразователей, перезаписывая существующие. Это означает, что вы можете написать собственный пользовательский преобразователь String, который возвращает пустое значение для пустых строк, а затем подождать, пока приложение Struts загрузится полностью, чтобы у вас не было сюрпризов (т.е. убедитесь, что ваш преобразователь последний зарегистрирован для типа String). ,

После загрузки приложения вы входите и перезаписываете конвертер String по умолчанию в своей собственной реализации. Например, вы можете сделать это с помощью ServletContextListener и вызвать ConvertUtils.register(...) в методе contextInitialized.

Затем вы настраиваете слушателя в web.xml, и вам должно быть хорошо идти .

1 голос
/ 28 декабря 2012

В web.xml используйте код ниже

<init-param>
      <param-name>convertNull</param-name>
      <param-value>true</param-value>
</init-param>
1 голос
/ 16 декабря 2011

Я думаю, вы могли бы также использовать свою собственную реализацию BeanUtils, переопределяя класс org.apache.commons.beanutils.converters.AbstractConverter и org.apache.commons.beanutils.converters.StringConverter

0 голосов
/ 01 мая 2015

Struts 2 предлагает хороший механизм для этого с перехватчиками, который, я думаю, намного безопаснее и проще, чем копаться с BeanUtils. Вот код, который я использовал, основанный на блоге Cimballi , но отредактированный для компиляции в Java 7 (оригинал был с 2009 года):

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

public class RemoveEmptyParametersInterceptor implements Interceptor {

public RemoveEmptyParametersInterceptor() {
    super();
}

/**
 * @see com.opensymphony.xwork2.interceptor.Interceptor#destroy()
 */
public void destroy() {
    // Nothing to do.
}

/**
 * @see com.opensymphony.xwork2.interceptor.Interceptor#init()
 */
public void init() {
    // Nothing to do.
}


public String intercept(final ActionInvocation invocation) throws Exception   {
   final String result;

    final ActionContext actionContext = invocation.getInvocationContext();
    final Map<String, Object> parameters = actionContext.getParameters();

    if (parameters == null) {
        // Nothing to do.
    } else {
        final Collection<String> parametersToRemove = new ArrayList<String>();

        for (final Map.Entry entry : parameters.entrySet()) {
            final Object object = entry.getValue();
            if (object instanceof String) {
                final String value = (String) object;

                if (StringUtils.isEmpty(value)) {
                    parametersToRemove.add((String) entry.getKey());
                }
            } else if (object instanceof String[]) {
                final String[] values = (String[]) object;

                final Object[] objects =
                    ArrayUtils.removeElement(values, "");

                if (objects.length == 0) {
                    parametersToRemove.add((String) entry.getKey());
                }
            } else {
                throw new IllegalArgumentException();
            }
        }

        for (final String parameterToRemove : parametersToRemove) {
            parameters.remove(parameterToRemove);
        }
    }

    result = invocation.invoke();

    return result;
  }
}

А вот как я использую его в моем файле struts.xml:

<package name="webdefault" namespace="/" extends="struts-default">
      <interceptors>
        <interceptor name="removeEmptyParameters" class="com.sentrylink.web.struts.RemoveEmptyParametersInterceptor"/>
        <interceptor-stack name="webStack">
            <interceptor-ref name="removeEmptyParameters"/>
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
      </interceptors>

     <default-interceptor-ref name="webStack"/>
     ...
</package>

Мне было указано, что ActionForm в исходном вопросе является соглашением Struts 1 (вопрос с тех пор был правильно помечен), но, поскольку Google все еще переносит его сюда с запросом Struts 2, я надеюсь, что этот ответ будет кому-то полезен еще.

0 голосов
/ 20 ноября 2013

Это небольшой старый вопрос, но я решил эту проблему, реализовав другое решение (я думаю, более простым способом).

Я реализую TypeConverter для преобразования пустой строки в ноль.Нужно два файла:

Конвертер.

public class StringEmptyToNullConverter implements TypeConverter {

    private static final Logger log = LoggerFactory.getLogger(StringEmptyToNullConverter.class);

    @Override
    public Object convertValue(Map arg0, Object arg1, Member member, String arg3, Object obj, Class arg5) {
        String[] value = (String[]) obj;
        if (value == null || value[0] == null || value[0].isEmpty()) {
            logDebug("is null or empty: return null");
            return null;
        }
        logDebug("not null and not empty: return '{}'", value[0]);
        return value[0];
    }

    private void logDebug(String msg, Object... obj) {
        if (log.isDebugEnabled()) {
            log.debug(msg, obj);
        }
    }
}

и регистр, названный xwork-conversion.properties.Вы должны поместить этот файл в свой путь Java.

# syntax: <type> = <converterClassName>
java.lang.String = StringEmptyToNullConverter

см. Документацию по стойкам

0 голосов
/ 12 марта 2013

Ср http://struts.apache.org/development/1.x/userGuide/configuration.html для convertNull; -)

convertNull - принудительное моделирование поведения версии 1.0 при заполнении форм. Если установлено значение «истина», числовые типы классов Java-оболочки (например, java.lang.Integer) по умолчанию будут иметь значение null (а не 0). (Начиная с версии 1.1) [false]

0 голосов
/ 01 июня 2011

См. Метод Apache StringUtils.stripToNull().

Что касается конфигурации, Struts не предоставил нам такую ​​функциональность (я не помню). Я бы предложил переопределить метод reset() из ActionForm, но он вызывается до того, как контроллер повторно заполняет компонент формы.

0 голосов
/ 01 июня 2011

Объявить строковое значение по умолчанию в ActionForm как NULL.
Eg: private String str = null;

РЕДАКТИРОВАТЬ: решение для этого есть. Я думаю, что для этого атрибута у вас есть методы setter и getter, в методе getter проверьте, является ли значение пустым, тогда вы точно установили нулевое значение.

...