Как вызвать ArrayList, хранящийся в applicationScope из другого класса - PullRequest
0 голосов
/ 03 марта 2019

Я хочу вызвать ArrayList, хранящийся в applicationScope, из другого класса

У меня есть класс, что-то вроде этого, который хранит отскок данных в открытых именах переменных AL_data, метод getAllData просто хранит данные вAL_data

public class Application implements Serializable{

    private static final long serialVersionUID = 1L;
    public ArrayList<District> AL_data;

    public Application(){
        try {
            getAllData();
        } catch (NotesException e) {
            e.printStackTrace();
        }
    }
}

И я установил класс в качестве управляемого компонента в Face-Config с помощью applicationScope

<managed-bean>
    <managed-bean-name>App</managed-bean-name>
    <managed-bean-class>com.utils.Application</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

У меня также есть другой класс, который я хочу использовать для чтения области приложения

public class actions {

    private static Map<String, Object> applicationScope() {
        FacesContext context = FacesContext.getCurrentInstance();
        return (Map<String, Object>) context.getApplication().getVariableResolver().resolveVariable(context,"applicationScope");
    }

    public Vector<String> getDataForCurrentUser() {

        try {

            // how do I access the AL_data arraylist stored in applicationscope
    // ArrayList m = (ArrayList) this.applicationScope();


        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

и я установил этот класс как компонент управления с помощью sessionScope.

<managed-bean>
    <managed-bean-name>Actions</managed-bean-name>
    <managed-bean-class>com.utils.actions</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

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

спасибо

Томас

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

До тех пор, пока это разрешено правилами области действия, наилучшим подходом является позволить инфраструктуре обрабатывать внедрение свойств и bean-компонентов в другие bean-компоненты.

Поскольку вам нужен bean-объект с областью приложения внутри сеанса-bean-объект scoped, вы можете просто определить внедрение следующим образом:

<managed-bean>
    <managed-bean-name>Actions</managed-bean-name>
    <managed-bean-class>com.utils.actions</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>application</property-name>
      <value>#{App}</value>
    </managed-property>
</managed-bean>

Чтобы принять инъекцию свойства внутри вас, bean-компонент Actions определяет открытый метод следующим образом:

public class actions implements Serializable {

    private Application app;

    public void setApplication(Application app) {
        this.app = app;
    }

}

Таким образомвы можете держать бин приложения в любом месте, где вам нужно, без необходимости разрешать его снова и снова, когда вам это нужно.Вы также можете решить, что ссылка на компонент приложения - это слишком много, и вам просто нужны данные.В этот момент вам просто нужно настроить faces-config.xml и способ получения соответственно, чтобы получить именно это.

    <managed-property>
      <property-name>allData</property-name>
      <value>#{App.allData}</value>
    </managed-property>
public class actions implements Serializable {

    private static final long serialVersionUID = 1L;

    private ArrayList<District> allData;

    public void setAllData(ArrayList<District> allData) {
        this.allData = allData;
    }

}

Теперь два совета.

  1. Я бы не рекомендовал вам инициализировать данные компонента в конструкторе.Бины предназначены для ленивого использования, и поэтому данные должны быть лениво загружены.Если вам нужно предварительно загрузить данные, конструктор не в нужном месте.К сожалению, мы застряли с нежитью XPages, поэтому нет ничего лучше, чем исправить проблему, проверив, установлена ​​ли рассматриваемая переменная или нет.Это означает использование подхода, подобного этому:
public class Application implements Serializable {

    private static final long serialVersionUID = 1L;

    private ArrayList<District> allData;

    //public Application(){
    //    try {
    //        getAllData();
    //    } catch (NotesException e) {
    //        e.printStackTrace();
    //    }
    //}

    public ArrayList<District> getAllData() {
        if (allData == null) {
           try {
                allData = // your logic result
            } catch (NotesException e) {
                throw new FacesException(e);
            }
        }

        return allData;
    }

}
Я бы рекомендовал вам использовать общепринятые соглашения об именах, которые говорят, что имена свойств должны начинаться с символов в нижнем регистре (приложение вместо приложения) и имен классов с символа в верхнем регистре (com.utils.Actions вместо com.utils.actions)
0 голосов
/ 03 марта 2019

Добавьте общедоступный метод к вашему компоненту в области приложения, который другие классы Java могут использовать для доступа к экземпляру этого компонента:

public static Application get() {
    FacesContext context = FacesContext.getCurrentInstance();
    return (Application) context.getApplication().getVariableResolver().resolveVariable("App");
}

Затем вы можете использовать этот метод для доступа к экземпляру области приложения.bean-компонент из вашего класса Actions, а затем получите доступ к методам и переменным этого bean-компонента:

public class actions {

public Vector<String> getDataForCurrentUser() {
        // Access the AL_data arraylist stored in the App application scoped bean
        ArrayList<District>  m = Application.get().AL_data;
}
...