Преобразование пользовательских входных данных в конкретные экземпляры класса
Фон
Пользователи вводят информацию в веб-форму, например:
<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_
входных значений:
- каков наиболее эффективный способ создания экземпляров классов Java, которые сопоставляются с типами пользовательского ввода, используя значения, предоставленные пользователем?
- существует ли лучший механизм для отображения типов пользовательского ввода таким образом, что создание экземпляров их репрезентативных классов проще реализовать?
- существует ли лучший способ представления типов пользовательского ввода в веб-форме?
Спасибо!
2 ответа:
Поместить информацию о типе в имена пар имя-значение-отличный способ сделать это. Это позволяет автоматизировать процесс. Например, можно написать фильтр, который повторяет параметры запроса, выполняет преобразование для каждого из них и сохраняет новые объекты в качестве атрибута запроса.
Кроме того, каждый из классов (за исключением
List
) содержит метод.valueOf(String)
, который будет выполнять большинство преобразований за вас. Вы могли бы лучше использовать aSimpleDateFormat
для создания ваши объекты времени и даты. Это позволит вам очистить ваши данные.
Единственный способ, который я нашел, чтобы преобразовать значения, это сделать это вручную:
Обратите внимание, что это означает, что карта, таким образом, не является необходимой, так как она добавляет неиспользуемый слой сложности: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.