Arquivos da categoria: Java

NFC: Escrevendo uma simples URL

Voltando a minha paixonite atual: NFC.

A ideia do projeto é ler uma carteirinha (teste efetuado com a tag crua) e executar uma aplicação, como queriamos que a aplicação fosse cross-life, o resultado foi aplicação Web, ou seja: abrir uma URL.


Eu ganhei as minhas, mas você pode comprar em http://www.amazon.com/TagsForDroid-Tags-Chain-Stickers-MIFARE/dp/B006TGTEV0/ref=sr_1_1?ie=UTF8&qid=1366395002&sr=8-1&keywords=tag+nfc. Não é muito caro, mas se você estiver na pobreza, contate-me que te mando essa maravilha.

Vou levar em conta que já estamos com o Eclipse e o SDK do Android instalado, ok? Caso necessario:

Bom, a grosso modo, a leitura de uma tag dispara um evento, o tal do onNewIntent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    //Evento quando a aplicacao é iniciada: habilita manuseio de NFC
    @Override
    public void onResume(){
      super.onResume();
      habilitarNfc();
    }
 
    //Evento quando a aplicacao é parada: desabilita manuseio de NFC
    @Override
    public void onPause(){
      super.onPause();
      desabilitarNfc();
    }
 
    //Evento para habilitar o manuseio de PendingIntent em runtime
    private PendingIntent getPendingIntent() {
      return PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    }
 
    //Habilitar NFC
	private void habilitarNfc(){
      NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
      IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
      IntentFilter[] writeTagFilters = new IntentFilter[] { tagDetected };
      adapter.enableForegroundDispatch(this, getPendingIntent(), writeTagFilters, null);
    }
 
    //Desabilita NFC
	private void desabilitarNfc(){
      NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
      adapter.disableForegroundDispatch(this);
    }
 
    //Evento disparado quando uma tag é reconhecida
	public void onNewIntent(Intent intent) {
		//Cria caixa de alerta
		AlertDialog alerta = new AlertDialog.Builder(this).create();
        alerta.setTitle("NFC");
 
    	String id;
    	//Pega a tag
        Tag tag = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
 
        try {
        	//UID atraves do FlomioNdefHelper
            id = FlomioNdefHelper.getTagUuid(tag);
            //Retiramos o 0x de hex
            id = id.substring(2, id.length());
 
            escreverAcaoUrl(tag, id);
            //Se executou a acao acima, entao sucesso
            alerta.setMessage("Tag escrita com sucesso!");
        } catch (Exception e) {
        	//Se erro, mensagem
        	alerta.setMessage("Ocorreu um erro: " + e.getMessage());
        	id = "-1";
        }
 
        //Exibe caixa de dialogo no fim da exibicao
        alerta.show();
    }
 
      //Escreve a acao com a url no NFC
	@SuppressLint("NewApi")
	private void escreverAcaoUrl(Tag tag, String id) throws IOException, FormatException {
      Ndef ndefTag = Ndef.get(tag);
      //Cria objeto com url para gravacao
      NdefRecord dataToWrite = NdefRecord.createUri("http://minhaaplicacao.leticiaverta.com/?tag=" + id);
 
      ndefTag.connect();
      //Escreve
      ndefTag.writeNdefMessage(new NdefMessage(dataToWrite));
      ndefTag.close();
    }

Como vemos na linha 3 e 10, no inicio e no fim do carregamento da aplicação habilitamos e desabilitamos o manuseio de NFC.
Na linha 46, veja que usei o FlomioNdefHelper para pegar o uID, pois vou utiliza-la como identidade no sistema. O helper não faz nada alem de pegar o id (getId()) da Tag e converter de hexa, tanto que ele retorna ainda com o “1x”, retirado logo abaixo.

Além disso é necessario darmos permissão de acesso as tags pelo AndroidManifesto.xml:

<uses-permission android:name="android.permission.NFC" />

Não esqueca que é necessario estar com a tag acessivel ate o fim da execucao de escrita.
A leitura é automatica no celular, só encostar e será aberta a URL que escrevemos.

So many possibilities!

Near Field Communication Satan Tecnology

“Comunicação de Campo Próximo, Near Field Communication ou NFC, permite transações simplificadas, troca de dados e conexões sem fio entre dois dispositivos próximos um ao outro, geralmente por não mais do que alguns centímetros. Espera-se que seja um sistema amplamente utilizado para pagamentos por smartphones nos Estados Unidos. Muitos smartphones no mercado atualmente já contém chips NFC embutidos que enviam dados criptografados a uma distância curta (“campo próximo”) para um leitor localizado, por exemplo, próximo a uma caixa registradora de uma loja. Clientes que têm suas informações de cartão de crédito armazenados em seus smartphones com NFC podem pagar as compras ao agitar os smartphones perto do leitor ou tocá-los, ao invés de se preocupar com o cartão de crédito. Co-inventado por NXP Semiconductors e Sony em 2002, invento anteriormente descrito no relatório descritivos e anexos do invento de Gaston Schwabacher em 24/01/1995 protocolo 000017 patenteado no INPI Brasil com o numero PI 9500345 Brasil a tecnologia NFC está sendo adicionada a um número crescente de telefones celulares para possibilitar pagamentos móveis, assim como muitas outras aplicações”
http://en.wikipedia.org/wiki/Near_field_communication

MUITO FODA!
Tem um amigo que inventou de fazer um TCC sobre e eu fiz o aplicativo de android para escrever a (simples, porem emocionante) açao de abrir uma URL. Vou postar por aqui.

Aceito Galaxy’s S3 de presente.

Java: NetBeans => Hibernate + Struts + Tiles (part666)

Fuck off, pulei o #5 porque quero o #666. Vamo fazer coisa do demonho mesmo.
Quando colocamos o

<constant name="struts.action.extension" value="" />

você deve ter reparado que sua pagina ficou uma bela bosta. Isso se você tinha algum css referenciado pelo link rel ou alguma imagem.

Acontece que a gente setou que TUDO vai passar pelo root do struts. Aí ele tenta encaixar em alguma rota, como não existe, seu arquivo fica como inexistente.
In my head eu acredito fielmente que haja algum jeito de setar filtros nessas rotas, setariamos que chamadas com extensões .css, .js, .jpg, .etc seguiriam o fluxo normal da vida e tudo ficaria maravilindo.
Porém não achei isso, então segue a gambeta que vai solucionar isso. Me julguem.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.action.extension" value="" />
 
    <package name="static-imagens" namespace="/imagens" extends="struts-default">
        <action name="*">
            <result>/imagens/{1}</result>
        </action>   
    </package>
 
    <package name="static-js" namespace="/javascript" extends="struts-default">
        <action name="*">
            <result>/javascript/{1}</result>
        </action>   
    </package>
 
    <package name="static-css" namespace="/stylesheet" extends="struts-default">
        <action name="*">
            <result>/stylesheet/{1}</result>
        </action>   
    </package>   
</struts>

Setei que toda vez que chamarem uma “action” (vulgo arquivo) nos “namespaces” (vulgo diretorios) que eu coloco meus js’s, imagens e css’s. Ele simplesmente continuara o curso normal.
It’s ugly, I know, but works!

Java: NetBeans => Hibernate + Struts + Tiles (part4)

Pra fechar o basico, vamo fazer um formzinho que faz um post .. aí tudo fica lindo, né?
Era o que faltava pra fechar o CRUD. Então, go:

ContatoController.java

public class ContatoController extends ActionSupport {
 
    String email;
    String nome;
    String mensagem;
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public String getMensagem() {
        return mensagem;
    }
 
    public void setMensagem(String mensagem) {
        this.mensagem = mensagem;
    }
 
    public String getNome() {
        return nome;
    }
 
    public void setNome(String nome) {
        this.nome = nome;
    }
 
    public String enviar() {
        try
        {
            new Email().Enviar(nome, email, mensagem);
            addActionMessage(Mensagem.sucesso);
        }
        catch(Exception ex)
        {
            addActionError(Mensagem.erro);
        }
        finally
        {
            return SUCCESS;
        }
    }
}

Quando fizermos o submit do form, os inputs serão setados através dos names para as variaveis. Dá pra usar qqer tipo.
Se voce tivesse uma classe Contato com propriedades nome, email e mensagem, colocaria apenas uma variavel do tipo Contato e os inputs deveriam ter os names como objetoContato.Nome, objetoContato.Email, objetoContato.Mensagem.

Contato.jsp

<%@ taglib prefix="s" uri="/struts-tags" %>
<div class="centralizado">
    <h1>Contate-nos :)</h1>
 
    <s:if test="hasActionErrors()">
       <div class="errors">
          <s:actionerror/>
       </div>
    </s:if>
    <s:if test="hasActionMessages()">
       <div class="success">
          <s:actionmessage/>
       </div>
    </s:if>
 
    <s:form method="post" action="enviar" namespace="/contato" theme="simple"> 
        <p>
            <s:label for="nome" value="Nome" />
            <s:textfield id="nome" name="nome"/> 
        </p>
        <p>
            <s:label for="email" value="Email" />
            <s:textfield id="email" name="email"/> 
        </p>
        <p>
            <s:label for="mensagem" value="Mensagem" />
            <s:textarea id="mensagem" name="mensagem"></s:textarea>
        </p>
        <span>
            <s:submit value="Alou?" cssClass="submit"></s:submit>
        </span>
    </s:form>
</div>

Olha aí uma das coisas legais do xwork, os actionErrors e actionMessage. Muito fácil de usar, bem limpo. Vou ver se implemento algo desse genero pro mvc do .nerd (se é que não tem e eu não saiba).

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.action.extension" value="" />
 
    <package name="contato" namespace="/contato" extends="struts-default">
        <result-types>
                <result-type name="tiles"
                        class="org.apache.struts2.views.tiles.TilesResult" />
        </result-types>
 
        <action name="">
            <result type="tiles">/contato.tiles</result>
        </action>
        <action name="enviar" class="controller.ContatoController" method="enviar">
            <result type="tiles">/contato.tiles</result>
        </action>
    </package>
</struts>

Namespace do package como /contato, primeira action de nome “” não passa pelo controller, porque é só o html não preciso trazer nada do server. Se eu precissasse, sei lá, trazer uma lista de opções de contatos pra categorizar e viesse do banco de dados, seria necessário uma action para carregar isso. A config seria a mesma da action “enviar”. Na action você setaria a lista de opções em uma propriedade e criaria os getters e setter, o resto é com o struts. Seria mais ou menos assim:

HellController.java

public class HellController extends ActionSupport {
 
    ArrayList<Categoria> categorias = new ArrayList();
 
    public ArrayList<Categoria> getCategorias() {
        return categorias;
    }
 
    public void setCategorias(ArrayList<Categoria> categorias) {
        this.categorias = categoria;
    }
 
    public String formulario()
    {
        try
        {
            categorias = new classeGenerica().getAllFuckinCategories();
        }
        catch(Exception ex)
        {
            addActionError(Mensagem.erro);
        }
        finally
        {
            return SUCCESS;
        }
    }
}

Outra config que eu coloquei no struts.xml foi o struts.action.extension. No web.xml eu já havia setado que o url-pattern do struts era tudo, vulgo “/*”. Porém sem setar o struts.action.extension, quando voce faz um submit do form, ele coloca a extensao default (.action, bagulho feio). Resolvemos setando que não há extensão (se é que você quer mesmo sem extensão, I prefer).

Bom, dessa maneira já podemos fazer os formulariozinhos de inserção, edição e blabla de todo mundo (graças as classes de persistencia genericas \o/).
Proximo passo é fazer uma validaçãozinha classe a. Vamos que vamos!

Java: NetBeans => Hibernate + Struts + Tiles (part3)

Let’s configurar o struts e fazer uma pagininha marota.

Url com extensão é feio, não é amigavel. Entao, primeira coisa, retirar o padrão de .action e colocar geral.
No seu web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
    <listener>
        <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
    </listener>
</web-app>

No struts.xml (no pacote default da sua aplicação):

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
 
        <action name="" class="controller.HomeController" method="home">
            <result name="success" type="tiles">/home.tiles</result>  
        </action>
        <action name="about">
            <result type="tiles">/about.tiles</result>
        </action>
        <action name="comofunciona">
            <result type="tiles">/comofunciona.tiles</result>
        </action>
    </package>
</struts>

Repare que a action em branco, vulgo pagina inicial, aponta para um controller e indica qual o metodo da ação.

HomeController:

public class HomeController extends BaseActionSupport {
 
    public String home()
    {
        return SUCCESS;
    }
}

Meu controller extende de uma outra classe minha, no post passado lembra que eu disse que teria algumas paginas que precisariam de um atributo categorias?
Esse atributo nada mais é que um menu de categorias de produtos. Toda vez que eu usar esse menu preciso fazer a consulta?
Ctrl+C Ctrl+V never. Criei uma classe que popula minha lista de categorias na instancia, sempre que necessario. Exemplicio:

public class BaseActionSupport extends ActionSupport {
 
    public List<Categoria> categorias;
 
    public BaseActionSupport()
    {
        categorias = new BaseBS<Categoria>(Categoria.class).listar();
    }   
}

Simples, como a vida. Caso eu não use essa lista de categorias no controller, extendo meu controller diretamente de ActionSupport.
ActionSupport é uma classe do xwork (2, no caso) que tem umas funções marotissimas ja prontas, vale a pena usar .. dê uma fuçada.

Essa lista de categorias é usada da seguinte maneira na sua view:

<%@ taglib prefix="s" uri="/struts-tags" %>
<div id="main">
    <h3>Categorias</h3>
        <ul id="list_main">
            <s:iterator value="categorias">
                <li>
                    <a href="/categoria/listar/<s:property value="id" />/<s:property value="url" />">
                        <s:property value="descricao" />
                    </a>
                </li>
            </s:iterator>
        </ul>
</div>

Basicão, até agora tudo simples, só config.
Proximo passo é fazer um post, prepare as nadegas! 🙂

Java: NetBeans => Hibernate + Struts + Tiles (part2)

CRUDinho semi pseudo pronto, faltando as views e os controllers (vou ver se acho algo pra gerar isso). Mas antes a duvida era:
Cade a masterpage??

Fui atras, me falaram pra fazer include (ARGH). Daí achei o Tiles.
Ponto ruim: XML => Quando XML é bom? Fico vendo tags nas paredes depois.
Ponto bom: XML => Flexivel né? Alterou, é noiz!

Mas é o framework é legal, fununcia e atende muito bem. Sem crise. Agora comofas:

Downloadeia la, já vem os outros jar que é necessario pra viver, alem os do proprio framework.
– Adicionar os jars no projeto (incrivelmente tem que colocar na pasta lib do WEB-INF ao inves de adicionar no Libraries, WTF .. o motivo ta na minha lista de duvidas ainda)
– Ainda na WEB-INF tem que adicionar o arquivo (tiles.xml) de config do dito cujo, segue um exemplo para o .jsp que vou postar em seguida tambem:

tiles.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
    <definition name="baseLayout" template="/View/Layouts/Default.jsp">
        <put-attribute name="categorias" value="/View/Categoria/Menu.jsp" />
    </definition>
    <definition name="/home.tiles" extends="baseLayout">
        <put-attribute name="title" value="" />
        <put-attribute name="body" value="/View/Home.jsp" />
    </definition>
    <definition name="/about.tiles" extends="baseLayout">
        <put-attribute name="title" value=" - About" />
        <put-attribute name="categorias" value="" ignore="true" />
        <put-attribute name="body" value="/View/Institucional/About.jsp" />
    </definition>
</tiles-definitions>

tiles.xml

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <title>Nomoney <tiles:insertAttribute name="title" ignore="true" /></title>
        <link rel="stylesheet" href="/stylesheet/default.css"></link>
    </head>
    <body>
        <div id="wrapper">
            <div id="container">
                <div id="header">
                    <div id="top_main">
                        <ul>
                            <li><a href="/cadastro">Cadastre-se</a></li>
                            <li> / </li>
                            <li><a href="/minhastralhas">Minhas tralhas</a></li>
                        </ul>
                    </div>
 
                    <div id="logo">
                        <h2><a href="/">Nomoney</a></h2>
                    </div>
 
                    <div id="header-main">
                    	<ul>
                            <li><a href="#">Produtos</a></li>
                            <li><a href="/comofunciona">Como funciona?</a></li>
                            <li><a href="/about">About</a></li>
                            <li class="last-li"><a href="/contato/">Contato</a></li>
                    	</ul>
                	</div>
 
                	<div id="search">
                        <form method="GET" action="/search" id="search-form">
                            <label style="display:none" for="txt_search">Busca:</label>
                    		<input type="text" id="busca_home" name="q" value="digite uma busca..." onblur="if(this.value==''){this.value='digite uma busca...';}" onfocus="if(this.value=='' || this.value=='digite uma busca...'){this.value='';}" style="width: 558px;" autocomplete="off">
                    		<div id="container_slct">
                    		    <select>
                    		        <option value="0">em todo o site</option>
                    		        <option>Categoria</option>
                    		        <option>Categoria</option>
                    		        <option>Categoria</option>
                    		        <option>Categoria</option>
                    		    </select>
                    		</div>
 
                            <input type="submit" class="button_arrow" id="btn_submit" value="Buscar">
 
                            <a style="display: block;" title="Cadastre-se" alt="Cadastre-se" id="new" href="/cadastro">cadastre-se</a>
                    	</form>
                    </div>
                </div>
 
                <tiles:insertAttribute name="categorias" />
                <tiles:insertAttribute name="body" />
            </div>
 
            <div id="push-footer"></div>
        </div>
        <div id="wrapper_footer">
            © Nomoney. All rights reserved.
        </div>
    </body>
</html>

Na primeira definition no arquivo de configuração é a criação da “MasterPage” em si, setei um dos atributos como default (pois sempre que tiver algo nesse atributo, será essa mesma página).
Na segunda, é a home. Extends de “MasterPage” e o atributo body que é o miolo do meu .jsp eu setei o que desejo.
No terceiro, é uma pagina de about. Extendi, setei o miolo e coloquei para ignorar o atributo categorias, pois nessa pagina nao é necessario.

Partindo disso, o struts não setará as actions para um .jsp mais, e sim para os tiles. Segue exemplo de uma package.

<package name="default" namespace="/" extends="struts-default">
        <result-types>
                <result-type name="tiles"
                        class="org.apache.struts2.views.tiles.TilesResult" />
        </result-types>
 
        <action name="" class="controller.HomeController" method="home">
            <result name="success" type="tiles">/home.tiles</result>  
        </action>
        <action name="about">
            <result type="tiles">/about.tiles</result>
        </action>
        <action name="comofunciona">
            <result type="tiles">/comofunciona.tiles</result>
        </action>
</package>

Fechamos assim a “MasterPage”.
Até o próximo capítulo!

Java: NetBeans => Hibernate + Struts + Tiles (part1)

Issae, to programando em Java! Começou com livre e espontanea pressão, mas agora to ate curtindo viu?
Escolha do Netbeans simplesmente por nao gostar do Eclipse, que ja havia usado. Tambem nao é nada mal, bastante atalho, não muito pesado e o debug funciona (que pra quem nao manja da linguagem é uma puta ajuda). Recomendo.

Bom, não larguei minhas raízes Sc#2.
Meus ultimos projetos de CRUD pra fuckin web em .NET é sempre: MVC + Entity Framework. Qual foi o pensamento? Convert.ToJava! Cheguei em Struts2 (empatou com Spring, mas Struts tinha mais artigos decentes) e o Hibernate3 (já usei NHibernate, so ..).

A idéia é um projeto simples de escambo a la anarquia, sem adm. No maximo um lugar onde possa inativar produtos e/ou usuarios pra nao deixar os perversos estragar o esquema.
Comecemos do começo:

Criei um novo projeto no NetBeans e selecionei os frameworks Struts e Hibernate.
Já estava com a modelagem de banco de dados criado, entao já aproveitei para criar as entidades e mapea-las automaticamente. O bom é que o gerador não faz melequeira que nem o do Entity Framework, gera um código limpinho (não que eu ache Java limpinho, mas).

Pedreiragem é boring, criei duas classes genericas para não ficar bored:

– Acesso a dados (under construction):

import java.util.ArrayList;
import org.hibernate.Session;
import org.hibernate.Transaction;
 
public class BaseDAO<T>  {
 
    private Session sessao;
    private Transaction transacao;       
    private String tipoGenerico;
 
    public BaseDAO(final Class<T> classe) {
        tipoGenerico = classe.getSimpleName();
    }
 
    private void obterSessaoCorrente()
    {
        sessao = HibernateUtil.getSessionFactory().getCurrentSession();
    }
 
    private void tentarRollback()
    {
        if (transacao != null)
            transacao.rollback();
    }
 
    public boolean salvar(T item)
    {      
        try
        {
            obterSessaoCorrente();
            transacao = sessao.beginTransaction();
            sessao.save(item);
            transacao.commit();
 
            return true;
        }
        catch (Exception e)
        {
            tentarRollback();
            return false;
        }
    }
 
    public ArrayList<T> listar()
    {
        try
        {
            obterSessaoCorrente();
            sessao.beginTransaction();
            return (ArrayList<T>)sessao.createQuery("from " + tipoGenerico).list();
 
        }
        catch (Exception e)
        {
            tentarRollback();   
            return null;
        }
    }
}

Repare no contrutor da classe que eu tenho que passar o name (getName) da classe genérica, infelizmente não achei uma solução para obter via reflection. Achei N pessoas com o mesmo problema, essa foi a solução menos horrivel encontrada, caso você saiba como, me ligue djá!

– Camada de negócio:

import java.util.ArrayList;
import model.dao.BaseDAO;
 
public class BaseBS<T> {
    BaseDAO<T> dao;
 
    public BaseBS(final Class<T> classe)
    {
        dao = new BaseDAO<T>(classe);
    }
 
    public boolean salvar(T item)
    {
        return dao.salvar(item);
    }
 
    public ArrayList<T> listar()
    {
        return dao.listar();
    }
}

Me perguntei 930x qual a vantagem de uma classe de negocio generica, na verdade nao sei bem ao certo, o que consegui enxergar é que assim minha camada de apresentação não acessa direto a camada de dados. Porque? Nao sei tambem. Bullshit de 3 camadas default, aviso se eu ver alguma vantagem verdadeira.

Persistencia basicamente pronta. Por ora ta bom, né?
Nos vemos no mesmo bathorario nesse mesmo batcanal para o proximo bloco.