Display uploaded image in JSF

前端 未结 3 816
半阙折子戏
半阙折子戏 2020-12-30 10:13

I have a view scoped bean where I create a person. A person can have a picture. This picture is uploaded the same page the person is created. The picture is not stored in a

相关标签:
3条回答
  • 2020-12-30 10:56

    I managed to do that by simply encoding uploaded image to base64 and then showing it normally via html <img> tag.

    Here's my managed bean:

    @ManagedBean
    @ViewScoped
    public class ImageMB {
    
    private String base64Image;
    
    public void onUploadImage(FileUploadEvent event) {
        String fileName = event.getFile().getFileName();
        //Get file extension.
        String extension = "png";
        int i = fileName.lastIndexOf('.');
        if (i > 0) {
            extension = fileName.substring(i + 1).toLowerCase();
        }
    
        String encodedImage = java.util.Base64.getEncoder().encodeToString(event.getFile().getContents());
        this.base64Image = String.format("data:image/%s;base64, %s", 
             extension, encodedImage));
    }
    

    And here's JSF part:

    <p:fileUpload id="imageFileUploader"
                  fileUploadListener="#{imageMB.onUploadImage}"
                  mode="advanced"    
                  multiple="false"
                  fileLimit="1"
                  allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
                  update="@form"/>
    
    <div>
        <img src="#{toolAddEditMB.base64Image}" 
             style="#{toolAddEditMB.base64Image eq null ? 'display: none' : ''}"/>
    </div>
    
    0 讨论(0)
  • 2020-12-30 11:00

    I've gone for a different approach. I initially went for displaying an uploaded image, however if the Person isn't created yet it seemed like a better idea to keep it all client side. I found this question and created the following based on the chosen answer:

    In the head I include html5shiv if the browser is IE and the version is less than 9 for compatibility:

    <h:outputText value="&lt;!--[if lt IE 9]&gt;" escape="false" />
    <h:outputScript library="js" name="html5shiv.js" />
    <h:outputText value="&lt;![endif]--&gt;" escape="false" />
    

    To display/upload the image I have these elements:

    <p:fileUpload binding="#{upload}" mode="simple"
        allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
        value="#{personBean.uploadedPicture}"/>
    <p:graphicImage value="#" height="150" binding="#{image}" />
    

    And some JavaScript/jQuery magic:

    function readPicture(input, output)
    {
        if (input.files && input.files[0])
        {
            var reader = new FileReader();
            reader.onload = function(e)
            {
                output.attr('src', e.target.result);
            };
            reader.readAsDataURL(input.files[0]);
        }
    }
    
    $("[id='#{upload.clientId}']").change(
        function()
        {
            readPicture(this, $("[id='#{image.clientId}']"));
        });
    

    The uploadedPicture property is now a simple property:

    @ManagedBean(name = "personBean")
    @ViewScoped
    public class PersonBean
    {
        private UploadedFile uploadedPicture;
    
        public UploadedFile getUploadedPicture()
        {
            return uploadedPicture;
        }
    
        public void setUploadedPicture(UploadedFile uploadedPicture)
        {
            this.uploadedPicture = uploadedPicture;
        }
    }
    
    0 讨论(0)
  • 2020-12-30 11:02

    Add.xhtml

    <h:form id="add-form" enctype="multipart/form-data">
             <p:growl id="messages" showDetail="true"/>
             <h:panelGrid columns="2">
                  <p:outputLabel for="choose" value="Choose Image :" />
                  <p:fileUpload id="choose" validator="#{productController.validateFile}" multiple="false" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"  value="#{productController.file}" required="true" mode="simple"/>
                <p:commandButton value="Submit" ajax="false" update="messages" id="save-btn" actionListener="#{productController.saveProduct}"/>
             </h:panelGrid>
    </h:form>
    

    Here is Managed Bean Code:

    @ManagedBean
    @RequestScoped
    public class ProductController implements Serializable{
        private ProductBean bean;
        @ManagedProperty(value = "#{ProductService}")
        private ProductService productService;
        private StreamedContent content;
        private UploadedFile file;
        public StreamedContent getContent() {
            FacesContext context = FacesContext.getCurrentInstance();
    
             if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
                    return new DefaultStreamedContent();
                }
             else{
                 String imageId = context.getExternalContext().getRequestParameterMap().get("id");
                Product product = getProductService().getProductById(Integer.parseInt(imageId));
                return new DefaultStreamedContent(new ByteArrayInputStream(product.getProductImage()));
             }
        }
        public ProductController() {
            bean = new ProductBean();
        }
    
        public void setContent(StreamedContent content) {
            this.content = content;
        }
        public UploadedFile getFile() {
            return file;
        }
    
        public void setFile(UploadedFile file) {
            this.file = file;
        }
        public void saveProduct(){
            try{
                Product product = new Product();
                product.setProductImage(getFile().getContents());
    
                getProductService().saveProduct(product);
                file = null;
    
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
        public void validateFile(FacesContext ctx,
                UIComponent comp,
                Object value) {
            List<FacesMessage> msgs = new ArrayList<FacesMessage>();
            UploadedFile file = (UploadedFile)value;
            int fileByte = file.getContents().length;
            if(fileByte > 15360){
                msgs.add(new FacesMessage("Too big must be at most 15KB"));
            }
            if (!(file.getContentType().startsWith("image"))) {
                msgs.add(new FacesMessage("not an Image file"));
            }
            if (!msgs.isEmpty()) {
                throw new ValidatorException(msgs);
            }
        }
    }
    

    Add these lines of code in web.xml

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    

    And following jar files in WEBINF/lib folder.

    commons-io-X.X  and commons-fileupload-X.X, recommended most recent version.
    

    commons-io-2.4,commons-io-2.4-javadoc,commons-io-2.4-sources,commons-io-2.4-tests,commons-io-2.4-test-sources,commons-fileupload-1.3,commons-fileupload-1.3-javadoc,commons-fileupload-1.3-sources,commons-fileupload-1.3-tests,commons-fileupload-1.3-test-sources

    View.xhtml

    <h:form id="ShowProducts">
        <p:dataTable rowsPerPageTemplate="3,6,9" var="products" paginator="true" rows="3" emptyMessage="Catalog is empty" value="#{productController.bean.products}">
            <p:column headerText="Product Name">
                <p:graphicImage width="80" height="80" value="#{productController.content}">
                    <f:param name="id" value="#{products.productId}" />
                </p:graphicImage>
                #{products.productName}
            </p:column>
        </p:dataTable>
    </h:form>
    
    0 讨论(0)
提交回复
热议问题