4

我在 Primefaces 组件图形图像中显示图像时遇到问题。

当我的 MB 是 SessionScoped 时,一切正常。但是当它是 ViewScoped 时,图像不会显示。

我可以保留 SessionScoped,但我的页面确实在图像中上传/删除,并且这些图像存储在 PostgreSQL 中(请,我的软件架构迫使我这样做)。问题是当我插入新图像或删除图像时,页面仍然显示最后的值(未刷新的值),直到我关闭浏览器并再次打开。我希望使用 ViewScoped 可以重新加载页面并解决我的问题。

这是页面的快照:

                    <p:panel id="panelListFotoProduto" header="Fotos do Produto" toggleable="true" collapsed="false" closable="false"
                             toggleSpeed="500" widgetVar="panelListFotoProduto" visible="true" >
                        <p:dataTable id="listFotoProduto" paginatorPosition="bottom" value="#{produtoMB.listProdutoFoto}" 
                                     lazy="true" var="pf" selectionMode="single" paginator="true" rows="1"
                                     rowKey="#{pf.id}">
                            <p:column style="width: 100%" >
                                <h:panelGrid columns="1" cellpadding="4"> 
                                    <p:graphicImage id="imageProduto" value="#{produtoMB.getFoto(pf)}" onclick="dialogFotoProduto.show()"/>
                                    <p:commandButton value="Excluir" style="width: 100%;" update=":growl :formProduto:panelListFotoProduto" actionListener="#{produtoMB.removeFoto(pf)}"/>
                                </h:panelGrid>     
                            </p:column>
                            <f:facet name="footer">
                                <h:panelGrid columns="1" cellpadding="4"> 
                                    <p:commandButton value="Adicionar" style="width: 100%;" update=":growl :formProduto:panelListFotoProduto" actionListener="#{produtoMB.adicionarFoto()}"/>
                                    <h:outputText id="totalProdutos" style="font-weight:bold" value="Total de Fotos Cadastrados: #{produtoMB.listProdutoFoto.size() }"/>
                                </h:panelGrid>                                      
                            </f:facet>
                        </p:dataTable>
                    </p:panel>

这是我的MB:

@ManagedBean
@SessionScoped
public class ProdutoMB {

    private Produto       produto_atual      = new Produto();
    private Produto_Foto  produto_foto_atual = new Produto_Foto();

    private List<Produto>      listProduto         = null;    
    private List<Produto_Foto> listProdutoFoto     = null;
    private List<Produto_Foto> listProdutoFoto_all = null;

    private boolean adicionarFoto = false;
    private StreamedContent last;

    public Produto getProduto_atual(){
        return produto_atual;
    }    

    public void setProduto_atual(Produto produto) throws SQLException, IOException{        
        if(produto != null && produto_atual != null 
        && produto.getCd_produto().equals(produto_atual.getCd_produto())){
            return ;
        }
        produto_atual = produto;
        produto_foto_atual = null;        
        listProdutoFoto    = new ArrayList<>();

        int index = 0;
        System.out.println("List >> " + getListProdutoFoto_all());
        for(Produto_Foto p_f : getListProdutoFoto_all()){
            if(produto_atual.getCd_produto().equals(p_f.getCd_produto())){
                p_f.setId(index++);
                p_f.setContent(getFoto_b(produto_atual.getCd_empresa(), p_f.getCd_imagem()));
                listProdutoFoto.add(p_f);
            } 
        }

        if(listProdutoFoto.isEmpty()){
            Produto_Foto p_f = new Produto_Foto();
            p_f.setId(-1);
            p_f.setCd_produto(produto_atual.getCd_produto());
            p_f.setCd_empresa(produto_atual.getCd_empresa());
            p_f.setCd_imagem(-1);
            p_f.setContent(getFoto_b(produto_atual.getCd_empresa(), p_f.getCd_imagem()));
            listProdutoFoto.add(p_f);
        }       
    }

    public void setProduto_foto_atual(Produto_Foto produto_foto) {
        if(produto_foto != null && produto_foto_atual != null 
        && produto_foto.getCd_produto().equals(produto_foto_atual.getCd_produto())){
            return ;
        }
        produto_foto_atual = produto_foto;
    }

    public ProdutoMB(){
    }

    public void handleFileUpload(FileUploadEvent event) throws SQLException, IOException{
        if(event != null){            
            UploadedFile imagem_upload = event.getFile();

            byte[] buf = imagem_upload.getContents();
            BufferedImage image = ImageIO.read(ImageIO.createImageInputStream(new ByteArrayInputStream(buf)));            

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write( image, "jpg", baos );
            baos.flush();
            buf = baos.toByteArray();
            baos.close();            

            BufferedImage scaledImage = Scalr.resize(image, 250);

            if(scaledImage != null){
                baos = new ByteArrayOutputStream();
                ImageIO.write( scaledImage, "jpg", baos );
                baos.flush();
                byte[] imageInByte = baos.toByteArray();
                baos.close();

                buf = imageInByte;
            }

            if(adicionarFoto){
                adicionarFoto = false;

                Produto_Foto p_f = new Produto_Foto();
                p_f.setId(listProdutoFoto.size());
                p_f.setCd_produto(produto_atual.getCd_produto());
                p_f.setCd_empresa(produto_atual.getCd_empresa());
                p_f.setCd_imagem(-1);
                p_f.setContent(buf);

                if(listProdutoFoto.size() == 1){
                    Produto_Foto p_f_aux = listProdutoFoto.get(0);
                    if(p_f_aux.getId() == -1){
                        p_f.setId(0);
                        listProdutoFoto.set(0, p_f);
                    } else {
                        listProdutoFoto.add(p_f);
                    }
                } else {
                    listProdutoFoto.add(p_f);
                }
                return;
            }

            if(produto_foto_atual != null){
                int index = produto_foto_atual.getId();
                if(index >= 0){
                    produto_foto_atual.setContent(buf);
                    listProdutoFoto.set(index, produto_foto_atual);
                } else if(index == -1){
                    produto_foto_atual.setContent(buf);
                    produto_foto_atual.setId(++index);
                    listProdutoFoto.set(index, produto_foto_atual);
                }
            }
        } 
    }

    public void adicionarFoto(){
        adicionarFoto = true;
        RequestContext.getCurrentInstance().execute("dialogFotoProduto.show()");
    }

    public void removeFoto(Produto_Foto produto_foto) throws SQLException, IOException{
        if(produto_foto == null){
            return ;
        }
        int index = produto_foto.getId();
        if(index >= 0){
            listProdutoFoto.remove(index);

            for(int i = 0; i < listProdutoFoto.size(); i++){
                Produto_Foto p_f = listProdutoFoto.get(i);
                if(p_f.getId() > index){
                    p_f.setId(p_f.getId() - 1);
                }
            }
        }
        if(listProdutoFoto.isEmpty()){
            Produto_Foto p_f = new Produto_Foto();
            p_f.setId(-1);
            p_f.setCd_produto(produto_atual.getCd_produto());
            p_f.setCd_empresa(produto_atual.getCd_empresa());
            p_f.setCd_imagem(-1);
            p_f.setContent(getFoto_b(produto_atual.getCd_empresa(), p_f.getCd_imagem()));
            listProdutoFoto.add(p_f);
        }    
    }

    public void removeFotoAtual(){
        if(produto_foto_atual == null){
            return ;
        }
        int index = produto_foto_atual.getId();
        if(index >= 0){
            listProdutoFoto.remove(index);

            for(int i = 0; i < listProdutoFoto.size(); i++){
                Produto_Foto p_f = listProdutoFoto.get(i);
                if(p_f.getId() > index){
                    p_f.setId(p_f.getId() + 1);
                }
            }
        }
    }

    public void removeFotoBanco(Produto_Foto pf_aux) throws SQLException{
        if(produto_atual == null){
            return ;
        }

        if(pf_aux == null){
            return ;
        }

        Integer cd_empresa = produto_atual.getCd_empresa();

        if(cd_empresa == null){
            return ;
        }

        Connection conn = null;
        Connection conn_p = null;
        PreparedStatement ps = null;
        ResultSet rs         = null;
        try {
            conn   = conectorImagemPostgreSQL.getConnection(); 
            conn_p = conectorPostgreSQL.getConnection();
            conn.setAutoCommit(false);

            ps = conn_p.prepareStatement(" DELETE FROM produto_foto WHERE cd_empresa = ? AND cd_produto = ? AND nm_foto = ? AND cd_imagem = ?;");                        
            ps.setInt(1, cd_empresa);
            ps.setString(2, produto_atual.getCd_produto());
            ps.setString(3, pf_aux.getNm_foto());
            ps.setInt(4, pf_aux.getCd_imagem());
            ps.executeUpdate();
            ps.close();
        } catch(Exception e){
            e.printStackTrace();
        } finally{
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
            conn.commit();
        }
    }

    public void salvaFotoBanco() throws SQLException{
        if(produto_atual == null){
            return ;
        }

        if(listProdutoFoto == null || listProdutoFoto.isEmpty()){
            return ;
        }

        Integer cd_empresa = produto_atual.getCd_empresa();

        if(cd_empresa == null){
            return ;
        }

        Connection conn = null;
        Connection conn_p = null;
        PreparedStatement ps = null;
        ResultSet rs         = null;

        conn   = conectorImagemPostgreSQL.getConnection(); 
        conn_p = conectorPostgreSQL.getConnection();  

        ps = conn_p.prepareStatement(" DELETE FROM produto_foto WHERE cd_empresa = ? AND cd_produto = ?;");

        ps.setInt(1, cd_empresa);
        ps.setString(2, produto_atual.getCd_produto());
        ps.executeUpdate();
        ps.close();

        conn_p.commit();

        for(Produto_Foto p_f : listProdutoFoto){                       
            try {
                conn.setAutoCommit(false);
                if(p_f.getId() >= 0 && p_f.getCd_imagem() < 0){

                    ps = conn.prepareStatement("SELECT f_sequencial('IMAGEMLO', ?) as cd_imagem");
                    ps.setInt(1, cd_empresa);
                    rs = ps.executeQuery();
                    if (rs != null) {
                        while(rs.next()) {
                            p_f.setCd_empresa(produto_atual.getCd_empresa());
                            p_f.setCd_produto(produto_atual.getCd_produto());
                            p_f.setCd_imagem(rs.getInt(1));
                        }
                    }
                    byte[] b = p_f.getContentBytes();

                    BufferedImage image = ImageIO.read(ImageIO.createImageInputStream(new ByteArrayInputStream(b)));            

                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ImageIO.write( image, "jpg", baos );
                    baos.flush();
                    b = baos.toByteArray();
                    baos.close();            

                    BufferedImage scaledImage = Scalr.resize(image, 250);

                    if(scaledImage != null){
                        baos = new ByteArrayOutputStream();
                        ImageIO.write( scaledImage, "jpg", baos );
                        baos.flush();
                        byte[] imageInByte = baos.toByteArray();
                        baos.close();

                        b = imageInByte;
                    }
                    LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();
                    int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
                    LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
                    obj.write(b);
                    obj.close();
                    ps = conn.prepareStatement(" INSERT INTO imagemlo(cd_empresa, cd_imagem, ds_imagem, by_imagem) "
                                                        + "VALUES (?, ?, ?, ?);");

                    String file_name = p_f.getCd_empresa() + "_" + 
                                p_f.getCd_produto() + "_" + 
                                p_f.getCd_imagem() + ".jpg";

                    ps.setInt(1, cd_empresa);
                    ps.setInt(2, p_f.getCd_imagem());
                    ps.setString(3, file_name);
                    ps.setLong(4, oid);
                    ps.executeUpdate();
                    ps.close();
                }
                ps = conn_p.prepareStatement(" INSERT INTO produto_foto(cd_empresa, cd_produto, nm_foto, cd_imagem) "
                                                    + "VALUES (?, ?, ?, ?);");

                String file_name = p_f.getCd_empresa() + "_" + 
                                p_f.getCd_produto() + "_" + 
                                p_f.getCd_imagem() + ".jpg";

                ps.setInt(1, cd_empresa);
                ps.setString(2, produto_atual.getCd_produto());
                ps.setString(3, file_name);
                ps.setInt(4, p_f.getCd_imagem());
                ps.executeUpdate();
                ps.close();
            } catch(Exception e){
                e.printStackTrace();
            } finally{
                if (rs != null) {
                    rs.close();
                }
                if (ps != null) {
                    ps.close();
                }
                conn.commit();
            }
        }
        FacesMessage msg = new FacesMessage("Alterações salvas com sucesso.", "");  
        FacesContext.getCurrentInstance().addMessage(null, msg); 
    }

    public void editaFoto(Produto_Foto produto_foto){
        if(produto_foto != null){
            produto_foto_atual = produto_foto;
        }
    }

    public StreamedContent getFotoAtual() throws SQLException, IOException{
        if(produto_foto_atual != null){
            int index = produto_foto_atual.getId();
            if(index >= 0){
                last = listProdutoFoto.get(index).getContent();
            }
        }
        return last;
    }

    public StreamedContent getFoto(Produto_Foto produto_foto) throws SQLException, IOException{
        if(produto_foto != null){
            produto_foto_atual = produto_foto;

            int index = produto_foto.getId();
            if(index >= 0){
                last = listProdutoFoto.get(index).getContent();
            }

            if(index == -1){
                last = listProdutoFoto.get(0).getContent();
            }
        }

        if(last == null){
            last = (new DefaultStreamedContent(new ByteArrayInputStream(getFoto_b(produto_atual.getCd_empresa(), -1)), "image/jpeg", "img_padrao"));
        }
        return last;
    }

    public StreamedContent getFoto(Integer cd_empresa, Integer cd_imagem) throws SQLException, IOException{
        Usuario u = (Usuario)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("LoggedUser");

        if(u == null){
            System.out.println("Usuário é nulo");
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));
            return (new DefaultStreamedContent(fis, "image/jpeg", "img_padrao"));
        }

        if(produto_atual == null){
            System.out.println("Produto Atual é nulo");
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));
            return (new DefaultStreamedContent(fis, "image/jpeg", "img_padrao"));
        }

        if(cd_empresa == null){
            System.out.println("cd_empresa é nulo");
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));
            return (new DefaultStreamedContent(fis, "image/jpeg", "img_padrao"));
        }

        if(cd_imagem == null || cd_imagem < 0){
            System.out.println("cd_imagem é nulo ou menor que zero");
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));
            return (new DefaultStreamedContent(fis, "image/jpeg", "img_padrao"));
        }

        Connection        conn = null;
        PreparedStatement   ps = null;
        ResultSet           rs = null;

        try {        
            conn = conectorImagemPostgreSQL.getConnection();  
            conn.setAutoCommit(false);
            LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();

            ps = conn.prepareStatement("SELECT ds_imagem, by_imagem FROM imagemlo WHERE cd_empresa = ? AND cd_imagem = ?");
            ps.setInt(1, cd_empresa);
            ps.setInt(2, cd_imagem);

            rs = ps.executeQuery();
            if (rs != null) {
                while(rs.next()) {

                    String ds_imagem = rs.getString("ds_imagem");   
                    int oid = rs.getInt("by_imagem");

                    LargeObject obj = lobj.open(oid, LargeObjectManager.READ);

                    //read the data
                    byte buf[] = new byte[obj.size()];
                    obj.read(buf, 0, obj.size());
                    obj.close();

                    BufferedImage image = ImageIO.read(ImageIO.createImageInputStream(new ByteArrayInputStream(buf)));            

                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ImageIO.write( image, "jpg", baos );
                    baos.flush();
                    buf = baos.toByteArray();
                    baos.close();            

                    BufferedImage scaledImage = Scalr.resize(image, 250);

                    if(scaledImage != null){
                        baos = new ByteArrayOutputStream();
                        ImageIO.write( scaledImage, "jpg", baos );
                        baos.flush();
                        byte[] imageInByte = baos.toByteArray();
                        baos.close();

                        buf = imageInByte;
                    }
                    return (new DefaultStreamedContent(new ByteArrayInputStream(buf), "image/jpeg", ds_imagem));
                }
            }
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));

            return (new DefaultStreamedContent(fis, "image/jpeg", "img_padrao"));
        } finally{
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
            conn.commit();
        }
    }    

    public byte[] getFoto_b(Integer cd_empresa, Integer cd_imagem) throws SQLException, IOException{
        Usuario u = (Usuario)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("LoggedUser");

        if(u == null){
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));

            ByteArrayOutputStream out = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024]; 
            while (fis.read(buffer) != -1) out.write(buffer); 

            return out.toByteArray();
        }

        if(produto_atual == null){
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));

            ByteArrayOutputStream out = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            while (fis.read(buffer) != -1) out.write(buffer); 

            return out.toByteArray();
        }

        if(cd_empresa == null){
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));

            ByteArrayOutputStream out = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024]; 
            while (fis.read(buffer) != -1) out.write(buffer); 

            return out.toByteArray();
        }

        if(cd_imagem == null || cd_imagem < 0){
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));

            ByteArrayOutputStream out = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024]; 
            while (fis.read(buffer) != -1) out.write(buffer); 

            return out.toByteArray();
        }

        Connection        conn = null;
        PreparedStatement   ps = null;
        ResultSet           rs = null;

        try {        
            conn = conectorImagemPostgreSQL.getConnection();  
            conn.setAutoCommit(false);
            LargeObjectManager lobj = ((org.postgresql.PGConnection)conn).getLargeObjectAPI();

            ps = conn.prepareStatement("SELECT ds_imagem, by_imagem FROM imagemlo WHERE cd_empresa = ? AND cd_imagem = ?");
            ps.setInt(1, cd_empresa);
            ps.setInt(2, cd_imagem);

            rs = ps.executeQuery();
            if (rs != null) {
                while(rs.next()) {

                    String ds_imagem = rs.getString("ds_imagem");   
                    int oid = rs.getInt("by_imagem");

                    LargeObject obj = lobj.open(oid, LargeObjectManager.READ);

                    //read the data
                    byte buf[] = new byte[obj.size()];
                    obj.read(buf, 0, obj.size());
                    obj.close();
                    BufferedImage image = ImageIO.read(ImageIO.createImageInputStream(new ByteArrayInputStream(buf)));            

                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    ImageIO.write( image, "jpg", baos );
                    baos.flush();
                    buf = baos.toByteArray();
                    baos.close();            

                    BufferedImage scaledImage = Scalr.resize(image, 250);

                    if(scaledImage != null){
                        baos = new ByteArrayOutputStream();
                        ImageIO.write( scaledImage, "jpg", baos );
                        baos.flush();
                        byte[] imageInByte = baos.toByteArray();
                        baos.close();

                        buf = imageInByte;
                    }
                    return buf;
                }
            }
            FileInputStream fis = new FileInputStream(FacesContext.getCurrentInstance().getExternalContext().getRealPath("image_not_found.png"));

            ByteArrayOutputStream out = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024]; 
            while (fis.read(buffer) != -1) out.write(buffer); 

            return out.toByteArray();
        } finally{
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
            conn.commit();
        }
    }    

    public void save() throws SQLException{
        salvaFotoBanco();
    }

    public List<Produto> getListProduto() {

        Usuario u = (Usuario)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("LoggedUser");

        if(u == null){
            return null;
        }        

        Integer cd_empresa = u.getCd_empresa();

        if(cd_empresa == null){
            return null;
        }

        if(listProduto == null){
            listProduto = getProduto(cd_empresa);
        }

        return listProduto;
    }

    public List<Produto_Foto> getListProdutoFoto_all() {
        if(listProdutoFoto_all == null){
            listProdutoFoto_all = getProduto_Foto(produto_atual.getCd_empresa());
        }
        return listProdutoFoto_all;
    }

    /**
     * Methods to get/set data in the DB...
     */
}

如果我可以使用 SessionScoped 重新加载内容,那就更好了。

谢谢您的帮助。

我正在使用 JBOSS 7,Primefaces 3.4.2

[]s 威廉·伯坦

4

2 回答 2

17

了解<p:graphicImage>with 的StreamedContent工作原理很重要。每个图像的遗嘱背后的属性<p:graphicImage value>基本上在两个完全独立的 HTTP 请求中进行查询。

第一个 HTTP 请求(执行所有 JSF 工作并因此负责生成包括<img>标签在内的一堆 HTML 代码的请求)基本上会查询属性以确定它返回的图像类型(例如 aString或 a StreamedContent),以便可以内联/自动生成正确的 URL。请注意,如果StreamedContent图像的内容未被读取。HTML 图像并不是这样工作的:不是网络服务器将它们内联到同一个 HTTP 请求中,而是网络浏览器在另一个 HTTP 请求中单独下载它。

使用时StreamedContent,则第二个 HTTP 请求(当浏览器需要根据<img>元素的 URL 下载具体图像文件以将其显示在 HTML 文档中的所需位置时触发的请求)将基本上咨询该属性再次以下载图像内容。

视图范围的 bean 通过隐藏的输入字段绑定到特定的 JSF 视图javax.faces.ViewState。如果这在 HTTP 请求中不存在(或具有不同的值),那么基本上意味着完全不同的视图。因此,这些图像请求不会重用相同的视图范围 bean 实例。每个图像请求都会获得一个全新的视图范围 bean 实例,所有属性都设置为默认值。会话范围的 bean 基本上与当前在客户端和服务器之间建立的 HTTP 会话一样长,因此相同的 bean 实例将被重用于这些图像请求,所以它就是这样工作的。

要解决您的具体问题,最好是创建一个应用程序或请求范围 bean,它通过其 ID 作为请求参数获取图像。这样,您也不需要一次用数十或数百张图像污染会话(这只会在多个并发用户查看相同图像的情况下浪费服务器内存)。您只需要拥有数据表的图像标识符列表,并通过单独的应用程序范围 bean 提供图像。

也可以看看:

于 2012-11-30T20:29:10.897 回答
0

我遇到了与 OP“类似”的问题,我来到了这里(以及 BalusC 的许多其他答案)。

BalusC 的解释和往常一样完美,但是如果像我和 OP 一样,你受到严格的限制,你如何解决这个问题?在我的情况下:bean 必须是 ViewScope,存储在 bean 中的图像字节在上传时立即“ajaxely”刷新,您无法根据属性(如 ID)再次检索图像,并将其取出数据库)。一般来说,任何时候你有一个一次性生成的图像(验证码?)或来自 ajaxely 的图像(上传的图像?用户修改的图像?)。

我知道,对于这种富含 ajax 的应用程序,JSF/PrimeFaces 并不是最好的框架,但应用程序完全是用 PrimeFaces 编写的,所以……也许你想坚持使用 PF,看看是否有解决方案。

您可以结合使用 ajax 组件和创造力,即 remoteCommand、一点 JS 和一堆我要链接的 StackOverflow 答案来做到这一点。

首先,您需要调用remoteCommand。我在 fileUploader 的“onupload”事件中执行此操作(类似于此答案),以及在文档准备时间(针对生成的图像)​​:

<p:fileUpload fileUploadListener="#{bean.handleFileUpload}"
              oncomplete="displayImageBegin();"

displayImageBegin只需调用远程命令:

function displayImageBegin() {
    if (typeof(getImage) == "function")
        getImage();
}

<p:remoteCommand name="getImage" action="#{bean.getImage()}"
                 oncomplete="displayImageEnd(xhr, status, args);"
                 style="display: none;" />

在 bean 方面,getImage 函数只返回图像字节。您在这里有两个选择:或者使用内联、base64 编码img src(参见这个答案这个),或者只返回和八进制流并将其放入canvas. 第二个选项更灵活,适用于更大的图像(我的图像很小,尺寸可控,所以 base64 编码很好):

您需要完全控制 XHR 答案的格式,就像在这个答案中一样(顺便说一句,我同意这是滥用 JSF 作为 REST 服务;将此代码视为一个有趣的实验):

public void getImage() throws IOException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    externalContext.setResponseContentType("application/text");
    externalContext.setResponseCharacterEncoding("UTF-8");

    if (getCurrentImagePresent()) {
        String base64Image = Base64.getEncoder().encodeToString(yourByteArray);
        externalContext.getResponseOutputWriter().write(base64Image);
    }
    else {
        externalContext.setResponseStatus(404);
    }
    facesContext.responseComplete();
}

remoteCommand oncomplete事件将从这个 bean 函数返回的数据连接到我们的 JS,就像在这个答案中一样:

function displayImageEnd(xhr, status, args) {
    if (xhr.status == 200) {
        $('#previewCurrentImage').attr("src", "data:image/png;base64," + xhr.responseText);
    }
}

(当然,您的 xhtml 中需要正确的 img 标签)

为什么这行得通?答案在这里

@ViewScoped bean 的寿命与 JSF 视图一样长。[...]

因此,@ViewScoped bean 在需要跨 Ajax 请求记住(更改的)视图状态的支持 Ajax 的丰富视图中特别有用。

图像的字节数组是作为 bean 创建的一部分生成的,和/或作为对页面上 ajax 操作的响应;然后可以通过页面上的任何其他 ajax 操作来检索它,因为它会命中同一个 ViewScoped bean。

这是一个适用于我的解决方案;我一般不推荐它,但如果你的约束非常相似,你可以做一些事情......相似!:)

我只是想分享它,因为它可能非常适合 OP 问题(或寻找类似问题的人),它是一个很好的 SO 答案的拼贴。

于 2016-07-14T09:03:33.683 回答