Rendering generated png into JSF - java

I built an image form PDF doc inside a JSF backing bean, i need to show image inside JSF page. I found that primefaces has a component named , I defined a variable:
private StreamedContent pdfImage;
according to this example http://www.primefaces.org/showcase/ui/dynamicImage.jsf. In my code
i built pdf using some data and apache PDFBox and save document into:
private byte[] bytesPdf;
My jsf line is
<p:graphicImage value="#{myBean.pdfImage}" rendered="#{myBean.showImage}"/>
After that i call following method that tranform first PDF document page to PNG i get:
public void buildPDFImage() throws IOException{
ByteArrayOutputStream os = new ByteArrayOutputStream();
//Build bufferedImage from pdf bytearray
InputStream input = new ByteArrayInputStream(bytesPdf);
PDDocument archivo=new PDDocument();
archivo=PDDocument.load(input);
PDPage firstPage = (PDPage) archivo.getDocumentCatalog().getAllPages().get(0);
BufferedImage bufferedImage = firstPage.convertToImage();
//File exit=new File("d:/exit.png"); if i do something like this and pass file as param to iowrite image is generated on file system
try {
ImageIO.write(bufferedImage, "png", os);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pdfImage = new DefaultStreamedContent(new ByteArrayInputStream(os.toByteArray()), "image/png");
}
When i run my app after generate pdf image i get this trace
GRAVE: Error Rendering View[/pages/apphuella.xhtml]
java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:2880)
at org.apache.catalina.connector.Request.getSession(Request.java:2577)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:920)
at com.sun.faces.context.SessionMap.getSession(SessionMap.java:235)
at com.sun.faces.context.SessionMap.put(SessionMap.java:126)
at com.sun.faces.context.SessionMap.put(SessionMap.java:61)
at org.primefaces.component.graphicimage.GraphicImageRenderer.getImageSrc(GraphicImageRenderer.java:105)
at org.primefaces.component.graphicimage.GraphicImageRenderer.encodeEnd(GraphicImageRenderer.java:45)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1756)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at
I would know if i´m using correctly if don´t how could i use it to show generated png(and other images)?, also if there´s other option to show runtime generated images on JSF pages.
Thanks in advance

At first, you need to keep the file a temporary directory. After that you should render the file again.
Try as below
Backing Bean
private String filePath;
public String filePath() {
return filePath;
}
private String getSystemPath() {
Object context = getFacesContext().getExternalContext().getContext();
String systemPath = ((ServletContext)context).getRealPath("/");
return systemPath;
}
public void buildPDFImage() throws IOException {
// create any kind of file types.
byte[] cotent = --> take byte array content of your files.
Stirng fileName = "xxx.pdf" or "xxx.png" --> your file name
String dirPath = "/pdf/" or "/images/"; --> a directory to place created files.
filePath = dirPath + fileName
createFile(new File(getSystemPath() + filePath), content);
}
private void createFile(File file, byte[] content) {
try {
/*At First : Create directory of target file*/
String filePath = file.getPath();
int lastIndex = filePath.lastIndexOf("\\") + 1;
FileUtils.forceMkdir(new File(filePath.substring(0, lastIndex)));
/*Create target file*/
FileOutputStream outputStream = new FileOutputStream(file);
IOUtils.write(content, outputStream);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Pages
<h:form enctype="multipart/form-data">
<h:commandButton value="Create"/>
<!-- Your Files is image -->
<p:graphicImage value="#{myBean.filePath}"/>
<!--
Your Files is pdf. You need PDF Viewer plugin for your browser.
My FireFox vesion is 20.0. It have default PDF Viewer.
If PDF File cannot display on your browser, it is depond on browser setting also.
-->
<p:media value="#{myBean.filePath}" width="100%" height="300px"/>
</h:form>

Related

Primefaces Download File Which is Outside FacesContext

I'm uploading an Excel Workbook to a directory which is outside the application context (for backup purposes) and saving its path into the database.
Now I need to download that file and I'm trying to use Primefaces Download, but I'm getting a null file.
Here is my code (much like Primefaces Showcase Download section):
Bean:
private StreamedContent file;
public void download(Arquivo arquivo) throws IOException {
InputStream stream = ((ServletContext)FacesContext.getCurrentInstance()
.getExternalContext().getContext()).getResourceAsStream(arquivo.getNomeArquivo());
file = new DefaultStreamedContent(stream);
}
View:
<h:commandLink id="btnDownload" title="Download Arquivo"
actionListener="#{arquivoBean.download(obj)}">
<p:fileDownload value="#{arquivoBean.file}" />
</h:commandLink>
Basically I need to pass an external path to InputStream instead of FacesContext.
From what I see my problem is that I'm passing my application context to the InputStream, appending the path in the argument of getResourceAsStream which, of course, is not found.
I'm new to this FileDownload thing. Thanks in advance!
If it can still be useful :
StreamedContent streamToReturn = DefaultStreamedContent.builder().name(FILE_NAME).contentType( FacesContext.getCurrentInstance().getExternalContext()
.getMimeType(FILE_PATH))
.stream(() -> {
try {
return new FileInputStream(FILE_PATH);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}).build();

Primefaces InputStream generating corrupted PDF in fileDownload

I need your help in solving the issue of generating a corrupted PDF file from an InputStream which is used in the fileDownload Component. I am having a PDF that is generated using the iText and then I am converting it to an inputStream, so I can use it as an input in the fileDownload component. After clicking on the download commandButton, I will download the file and open it, it will show a message:
The Adobe Reader can not open the file "sample.pdf" because it is
either not supported file type or it is damaged
The bean code is:
private StreamedContent file;
public void createPdf() {
try {
Document doc = Document(PageSize.A4, 50, 50, 50, 50);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in ;
PdfWriter writer;
writer = PdfWriter.getInstance(doc, out);
doc.open();
doc.add(new Paragraph("Hello World!"));
in = new ByteArrayInputStream(out.toByteArray());
file = new DefaultStreamedContent(in, "application/pdf", "sample.pdf");
} catch (Exception e) {
e.printStackTrace();
}
}
And the jsf code is:
<p:commandButton value="Download" ajax="false"
onclick="PrimeFaces.monitorDownload(start, stop);"
icon="ui-icon-arrowthick-1-s" actionListener="#{pdf.createPdf}">
<p:fileDownload value="#{pdf.file}"/>
</p:commandButton>
So how to fix the issue
Shouldn't there be doc.close() before you start coping bytes from out? Is the file also corrupted if you save it to hard drive instead of sending it to browser?

Download to folder/files android apps

my problem is that I use in my practice are pdf files. I did not add them into my application. I want pdf files from ftp or a URL to download it. I have no idea about the solution. I've tried a lot ftp code and URL code. All I want, when you pressed the button of the sdcard files from a URL or FTP address to get a download. Thanks for your help.
this code is working for me
public void onClick(View v) {
PrintAttributes printAttrs = new PrintAttributes.Builder().
setColorMode(PrintAttributes.COLOR_MODE_COLOR).
setMediaSize(PrintAttributes.MediaSize.NA_LETTER).
setResolution(new PrintAttributes.Resolution("zooey", PRINT_SERVICE, 300, 300)).
setMinMargins(PrintAttributes.Margins.NO_MARGINS).
build();
PdfDocument document = new PrintedPdfDocument(DynamicPDFHelloWorld.this, printAttrs);
// crate a page description
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(300, 300, 1).create();
// create a new page from the PageInfo
PdfDocument.Page page = document.startPage(pageInfo);
// repaint the user's text into the page
View content = findViewById(R.id.textarea);
content.draw(page.getCanvas());
content.draw(edt.getText().toString().);
// do final processing of the page
document.finishPage(page);
// Here you could add more pages in a longer doc app, but you'd have
// to handle page-breaking yourself in e.g., write your own word processor...
// Now write the PDF document to a file; it actually needs to be a file
// since the Share mechanism can't accept a byte[]. though it can
// accept a String/CharSequence. Meh.
try {
File f = new File(Environment.getExternalStorageDirectory().getPath() + "/pruebaAppModerator.pdf");
FileOutputStream fos = new FileOutputStream(f);
document.writeTo(fos);
document.close();
fos.close();
} catch (IOException e) {
throw new RuntimeException("Error generating file", e);
}
}
});

File download returns corrupted file (I think) in Play framework 2.2.2

I'm struggling with getting file upload/download to work properly in Play framework 2.2.2. I have a Student class with a field called "cv". It's annotated with #Lob, like this:
#Lob
public byte[] cv;
Here are the upload and download methods:
public static Result upload() {
MultipartFormData body = request().body().asMultipartFormData();
FilePart cv = body.getFile("cv");
if (cv != null) {
filenameCV = cv.getFilename();
String contentType = cv.getContentType();
File file = cv.getFile();
Http.Session session = Http.Context.current().session();
String studentNr = session.get("user");
Student student = Student.find.where().eq("studentNumber", studentNr).findUnique();
InputStream is;
try {
is = new FileInputStream(file);
student.cv = IOUtils.toByteArray(is);
} catch (IOException e) {
Logger.debug("Error converting file");
}
student.save();
flash("ok", "Vellykket! Filen " + filenameCV + " ble lastet opp til din profil");
return redirect(routes.Profile.profile());
} else {
flash("error", "Mangler fil");
return redirect(routes.Profile.profile());
}
}
public static Result download() {
Http.Session session = Http.Context.current().session();
Student student = Student.find.where().eq("studentNumber", session.get("user")).findUnique();
File f = new File("/tmp/" +filenameCV);
FileOutputStream fos;
try {
fos = new FileOutputStream(f);
fos.write(student.cv);
fos.flush();
fos.close();
} catch(IOException e) {
}
return ok(f);
}
The file seems to be correctly saved to the database (the cv field is populated with data, but it's obviously cryptic to me so I don't know for sure that the content is what it's supposed to be)
When I go to my website and click the "Download CV" link (which runs the download action), the file gets downloaded but can't be opened - saying the PDF viewer can't recognize the file etc. (Files uploaded have to be PDF)
Any ideas on what might be wrong?
Don't keep your files in DB, filesystem is much better for that! Save uploaded file on the disk with some unique name, then in your database keep only path to the file as a String!
It's cheaper in longer run (as said many times)
It's easier to handle downloads, i.e. in Play all you need to serve PDF is:
public static Result download() {
File file = new File("/full/path/to/your.pdf");
return ok(file);
}
it will set proper headers, like Content-Disposition, Content-Length and Content-Type not only for PDFs

file upload with spring MVC

I am uploading file using spring MVC and jquery. Inside my class method I have written
#RequestMapping(value="attachFile", method=RequestMethod.POST)
public #ResponseBody List<FileAttachment> upload(
#RequestParam("file") MultipartFile file,
HttpServletRequest request,
HttpSession session) {
String fileName = null;
InputStream inputStream = null;
OutputStream outputStream = null;
//Save the file to a temporary location
ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath("/");
fileName = realContextPath +"/images/"+file.getOriginalFilename();
//File dest = new File(fileName);
try {
//file.transferTo(dest);
inputStream = file.getInputStream();
outputStream = new FileOutputStream(fileName);
inputStream.close();
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Its uploading the file correctly I am using
ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath("/");
to get the path. My first question is , Is this the correct way to get the path and it stores the file somewhere at
workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/images
and when I am trying to display this image on my jsp page using the following code
<img src="<%=request.getRealPath("/") + "images/images.jpg" %>" alt="Upload Image" />
It does not display the image, Its generating the following html
<img src="/home/name/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/myproject/images/images.jpg" alt="Upload Image">
Am I doing the things right? In my project I have to upload large number of files everyday.
Please let me know if you need anything else to understand my question
It will be better if you upload your files in some directory by absolute path(e.g. C:\images\) instead of relative (your approach). Usually, web apps runs on linux mathines on production and it is good practice to make save path configurable.
Create some application property which will holds save path for files(in xml or property file).

Categories