"Streaming" a File to an Element (not a download)?

Ok, I’ve clean run out of talent on this one…

I need to embed PDFs in a portlet - no big whoop - except the PDFs are generated by an IS.

I can DOWNLOAD them just fine using the export bean as there is a share on the IS that the MWS has access to but, obviously, that directory isn’t served up by the MWS.

So…

Is there a way to stream the file to a CONTROL and display it in line rather than have the browser download it?

Any help is appreciated,

Lucas.

Hummm…

So I’ve tried passing HTML like the below thru a WS call put the Adobe plug in doesn’t like it. It seemed like a good idea… except I was concerned about maxing out the URI lenght.

THIS IS MY HTML

Anyway, now I’m wondering if I can move the PDF from the IS to the USERS folder in the MWS taxonomy, but I don’t know how to reference it in the server side Java code. Any ideas?

Thanks,

Lucas.

You can construct a portlet action url that would stream the pdf content back to the browser. Then you can just set that portlet action URL as the target of your tag.

For example, in your page bean you could create a new java method that constructs your action URL:


	public String getMyPdfActionUrl() {
		try {
			IPortletURL actionUrl = createActionUrl();
			actionUrl.setAXSRFT(true);
			actionUrl.setTargetAction("exportPDF_action"); 
			
			return "fe:" + actionUrl.toString(); //prepend fe: to make url relative to the front end url instead of this webapp context
		} catch (Exception e) {
			error(e);
			return "javscript:void(0)"; //return a do nothing url
		}
	}

… and the target action that the portlet action url will execute:


	@PortletAction
	public String exportPDF_action() {
		try {
			//TODO: get the PDF content from the source and create a file export bean  
			//    See the wm_caf_misc sample from the SDK for examples
			IFileExportBean exportBean = [TODO]; //TODO: create this object for your PDF data.
			streamFileDataToResponse(exportBean);
		} catch (Exception e) {
			throw new FacesException(e);
		}
		
	    return OUTCOME_OK;
	}

…and then your html markup would look something like this:


<object data="#{activePageBean.myPdfActionUrl}" type="application/pdf" width="100%" height="100%">
 
  <p>It appears you don't have a PDF plugin for this browser.
  No biggie... you can <a href="#{activePageBean.myPdfActionUrl}">click here to
  download the PDF file.</a></p>
  
</object>

Thanks a million, Eric, but I’m struggling with some things…

  • Did you mean for me to literally append “fe:” to the URL, or is that a place holder for something?

  • The action doesn’t seem to run, and when I follow the link manually I get the following error:

This is the URL that’s generated, with some redactions for privacy:


http://<server>:<port>/meta/default/folder/0000010933?wmp_tc=10937&wmp_rt=action&wmp_ax=8Q38Qf1%2b6oMBqVGFoAmsOZ8x1cA%3d&wmp_ta=exportPDF_action

Thanks so much!

(edited)

Eric:

I got it working! The URl creation code had an error. The line in question should have looked like this:

actionUrl.setTargetAction([b]"#{DownloadDefaultviewView.exportPDF_action}"[/b]);

Thanks a million.

Mark,

Thanks.

Lucas,

Hi Lucas,

If your portlet is not using annotated portlet actions then yes, setting the target action to a binding expression is the way to make it work.

In the example I provided, I was assuming you were using annotated portlet actions (this is the default for new portlets created in designer v8.2) as described in the “Mitigate Portlet Security Vulnerabilities” section of the CAF Development Help (see page 512 @ http://techcommunity.softwareag.com/ecosystem/documentation/webmethods/wmsuites/wmsuite8-2_sp2/Designer/8-2-SP1_CAF_Development_Help.pdf)

Hello experts. I have a similar issue but I couldn’t solve it with your examples. Can you help me?

  • I have a IS Service that generates the PDF and returns it as a base64 String.
  • Service is called on Initialize of view. No issues.
  • I have created the actions:
	public String getPDFActionUrl() {
		try {  
			IPortletURL actionUrl = createActionUrl();  
			actionUrl.setAXSRFT(true);  
			actionUrl.setTargetAction("exportPDF_action");   

			return "fe:" + actionUrl.toString(); //prepend fe: to make url relative to the front end url instead of this webapp context  
		} catch (Exception e) {  
			error(e);  
			return "javscript:void(0)"; //return a do nothing url  
		}  

	}

and

	@PortletAction
	public String exportPDF_action() {  
		try {  

			byte[]  arq = javax.xml.bind.DatatypeConverter.parseBase64Binary(myService().getResult().getBase64String());

			IFileExportBean exportBean = new SimpleFileExportBean("ficha.pdf", "application/pdf ", arq.length, true, arq);

			streamFileDataToResponse(exportBean);  			
			
		} catch (Exception e) {  
			error(e);  
			log(e);
		}  

		return OUTCOME_OK;  
	}  

In my view, I have an ‘Include HTML’ that refers to an html file in my project that contains. The ‘evaluate’ property is set to ‘true’


<object data="#{ModuloTesteDDTestePDFView.PDFActionUrl}" type="application/pdf" width="100%" height="100%">  
  
  <p>It appears you don't have a PDF plugin for this browser.  
  No biggie... you can <a href="#{ModuloTesteDDTestePDFView.PDFActionUrl}">click here to  
  download the PDF file.</a></p>  
    
</object>  

What can I be doing wrong?

Thanks in advance.

Prepending “fe:” to your action url is not needed in this use case.

For example:


	public String getPDFActionUrl() {
		try {  
			IPortletURL actionUrl = createActionUrl();  
			actionUrl.setAXSRFT(true);  
			actionUrl.setTargetAction("exportPDF_action");   

			return actionUrl.toString(); 
		} catch (Exception e) {  
			error(e);  
			return "javscript:void(0)"; //return a do nothing url  
		}  
	}

Removing “fe:” solved the problem, thanks! When should I use it?

Also, PDF controls (print, save, zoom etc) from the object embed are not showing. Should I add some specific parameters to my html page so the user can use those options?

Basically, if the code is inside of a CAF portlet, then the “fe:” prefix is usually not needed.

In general, the “fe:” prefix is only needed when current request is not being serviced by the main MWS servlet context. For example by some standalone CAF page in a (non-MWS) web application.

And the context where the value is used must know how to interpret the string to replace the “fe:” prefix with the real value. The ‘Image’ control and others do that automatically, but if you are using an expression in some other place it likely won’t know what to do with that.