【发布时间】:2015-08-28 19:19:43
【问题描述】:
我首先要说:
- 我正在使用 ODA (godmode,khan,marcel)。
- 我是唯一的代码签名者。
- sessionAsSigner 在我第一次加载调用它的 XPage 时工作。
- sessionAsSigner 在我重新加载页面 (cmd + R) 后变为 null,但当我随后在 viewScope 生命周期的上下文中的任何操作中引用它时不会。
- 我正在实施@Gidgerby 's concept of controller classes
如果我只准备一个执行以下操作的简单 XPage,我还要补充一点,sessionAsSigner 可以始终如一地工作:
<p>
<xp:text value="session: #{session.effectiveUserName}" />
</p>
<p>
<xp:text value="sessionAsSigner: #{sessionAsSigner.effectiveUserName}" />
</p>
现在,我没有使用 SSJS。根据我目前的知识,我尽可能地面向 JSF/EL。所以,我访问 Domino 后端的方式对于 Domino XPages 程序员来说是非常规的。
当我尝试做上述事情时,我无法让 getSessionAsSigner 始终如一地工作......
这是我的 XPage 控制器(支持 bean):
public class TestPageController extends StandardXPageController {
private static final long serialVersionUID = 1L;
private AnswerDTO answer;
public TestPageController() {
loadQuotation();
}
private void loadQuotation() {
AnswerDAO answerDAO = Factory.createAnswerDAO();
try {
answer = answerDAO.read("doc_id");
} catch (Exception e) {
e.printStackTrace();
}
}
public AnswerDTO getAnswer() {
return answer;
}
}
AnswerDTO 是 POJO。我正在使用 DAO/DTO 设计模式。 AnswerDAO 实现 - 使用简化的代码(包装方法只是字段的映射) - 如下:
public class AnswerDAODominoImpl implements AnswerDAO {
private transient Session s;
private transient Database db;
private Session getSession() {
if (s == null) {
s = XSPUtil.getCurrentSessionAsSigner();
}
return s;
}
private Database getDatabase() throws NotesException {
if (db == null) {
db = getSession().getDatabase("server_name", "server_path");
}
return db;
}
public AnswerDTO read(String id) throws Exception {
Database db = getDatabase();
return wrap(db.getDocumentByID(id));
}
}
这是 ViewHandler 类:
public class ViewHandler extends ViewHandlerExImpl {
public ViewHandler(final javax.faces.application.ViewHandler delegate) {
super(delegate);
}
@SuppressWarnings("unchecked")
public UIViewRoot createView(final FacesContext context, final String pageName) {
try {
// pageName is the XPage name prefixing the slash (e.g. "/home")
String pageClassName = pageName.substring(1);
Class<? extends XPageController> controllerClass = null;
try {
controllerClass = (Class<? extends XPageController>) context.getContextClassLoader().loadClass(
"com.sea.xsp.controller." + StringUtil.getProperCaseString(pageClassName) + "PageController");
} catch (ClassNotFoundException cnfe) {
controllerClass = StandardXPageController.class;
}
XPageController controller = controllerClass.newInstance();
Map<String, Object> requestScope = (Map<String, Object>) context.getApplication().getVariableResolver().resolveVariable(context, "requestScope");
requestScope.put("controller", controller);
UIViewRootEx root = (UIViewRootEx) super.createView(context, pageName);
root.getViewMap().put("controller", controller);
requestScope.remove("controller");
// MethodBinding beforePageLoad = context.getApplication().createMethodBinding("#{controller.beforePageLoad}", new Class[] { PhaseEvent.class });
// root.setBeforePageLoad(beforePageLoad);
return root;
} catch (Exception e) {
e.printStackTrace();
}
return super.createView(context, pageName);
}
}
基本上,viewhandler 所做的是检查是否存在一个前缀是 XPage 名称本身的 java 类。
例如。 test.xsp = something.something.package.TestPageController
这种方法让我忘记了在 faces-config.xml 中将特定的 XPage 相关类声明为通用托管 bean 所有 XPage 都将轻松处理其相应的支持 bean,该支持 bean 将始终命名为 #{controller}
现在,话虽如此,如果我只是在 XPage 中编写以下内容,那么第一次一切都会正常,但不会第二次(getSession() 可以,getSessionAsSigner 为空),以后再也不会了。我需要将新的更改推送到数据库(对 java 代码和 xsp.application.forcefullrefresh=true 进行任何更改后的设计更新)它会再次工作,但是,再次,只是第一次页面已加载。
<p>
<xp:text value="answer doc id: #{controller.answer.id}" />
</p>
想法?
【问题讨论】: