JSF PDF not downloadable while returned from Servlet [duplicate] - pdf

This question already has an answer here:
Internet Explorer 9 does not use file name for inline attachments
(1 answer)
Closed 3 years ago.
I have a form that once completed opens a new tab and calls my bean method annonceReturn().
This method sends back a pdf file. The problem is that as I open a new tab with _blank, the URL ends with .xhtml. Even the filename is displayed as being in my exemple "list.xhtml" (the last part of the URL). The problem is that I can't download this file because it's not considerated as a pdf file.
This is my xhtml file :
<h:form id="form">
<p:commandButton id="envoiRetour" onclick="this.form.target = '_blank';"
actionListener="#{returnCtrl.announceReturn()}"
value="Open PDF in new tab"
ajax="false" />
</h:form>
This is the returnCtrl.annonceReturn() method :
public void announceReturn() throws MalformedURLException, FileNotFoundException, DocumentException, BadElementException, IOException, InterruptedException {
String referenceAnnouncement = "C:/Users/path_to_my_pdf_file.pdf";
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(referenceAnnouncement), 10240);
response.reset();
response.setHeader("Content-type", "application/pdf");
response.setContentLength((int)new File(referenceAnnouncement).length());
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setHeader("Content-disposition", "inline; filename=" + "file.pdf");
response.setHeader("pragma", "public");
output = new BufferedOutputStream(response.getOutputStream(), 10240);
byte[] buffer = new byte[10240];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
} finally {
output.close();
input.close();
}
}
How can I do to open this PDF in a new tab and be able to download it ?
When I try to download it, it says there is a network error (and it tries to save it as xhtml file).
EDIT : this is the question that helped me : How to open a PDF file in a new tab
EDIT 2 : the problem is not that the PDF doesn't show. The problem is that it shows in the new tab but when I try to download it, the explorer wants to save it as an XHTML file.
EDIT 3 : as mentionned here -> Open PDF in new tab, saving file gives wrong file name
it seems the filename is ignored if the disposition is not "attachment"... So I think I need to think about another way to do it.
Thanks for your time.

Try 'attachment' instead of 'inline' to force the browser saving the file (instead of trying to open with the associated plugin - if installed)
response.setHeader("Content-disposition", "attachment; filename=" + "file.pdf");
Hope it helps.
Beppe

Here is my code, hope it helps.
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
File temp = File("./path/abc.pdf");
temp.deleteOnExit();
ec.responseReset();
ec.setResponseContentType("application/pdf");
ec.setResponseContentLength((int)temp.length());
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + temp.getName() + "\""); //inline;
OutputStream output = ec.getResponseOutputStream();
Files.copy(temp.toPath(), output);
fc.responseComplete();

I have tested in my project, here is the solution:
1 - Create button
<h:commandButton
onclick="this.form.target='_blank'"
id="cmdOpenPDF"
action="#{bean.openPDF(bean.code)}"
value="New PDF">
</h:commandButton>
2 - The bean has a function with a redirect link to PDF. This sample the pdf in the root folder.
public void openPDF(String code) throws Exception {
String filePdfName ="";
try {
//Make sure that this file in root
File pdf = new File("sample.pdf");
filePdfName = pdf.getName();
} catch (Exception ex) {
ex.printStackTrace();
}
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + "/" + filePdfName);
}

Related

Error While trying to view PDF document in browser it just get downloaded [ASP.net Core 3.0]

I have tried to view pdf documents in my ASP.net core application but when I clicked on Read button the pdf document just get downloaded
Here is My Code
In my Home Controller I have GetPdf Action
public ActionResult GetPdf(string fileName)
{
string filePath = "~/file/" + fileName;
Response.Headers.Add("Content-Disposition", "inline; filename=" + fileName);
return File(filePath, "application/pdf");
}
and in the View part I have used
Read
Turn off any download manager software installed on your system. When you try to read the pdf the download manager will take it over to download it.
Change your ActionMethod to this -
public ActionResult GetPdf(string fileName)
{
string filePath = "~/file/" + fileName;
Response.AddHeader("Content-Disposition", "inline; filename=" + fileName);
return File(filePath, "application/pdf");
}
Note the change of Response.Headers.Add to Response.AddHeader

Xamarin Android: How to Share PDF File From Assets Folder? Via WhatsApp I get message that the file you picked was not a document

I use Xamarin Android. I have a PDF File stored in Assets folder from Xamarin Android.
I want to share this file in WhatsApp, but I receive the message:
The file you picked was not a document.
I tried two ways:
This is the first way
var SendButton = FindViewById<Button>(Resource.Id.SendButton);
SendButton.Click += (s, e) =>
{
////Create a new file in the exteranl storage and copy the file from assets folder to external storage folder
Java.IO.File dstFile = new Java.IO.File(Environment.ExternalStorageDirectory.Path + "/my-pdf-File--2017.pdf");
dstFile.CreateNewFile();
var inputStream = new FileInputStream(Assets.OpenFd("my-pdf-File--2017.pdf").FileDescriptor);
var outputStream = new FileOutputStream(dstFile);
CopyFile(inputStream, outputStream);
//to let system scan the audio file and detect it
Intent intent = new Intent(Intent.ActionMediaScannerScanFile);
intent.SetData(Uri.FromFile(dstFile));
this.SendBroadcast(intent);
//share the Uri of the file
var sharingIntent = new Intent();
sharingIntent.SetAction(Intent.ActionSend);
sharingIntent.PutExtra(Intent.ExtraStream, Uri.FromFile(dstFile));
sharingIntent.SetType("application/pdf");
this.StartActivity(Intent.CreateChooser(sharingIntent, "#string/QuotationShare"));
};
This is the second
//Other way
var SendButton2 = FindViewById<Button>(Resource.Id.SendButton2);
SendButton2.Click += (s, e) =>
{
Intent intent = new Intent(Intent.ActionSend);
intent.SetType("application/pdf");
Uri uri = Uri.Parse(Environment.ExternalStorageDirectory.Path + "/my-pdf-File--2017.pdf");
intent.PutExtra(Intent.ExtraStream, uri);
try
{
StartActivity(Intent.CreateChooser(intent, "Share PDF file"));
}
catch (System.Exception ex)
{
Toast.MakeText(this, "Error: Cannot open or share created PDF report. " + ex.Message, ToastLength.Short).Show();
}
};
In other way, when I share via email, the PDF file is sent empty (corrupt file)
What can I do?
The solution is copying de .pdf file from assets folder to a local storage. Then We able to share de file.
First copy the file:
string fileName = "my-pdf-File--2017.pdf";
var localFolder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var MyFilePath = System.IO.Path.Combine(localFolder, fileName);
using (var streamReader = new StreamReader(Assets.Open(fileName)))
{
using (var memstream = new MemoryStream())
{
streamReader.BaseStream.CopyTo(memstream);
var bytes = memstream.ToArray();
//write to local storage
System.IO.File.WriteAllBytes(MyFilePath, bytes);
MyFilePath = $"file://{localFolder}/{fileName}";
}
}
Then share the file, from local storage:
var fileUri = Android.Net.Uri.Parse(MyFilePath);
var intent = new Intent();
intent.SetFlags(ActivityFlags.ClearTop);
intent.SetFlags(ActivityFlags.NewTask);
intent.SetAction(Intent.ActionSend);
intent.SetType("*/*");
intent.PutExtra(Intent.ExtraStream, fileUri);
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
var chooserIntent = Intent.CreateChooser(intent, title);
chooserIntent.SetFlags(ActivityFlags.ClearTop);
chooserIntent.SetFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(chooserIntent);
the file you picked was not a document
I had this issue when I trying to share a .pdf file via WhatsApp from assets folder, but it gives me the same error as your question :
the file you picked was not a document
Finally I got a solution that copy the .pdf file in assets folder to Download folder, it works fine :
var pathFile = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
Java.IO.File dstFile = new Java.IO.File(pathFile.AbsolutePath + "/my-pdf-File--2017.pdf");
Effect like this.

Import annotations (XFDF) to PDF

I have created a sample program to try to import XFDF to PDF using the Aspose library. The program can be run without exception, but the output PDF does not include any annotations. Any suggestions to solve this problem?
Update - 2014-12-12
I have also sent the issue to Aspose. They can reproduce the same problem and logged a ticket PDFNEWJAVA-34609 in their issue tracking system.
Following is my sample program:
public static void main(String[] args) {
final String ROOT = "C:\\PdfAnnotation\\";
final String sourcePDF = "hackermonthly-issue.pdf";
final String destPDF = "output.pdf";
final String sourceXFDF = "XFDFTest.xfdf";
try
{
// Specify the path of license file
License lic = new License();
lic.setLicense(ROOT + "Aspose.Pdf.lic");
//create an object of PdfAnnotationEditor class
PdfAnnotationEditor editor = new PdfAnnotationEditor();
//bind input PDF file
editor.bindPdf(ROOT + sourcePDF);
//create a file stream for input XFDF file to import annotations
FileInputStream fileStream = new FileInputStream(ROOT + sourceXFDF);
//create an enumeration of all the annotation types which you want to import
//int[] annType = {AnnotationType.Ink };
//import annotations of specified type(s) from XFDF file
//editor.importAnnotationFromXfdf(fileStream, annType);
editor.importAnnotationFromXfdf(fileStream);
//save output pdf file
editor.save(ROOT + destPDF);
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
}
}

<p:media display pdf from folder dynamically

I have several pdf files saved in ...WebContent/Manuals/filename.pdf that I am trying to display on my page. I am getting "Failed to Load PDF document" message in Chrome.
My Jsf:
<p:media value="#{reviewBean.manual}" player="pdf" height="600px" width="1000px" />
My #SessionScoped Bean:
public StreamedContent getManual() throws IOException {
String type = "application/pdf";
String path = "";
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
path = "C:\\.....\\WebContent\\Manuals\\filename.pdf";
InputStream is = new ByteArrayInputStream(path.getBytes());
return new DefaultStreamedContent(is, type);
}
}
There is additional logic that i have left out for clarity which decides which pdf is displayed.
I have also tried the file path of /Manuals/filename.pdf as path
I tried following the below example:
How to bind dynamic content using <p:media>?
In my case I do not need to retrieve a value using <f:param
Is my file path incorrect to display the image? Or am I building the Stream incorrectly? Any guidance is much appreciated.
I solved this by merely returning the url as a String.
public String getManual() {
return user.getManuals().get(user.getLData().getDepart());
}
Where the returned value is the file path of the pdf: Manuals/filename.pdf

download pdf servlet using content disposition not working fine with IE, chrome and firefox but not in Opera

I m using content disposition to download pdf file from my servlet. My code works fine for chrome, firefox and IE but the problem is when I try to download pdf file using opera, it removes pdf extension and adds htm. The following is my code:
String filename = "abc.pdf";
String filepath = "/pdf/" + filename;
System.out.println("filepath "+filepath);
resp.addHeader("content-disposition", "attachment; filename=" + filename);
ServletContext ctx = getServletContext();
InputStream is = ctx.getResourceAsStream(filepath);
System.out.println(is.toString());
int read = 0;
byte[] bytes = new byte[1024];
OutputStream os = resp.getOutputStream();
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
System.out.println(read);
os.flush();
os.close();
}catch(Exception ex){
logger.error("Exception occurred while downloading pdf -- "+ex.getMessage());
System.out.println(ex.getStackTrace());
}
You should probably set the content type of the response to application/pdf, to let the browser know that the downloaded file is not a HTML file, but a PDF file.
See ServletResponse.setContentType().