Преобразование пользовательских входных данных в конкретные экземпляры класса


Фон

Пользователи вводят информацию в веб-форму, например:

<input type="text" name="report_name" value="First name" />
<select name="report_date_birthday">
  <option value="2038-01-19">Jan 19, 2038</option>
</select>
<input type="checkbox" name="report_array_colour[]" value="Blue" />Blue
<input type="checkbox" name="report_array_colour[]" value="Red" />Red
Эти значения в конечном счете передаются в программное обеспечение для составления отчетов. API программного обеспечения для отчетов требует пар имя-значение с именами в виде экземпляров String и значениями в виде классов Java.

Задача

Подкласс реализует абстрактный метод (который связывает типы пользовательского ввода с классами Java) следующим образом:
private static final String REPORT_VARIABLE_PREFIX = "report_";

protected Map<String, Class<?>> getPrefixes() {
  Map<String, Class<?>> map = new HashMap<String, Class<?>>();

  map.put( REPORT_VARIABLE_PREFIX + "", java.lang.String.class );
  map.put( REPORT_VARIABLE_PREFIX + "int_", java.lang.Integer.class );
  map.put( REPORT_VARIABLE_PREFIX + "float_", java.math.BigDecimal.class );
  map.put( REPORT_VARIABLE_PREFIX + "array_", java.util.List.class );
  map.put( REPORT_VARIABLE_PREFIX + "date_", java.util.Date.class );
  map.put( REPORT_VARIABLE_PREFIX + "time_", java.sql.Time.class );
  map.put( REPORT_VARIABLE_PREFIX + "timestamp_", java.sql.Timestamp.class );

  return map;
}

Все входные данные пользователя представляются в виде значений java.lang.String, за исключением report_array_ ценности.

Вопросы

Игнорирование report_array_ входных значений:

  1. каков наиболее эффективный способ создания экземпляров классов Java, которые сопоставляются с типами пользовательского ввода, используя значения, предоставленные пользователем?
  2. существует ли лучший механизм для отображения типов пользовательского ввода таким образом, что создание экземпляров их репрезентативных классов проще реализовать?
  3. существует ли лучший способ представления типов пользовательского ввода в веб-форме?

Спасибо!

2 2

2 ответа:

Поместить информацию о типе в имена пар имя-значение-отличный способ сделать это. Это позволяет автоматизировать процесс. Например, можно написать фильтр, который повторяет параметры запроса, выполняет преобразование для каждого из них и сохраняет новые объекты в качестве атрибута запроса.

Кроме того, каждый из классов (за исключением List) содержит метод .valueOf(String), который будет выполнять большинство преобразований за вас. Вы могли бы лучше использовать a SimpleDateFormat для создания ваши объекты времени и даты. Это позволит вам очистить ваши данные.

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

protected Object convertValue( String prefix, String value ) {
  Class<?> c = getPrefixes().get( prefix );
  Object result = value;

  try {
    if( c == java.lang.String.class ) {
      result = new String( value );
    }
    else if( c == java.sql.Timestamp.class ) {
      result = Timestamp.valueOf( value );
    }
    else if( c == java.sql.Time.class ) {
      result = Time.valueOf( value );
    }
    else if( c == java.util.Date.class ) {
      DateFormat sdf = createDateFormat();
      result = sdf.parse( value );
    }
    else if( c == java.math.BigDecimal.class ) {
      result = new BigDecimal( value );
    }
    else if( c == java.lang.Integer.class ) {
      result = Integer.valueOf( value );
    }
    else if( prefix.equalsIgnoreCase( PARAM_VARIABLE_PREFIX + "array_int_" ) ) {
      result = parseIntegerArray( value );
    }
  }
  catch( Exception e ) {
    throw new RuntimeException( e );
  }

  return result;
}
Обратите внимание, что это означает, что карта, таким образом, не является необходимой, так как она добавляет неиспользуемый слой сложности:
  map.put( REPORT_VARIABLE_PREFIX + "", java.lang.String.class );
  map.put( REPORT_VARIABLE_PREFIX + "int_", java.lang.Integer.class );
  map.put( REPORT_VARIABLE_PREFIX + "float_", java.math.BigDecimal.class );
  map.put( REPORT_VARIABLE_PREFIX + "array_", java.util.List.class );
  map.put( REPORT_VARIABLE_PREFIX + "date_", java.util.Date.class );
  map.put( REPORT_VARIABLE_PREFIX + "time_", java.sql.Time.class );
  map.put( REPORT_VARIABLE_PREFIX + "timestamp_", java.sql.Timestamp.class );
Поскольку карта не добавляет никакого значения процессу преобразования, ее можно удалить, что означает, что метод convertValue становится:
  protected Object convertValue( String prefix, String value ) {
    Object result = value;

    try {
      if( prefix.equalsIgnoreCase( PARAM_VARIABLE_PREFIX + "" ) ) {
        result = new String( value );
      }
      else if( prefix.equalsIgnoreCase( PARAM_VARIABLE_PREFIX + "timestamp_" ) ) {
        result = Timestamp.valueOf( value );
      }
      // ... etc.