我想在 JSF 应用程序中配置自定义范围。我们在 Websphere 8.0/8.5 上使用 JSF 2.0 和 Primefaces 5.3.17。现在我们有带有命名注释的 RequestScoped Core- 和 SessionScoped Model-Beans。模型通过 Inject 传递给 Core。现在我们需要提供一种在许多浏览器选项卡上并行处理模型的方法。我们的想法是使用过滤器将生成的选项卡 ID 注入到响应中,然后从发布请求中提取它并将其传递给 Extension 以从地图加载/创建所需的 bean,每个视图的 bean 存储在会话中。我想过滤器工作正常 - 没有范围更改,生成的选项卡 ID 被注入表单等的操作属性中,并且没有错误。
但问题是,当我为某些模型 bean 设置新的自定义范围以证明它是否有效时。我遇到了一个例外,即“未定义 jquery”。对我来说,Java 部分看起来不错 - 在上下文中创建所需的 bean,然后在核心中使用相同的 bean。但事实证明,每个负责加载 js 的请求都会得到空响应。我没有看到任何堆栈跟踪,我完全不知道它为什么会发生,我如何以及在哪里可以找到导致这种行为的原因。
一些代码示例:
语境:
public class TabScopeContext implements Context, Serializable {
/**
* SerialId.
*/
private static final long serialVersionUID = -558257182139134232L;
public TabScopeContext() {}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public <T> T get(Contextual<T> contextual) {
final Bean<T> bean = (Bean<T>) contextual;
Map<String, Object> beans = getBeansForCurrentTab();
if (beans.containsKey(bean.getName())) {
return (T) beans.get(bean.getName());
} else {
return null;
}
}
private Map<String, Object> getBeansForCurrentTab() {
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
Map<Integer, Map<String, Object>> tabScope;
if (isTabScopeAlreadyInSession(session)) {
tabScope = getTabScope(session);
} else {
tabScope = initScopeInSession(session);
}
Integer viewId = TabScopeViewIdPersister.getInstance().getViewId();
if (isViewAlreadyInScope(viewId, tabScope)) {
return tabScope.get(viewId);
} else {
return initBeansForView(tabScope, viewId);
}
}
private Map<String, Object> initBeansForView(Map<Integer, Map<String, Object>> tabScope, Integer viewId) {
Map<String, Object> beans = new HashMap<String, Object>();
tabScope.put(viewId, beans);
return beans;
}
private boolean isViewAlreadyInScope(Integer viewId, Map<Integer, Map<String, Object>> tabScope) {
return tabScope.containsKey(viewId);
}
private Map<Integer, Map<String, Object>> initScopeInSession(HttpSession session) {
Map<Integer, Map<String, Object>> beansPerView = new HashMap<Integer, Map<String, Object>>();
session.setAttribute(TabScope.NAME, beansPerView);
return beansPerView;
}
private boolean isTabScopeAlreadyInSession(HttpSession session) {
return getTabScope(session) != null;
}
@SuppressWarnings("unchecked")
private Map<Integer, Map<String, Object>> getTabScope(HttpSession session) {
return (Map<Integer, Map<String, Object>>) session.getAttribute(TabScope.NAME);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext) {
final Bean<T> bean = (Bean<T>) contextual;
Map<String, Object> scopeBeansMap = getBeansForCurrentTab();
if (scopeBeansMap.containsKey(bean.getName())) {
return (T) scopeBeansMap.get(bean.getName());
} else {
T t = bean.create(creationalContext);
scopeBeansMap.put(bean.getName(), t);
return t;
}
}
/**
* {@inheritDoc}
*/
@Override
public Class<? extends Annotation> getScope() {
return TabScope.class;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isActive() {
return true;
}
}
延期:
public class TabScopeContextExtension implements Extension {
public void registerContext(@Observes AfterBeanDiscovery event) {
event.addContext(new TabScopeContext());
}
}
范围:
@NormalScope(passivating=true)
@Target({TYPE, FIELD, METHOD })
@Retention(value = RUNTIME)
@Documented
@Inherited
public @interface TabScope {
public static final String NAME = "TAB_SCOPE";
}
任何人都知道这个问题如何与范围更改联系起来以及如何解决它?在此先感谢您的帮助。