Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
106 views
in Technique[技术] by (71.8m points)

java - Name of the downloaded file in <af:fileDownloadActionListener>, calculated directly when clicking <af:commandImageLink>

I am trying to improve an old application that uses Oracle ADF 12c. I need to compute the file name before it will be downloaded.

Currently the download of the file is written like this.

<af:table value="#{DocListManagedBean.list}" var="row" 
    disableColumnReordering="true" varStatus="vs" id="t1" 
    columnStretching="column:c2" emptyText="#{PageLabels.emptyText}" 
    styleClass="AFStretchWidth">
    <af:column width="100px" align="center">
        <f:facet name="header">
            <af:outputText value="#{PageLabels.document}"/>
        </f:facet>
        <af:commandImageLink shortDesc="#{PageLabels.downloadDocument} ID: #{row.idDocument}" 
            icon="/skin/images/icons/pdf_icon4.gif">
            <af:setPropertyListener from="#{row.idDocument}" 
                to="#{DocListManagedBean.selectedIdDocument}" type="action"/>
            <af:fileDownloadActionListener contentType="application/pdf" 
                filename="#{row.documentName}" 
                method="#{DocListManagedBean.downloadFileListener}"/>
        </af:commandImageLink>
    </af:column>
    <af:column>
        <f:facet name="header">
            <af:outputText value="#{PageLabels.documentName}"/>
        </f:facet>
        <af:outputText value="#{row.documentName}"/>
    </af:column>
</af:table>

And it should now be so that (based on the document id) the file name should be computed, i.e. concatenated from several elements that are not in the object, the list of which is presented in af:table. I already have the method returning the new file name in managed bean (called generateDocumentFileName). This method based on selectedIdDocument field in DocListManagedBean computes the correct filename and saves it in another field DocListManagedBean named selectedDocumentNewFilename.

Is it possible (without changing - without adding another field to the type of object presented by af:table) before running the af:downloadFileListener method, to run another method in managed bean (my generateDocumentFileName) ? ... which would calculate the missing name, save it to the field selectedDocumentNewFilename in managed bean and then new filename will be available e.g. via

<af:fileDownloadActionListener contentType="application/pdf" 
                filename="#{DocListManagedBean.selectedDocumentNewFilename}" 
                method="#{DocListManagedBean.downloadFileListener}"/>

Where I should put a call to my generateDocumentFileName method in the code above or is it a stupid idea and I should have done it differently ?

Thanks for help,

koli

question from:https://stackoverflow.com/questions/66045288/name-of-the-downloaded-file-in-affiledownloadactionlistener-calculated-direc

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The idea is mostly correct. You can programmatically set the file name in the filename attribute of the af:fileDownloadActionListener. (no need to call another function before hand - so you can remove the af:setPropertyListener).

You can get value from any iterator binding using the resolveExpression from the JsfUtils library. (detailled here https://cedricleruth.com/how-to-retreive-the-value-of-an-iterator-binding-variable-programmatically-in-adf/) For example your #{DocListManagedBean.selectedDocumentNewFilename} could look like this :

private String selectedDocumentNewFilename;

public String getSelectedDocumentNewFilename(){      
  //Using below function you can easily get any of those value in your ADF Bean as follow : 
  Long currentIdDocument = (Long)resolveExpression("#{row.idDocument}");//if idDocument is a Long in your VO
  String currentNameDocument= (String)resolveExpression("#{row.documentName}"); //for example
  String anyOtherStringValueYouWant= (String)resolveExpression("#{bindings.YOUR_VO.YOUR_VO_ATTRIBUTE.inputValue}"); //for example
  //add any function to do something with this ID
  String generatedName = this.generateDocumentFileName(currentIdDocument);
  return "" + currentIdDocument.toString() + "_" + currentNameDocument + ".pdf"; //format as you like
  //or in your case : return "" + generatedName + ".pdf";
}


/**
 * Method for taking a reference to a JSF binding expression and returning
 * the matching object (or creating it).
 * @param expression EL expression
 * @return Managed object
 * @author : Duncan Mills, Steve Muench and Ric Smith's JSFUtils class
 */
public static Object resolveExpression(String expression) {
    FacesContext facesContext = getFacesContext();
    Application app = facesContext.getApplication();
    ExpressionFactory elFactory = app.getExpressionFactory();
    ELContext elContext = facesContext.getELContext();
    ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
    return valueExp.getValue(elContext);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...