2012-04-19 2 views
0

Я реализовал Autoconverter (с forceSelection = false) на экране обслуживания. Чтобы изменить существующую запись, пользователь выберет идентификатор из списка автозаполнения.Реализация JSF-конвертера

Чтобы добавить новую запись, пользователь вводит новый идентификатор в том же поле.

В конвертере приложение попытается выполнить поиск записи в БД с использованием ID.
Если не найден, создается новый пустой объект с указанным идентификатором и во избежание дублирования этот объект добавляется в список массивов, поддерживаемый в конвертере.

Это работает как ожидается в сеансе с одним браузером. но при тестировании с несколькими браузерами я обнаружил, что список Array используется для всех экземпляров.

Я не уверен, что подход, который я принял, прав? если нет, можете ли вы предложить мне альтернативный подход.

private List<SchoolMasterDetails> schoolMasterDetailsDB = new ArrayList<SchoolMasterDetails>(); 


@Override 
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) { 
SchoolMasterDetails selectedObject = null; 

System.out.println("getAsObject ==> Entering."); 
System.out.println("getAsObject ==> '" + submittedValue + "'"); 

if (!submittedValue.trim().equals("")) { 
    selectedObject = (SchoolMasterDetails) getMasterService().getSchoolbyCode(submittedValue); 

    if (selectedObject == null) { 
     // search Object on localDB 
     for (SchoolMasterDetails p : schoolMasterDetailsDB) { 
      if (p.getSchoolCode().equalsIgnoreCase(submittedValue.trim())) { 
       System.out.println("getAsObject from ArrayList ==> " + p); 
       return p; // return selectedObject from list of created objects 
      } 
     } 

     System.out.println("getAsObject ==> selectedObject is null, Hence Creating new Object"); 
     selectedObject = new SchoolMasterDetails(); 
     selectedObject.setSchoolCode(submittedValue.trim()); 
     selectedObject.setSchoolName("TEST TEST TEST"); 
     schoolMasterDetailsDB.add(selectedObject); 
    } 
    else { 
     System.out.println("getAsObject from Database ==> " + selectedObject); 
    } 
} 
System.out.println("getAsObject ==> " + selectedObject); 
} 
System.out.println("getAsObject ==> Exiting.");  
return selectedObject; 
} 

С уважением,

Shirish

ответ

1

Насколько я это понимаю (еще учусь сам), преобразователь выполняет ровно одну цель: Он готовит пользовательские объекты, которые будут использоваться в представлениях (getAsString) и переводит строки обратно в объекты (getAsObject). Он будет использоваться всякий раз, когда вход (список радиостанций, текстовое поле, автозаполнение) привязан к переменной в бэк-компоненте, который относится к типу вашего настраиваемого объекта. В вашей свободе можно решить, что String следует использовать для представления вашего объекта и как вы используете эту String для поиска объектов.

Учитывая это, я бы не использовал конвертер для хранения локального списка объектов и не позволял ему обрабатывать сам процесс создания. Вместо этого я бы предположил, что где-то есть бэк-компонент, который хранит ваши объекты данных и заботится обо всей вашей логике. Этот компонент может иметь список, скажем, школьных мастеров, которые могут быть запрошены для объектов, которые он содержит (аналогично тому, что вы делаете). Затем вы можете реализовать поиск таким образом, чтобы он обрабатывал не найденный случай и всегда возвращал действительный объект (который может быть новым), или вы могли поймать не найденный случай в конвертере, а затем запустить a createNew() от bean, чтобы получить новый экземпляр.

IMHO это отделяет управление экземплярами более четко от цели перевода вашего конвертера. Кроме того, из вашего кода кажется, что у вас есть два места для поиска объектов - через getMasterService() (локальный метод?) И внутри вашего сохраненного ArrayList. Я не совсем понимаю это ...


Что касается вашей проблемы с браузерами, совместно использующими экземпляр: это звучит как проблема с областью. Если ваш бэк-файл, который должен хранить и управлять вашими данными, находится в области приложения, тогда один и тот же набор данных будет доступен до тех пор, пока выполняется приложение. Эти данные будут доступны в браузерах, а также для всех пользователей.

С другой стороны, если вы поместите бит в область сеанса, каждый сеанс создаст свой собственный экземпляр компонента и сохранит уникальные данные. Точно так же просмотр бобов в режиме реального времени будет продолжаться до тех пор, пока один просмотр и бобы запроса будут стерты и регенерированы для каждого HTTP-запроса. Вы можете узнать больше здесь: How to choose the right scope

В ответах там рассказывается о бобах (где обычно живут ваши данные). Я не уверен в конвертерах, я рассматриваю их как классы, которые доступны для широкого применения, так что каждый сеанс и представление могут использовать их для перевода - если вы поддерживаете список там, он вполне может быть доступен по всему миру.