【问题标题】:Using Rich Text with Java Managed Bean in XPages在 XPage 中将富文本与 Java 托管 Bean 一起使用
【发布时间】:2015-05-17 11:59:58
【问题描述】:

谁能提供一个示例,说明如何使用托管 bean 执行基本的 CRUD 操作,带有后端 RichText 字段,因此最终结果与在标准 XPage 开发中使用文档数据源相同。

以下代码显然是错误的或不完整的,但我找不到任何文档来进一步说明。

我知道我还没有回收任何东西。

非常感谢。

public class RichTextTest implements Serializable {
private static final long serialVersionUID = 1L;
private String plainItem;
private RichTextItem richItem;
private String unid;


public RichTextTest ()throws NotesException {

String docID = ExtLibUtil.readParameter(FacesContext.getCurrentInstance(),"key");
if (StringUtil.isNotEmpty(docID)){load(docID);}}

public void load(String ID) throws NotesException{
Document doc = null;
setUnid(ID);

doc = ExtLibUtil.getCurrentDatabase().getDocumentByUNID(ID);
setPlainItem(doc.getItemValueString("PlainTextField"));
setRichItem ((RichTextItem) doc.getFirstItem("RichTextField"));

}

public void save() throws NotesException{

    Database database = ExtLibUtil.getCurrentDatabase();
    Document doc = database.getDocumentByUNID(getUnid());
    doc.replaceItemValue("PlainTextField", getPlainItem());
    doc.replaceItemValue("RichTextField",getRichItem());
    doc.save();


}



public String getPlainItem() {
    return plainItem;
}
public void setPlainItem(String plainItem) {
    this.plainItem = plainItem;
}
public RichTextItem getRichItem() {
    return richItem;
}
public void setRichItem(RichTextItem richItem) {
    this.richItem = richItem;
}
public void setUnid(String unid) {
    this.unid = unid;
}
public String getUnid() {
    return unid;
}

在 XPage 上

    <xp:inputText value="#{richTextTest.plainItem}" id="plainTextField1">     </xp:inputText>
<xp:br></xp:br>
<xp:inputRichText value="#{richTextTest.richItem}" id="richTextField1"></xp:inputRichText>
<xp:br></xp:br>
<xp:button value="Save" id="button1"><xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
    <xp:executeScript script="#{richTextTest.save}"></xp:executeScript>
</xp:this.action></xp:eventHandler></xp:button>

【问题讨论】:

  • 托管 bean 在序列化期间不能保存 Notes 对象,因此私有变量将不起作用。您可以将 RichText 存储为纯字符串。在您的 SAVE 事件中,还有一些工作要做。最简单/最节省的方法是将 RichText(不是 Richtext,而是 HTML - 网络上没有 RichText)视为 Mime 并使用 Mime 类进行保存
  • @stwissel 非常感谢您的帮助。在 XPages 中绕过 Java/Managed Beans 是一条非常曲折的道路,没有任何关于该做什么和不该做什么的详细文档。是的,我认为序列化和 Notes 对象存在一些问题,我在努力中遇到了一些问题。我没有使用 Mime 的经验,所以我想这是我的下一步。

标签: xpages


【解决方案1】:

首先,正如 Stephan 在他的 cmets 中所说,RichTextItem 在 XPages 中找不到。 Domino 可以通过 2 种方式存储“富文本”字段:

  • 作为 Notes 客户端通常使用的经典“RichTextItem”
  • 作为完全是另一种格式的 Mime/Html,由 lotus.domino.MimeEntity 组成

您通过 XPages 访问/修改并保存的任何“RichTextItem”字段都将转换为 Mime。如果您打算对发送/处理电子邮件做任何事情,那么学习 Mime 并了解它是如何工作的非常值得。

如果您希望将 inputRichText 与嵌入式图像一起使用,那么我认为没有人能够为您提供示例。 inputRichText 控件与 Domino Document 数据源的绑定非常紧密。 可能会想出一个解决方案,但这将涉及创建您自己的 DataSource 类型、创建 DocumentAdapter、创建 DocumentAdapterFactory、通过 XspContributor 提供它并重新实现 DominoDocument 中的许多功能,这本身并不是微不足道的。

如果您只希望允许 HTML 内容(没有嵌入的图像或文件),那么您可以在之前回答的堆栈溢出问题中使用以下解决方案。 Bind an inputRichText to a Bean 这个答案描述了如何使用 MimeMultipart 类将 bean 绑定到 inputRichText 控件。我从来没有使用过这个解决方案,所以我无法评论它的有效性,但是它有 7 个赞成票,所以看起来不错。 您可能希望禁用用于上传图像的编辑器工具栏图标,这样用户就不会认为他们可以上传(因为他们无法上传)

猜测一下,当您将 MimeMultipart 保存到 Document 时,您将有 2 个选项。

  • 将其保存为字符串
    • 为了省钱,我想你会使用 MimeMultipart 的 getHTML() 函数来获取 HTML 字符串
    • 要加载,您可以使用静态方法 MimeMultipart.fromHTML(yourhtml) 创建 MimeMultipart
  • 将其保存为 MimeEntity
    • 要保存创建 MimeEntity (doc.createMimeEntity()) 并使用 setContentFromText(),使用 NotesStream 传入 getHTML(),请参阅帮助中的示例
    • 要加载,结合使用 getContentAsText() 和静态 MimeMultipart.fromHTML(mimeEntity.getContentAsText())

抱歉,以上内容都不全面,但至少您有一些探索途径。请注意,您还应该查看 session.convertMime 设置及其工作原理 - 学习 Mime 很有趣,不是吗? :)

替代方案 所有这一切的替代方法是使用 Document DataSource + bean 的混合方法。将文档数据源绑定到 inputRichText 控件,然后将 bean 绑定到其他控件。 要加载 bean 的数据,您可以使用变量解析器访问 DominoDocument。 DominoDocument 是一个包装了“后端”lotus.domino.Document 类的 java 类。它做了很多事情,比如跟踪哪些字段发生了变化,以及自从你加载文档后其他人是否修改了文档。您可以使用 DominoDocument 的 getDocument() 函数访问后端类,但如果您使用这种混合方法,请不要直接保存后端文档,始终通过 DominoDocument 的 save() 方法保存。

例如如果您的文档数据源是“document1”,请将自己设为私有函数

private DominoDocument getDominoDocument() {
    Object o = ExtLibUtil.resolveVariable(FacesContext.getCurrentInstance(), "document1");

    if (o == null) return null;

    if (o instanceof DominoDocument) {
        return (DominoDocument)o;
    } else if (o instanceof DominoDocumentData) {
        return ((DominoDocumentData)o).getDocument();
    }
}

然后在你的 bean 中你可以用来加载的其他函数中,注意调用它的时间可能很重要(也许是 postOpenDocument?)

public void loadFromDominoDocument() {
    DominoDocument ddoc = getDominoDocument();

    this.someBeanVar = ddoc.getItemValueString("someBeanVar");
    this.anotherBeanVar = ddoc.getItemValueString("anotherBeanVar");

}

相反,您将有一些其他功能来使用 bean 值更新到 domino 文档。

public void updateDominoDocument() {

    DominoDocument ddoc = getDominoDocument();

    ddoc.replaceItemValue("someBeanVar",this.someBeanVar);
    ddoc.replaceItemValue("anotherBeanVar", this.anotherBeanVar);

}

注意:我还没有进行任何保存,如果您使用此混合模型,请注意您必须使用“DominoDocument”类(bean 中的 save() 方法或标准文档保存操作)进行所有保存- 调用 save() 方法)。 这是因为 save 方法会跟踪“最后修改日期”,如果您使用后端文档保存,它会保存一次,然后如果您尝试使用 DominoDocument 保存,它将失败,因为它会认为文档已被其他人修改(因为上次修改的日期与其先前已知的值不匹配)。不幸的是,“并发”设置都没有改变这种行为。

上面的代码是一个指南,我只是从头顶写的,所以如果有任何问题,请告诉我,我会更深入地研究。我相信你会有一些问题! :)

【讨论】:

  • 哇,感谢卡梅伦的出色回应。我对这两种解决方案都感兴趣,因为我正在使用这个特定的开发作为 XPages 中 Java 的学习曲线。我想我应该首先使用 Mime,因为它将为我提供其他未来的应用程序。所以我目前没有任何问题,但我相信我会回来的!
猜你喜欢
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
相关资源
最近更新 更多