【问题标题】:getSessionAsSigner is null while using frostillic.us controller classes使用frostillic.us 控制器类时getSessionAsSigner 为空
【发布时间】: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>

想法?

【问题讨论】:

    标签: java jsf xpages


    【解决方案1】:

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

    【讨论】:

    • 那是它!非常感谢! sessionAsSigner 终于稳定了!
    【解决方案2】:

    如果在 Java 调试器中运行会发生什么?第二轮进入XSPUtil.getSessionAsSigner()吗?

    如果启用了 Godmode,我倾向于使用 ExtLibUtil.resolveVariable() 来获取 sessionAsSigner 的句柄。或者,还有org.openntf.domino.utils.Factory.getSessionAsSigner()。这些会给出不同的结果吗?

    (在 RC3 中仍然可用,但标记为不推荐使用 Factory.getSession(SessionType.SIGNER),因为我们支持 XPage 之外的实现,因此涉及更多会话类型。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多