Mudanças entre as edições de "POO - 2014-2"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
 
(113 revisões intermediárias por 4 usuários não estão sendo mostradas)
Linha 109: Linha 109:
  
 
  Utilize uma das classes que aprendemos, e tente transformá-la para serializable.  
 
  Utilize uma das classes que aprendemos, e tente transformá-la para serializable.  
  As classes podem sem: Motor, Bicicleta, Triangulo, Calculadora, etc...
+
  As classes podem sem: Motor, Bicicleta, Triângulo, Calculadora, etc...
 
  Após isso, salve o objeto em um arquivo e recupere as informações, faça uma chamada a algum método.
 
  Após isso, salve o objeto em um arquivo e recupere as informações, faça uma chamada a algum método.
  
Linha 117: Linha 117:
  
  
Para Exercício 2:
+
Para Exercício 2 (ver slides):
  
 
  public static void main(String[] args) {
 
  public static void main(String[] args) {
Linha 145: Linha 145:
 
Crie um projeto no NetBeans com o nome ecoServer.
 
Crie um projeto no NetBeans com o nome ecoServer.
 
Insira os dois .java dentro da pasta src.
 
Insira os dois .java dentro da pasta src.
Compile e execute.  
+
Leia a descrição do código abaixo, entenda e modifique conforme o necessário.
  
  [[Media:POO-20142-ServidorClienteEco.java | Servidor e Clientes de Eco ]]
+
  [[Media:POO-20142-ServidorClienteEco2.zip | Servidor e Clientes de Eco ]]
  
  
'''Vamos Entender o código do CLIENTE.'''
+
=='''Vamos entender o código do CLIENTE.'''==
  
----
 
  
 
Declara a criação de um novo socket e dá o nome de echoSocket.  
 
Declara a criação de um novo socket e dá o nome de echoSocket.  
Linha 187: Linha 186:
 
  # 5 Fechar o socket.
 
  # 5 Fechar o socket.
  
 +
=='''Vamos entender o código do SERVIDOR.'''==
  
'''Vamos Entender o código do SERVIDOR.'''
 
 
----
 
  
 
ServerSocket inicia tentativa de escutar a porta definida, caso não seja possível uma excessão  
 
ServerSocket inicia tentativa de escutar a porta definida, caso não seja possível uma excessão  
Linha 201: Linha 198:
  
 
Se o servidor conseguiu fazer a ligação com a porta definida,  
 
Se o servidor conseguiu fazer a ligação com a porta definida,  
o objeto do servidor (ServerSocket) é criado com sucesso e o servidor contunua no próximo passo.
+
o objeto do servidor (ServerSocket) é criado com sucesso e o servidor continua no próximo passo.
 
Que é aceitar a conexão com o cliente.  
 
Que é aceitar a conexão com o cliente.  
 
O método serverSocket.accept() vai esperar até que uma conexão seja estabelecida (somente uma).
 
O método serverSocket.accept() vai esperar até que uma conexão seja estabelecida (somente uma).
 
  Socket clientSocket = serverSocket.accept();
 
  Socket clientSocket = serverSocket.accept();
  
Os métodos PrintWriter e BufferedReader seguem a mesma lógica de PrintWriter e BufferedReader.  
+
Os métodos PrintWriter e BufferedReader seguem a mesma lógica de PrintWriter e BufferedReader do cliente.  
 
  PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
 
  PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
 
  BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));
 
  BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));
Linha 217: Linha 214:
 
[[imagem:POO-20142-IMGClienteServerEcho.png]]
 
[[imagem:POO-20142-IMGClienteServerEcho.png]]
  
 +
'''Para testar:'''
 +
 +
Compile os códigos.
 +
 +
Execute o servidor usando: java EchoServer <port number>
 +
 +
Execute o cliente usando: java EchoClient <host name> <port number>
 +
 +
Ou Execute $telnet localhost 5000 onde 5000 é a porta definida na criação do servidor.
 +
 +
Para verificar utilize: $ netstat -na|head -n 20 e verifique se a porta
 +
que você endereçou está aberta.
 +
Para filtrar de forma mais refinada utilize: netstat -na|grep :<portNumber>
 +
onde <portNumbe> deve ser substituido pela porta utilizada.
 +
 +
Lembrando que a porta deve ser a mesma.
 +
 +
Logo após executar o cliente digite algo e pressione enter.
 +
 +
Se você recebeu de volta o que escreveu, está ok.
 +
 +
Faça as atividades.
  
 
'''Atividades:'''
 
'''Atividades:'''
 +
 +
Lembrando da aula de escrita e leitura de arquivos:
  
 
Faça com que cada mensagem enviada pelo cliente de eco seja salva em disco (no servidor).  
 
Faça com que cada mensagem enviada pelo cliente de eco seja salva em disco (no servidor).  
Linha 224: Linha 245:
 
Faça com que a mensagem seja salva no servidor em um arquivo chamado reqEco.txt.
 
Faça com que a mensagem seja salva no servidor em um arquivo chamado reqEco.txt.
  
 +
 +
 +
Possível Solução, verifique através do arquivo:
 +
 +
[[Media:Projeto-ServerSol-POO2014-2.zip | Projeto Servidor, possível Solução.]]
 +
 +
Ou altere o código do servidor, o método while:
 +
 +
String inputLine;
 +
            while ((inputLine = in.readLine()) != null) {
 +
                out.println(inputLine);
 +
                try {
 +
                    OutputStream os = new FileOutputStream("meusDados.txt");
 +
                    OutputStreamWriter osw = new OutputStreamWriter(os);
 +
                    BufferedWriter bw = new BufferedWriter(osw);
 +
                    bw.write("Info: " + inputLine);
 +
                    bw.close();
 +
                } catch (IOException ex) {
 +
                    System.err.println("erro: " + ex.toString());
 +
                }
 +
                out.println("Informação Salva!");
 +
                System.out.println("Informação: "+inputLine+ " salva!");
 +
            }
 +
 +
 +
Se a versão do Java for menor que 1.7 ocorrerá incompatibilidade.
 +
Para resolver, faça o downgrade do código.
 +
Utilize o try sem os ();
 +
 +
Dessa forma:
 +
try { ... }
 +
catch () { ... }
 +
 +
Ao invés de:
 +
try ( ... ) { ... }
 +
catch () { ... }
 +
           
 +
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Aula 13 - 25/09/14, 01/10/2014: Sockets, Servidor de eco, continuação. }}
 +
 +
Pré-requisito: Ler, fazer e entender aulas 10 e 12.
 +
 +
== Modificações no servidor. ==
 +
 +
1
 +
Faça com que ao digitar "quit" ou "exit" a conexão e o servidor sejam fechados.
 +
Faça o tratamento das palavras reservadas quit e exit, para que as mesmas não sejam salvas.
 +
 +
Possível solução para a modificação 1:
 +
 +
Tratamento para não salvar palavras reservadas (quit, exit...)
 +
if(!inputLine.equalsIgnoreCase("quit")
 +
    && !inputLine.equalsIgnoreCase("exit")
 +
    && !inputLine.equalsIgnoreCase("saveData")                       
 +
    && !inputLine.equalsIgnoreCase("cleanData")
 +
    && !inputLine.equalsIgnoreCase("showData") ){
 +
    buffer[i++] = inputLine.toString();
 +
    System.out.println("Bufferizando: \""+inputLine.toString()+ "\"");
 +
}
 +
 +
Tratamento para término do servidor.
 +
if(inputLine.equalsIgnoreCase("exit") ||
 +
    inputLine.equalsIgnoreCase("quit")){
 +
    System.exit(0);
 +
}
 +
 +
 +
----
 +
 +
 +
2
 +
Transforme em um método privado a parte que faz a gravação dos dados dentro do while (servidor).
 +
O método deve retornar um boolean informando se a gravação foi efetuada com sucesso.
 +
Verifique o método FileOutputStream() para ver se é possível salvar concatenando o arquivo
 +
ao invés de apagar como está sendo feito. 
 +
 +
 +
Possível solução para a modificação 2:
 +
 +
Método privado para salvar dados no disco.
 +
Esse método deve estar na mesma classe do servidor.
 +
Perceba que o método recebe dois parâmetros, o primeiro consiste
 +
do dado a ser salvo, e o segundo onde deve ser salvo.
 +
 +
O método deve ser chamado da seguinte forma:
 +
 +
salvaDadoNoDisco(buffer[x], "arquivo.txt");
 +
 +
Sendo que buffer[x] é o elemento do vetor que contém a informação a ser salva.
 +
O segundo parâmetro "arquivo.txt" contém o nome do arquivo onde deve ser salvo o dado.
 +
 +
private static boolean salvaDadoNoDisco(String inputLine, String file) {
 +
    try {
 +
        OutputStream os = new FileOutputStream(file, true);
 +
        OutputStreamWriter osw = new OutputStreamWriter(os);
 +
        BufferedWriter bw = new BufferedWriter(osw);
 +
        bw.write("\n" + inputLine.toString());
 +
        bw.close();
 +
        return true;
 +
    } catch (IOException ex) {
 +
        System.err.println("erro: " + ex.toString());
 +
        return false;
 +
    }
 +
}
 +
 +
 +
----
 +
 +
 +
3
 +
Crie um vetor chamado "buffer" com 4 posições.
 +
Nele devem ser armazenadas as informações que o cliente enviar por telnet (somente as válidas, ou seja, não salvar as palavras reservadas nem dados vazios).
 +
Quando o cliente enviar o comando "SaveData" os dados contidos no buffer devem ser salvos em disco.
 +
Quando o buffer encher, deve-se salvar automaticamente os dados em disco.
 +
Obs.: somente os valores devem ser salvos em disco.
 +
 +
4
 +
Para os apaixonados que terminaram a etapa anterior, adicione a palavra reservada "showData".
 +
O cliente ao digitar "showData", todas as informações contidas no arquivo devem ser retornadas ao cliente.
 +
 +
5
 +
Finalizando, adicione a palavra reservada "cleanData", quando o servidor receber o comando
 +
"cleanData" o conteúdo do arquivo meusDados.txt deve ser apagado.
 +
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Aula 14 - 02/10/2014: Classe java.lang.String. }}
 +
 +
É necessário ler a apostila ou outras fontes para resolução.
 +
 +
Baixe o arquivo abaixo, crie um projeto no NetBeans e resolva o que está comentado.
 +
 +
[[Media:POO-201402-ExecString2.zip | Exercício manipulação de String]]
 +
 +
Obs.: o exercício está comentado dentro do código java. Abra e veja.
 +
 +
Coloquei aqui numerado:
 +
 +
    #1 Separe os nomes da frase f1 utilizando o caracter : como separador
 +
    e mostre os valores separados.
 +
    #2 Substitua na frase f2 a palavra Java por C++   
 +
    #3 Verifique na frase f2 se existe a palavra Java
 +
    #4 Verifique na frase f2 se existe a palavra C++
 +
    #5 Verifique se a frase f3 inicia com Meu pé
 +
    #6 Verifique se a frase f3 inicia com Me
 +
    #7 Verifique se a frase f3 termina com lima.
 +
    #8 Verifique se a frase f3 termina com ma.   
 +
    #9 Faça com que a frase f4 fique com todas as palavras em maiúsculas.   
 +
    #10 Faça com que a frase f5 fique com todas as palavras em minúsculas.   
 +
    #11 Retornar o valor ASCII de cada elemento do vetor ascii
 +
    #12 Verificar igualdade da frase f6, respeitando maiúsculas e minúsculas (utilizar a palavra João)
 +
    #13 e sem respeitar maiúsculas e minúsculas (utilizar a palavra João)
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Aula 15 - 22/10/2014: Servidor Eco + Cliente + Interação Servidor-Servidor. }}
 +
 +
Após terminar o servidor de eco
 +
 +
1 - Quando o usuário entrar com o comando "saveData localSalvar.txt" as informações no buffer devem
 +
ser salvas no segundo parâmetro do comando saveData.
 +
Caso contrário devem ser salvar no local padrão.
 +
 +
2 - Utilização do cliente. O cliente deve interpretar os comandos: "ExportFile nomeDoArquivo.txt"
 +
Quando o cliente entrar com o comando "ExportFile nomeDoArquivo.txt" o cliente deve buscar localmente
 +
pelo arquivo, ler todo seu conteúdo e posteriormente enviar todas informações para o servidor.
 +
As informações deve ser repassadas para o servidor utilizando o mesmo nome.
 +
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Prova 2 - 29/10/2014. Com possível solução e código dos alunos. }}
 +
 +
 +
[[Media:POO-201402-EcoServerProva.zip | EcoServer para usar na prova]]
 +
 +
 +
<!--[[Media:POO-201402-PossivelSolucaoProva2.zip | Código dos alunos junto com uma possível solução. ]]-->
 +
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Trabalho 1 - 05/11/2014. Abstração Locadora de filmes}}
 +
 +
Pense em uma abstração para uma locadora de filmes.
 +
 +
Deve ser possível armazenar informações a respeito dos clientes, funcionários e filmes.
 +
 +
Uma vez inseridas as informações essas devem perdurar, ou seja, não devem ser perdidas.
 +
 +
Os dados salvos pela aplicação devem estar sob a pasta "dataBase".
 +
 +
Desenhar o Diagrama de classes, as classes devem conter nomes no singular.
 +
 +
 +
Sobre Inserção dos Dados:
 +
 +
Deve-se poder inserir as informações a respeito dos clientes, funcionários e filmes.
 +
Pode-se utilizar a classe scanner ou outra para fazer a captura dos dados.
 +
 +
Os métodos para captura dos dados do cliente, dos funcionário e filmes,
 +
devem estar em uma única classe.
 +
Você pode pensar em uma classe única chamada CapturaDados.
 +
 +
 +
 +
Sobre padronização para entrega:
 +
 +
Colocar o diagrama de classes em um arquivo PDF contendo: Nome completo, curso e data.
 +
Colocar o projeto em um arquivo ZIP junto com o arquivo PDF.
 +
O nome dos arquivos devem ser no formato: seuNome-seuSobreNome.zip e seuNome-seuSobreNome.pdf.
 +
Dentro do ZIP deve conter somente os arquivos .java e .pdf salvo excessão abaixo.
 +
Caso alguma informação seja necessária para a execução / configuração, a mesma deve estar contida em um arquivo chamado Leiame.txt dentro do arquivo seuNome-seuSobreNome.zip.
 +
 +
 +
Sobre Entrega:
 +
 +
Data: 06/11/2014 - Final da aula.
 +
# Entregou no prazo A, um dia de atraso B, dois dias C, três dias D.
 +
 +
Critérios de avaliação:
 +
 +
# Diagrama de classes.
 +
# Seguiu as especificações definidas A, deixou uma B, duas C, três D.
 +
# Codificação correta das classes.
 +
# Gravação dos objetos.
 +
# Leitura dos objetos.
 +
# Execução de todas funcionalidades A, deixou uma B, duas C, três D.
 +
 +
 +
Sobre as funcionalidades:
 +
 +
# Inserção dos dados dos clientes.
 +
# Inserção dos dados dos funcionários.
 +
# Inserção dos dados dos filmes.
 +
# Gravação das informações dos clientes em disco.
 +
# Gravação das informações dos funcionários em disco.
 +
# Gravação das informações dos filmes em disco.
 +
# Quando o programa iniciar, as informações salvas devem ser recuperadas e impressas na tela.
 +
 +
 +
 +
 +
OBS.: Vejam como funciona a estrutura de dados Map, hashMap e similares.
 +
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Trabalho Final - Início: 13/11/2014, Entrega: 04/12/2014. Abstração Locadora de Filmes}}
 +
 +
O trabalho final é continuação do trabalho 1, sendo assim, todas funcionalidades e características
 +
do trabalho 1 devem ser mantidas, salvo especificação contrária.
 +
 +
 +
 +
Funcionalidades:
 +
 +
# Inserção / Remoção / Atualização dos dados dos clientes.
 +
# Inserção / Remoção / Atualização dos dados dos funcionários.
 +
# Inserção / Remoção / Atualização dos dados dos filmes.
 +
# Gravação das informações dos clientes em disco.
 +
# Gravação das informações dos funcionários em disco.
 +
# Gravação das informações dos filmes em disco.
 +
# Busca por nome de cliente, funcionário ou título de filmes.
 +
# Listagem por categoria (filme, cliente, funcionário).
 +
# Quando o programa iniciar uma tela/texto com opções deve aparecer para o cliente.
 +
# Deve ser possível efetuar / devolver uma locação.
 +
# Deve ser possível listar as locações sem pendência e com pendência.
 +
 +
 +
Sobre Entrega:
 +
 +
Data: 04/12/2014 - até 12:00.
 +
# Entregou no prazo A, um dia de atraso B, dois dias C, três dias D.
 +
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Aula 16 - 27/11/2014. Threads e Tratamento de Excessões}}
 +
 +
 +
[[Media:ExemplosThreads-POO2014-2.zip | Código com exemplo de Threads]]
 +
 +
[[Media:SlidesProfEmersonPOO2014-2.pdf |  Slides Professor Emerson Ribeiro]]
 +
 +
[[Media:ExemploBarbearia-POO-2014-2.zip |  Exemplo Barbearia]]
 +
 +
 +
Exercícios:
 +
 +
Imagine um Sistema Consumidor/Fornecedor.
 +
 +
O fornecedor irá inserir informações em um período de tempo determinado.
 +
 +
O consumidor recuperará os dados em um período pré estabelecido.
 +
 +
Imagine três threads, uma sendo a principal (main), as outras duas o consumidor e fornecedor.
 +
 +
A thread principal conterá a estrutura de dados utilizada para armazenar as informações, vamos supor notícias.
 +
 +
A estrutura de dados será manipulada pelo(s) fornecedor(es) e consumidor(es).
 +
É necessário os métodos gets e sets.
 +
 +
 +
 +
Obs.:
 +
O fornecedor inserirá um dado a cada 2,7", pesquise por: Thread.sleep();.
 +
Deve-se informar qual dado está sendo inserido (utilize um método randômico e insira caracteres aleatórios ou frases).
 +
 +
O consumidor recuperará um dado no período de 1,2".
 +
Ao recuperar o dado mostre-o na tela e remova.
 +
 +
 +
Após implementado e funcionando teste da seguinte forma, C -> Consumidor e F -> Fornecedor,
 +
4 F - 3 C, significa 4 threads para o fornecedor e 3 para o consumidor.
 +
 +
1 F - 1 C
 +
2 F - 2 C
 +
4 F - 3 C
 +
8 F - 4 C
 +
16 F - 5 C
 +
 +
 +
Necessário tratar concorrência.
 +
 +
Informar ocorrência de excessões.
 +
 +
 +
Pesquisar:
 +
 +
Thread Interference - Interferência entre threads.
 +
Memory Consistency Errors - Erros de consistência em memória.
 +
Synchronized Methods - Métodos sincronizados.
 +
 +
Leitura complementar:
 +
 +
http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
 +
 +
 +
{{collapse bottom}}
 +
 +
{{collapse top | Prova Recuperação - 11/12/2014. Prova recuperação.}}
 +
 +
[[Media:ExecStringPOO-2014-2.zip | String.zip]]
  
 
{{collapse bottom}}
 
{{collapse bottom}}
Linha 245: Linha 614:
  
 
* [[Media:CST-POO-2014-2-ProjetosAte06.zip| Projetos Até Aula 6]]
 
* [[Media:CST-POO-2014-2-ProjetosAte06.zip| Projetos Até Aula 6]]
 +
 +
* [[Media:CST-POO-2014-2-Heranca.zip| Herança e Estrutura HashMap]]
  
 
=Links Úteis=
 
=Links Úteis=
 
[http://www.sj.ifsc.edu.br/~mello/livros/java/ Apostila Caleum e outros]
 
[http://www.sj.ifsc.edu.br/~mello/livros/java/ Apostila Caleum e outros]
 +
 +
 +
 +
=Exemplos de Código =
 +
 +
 +
private static HashMap<Integer, Cliente> mC = new HashMap<>();
 +
 +
 +
 +
public static void removeElemento(int key){
 +
        mC.remove(key);
 +
}
 +
 +
public static void showAll() {
 +
        //Listar todos elementos de um mapa, note a utilização da
 +
        //variável key.
 +
        for (Integer key : mC.keySet()) {
 +
            System.out.print("ID: "
 +
                    + key);
 +
            System.out.print("\tNome: "
 +
                    + mC.get(key).getPessoa().getNome());
 +
            System.out.print("\tCPF: "
 +
                    + mC.get(key).getPessoa().getCPF());
 +
            System.out.println("\tStatus: "
 +
                    + mC.get(key).getStatus());
 +
        }
 +
}
 +
 +
 +
public static String verificaExistencia(String inNome) {
 +
        //Busca pela existência de um elemento.
 +
        //Essa busca foi feita pelo nome, mas poderia ser por outro tipo.
 +
        //Retorna na primeira ocorrência...
 +
        for (Integer key : mC.keySet()) {
 +
            if (mC.get(key).getPessoa().getNome().equalsIgnoreCase(inNome)) {
 +
                return "Sim";
 +
            }
 +
           
 +
        }
 +
        return "Não";
 +
}

Edição atual tal como às 20h55min de 10 de dezembro de 2014

Diário de aulas

Aula 1 - 30/07/14: Apresentação da disciplina e Introdução ao Java
  1. Introdução ao Java
    1. Surgimento
Aula 2 - 31/07/14: Introdução ao Ambiente de Desenvolvimento Integrado - IDE
Aula 3 - 06/08/14: Revisão dos conceitos: classes, métodos e atributos
Aula 4 - 07/08/14: Revisão portas lógicas, estruturas de controle, repetição e vetores.
  1. Revisão
    1. Revisão Portas .E. e .OU.
    2. Revisão Estruturas de Controle (if e switch).
    3. Revisão Estruturas de Repetição (for e while).
    4. Revisão Vetores.


Aula 5 - 13/08/14: Revisão exercícios.

Media:AulaRevisao.pdf

Aula 6 - 14/08/14: Sobre carga de métodos e palavras reservadas: this, static e final.

Slides aula 6

Aula 7 - 20 e 21/08/14: Trabalho


Trabalho para fazer:

Pense em um problema para resolver utilizando os conceitos aprendidos em sala de aula. O problema deve ser simples, uma calculadora, um relógio, um carro, qualquer coisa.

Para resolução deve-se seguir os seguintes passos.

Quantidade mínima de atributos: 4-8 sendo que é necessário um vetor[]. Para o atributo vetor é necessário poder (adicionar, remover, listar e verificar existência).

Pense em atributos estáticos (static) e normais quando e porque usar.

Utilize sempre que possível this para referenciar variáveis locais a classe.

Quantidade mínima de métodos:

Construtor padrão e construtor modificado.
3 - Métodos para recuperar informação (usar getNomeDoMetodo()).
3 - Métodos para definir informações (usar setNomeDoMetodo(parâmetros)). 

UML:

Desenhar o diagrama de classes.

Entrega: A definir.

  • obs: utilizar exemplos diferentes dos aprendidos em sala

Programas:

Utilizar o seguinte programa para geração do diagrama de classe.
http://www.genmymodel.com/
Aula 8 - 28/08/14: Estrutura de dados HashMap<Integer, Classe>

Baixar projeto e descompactar.

Abrir com o NetBeans.

Analisar o arquivo Main.java do pacote herancaAgregacao


Projeto Até Aula 8

Aula 9 - 11/09/14: Composição, Agregação, Variáveis Primitivas e Escopo de Variáveis

Variáveis Primitivas, Escopo de Variáveis e Operadoes.

Agregação e Composição.


Aula 10 - 17/09/14: A classe Serializable. Leitura e Escrita em arquivos
Utilize uma das classes que aprendemos, e tente transformá-la para serializable. 
As classes podem sem: Motor, Bicicleta, Triângulo, Calculadora, etc...
Após isso, salve o objeto em um arquivo e recupere as informações, faça uma chamada a algum método.


Slides Aula java.io.Serializable.


Para Exercício 2 (ver slides):

public static void main(String[] args) {
       Principal2 p = new Principal2();
       System.out.println("Chamando salvarEmDisco.");
       p.salvarEmDisco();
       System.out.println("Chamando lerDoDisco.");
       p.lerDoDisco();
}
Aula 11 - 18/09/14: Sockets.
  1. Lembrar de definir o diretório de trabalho no NetBeans;
  2. Lembrar de criar o arquivo socketData.txt dentro do diretório de trabalho.

Projeto Servidor.

Slides Aula Cliente Servidor.

Aula 12 - 24/09/14: Sockets, Servidor de eco.

Baixe o servidor e cliente de eco. Crie um projeto no NetBeans com o nome ecoServer. Insira os dois .java dentro da pasta src. Leia a descrição do código abaixo, entenda e modifique conforme o necessário.

 Servidor e Clientes de Eco  


Vamos entender o código do CLIENTE.

Declara a criação de um novo socket e dá o nome de echoSocket. O construtor do socket necessita que passe como parâmetro o hostName e número da porta.

Socket echoSocket = new Socket(hostName, portNumber);

Obtém a saída do socket e abre um canal de escrita (PrintWriter).

PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);

Inverso do anterior, obtém a entrada do socket e abre um canal de leitura (BufferedReader)

BufferedReader in = new BufferedReader( new InputStreamReader(echoSocket.getInputStream()));

Para enviar dados através do socket, usa-se o PrintWriter. Para obter a resposta do servidor de eco, usa-se BufferedReader.

BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in))

A próxima parte interessante é o laço (while). O laço lê uma linha por vez do fluxo de entrada padrão do usuário (teclado) e imediatamente envia para o servidor. Para isso escreve-se no PrintWriter conectado ao socket, a saber out.println(userInput);.

String userInput;
while ((userInput = stdIn.readLine()) != null) {
   out.println(userInput);
   System.out.println("echo: " + in.readLine());
}


Passos necessários:

# 1 Abrir o socket.
# 2 Abrir o fluxo de entrada e saída do socket.
# 3 Ler de e Escrever para no fluxo conforme o protocolo utilizado.
# 4 Fechar o fluxo.
# 5 Fechar o socket.

Vamos entender o código do SERVIDOR.

ServerSocket inicia tentativa de escutar a porta definida, caso não seja possível uma excessão é lançada (ex.: caso a porta já esteja em uso).

ServerSocket serverSocket = new ServerSocket(portNumber);

É preciso alterar o código do servidor para que int portNumber = Integer.parseInt(args[0]); Ou seja definido estaticamente, ou através do argumento (args[0]) como está. Se não quiser fazer alterações use: java echoServer 5000

Se o servidor conseguiu fazer a ligação com a porta definida, o objeto do servidor (ServerSocket) é criado com sucesso e o servidor continua no próximo passo. Que é aceitar a conexão com o cliente. O método serverSocket.accept() vai esperar até que uma conexão seja estabelecida (somente uma).

Socket clientSocket = serverSocket.accept();

Os métodos PrintWriter e BufferedReader seguem a mesma lógica de PrintWriter e BufferedReader do cliente.

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream()));

O laço while, retorna ao cliente todos dados recebidos.


Como a comunicação acontece:

POO-20142-IMGClienteServerEcho.png

Para testar:

Compile os códigos.

Execute o servidor usando: java EchoServer <port number>

Execute o cliente usando: java EchoClient <host name> <port number>

Ou Execute $telnet localhost 5000 onde 5000 é a porta definida na criação do servidor.

Para verificar utilize: $ netstat -na|head -n 20 e verifique se a porta que você endereçou está aberta. Para filtrar de forma mais refinada utilize: netstat -na|grep :<portNumber> onde <portNumbe> deve ser substituido pela porta utilizada.

Lembrando que a porta deve ser a mesma.

Logo após executar o cliente digite algo e pressione enter.

Se você recebeu de volta o que escreveu, está ok.

Faça as atividades.

Atividades:

Lembrando da aula de escrita e leitura de arquivos:

Faça com que cada mensagem enviada pelo cliente de eco seja salva em disco (no servidor).

Faça com que a mensagem seja salva no servidor em um arquivo chamado reqEco.txt.


Possível Solução, verifique através do arquivo:

 Projeto Servidor, possível Solução.

Ou altere o código do servidor, o método while:

String inputLine;
           while ((inputLine = in.readLine()) != null) {
               out.println(inputLine);
               try {
                   OutputStream os = new FileOutputStream("meusDados.txt");
                   OutputStreamWriter osw = new OutputStreamWriter(os);
                   BufferedWriter bw = new BufferedWriter(osw);
                   bw.write("Info: " + inputLine);
                   bw.close();
               } catch (IOException ex) {
                   System.err.println("erro: " + ex.toString());
               }
               out.println("Informação Salva!");
               System.out.println("Informação: "+inputLine+ " salva!");
           }


Se a versão do Java for menor que 1.7 ocorrerá incompatibilidade. Para resolver, faça o downgrade do código. Utilize o try sem os ();

Dessa forma:

try { ... } 
catch () { ... }

Ao invés de:

try ( ... ) { ... } 
catch () { ... }
           


Aula 13 - 25/09/14, 01/10/2014: Sockets, Servidor de eco, continuação.
Pré-requisito: Ler, fazer e entender aulas 10 e 12.

Modificações no servidor.

1

Faça com que ao digitar "quit" ou "exit" a conexão e o servidor sejam fechados. 
Faça o tratamento das palavras reservadas quit e exit, para que as mesmas não sejam salvas.

Possível solução para a modificação 1:

Tratamento para não salvar palavras reservadas (quit, exit...)

if(!inputLine.equalsIgnoreCase("quit") 
   && !inputLine.equalsIgnoreCase("exit") 
   && !inputLine.equalsIgnoreCase("saveData")                        
   && !inputLine.equalsIgnoreCase("cleanData") 
   && !inputLine.equalsIgnoreCase("showData") ){
   buffer[i++] = inputLine.toString();
   System.out.println("Bufferizando: \""+inputLine.toString()+ "\"");
}

Tratamento para término do servidor.

if(inputLine.equalsIgnoreCase("exit") || 
   inputLine.equalsIgnoreCase("quit")){
   System.exit(0);
}




2

Transforme em um método privado a parte que faz a gravação dos dados dentro do while (servidor).
O método deve retornar um boolean informando se a gravação foi efetuada com sucesso.
Verifique o método FileOutputStream() para ver se é possível salvar concatenando o arquivo
ao invés de apagar como está sendo feito.  


Possível solução para a modificação 2:

Método privado para salvar dados no disco. Esse método deve estar na mesma classe do servidor. Perceba que o método recebe dois parâmetros, o primeiro consiste do dado a ser salvo, e o segundo onde deve ser salvo.

O método deve ser chamado da seguinte forma:

salvaDadoNoDisco(buffer[x], "arquivo.txt");

Sendo que buffer[x] é o elemento do vetor que contém a informação a ser salva. O segundo parâmetro "arquivo.txt" contém o nome do arquivo onde deve ser salvo o dado.

private static boolean salvaDadoNoDisco(String inputLine, String file) {
   try {
       OutputStream os = new FileOutputStream(file, true);
       OutputStreamWriter osw = new OutputStreamWriter(os);
       BufferedWriter bw = new BufferedWriter(osw);
       bw.write("\n" + inputLine.toString());
       bw.close();
       return true;
   } catch (IOException ex) {
       System.err.println("erro: " + ex.toString());
       return false;
   }
}




3

Crie um vetor chamado "buffer" com 4 posições. 
Nele devem ser armazenadas as informações que o cliente enviar por telnet (somente as válidas, ou seja, não salvar as palavras reservadas nem dados vazios). 
Quando o cliente enviar o comando "SaveData" os dados contidos no buffer devem ser salvos em disco.
Quando o buffer encher, deve-se salvar automaticamente os dados em disco. 
Obs.: somente os valores devem ser salvos em disco.

4

Para os apaixonados que terminaram a etapa anterior, adicione a palavra reservada "showData".
O cliente ao digitar "showData", todas as informações contidas no arquivo devem ser retornadas ao cliente. 

5

Finalizando, adicione a palavra reservada "cleanData", quando o servidor receber o comando
"cleanData" o conteúdo do arquivo meusDados.txt deve ser apagado. 

Aula 14 - 02/10/2014: Classe java.lang.String.

É necessário ler a apostila ou outras fontes para resolução.

Baixe o arquivo abaixo, crie um projeto no NetBeans e resolva o que está comentado.

Exercício manipulação de String

Obs.: o exercício está comentado dentro do código java. Abra e veja.

Coloquei aqui numerado:

   #1 Separe os nomes da frase f1 utilizando o caracter : como separador
   e mostre os valores separados.
   #2 Substitua na frase f2 a palavra Java por C++    
   #3 Verifique na frase f2 se existe a palavra Java
   #4 Verifique na frase f2 se existe a palavra C++
   #5 Verifique se a frase f3 inicia com Meu pé
   #6 Verifique se a frase f3 inicia com Me
   #7 Verifique se a frase f3 termina com lima.
   #8 Verifique se a frase f3 termina com ma.    
   #9 Faça com que a frase f4 fique com todas as palavras em maiúsculas.    
   #10 Faça com que a frase f5 fique com todas as palavras em minúsculas.    
   #11 Retornar o valor ASCII de cada elemento do vetor ascii
   #12 Verificar igualdade da frase f6, respeitando maiúsculas e minúsculas (utilizar a palavra João)
   #13 e sem respeitar maiúsculas e minúsculas (utilizar a palavra João)
Aula 15 - 22/10/2014: Servidor Eco + Cliente + Interação Servidor-Servidor.

Após terminar o servidor de eco

1 - Quando o usuário entrar com o comando "saveData localSalvar.txt" as informações no buffer devem ser salvas no segundo parâmetro do comando saveData. Caso contrário devem ser salvar no local padrão.

2 - Utilização do cliente. O cliente deve interpretar os comandos: "ExportFile nomeDoArquivo.txt" Quando o cliente entrar com o comando "ExportFile nomeDoArquivo.txt" o cliente deve buscar localmente pelo arquivo, ler todo seu conteúdo e posteriormente enviar todas informações para o servidor. As informações deve ser repassadas para o servidor utilizando o mesmo nome.


Prova 2 - 29/10/2014. Com possível solução e código dos alunos.


EcoServer para usar na prova



Trabalho 1 - 05/11/2014. Abstração Locadora de filmes

Pense em uma abstração para uma locadora de filmes.

Deve ser possível armazenar informações a respeito dos clientes, funcionários e filmes.

Uma vez inseridas as informações essas devem perdurar, ou seja, não devem ser perdidas.

Os dados salvos pela aplicação devem estar sob a pasta "dataBase".

Desenhar o Diagrama de classes, as classes devem conter nomes no singular.


Sobre Inserção dos Dados:

Deve-se poder inserir as informações a respeito dos clientes, funcionários e filmes. 
Pode-se utilizar a classe scanner ou outra para fazer a captura dos dados. 
Os métodos para captura dos dados do cliente, dos funcionário e filmes, 
devem estar em uma única classe. 
Você pode pensar em uma classe única chamada CapturaDados.


Sobre padronização para entrega:

Colocar o diagrama de classes em um arquivo PDF contendo: Nome completo, curso e data.
Colocar o projeto em um arquivo ZIP junto com o arquivo PDF.
O nome dos arquivos devem ser no formato: seuNome-seuSobreNome.zip e seuNome-seuSobreNome.pdf.
Dentro do ZIP deve conter somente os arquivos .java e .pdf salvo excessão abaixo.
Caso alguma informação seja necessária para a execução / configuração, a mesma deve estar contida em um arquivo chamado Leiame.txt dentro do arquivo seuNome-seuSobreNome.zip.


Sobre Entrega:

Data: 06/11/2014 - Final da aula. 
# Entregou no prazo A, um dia de atraso B, dois dias C, três dias D. 

Critérios de avaliação:

# Diagrama de classes.
# Seguiu as especificações definidas A, deixou uma B, duas C, três D.
# Codificação correta das classes. 
# Gravação dos objetos.
# Leitura dos objetos.
# Execução de todas funcionalidades A, deixou uma B, duas C, três D.


Sobre as funcionalidades:

# Inserção dos dados dos clientes. 
# Inserção dos dados dos funcionários. 
# Inserção dos dados dos filmes. 
# Gravação das informações dos clientes em disco. 
# Gravação das informações dos funcionários em disco. 
# Gravação das informações dos filmes em disco. 
# Quando o programa iniciar, as informações salvas devem ser recuperadas e impressas na tela.



OBS.: Vejam como funciona a estrutura de dados Map, hashMap e similares.


Trabalho Final - Início: 13/11/2014, Entrega: 04/12/2014. Abstração Locadora de Filmes

O trabalho final é continuação do trabalho 1, sendo assim, todas funcionalidades e características do trabalho 1 devem ser mantidas, salvo especificação contrária.


Funcionalidades:

# Inserção / Remoção / Atualização dos dados dos clientes. 
# Inserção / Remoção / Atualização dos dados dos funcionários. 
# Inserção / Remoção / Atualização dos dados dos filmes. 
# Gravação das informações dos clientes em disco. 
# Gravação das informações dos funcionários em disco. 
# Gravação das informações dos filmes em disco. 
# Busca por nome de cliente, funcionário ou título de filmes. 
# Listagem por categoria (filme, cliente, funcionário).
# Quando o programa iniciar uma tela/texto com opções deve aparecer para o cliente.
# Deve ser possível efetuar / devolver uma locação.
# Deve ser possível listar as locações sem pendência e com pendência.


Sobre Entrega:

Data: 04/12/2014 - até 12:00. 
# Entregou no prazo A, um dia de atraso B, dois dias C, três dias D. 


Aula 16 - 27/11/2014. Threads e Tratamento de Excessões


Código com exemplo de Threads

Slides Professor Emerson Ribeiro

Exemplo Barbearia


Exercícios:

Imagine um Sistema Consumidor/Fornecedor.

O fornecedor irá inserir informações em um período de tempo determinado.

O consumidor recuperará os dados em um período pré estabelecido.

Imagine três threads, uma sendo a principal (main), as outras duas o consumidor e fornecedor.

A thread principal conterá a estrutura de dados utilizada para armazenar as informações, vamos supor notícias.

A estrutura de dados será manipulada pelo(s) fornecedor(es) e consumidor(es). É necessário os métodos gets e sets.


Obs.:

O fornecedor inserirá um dado a cada 2,7", pesquise por: Thread.sleep();.
Deve-se informar qual dado está sendo inserido (utilize um método randômico e insira caracteres aleatórios ou frases).
O consumidor recuperará um dado no período de 1,2".
Ao recuperar o dado mostre-o na tela e remova.


Após implementado e funcionando teste da seguinte forma, C -> Consumidor e F -> Fornecedor, 4 F - 3 C, significa 4 threads para o fornecedor e 3 para o consumidor.

1 F - 1 C
2 F - 2 C
4 F - 3 C
8 F - 4 C
16 F - 5 C


Necessário tratar concorrência.

Informar ocorrência de excessões.


Pesquisar:

Thread Interference - Interferência entre threads. 
Memory Consistency Errors - Erros de consistência em memória.
Synchronized Methods - Métodos sincronizados.

Leitura complementar:

http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html


Prova Recuperação - 11/12/2014. Prova recuperação.

String.zip

Projetos

Para carregar os projetos abaixo, primeiramente você deve baixar e descompactar o arquivo .zip.

Logo após descompactar você entre no NetBeans e siga os passos:

Arquivo -> Abrir Projeto -> e vá até onde você descompactou o arquivo.zip e clique em cima duas vezes.

Pronto, seu projeto é para ter sido importado.


Links Úteis

Apostila Caleum e outros


Exemplos de Código

private static HashMap<Integer, Cliente> mC = new HashMap<>();


public static void removeElemento(int key){
       mC.remove(key);
}
public static void showAll() {
       //Listar todos elementos de um mapa, note a utilização da
       //variável key.
       for (Integer key : mC.keySet()) {
           System.out.print("ID: "
                   + key);
           System.out.print("\tNome: "
                   + mC.get(key).getPessoa().getNome());
           System.out.print("\tCPF: "
                   + mC.get(key).getPessoa().getCPF());
           System.out.println("\tStatus: "
                   + mC.get(key).getStatus());
       }
}

public static String verificaExistencia(String inNome) {
       //Busca pela existência de um elemento. 
       //Essa busca foi feita pelo nome, mas poderia ser por outro tipo.
       //Retorna na primeira ocorrência... 
       for (Integer key : mC.keySet()) {
           if (mC.get(key).getPessoa().getNome().equalsIgnoreCase(inNome)) {
               return "Sim";
           }
           
       }
       return "Não";
}