使用frostillic.us控制器类时,getSessionAsSigner为null

shi*_*lem 2 java jsf xpages

我将首先说:

  • 我正在使用ODA(godmode,khan,marcel).
  • 我是唯一的代码签名者.
  • sessionAsSigner在我第一次加载调用它的XPage时工作.
  • 在重新加载页面(cmd + R)后,sessionAsSigner变为null,但是当我在viewScope生命周期的上下文中随后在任何操作中引用它时,它不会变为空.
  • 我正在实现@Gidgerby的控制器类概念

我还要补充说,如果我只是准备一个执行以下操作的简单XPage,那么sessionAsSigner可以一致地工作:

<p>
    <xp:text value="session: #{session.effectiveUserName}" />
</p>

<p>
    <xp:text value="sessionAsSigner: #{sessionAsSigner.effectiveUserName}" />
</p>
Run Code Online (Sandbox Code Playgroud)

现在,我没有使用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;
 }
}
Run Code Online (Sandbox Code Playgroud)

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));
 }
}
Run Code Online (Sandbox Code Playgroud)

这是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);
}
}
Run Code Online (Sandbox Code Playgroud)

基本上,viewhandler所做的是检查java类的存在,前缀是XPage名称本身.

例如.test .xsp = something.something.package.测试 PageController

这种方法让我忘记了在faces-config.xml中将特定的XPage相关类声明为通用托管bean所有XPage都可以轻松处理相应的支持bean,它始终命名为#{controller}

现在,如果我只是在XPage中编写以下内容,那么一切都将在第一次工作,但不是第二次(getSession()没问题,getSessionAsSigner为null),永远不会再次.我需要对数据库进行新的更改(在对java代码进行任何更改后设计更新并且xsp.application.forcefullrefresh = true)并且它将再次起作用,但是,再次,只是第一次加载页面.

<p>
    <xp:text value="answer doc id: #{controller.answer.id}" />
</p>
Run Code Online (Sandbox Code Playgroud)

想法?

Jes*_*her 6

这可能是由于我们在XPages运行时发现的一个错误,以某种方式与之相关ClassLoader#loadClass.事实证明,使用它(和我以前一样)可能导致sessionAsSigner在第一页加载后停止工作.修复方法是切换到Class.forName(String, true, ClassLoader):https://github.com/jesse-gallagher/XPages-Scaffolding/commit/d65320fd6d98ff2fbaa814a95eb38ce7bad5a81d