VRaptor - Cap8 - Carregar imagem externa pelo VRaptor

Eu preciso carregar uma imagem no meu .jsp As imagens estão em diretório do meu servidor, como por exemplo F:\Produtos\Imagens Na minha tabela de Produtos eu tenho dois atributos para isso “localImagem” e “imagem”, que refere-se ao nome da imagem Ao selecionar um registro na tabela de produtos eu quero carregar essa imagem em um input.

Com base no e-book vraptor-desenvolvimento-agil-para-web-com-java, fiz as alterações…

Criei a interface Diretorio:

package br.com.empresa.modelo;

import java.net.URI;

public interface Diretorio {

    URI grava(Arquivo arquivo);

    Arquivo recupera(URI chave);
}

Criei a classe DiretorioDeImagens:

package br.com.empresa.modelo;

import java.net.URI;

import javax.inject.Inject;
import javax.persistence.EntityManager;

public class DiretorioDeImagens implements Diretorio {

    private EntityManager manager;
    private Produto produto;

    @Inject
    public DiretorioDeImagens(EntityManager manager, Produto produto) {
        this.manager = manager;
        this.produto = produto;
    }

    // PARA USO DO CDI
    public DiretorioDeImagens() {
    }

    @Override
    public URI grava(Arquivo arquivo) {
        return null;
    }

    @Override
    public Arquivo recupera(URI chave) {
        if (chave == null)
            return null;

        if (!chave.getScheme().equals(produto.getLocalImagem())) {
            throw new IllegalArgumentException(chave + "não é uma URI do diretório de imagens.");
        }

        Long id = Long.valueOf(chave.getAuthority());
        return manager.find(Arquivo.class, id);
    }
}

Criei a classe Arquivo:

package br.com.empresa.modelo;

public class Arquivo {

    private String nome;
    private byte[] conteudo;
    private String contentType;

    public Arquivo(String nome, byte[] conteudo, String contentType) {
        this.nome = nome;
        this.conteudo = conteudo;
        this.contentType = contentType;
    }

    public String getNome() {
        return nome;
    }

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

    public byte[] getConteudo() {
        return conteudo;
    }

    public void setConteudo(byte[] conteudo) {
        this.conteudo = conteudo;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }
}

Alterei o construtor do ProdutoController:

    @Inject
    public ProdutoController(ProdutoDao produtoDao, Diretorio imagens, Result result, Validator validator) {
        this.produtoDao = produtoDao;
        this.imagens = imagens;
        this.result = result;
        this.validator = validator;

    }

E no ProdutoController, criei o método para retornar a imagem:

    @Get("/produto/{id}/imgProduto")
    public Download imgProduto(Integer id) {
        Produto produto = produtoDao.buscaPorId(id);
        Arquivo imgProduto = imagens.recupera(produto.getLocalImagem());
        return new ByteArrayDownload(imgProduto.getConteudo(), imgProduto.getContentType(), imgProduto.getNome());
    }

Porém o Eclise está reclamando dessa implementação… Erro:

The method recupera(URI) in the type Diretorio is not applicable for the arguments (String)

3 quick fixes avaliable:

Change method 'recupera URI' to 'recupera String'
Change return method type 'getLocalImagem(...)' to 'URI'
Change method 'recupera (String)' in type 'Diretorio'

Escolhi a segunda opção, e alterei o getLocalImagem, na classe Produto:

    public URI getLocalImagem() {
        if (localImagem == null)
            return null;
        return URI.create(localImagem);
    }

    public void setLocalImagem(URI localImagem) {
        this.localImagem = localImagem == null ? null : localImagem.toString();
    }

Porém ao tentar carregar a lista de produtos, não carregou mais os itens da tabela, verifiquei que no console do Eclipse, gerou erro:

fev 06, 2017 9:55:29 AM org.apache.catalina.core.ApplicationDispatcher invoke
GRAVE: Servlet.service() for servlet jsp threw exception
java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\Users\edonati\Pictures
    at java.net.URI$Parser.fail(Unknown Source)
    at java.net.URI$Parser.checkChars(Unknown Source)
    at java.net.URI$Parser.parse(Unknown Source)
    at java.net.URI.<init>(Unknown Source)
    at java.net.URI.create(Unknown Source)
    at br.com.ebf.modelo.Produto.getLocalImagem(Produto.java:472)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)