代码之家  ›  专栏  ›  技术社区  ›  Nuri Ensing

通过带有OpenURL命令的Java WebAgent接收帖子时Lotus更改的字符

  •  3
  • Nuri Ensing  · 技术社区  · 7 年前

    我在Lotus Domino中有一个Java WebAgent,它通过OpenURL命令运行( https://link.com/db.nsf/agentName?openagent ). 创建此代理是为了接收包含XML内容的帖子。在解析或保存(XML)内容之前,webagent会将内容保存到内存中的文档中:

    对于使用OpenAgent URL命令从浏览器运行的代理 内存中文档是一个新文档,包含每个CGI的一个项 (公共网关接口)Domino支持的变量。每个项目 具有支持的CGI变量的名称和当前值。(无设计 你的工作是需要的;CGI变量可用 自动。) https://www.ibm.com/support/knowledgecenter/en/SSVRGU_9.0.1/basic/H_DOCUMENTCONTEXT_PROPERTY_JAVA.html

    帖子内容将(由Lotus)保存到 request_content 领域接收包含以下字符的内容时,例如:

     <Name xml:lang="en">tést</Name>
    

    Lotus将更改为a?。这也是我在阅读 请求\u内容 文档属性中的字段。是否可以将另存为a而不是:?在Lotus中?

    解决方案 :

    我是通过这篇帖子来解决这个问题的:

    Link which help me solve this problem

    Java解决方案:

     /****** INITIALIZATION ******/
                  session = getSession();
                  AgentContext agentContext = session.getAgentContext();
    
                  Stream stream = session.createStream();
                  stream.open("C:\\Temp\\test.txt", "LMBCS");
            stream.writeText(agentContext.getDocumentContext().getItemValueString("REQUEST_CONTENT"));
                  stream.close();
                  stream.open("C:\\Temp\\test.txt", "UTF-8");
                  String Content = stream.readText();
                  stream.close();
                  System.out.println("Content: " + Content);
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Richard Schwartz    7 年前

    我以前已经处理过这个问题,但我不再有访问代码的权限,所以我将不得不从内存中工作。

    这看起来像是UTF-8对UTF-16的问题,但最多有五个字符集可以发挥作用:执行POST的代码中使用的字符集、代理运行的JVM的字符集、Domino服务器代码的字符集、NSF的字符集(始终是LMBCS)和Domino服务器主机操作系统的字符集。

    如果我回忆正确,REQUEST\u内容将被视为原始数据,而不是字符数据。要正确地进行转换,您必须自己处理REQUEST\u内容的转换。

    用于在Java代理中保存数据的Notes API调用将自动从Unicode转换为LMBCS,反之亦然,但这仅在Java正确解释了传入数据流的情况下才起作用。我认为在大多数情况下,在Domino下运行的JVM是为UTF-16配置的,尽管情况可能并非如此。(我记得日本的一台服务器出现了一些问题,其中一个字符集是JIS标准字符集,但我不记得这是否在JVM中。)

    因此,如果我没有记错,您需要使用以下命令将REQUEST\u内容作为UTF-8从字符串读取到字节数组中 getBytes("UTF-8") 然后使用 new String(byte[] bytes, "UTF-16") . 假设然后将字符串传递给 NotesDocument.ReplaceItemValue() 因此,Notes API调用应该正确解释它。

    我这里可能有一些细节错误。已经有一段时间了。很久以前,我建立了一个数据库,其中显示了多年前所有Unicode字符的LMBCS、UTF-8和UTF-16值。如果您能够深入了解字节值,它将是查看此类数据并了解实际情况的有用工具。它是 downloadable from OpenNTF here . 在这种情况下,我记得我编写的代码获取字节数组并将其转换为十六进制,然后将其写入NotesItem,这样我就可以准确地看到输入的内容,并将其与数据库条目进行比较。

    而且,是的,根据评论,如果让双方的XML工具处理字符集问题和编码,效果会更好,但这并不总是万无一失的。您正在向流程中添加另一层字符集!你必须把它做好。如果目标是将数据存储在NotesItems中,那么仍然必须确保服务器端XML工具解码为正确的字符集,这可能不是默认值。

        2
  •  2
  •   Normunds Kalnberzins    7 年前

    看着这个,我的心都碎了。我也刚刚经历了这个地狱,找到了老建议,但是。。。我只是无法通过写磁盘来解决这件小事。

    Item item = agentContext.getDocumentContext().getFirstItem("REQUEST_CONTENT");
    byte[] bytes = item.getValueCustomDataBytes("");
    String content= new String (bytes, Charset.forName("UTF-8"));
    

    根据OP的评论编辑:有一篇关于这个主题的旧帖子: http://www-10.lotus.com/ldd/nd85forum.nsf/DateAllFlatWeb/ab8a5283e5a4acd485257baa006bbef2?OpenDocument (与OP用于解决方案的线程相同)

    这家伙声称,当他使用特定的http头时,该方法会失败。 现在他正在使用8.5和LS。在我的情况下,我不能通过发送额外的头(或在字符串参数的函数中)使其失败

    我是如何学会停止担忧,爱上笔记/多米诺骨牌的 : 为了它的价值 getValueCustomDataBytes() 仅适用于非常短的有效载荷。取决于内容!以重音字符(如“”)开头的文本将增加其仍然可用的长度。。。但无论我尝试什么,我都无法超过195个字符。我感到惊讶吗?在写了这么多年的笔记之后,我必须承认我仍然。。。

    嗯,诚然,它本来就不应该工作,因为它被记录为只用于用户定义的数据字段。

    最后 使用IBM的icu4j和icu4j字符集包—将它们放在jvm/lib/ext中。然后代码变成:

    byte[] bytes = item.getText().getBytes(CharsetICU.forNameICU("LMBCS"));
    String content= new String (bytes, Charset.forName("UTF-8"));
    

    是的,需要java中的权限。政策:

    permission java.lang.RuntimePermission "charsetProvider"; 
    

    这比通过文件系统更好吗?不知道。但看起来有点干净。