File Download sem framework web MVC

O que aprendi em quase 10 anos de experiência com desenvolvimento de software foi que conceitos são mais importantes do que ferramentas e tecnologias. Conceitos perduram por muitos anos, ferramentas não.

O que estou querendo dizer é que entender bem MVC é mais importante e útil do que saber como usar o último framework MVC da moda; saber OO é mais importante do que saber a sintaxe de uma linguagem de programação. Independentemente da linguagem ou plataforma.

Quando trabalhamos com aplicações Web é comum ter a ajuda do framework MVC para disponibilizar um arquivo para o cliente (navegador). No caso do VRaptor, normalmente basta um código como este abaixo:

public File foto(Perfil perfil) {
    return new File("/caminho/foto-" + perfil.getId() + ".jpg");
}

O código é simples e resolve bem o problema, pois este é o objetivo de uma framework, certo? Mas o que acontece por debaixo dos panos? O que é enviado para o navegador? A imagem acima será exibida diretamente no browser ou o usuário poderá baixá-la? Qual o nome do arquivo será exibido para o usuário ao fazer download?

Muitas perguntas, muitas vezes desnecessárias… desnecessárias até o 1o problema surgir e você ter que identificar se o problema está no framework, servidor ou proxy da sua rede. Enfim, para ajudá-lo a entender parte do processo de download de arquivos numa aplicação Web nós blogamos exatamente sobre o assunto:

>> Como disponibilizar arquivos para download em Java

No post você vai aprender como fazer o download de um arquivo diretamente de uma Servlet, pois é exatamente isso que um framework MVC faz. Você vai aprender alguns cabeçalhos HTTP importantes e claro, como forçar aquela janelinha “Salvar como…”.

E aí, já desceu alguma vez do salto para programar mais baixo nível sem ajuda do seu framework favorito?

 

O perigo do relacionamento bidirecional com JPA e Hibernate

Eu já bati muito a cabeça com JPA e Hibernate para aprender que relacionamento bidirecional no geral atrapalha mais do que ajuda. A verdade é que deveríamos evitar relacionamento bidirecional (o tal do mappedBy) sempre que possível. Ele só deveria ser utilizado em último caso, quando realmente não tiver para onde correr…

Por exemplo, será que o código abaixo funcionaria em um relacionamento bidirecional?

Item curso = new Item("Curso de Java e Orientação a Objetos", 1);

Carrinho carrinho = dao.buscaPor(id);

carrinho.getItens().add(curso);

dao.atualiza(carrinho);

E se eu te dissesse que NÃO? Esse código não funcionaria!

Quando trabalhamos com bidirecional somos obrigados a escrever um código mais complicado para manter a consistência entre as entidades, o que nem sempre é fácil. Para entender do que estou falando dá uma lida no novo post do blog da TriadWorks:

>> JPA: por que você deveria evitar relacionamento bidirecional

Se você ainda insistir em usá-lo nos post acima eu te dou algumas dicas de orientação a objetos (ENCAPSULAMENTO, tan dãn!!) para manter a consistência do relacionamento. Dessa forma você diminui as chances de ter dor de cabeça.

E aí, o que achou do post?

CDI: Não use @Inject e @ManagedBean nas suas classes

Algumas semanas atrás tive uma experiência bem estressante e chata ao misturar as anotações do JSF com as anotações do CDI. Apesar de saber que EM TEORIA eu não deveria fazer isso eu acabei fazendo e percebendo o problema NA PRÁTICA.

O problema ocorria quando minha página processava uma EL (Expression Language) que apontava para um managed bean anotado com @ManagedBean e tinha suas dependências injetadas pelo CDI através da anotação @Inject… nesse momento a injeção não ocorria. Sendo mais específico, simplesmente o container (qual deles? JSF ou CDI?) injetava null no atributo da classe. O código era semelhante a este:

@ManagedBean
public class AlunosBean {

    @Inject
    private AlunosDao dao;

}

A coisa fica ainda mais feia quando misturava os escopos do CDI com o escopos do JSF. Imagina um managed bean sendo instanciado trocentas vezes? Pois é…

Depois de muito ler e discutir com amigos que sacam mais de CDI do que eu, como o Raphael Lacerda e Daniel Cunha, eu percebi que NÃO era uma boa prática misturar as anotações. Para você entender mais a fundo do que estou falando eu bloguei no blog da TriadWorks sobre isso. Você pode ler o post completo no link abaixo:

>>> NÃO misture anotações do JSF com as anotações do CDI

O post fala um pouco sobre meu problema e de quebra ensina como você pode migrar seus managed beans do JSF para beans do CDI. Onde com certeza essa é a melhor escolha que você poderia tomar.

Enfim, uma experiência interessante que quis compartilhar.