Ta dificil, jsf + a4j:mediaoutput + rich:datatable + hibernate

2 respostas
L
Aew galera, Esse problema tá estranho: Tenho a entidade Imagem:
@Entity
public class Imagem implements Serializable {

    @Id @GeneratedValue
    private long id;
    private String nome = "";
    private String tipo = "";
    @Lob
    private byte[] bytes;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getTipo() {
        return tipo;
    }

    public void setTipo(String tipo) {
        this.tipo = tipo;
    }

    public byte[] getBytes(){
        return bytes;
    }
    public void setBytes(byte[] imagem) {
        this.bytes = imagem;
    }

}
Que persisto em um banco MySQL, meu sistema web com o rich:fileupload salva tudo isso no banco d boa. Agora para mostrar as imagens que tenho no banco uso o bean com escopo de sessão:
public class ImagensBean {

    private Imagem imagem = new Imagem();

    public Imagem getImagem() {
        return imagem;
    }

    public void setImagem(Imagem imagem) {
        this.imagem = imagem;
    }

    public void uploadListener(UploadEvent event) {
        UploadItem arquivo = event.getUploadItem();
        Imagem novaImagem = new Imagem();
        novaImagem.setBytes(arquivo.getData());
        String nome = arquivo.getFileName();
        int ponto = arquivo.getFileName().lastIndexOf('.');
        novaImagem.setNome(nome.substring(0, ponto));
        String tipo = nome.substring(ponto +1);
        if("jpg".equals(tipo))
            novaImagem.setTipo("image/jpeg");
        else
            novaImagem.setTipo("image/"+tipo);
        new NegocioImagens().salvar(novaImagem);
    }

    public List<Imagem> getImagens() {
        return new NegocioImagens().listarImagens();
    }

    public void montarImagem(OutputStream stream, Object object) throws IOException{
        stream.write( ((Imagem)object).getBytes() );
    }

    public String excluirImagem(){
        new NegocioImagens().excluir(imagem);
        return "";
    }

    public String salvarImagem(){
        new NegocioImagens().salvar(imagem);
        return "";
    }
}
E a tela:
<f:subview id="gerenciarimagens">
    <h:form>
        <div align="center">
            <rich:dataTable value="#{ImagensMB.imagens}" var="i" id="imagens">
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="NOME"/>
                    </f:facet>
                    <h:outputText value="#{i.nome}"/>
                </h:column>
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="IMAGEM"/>
                    </f:facet>
                    <a4j:mediaOutput element="img" mimeType="#{i.tipo}" cacheable="false"
                                     createContent="#{ImagensMB.montarImagem}" value="#{i}" session="true"/>
                </h:column>
                <h:column>
                    <a4j:commandButton value="Renomear" onclick="#{rich:component('renomear')}.show()"
                                       reRender="panelRenomear">
                        <f:setPropertyActionListener value="#{i}" target="#{ImagensMB.imagem}"/>
                    </a4j:commandButton>
                </h:column>
                <h:column>
                    <a4j:commandButton value="Excluir" onclick="#{rich:component('confirmar')}.show()"
                                       reRender="panelConfirmar">
                        <f:setPropertyActionListener value="#{i}" target="#{ImagensMB.imagem}"/>
                    </a4j:commandButton>
                </h:column>
            </rich:dataTable>
            <rich:fileUpload fileUploadListener="#{ImagensMB.uploadListener}" autoclear="true"
                             acceptedTypes="jpg, gif, png, bmp" immediateUpload="true"
                             addControlLabel="Adicionar Nova Imagem" listHeight="0"
                             listWidth="160" id="uploader">
                <a4j:support event="onuploadcomplete" reRender="imagens,uploader"/>
            </rich:fileUpload>
        </div>
        <rich:modalPanel id="renomear">
            <div align="center">
                <rich:panel id="panelRenomear">
                    <f:facet name="header">
                        <h:outputText value="Renomear Imagem" />
                    </f:facet>
                    <h:inputText value="#{ImagensMB.imagem.nome}"/>
                    <h:outputText value="   "/>
                    <a4j:commandButton value="OK" action="#{ImagensMB.salvarImagem}"
                                       onclick="#{rich:component('renomear')}.hide()"
                                       reRender="imagens">
                    </a4j:commandButton>
                    <a4j:commandButton value="Cancelar" onclick="#{rich:component('renomear')}.hide()"/>
                </rich:panel>
            </div>
        </rich:modalPanel>
        <rich:modalPanel id="confirmar">
            <div align="center">
                <rich:panel id="panelConfirmar">
                    <f:facet name="header">
                        <h:outputText value="Deseja realmente excluir a imagem?" />
                    </f:facet>
                    <h:outputText value="#{ImagensMB.imagem.nome}  "/>
                    <a4j:mediaOutput element="img" cacheable="false" session="true"
                                     createContent="#{ImagensMB.montarImagem}" value="#{ImagensMB.imagem}"/>
                    <h:outputText value="   "/>
                    <a4j:commandButton value="Sim" action="#{ImagensMB.excluirImagem}"
                                       onclick="#{rich:component('confirmar')}.hide()"
                                       reRender="imagens">
                    </a4j:commandButton>
                    <a4j:commandButton value="Não" onclick="#{rich:component('confirmar')}.hide()"/>
                </rich:panel>
            </div>
        </rich:modalPanel>
    </h:form>
</f:subview>
E funciona bem com a maioria das imagens. Porém algumas imagens não aparecem, ficam com o simbolo de imagem vazia, mesmo sendo do mesmo formato que outras que aparecem. Desconfio que seja por causa do tamanho mas não achei nada na documentação do a4j:mediaOutput que sugerisse isso. O mais estranho é que ao debugar o código, percebo que no método montarImagem(OutputStream stream, Object object) o object passado é null e da NullPointerException. Posso limpar o banco e inserir as imagens em ordem diferente que sempre as mesmas dao o mesmo erro. Alguem sabe porque o dataTable estaria passando o valor nulo nessas ocasiões? Obrigado!

2 Respostas

L

Corrigindo, o object nao vem null, ele de fato é uma instancia de Imagem como deveria ser, porem não vem com os dados populados, ou seja, vem com id=0, nome="", tipo="" e bytes= um array vazio, o que é mais estranho ainda…
[]s

L

e definitivamente tem a ver com o tamanho da imagem, acabei de pegar a mesma imagem que nao da certo, reduzi, dei upload e entao ela aparece. Ainda não consegui entender porque isso acontece, ja que no banco todas sao salvas corretamente, consigo ver todas pelo vizualizador do mysql.

Criado 22 de julho de 2010
Ultima resposta 22 de jul. de 2010
Respostas 2
Participantes 1