I'm trying to use a p:graphicImage with an SVG in a streamed content.
Right now I'm stuck 'cause if I set the entire path of the file, I'm able to see the image.
If I use the StreamedContent (org.primefaces.model.StreamedContent) and I'll watch inside the Console source, I'm not able to see anything.
<p:graphicImage id="imgExpo_#{idPrefix}" value="#{bck.streamedImage}" cache="false" stream="true" >
public StreamedContent getStreamedImage() {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return defaultEmpty;
}
else {
image = new DefaultStreamedContent(BckUtils.getImageManager.getImageStream(context.getExternalContext().getRequestParameterMap() , user));
return image;
}
}
Anyone with some suggestions?
Thanks, Riccardo.
Primefaces 7.0
Related
public StreamedContent getVideoFile() {
HttpSessionUtil<byte[]> sessionUtil = new HttpSessionUtil<byte[]>();
byte[] videoFile = sessionUtil.getFromSessionMap("video");
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
videoFile = convertDefaultVideoToBytes(videoFile);
return new DefaultStreamedContent(new
ByteArrayInputStream(videoFile), "video/mp4");
}
if(videoFile != null && videoFile.length > 0){
videoFile = new DefaultStreamedContent(new
ByteArrayInputStream(videoFile), "video/mp4");
}else{
videoFile = convertDefaultVideoToBytes(videoFile);
videoFile = new DefaultStreamedContent(new
ByteArrayInputStream(videoFile), "video/mp4");
}
return videoFile;
}
xhtml code:
<p:media value="#{vesumeBean.videoFile}" width="100%" height="400"
player="quicktime">
<f:param name="autoPlay" value="true" />
</p:media>
The ManagedBean is javax.faces.bean.SessionScoped
The final byte[] length of video comes around 480835
The objective is the video should start playing after the screen is loaded.
Not able to play video using p:media.
Tech stack used : JSF/Primefaces 6.0/Wildfly10.1.0 Final. Problem:
p:media doesnot load/play the video file
Error:[org.primefaces.application.resource.StreamedContentHandler] :
Error in streaming dynamic resource. null
The video should get loaded from the specified path and start playing.
FacesContext.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE this block is executed twice and third time it comes to the else part
It works in Firefox perfectly. Any help related to this is highly appreciated.
I am using PrimeFaces 5.3 <p:fileUpload> to upload a PNG image and I would like to show a preview of it in <p:graphicImage> before saving in database.
Here's a MCVE:
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{bean.uploadedFile}" mode="simple" />
<p:graphicImage value="#{bean.image}" />
<p:commandButton action="#{bean.preview}" ajax="false" value="Preview" />
</h:form>
private UploadedFile uploadedFile;
public UploadedFile getUploadedFile() {
return uploadedFile;
}
public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}
public void preview() {
// NOOP for now.
}
public StreamedContent getImage() {
if (uploadedFile == null) {
return new DefaultStreamedContent();
} else {
return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents()), "image/png");
}
}
No error occurring on the backing bean, and the image won't be load and display at front-end. The client mentions that the image returned a 404 not found error.
Your problem is two-fold. It failed because the uploaded file contents is request scoped and because the image is requested in a different HTTP request. To better understand the inner working, carefully read the answers on following closely related Q&A:
Display dynamic image from database with p:graphicImage and StreamedContent
How to choose the right bean scope?
To solve the first problem, you need to read the uploaded file contents immediately in the action method associated with the form submit. In your specific case, that would look like:
private UploadedFile uploadedFile;
private byte[] fileContents;
public void preview() {
fileContents = uploadedFile.getContents();
}
// ...
To solve the second problem, your best bet is to use the data URI scheme. This makes it possible to render the image directly in the very same response and therefore you can safely use a #ViewScoped bean without facing "context not active" issues or saving the byte[] in session or disk in order to enable serving the image in a different request. Browser support on data URI scheme is currently pretty good. Replace the entire <p:graphicImage> with below:
<ui:fragment rendered="#{not empty bean.uploadedFile}">
<img src="data:image/png;base64,#{bean.imageContentsAsBase64}" />
</ui:fragment>
public String getImageContentsAsBase64() {
return Base64.getEncoder().encodeToString(imageContents);
}
Note: I assume that Java 8 is available to you as java.util.Base64 was only introduced in that version. In case you're using an older Java version, use DatatypeConverter.printBase64Binary(imageContents) instead.
In case you happen to use JSF utility library OmniFaces, you can also just use its <o:graphicImage> component instead which is on contrary to <p:graphicImage> capable of directly referencing a byte[] and InputStream bean property and rendering a data URI.
<o:graphicImage value="#{bean.imageContents}" dataURI="true" rendered="#{not empty bean.imageContents}">
When I generate barcode dynamically, it always prints the previous input, not the latest code. When I refresh the page with refresh button on the browser, the correct barcode is displayed. But If I refresh the page with a JSF commandbutton, still the previous result. Where have I gone wrong ?
JSF 2.1
Primefaces 4.0
Barbecue 1.5 beta
Chrome/Firefox Latest Updates
<p:graphicImage value="#{barcodeController.createBarcodeByCode(patientController.current.code)}"
style="max-width: 7.5cm; padding: 10px; margin: 10px;" >
</p:graphicImage>
This is from the JSF controller with request scope.
public StreamedContent createBarcodeByCode(String code) {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
} else {
barcode = null;
System.out.println("code = " + code);
if (code == null || code.trim().equals("")) {
return null;
}
File barcodeFile = new File(code);
try {
BarcodeImageHandler.saveJPEG(BarcodeFactory.createCode128C(code), barcodeFile);
barcode = new DefaultStreamedContent(new FileInputStream(barcodeFile), "image/jpeg");
} catch (Exception ex) {
System.out.println("ex = " + ex.getMessage());
}
return barcode;
}
}
References:
1. Dynamic StreamContent Answer by BalusC
2. Dynamic Barcode with Primefaces
Set cache="false" on the p:graphicImage.
I use the <p:media> to display static PDF content.
<p:media value="/resource/test.pdf"
width="100%" height="300px" player="pdf">
</p:media>
How can I change it to display dynamic content?
Like as in <p:graphicImage>, the value attribute can point to a bean property returning StreamedContent. This only requires a special getter method for the reasons which is explained in detail in the following answer on using <p:graphicImage> with a dynamic resource from a database: Display dynamic image from database with p:graphicImage and StreamedContent.
In your particular example, it would look like this:
<p:media value="#{mediaManager.stream}" width="100%" height="300px" player="pdf">
<f:param name="id" value="#{bean.mediaId}" />
</p:media>
With
#ManagedBean
#ApplicationScoped
public class MediaManager {
#EJB
private MediaService service;
public StreamedContent getStream() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
} else {
// So, browser is requesting the media. Return a real StreamedContent with the media bytes.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Media media = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(media.getBytes()));
}
}
}
I'm trying to dynamically display an image in primefaces using the p:graphicImage tag as follows:
<p:graphicImage value="#{submissionBean.contestImage}">
<f:param name="imageName"
value="#{contestBean.createContest.submissions[0].fileName}" />
</p:graphicImage>`
The managed bean is as follows:
#ManagedProperty("#{param.imageName}")
private String imageName;
public String getImageName()
{
return imageName;
}
public void setImageName(String imageName)
{
this.imageName = imageName;
}
private StreamedContent contestImage;
public StreamedContent getContestImage()
{
FacesContext context = FacesContext.getCurrentInstance();
if (imageName == null)
imageName = Constants.SUBMISSION_FILE_DIR + "/" + "sacxzx_asdsdaas_icon.png";
if (context.getRenderResponse())
{
// So, we're rendering the view. Return a stub StreamedContent so
// that it will generate right URL.
return new DefaultStreamedContent();
}
else
{
return new DefaultStreamedContent(this.getClass().getResourceAsStream(Constants.SUBMISSION_FILE_DIR + "/" + imageName));
}
}
I'm always getting the error of "SEVERE: Error in streaming dynamic resource."
Checking the URL for the image seems just fine:
http://localhost:8080/mashup/javax.faces.resource/dynamiccontent.xhtml?ln=primefaces&pfdrid=pfdrid_4290aa0c-8eef-45ea-a281-638e460e33bf&imageName=sacxzx_asdsdaas_icon.png
Any idea why this is?
Thanks!
Should be SessionScoped. As method getContestImage() is called multiple times during page processing, it is better to create the stream only once.