处理Xpages中的附件时出现问题

时间:2017-04-26 19:30:00

标签: xpages xpages-ssjs

我正在尝试编写一个带有Bootstrap外观的fileUpload / fileDownload自定义控件。我看起来很满意(见下文)。

enter image description here

但是,我的行为非常不一致。我非常希望用户能够单击删除按钮并删除附件并刷新重复控件。以类似的方式,如果用户选择"上传"我认为附件应该上传到文档中,并且重复控件也会刷新。

我将附件存储在与主文档分开的单个文档中[它存储在与代码不同的数据库中]。

我正在使用带有上传控件的js fileInput库。

我正在使用重复控件来滚动自己的文件下载查看器。

代码在某些时候有效,但并非总是如此。当页面失败时,我收到此错误消息(见下文)。

任何建议都将不胜感激。

Context Path: /scoApps/OTM1/OTM1.nsf
Page Name: /xpTest.xsp
javax.faces.FacesException
    at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:106)
    at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:210)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:96)
    at com.ibm.xsp.controller.FacesControllerImpl.execute(FacesControllerImpl.java:256)
    at com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:228)
    at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:157)
    at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
    at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138)
    at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
    at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576)
    at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1335)
    at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:853)
    at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796)
    at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565)
    at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1319)
    at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:662)
    at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:482)
    at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:357)
    at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:313)
    at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
Caused by: java.lang.IllegalArgumentException
    at javax.faces.model.ListDataModel.getRowData(ListDataModel.java:141)
    at com.ibm.xsp.component.UIRepeatContainer.addIndexedDataContext(UIRepeatContainer.java:173)
    at com.ibm.xsp.component.UIRepeatContainer.getDataContexts(UIRepeatContainer.java:86)
    at com.ibm.xsp.util.DataPublisher.getDataContextList(DataPublisher.java:349)
    at com.ibm.xsp.util.DataPublisher.revokeControlData(DataPublisher.java:271)
    at com.ibm.xsp.component.UIDataPanelBase.revokeControlData(UIDataPanelBase.java:319)
    at com.ibm.xsp.component.UIDataPanelBase.processDecodes(UIDataPanelBase.java:334)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1177)
    at com.ibm.xsp.component.UIRepeat.processDecodes(UIRepeat.java:526)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1177)
    at com.ibm.xsp.component.UIDataPanelBase.processDecodes(UIDataPanelBase.java:331)
    at javax.faces.component.UIForm.processDecodes(UIForm.java:166)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1177)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1177)
    at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:343)
    at com.ibm.xsp.component.UIViewRootEx._processDecodes(UIViewRootEx.java:1438)
    at com.ibm.xsp.component.UIViewRootEx.processDecodes(UIViewRootEx.java:1399)
    at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:98)
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
   <xp:this.data>
      <xp:dominoDocument var="document1" databaseName="scoApps\OTM1\OTM1Data.nsf" formName="attachment" action="editDocument" documentId="349CDB2FB259D5D3862581090076AC50" />
   </xp:this.data>
   <script src="fileinput/js/fileinput.js" type="text/javascript" />
   <link href="fileinput/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" />
   <xp:scriptBlock id="scriptBlockInitFile">
      <xp:this.value><![CDATA[$(document).ready(
function() {
$('input[type=file]').fileinput({
previewFileType: "image",
browseClass: "btn btn-primary",
browseLabel: "Browse...",
browseIcon: '<i class="glyphicon glyphicon-plus"></i>',
removeClass: "btn btn-danger",
removeLabel: "Delete",
removeIcon: '<i class="glyphicon glyphicon-trash"></i>',
uploadClass: "btn btn-info",
});
}
);]]></xp:this.value>
   </xp:scriptBlock>
   <xp:div themeId="container" style="width:800px">
      <xp:br />
      <xp:fileUpload id="fileUpload1" value="#{document1.attachments}">
         <xp:this.attrs>
            <xp:attr name="multiple" value="true" />
            <xp:attr name="data-show-preview" value="false" />
         </xp:this.attrs>
      </xp:fileUpload>
      <xp:br />
      <xp:button value="Save Changes" id="button1" styleClass="btn btn-primary">
         <xp:eventHandler event="onclick" submit="true" refreshMode="complete" disableValidators="true">
            <xp:this.action>
               <xp:actionGroup>
                  <xp:save />
               </xp:actionGroup>
            </xp:this.action>
         </xp:eventHandler>
      </xp:button>
   </xp:div>
   <xp:repeat rows="30" id="attrepeat" first="0" var="att" indexVar="attachmentIndex">
      <xp:this.facets>
         <xp:text disableTheme="true" xp:key="header" escape="false">
            <xp:this.value><![CDATA[<table class="table table-striped table-bordered table-hover"><col width="150"><col width="450"><th>File Name</th><th style="text-align:right">Delete</th>]]></xp:this.value>
         </xp:text>
         <xp:text disableTheme="true" xp:key="footer" escape="false">
            <xp:this.value><![CDATA[</table>]]></xp:this.value>
         </xp:text>
      </xp:this.facets>
      <xp:this.value><![CDATA[#{javascript:var bckDoc = document1.getDocument() 
var attachments:java.util.Vector = session.evaluate("@AttachmentNames",bckDoc);
attachments}]]></xp:this.value>
      <xp:tr>
         <xp:td>
            <xp:link escape="true" id="link1" target="_blank" text="#{javascript:att.toString();}">
               <xp:this.value><![CDATA[#{javascript:var tmpStr:String;  
var str:String; 
var bckDoc = document1.getDocument()    
var attachments:java.util.Vector = session.evaluate("@AttachmentNames",bckDoc);
tmpStr = attachments.toString;
tmpStr

var bckDoc = document1.getDocument()    
var attachments:java.util.Vector = session.evaluate("@AttachmentNames",bckDoc); 
tmpStr = attachments.elementAt(0);


var unid = "349CDB2FB259D5D3862581090076AC50"


var dbPath = "scoApps/OTM1/OTM1.nsf/"
var dbDataPath = "scoApps/OTM1/OTM1Data.nsf/"

var url = "http://localhost/";
url += dbPath; 
url += "/xsp/.ibmmodres/domino/OpenAttachment/";
url += dbDataPath + "/";
url += unid
url += "/" + "attachments" + "/";
url += tmpStr;
url}]]></xp:this.value>
               <xp:image id="image1" rendered="false">
                  <xp:this.url><![CDATA[#{javascript:var pdfImage = 'pdf.gif';
//if(attachment.indexOf("pdf")> 0)
return pdfImage;                            }]]></xp:this.url>
               </xp:image>
               &amp;#160;
            </xp:link>
         </xp:td>
         <xp:td style="text-align:right">
            <xp:button value="Delete" id="button2" styleClass="btn btn-danger">
               <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
                  <xp:this.action><![CDATA[#{javascript:function removeAttachment(targDB,doc_Url,fileName,docUnid2) {

//passing parameters by reference
var docUrl:String= doc_Url;


var targetDB:NotesDatabase = session.getDatabase(session.getCurrentDatabase().getServer(),targDB);
var attachmentName:String =fileName;

//deducing the document's unid from the document's url
 //docUrl=@Left(docUrl,"?");
 //var docUnid=@RightBack(docUrl,"/");
print (docUnid2);

 //setting the handle to the document
 var docContext:NotesDocument=targetDB.getDocumentByUNID(docUnid2);
 if (docContext==null) {
  viewScope.CodeError="Either the UNID is invalid or the target db does not contain the doc or both";
  return;
 }


//getting the handle to the concerned attachment
 var embObj:NotesEmbeddedObject=docContext.getAttachment(attachmentName);
if (embObj==null) {
  viewScope.CodeError="No attachment is found by the name "+ attachmentName;
  return;
 }

//remove the attachment
embObj.remove()
docContext.save(true,false);
}

var fleNme = att.toString();
print (fleNme);
removeAttachment("scoApps/OTM1/OTM1Data.nsf","http://localhost/scoApps/OTM1/OTM1.nsf//xsp/.ibmmodres/domino/OpenAttachment/scoApps/OTM1/OTM1Data.nsf//349CDB2FB259D5D3862581090076AC50/attachments/ITReport.xlsx",fleNme,"349CDB2FB259D5D3862581090076AC50");}]]></xp:this.action>
               </xp:eventHandler>
            </xp:button>
         </xp:td>
      </xp:tr>
   </xp:repeat>
</xp:view>

1 个答案:

答案 0 :(得分:1)

它在ApplyRequestValues阶段失败,这与在repeat中运行行的代码有关。我之前在数据视图中使用过缓存只是ID。关键是确定哪个组件的代码失败(重复的值,链接,图像或按钮 - 如果它是一个组件,属性)以及它是否需要在该阶段运行。它可能没有。

查看堆栈跟踪,getRowData()上的“由...引起”失败意味着重复的value可能存在问题,但我不完全确定。它可能是重复的子组件之一失败。

如果它是一个只读的代码位,它可以包装在if (view.isRenderingPhase())块中。只需确保输出对其他阶段有效的内容!例如。对于rendered属性,将其他阶段的结果设置为true(之前我错过了并导致自己出现问题!)

如果是因为document数据源尚未在该阶段初始化,那么将所有内容包装在Panel中可以解决问题,方法是将dominoDocument数据源关联为Panel的子级,这可能会鼓励它在restoreView阶段更好地重新初始化。这是一个彻头彻尾的黑暗,但我知道在页面加载期间,当一个dominoDocument数据源是一个Panel的子级而不是XPage本身的子级时,会在不同的时间加载它。