terça-feira, 24 de agosto de 2010

Enviando Objetos via Socket

Antes de tudo, para enviar Objetos via socket para um Client/Servidor, precisamos SERIALIZAR o objeto a ser enviado. Conseguimos enviar uma String (que é um objeto) porque ela implementa Serializable em sua classe.
Se tiver um objeto próprio, implemente Serializable. Agora se tiver uma classe específica que baixou de algum lugar, como por exemplo org.jdom.Document ( jdom são classes para manipular  xml´s), podemos criar uma classe qualquer implementando Serializable somente para receber esse objeto.
Por exemplo:
import org.jdom.Document;

public class SerializeiDocument implements Serializable{

private static final long serialVersionUID = 1L;
private Document doc;

public Document getDoc() {
    return doc;
}

public void setDoc( Document doc ){
   this.doc = doc; 
}

}
Fazendo isso você já possui uma classe serializada que guarda uma instância do objeto que deseja enviar.

SerializeiDocument  doc = ( SerializeiDocument ) objInputStream.readObject() ;


A classe criada deve conter a mesma estrutura de package tanto no servidor, como no cliente.

Por fim, vamos enviar o objeto de um Cliente para um Servidor...

Classe jars.client.Cliente
import util.SerializeiDocument;
//outros imports...

public class Cliente {

Socket client = null;

ObjectOutputStream oos = null;
SerializeiDocument serialDoc;

public Client(){
    try{
    client = new Socket ( HOST, PORTA );
    oos = new ObjectOutputStream( client.getOutputStream() );
    //Supondo que serialDoc já esteja setado...
    oos.writeObject( serialDoc );
    oos.flush();
    }catch( Exception e ){ }
    finally{ 
        oos.close(); 
        client.close();
    }
}
Classe jars.server.Servidor
import utils.SerializeiDocument;
//outros imports...

public class Servidor {

     ServerSocket server;
     Socket client;

public void go(){
  try{
    server = new SocketServer( PORTA );
    client = server.accept();
    ObjectInputStream ois = new ObjectInputStream( client.getInputStream() );
    SerializeiDocumet sdoc = (SerializeiDocument) ois.readObject();
    //Pronto... sdoc está pronto para ser usado no servidor...
    }catch( Exception e ){}
    finally{ 
      ois.close();
      client.close();
   }
 }
}

terça-feira, 10 de agosto de 2010

Listar e matar processos de Java

Para listarmos os processos que estão executando em Java pelo nome do processo, usamos o comando JPS. Experimente no console digitar 'jps', exibirá a lista dos processos em java com o número do processo (PID) e o nome da Classe.

Abaixo crio uma classe que listará os processos ativos e pegaremos um determinado processo para finaliza-lo.

public void mataProcesso(){

try{
   //Executa comando que lista todos os processos ativos de java
   Process p = Runtime.getRuntime().exec("jps");

   //Ler lista de processos
   InputStream is = p.getInputStream();
   InputStreamReader readerInput = new InputStreamReader( is ) ;
   BufferedReader reader = new BufferedReader( readerInput ); 

   String linha = "";
   //Enquanto linha não for nula, exibe linha
   while ( ( linha = reader.readLine() ) != null ){

      //Se existir o processo abaixo, divide a String em 2, PID e NomeProcesso.
      //nomeDoProcesso é o nome do processo que  mataremos. 
      if ( linha.contains("nomeDoProcesso")){

      String[] getPID = linha.split(" ");
 
      System.out.println("PID: "+ getPID[0]);
      System.out.println("Process name: "+ getPID[1]);

      //Mata Processo pelo pid
      Runtime.getRuntime().exec("taskkill /f /pid "+getPID[0] );
      }
   }
}catch(Exception e){
   e.printStackTrace();
}

Um exemplo de saída dos processos (Meus processos ativos que estavam rodando no momento da execução) :

652 Jps
2164 jMentor
2444 Bootstrap
3428

sexta-feira, 6 de agosto de 2010

Graficos dinâmicos para web com Cewolf

Cewolf é um framework para desenvolvimento de gráficos para web jsp/servlet utilizando o padrão MVC. Temos uma classe para gerar os dados do gráfico e um arquivo jsp para exibição do mesmo. Neste tutorial utilizarei o gráficos do tipo ‘timeseries’.
Primeiro é necessário baixar os arquivos e colocá-los no classpath do projeto:
http://cewolf.sourceforge.net/new/index.html

Copie também os arquivos TLD do cewolf para a pasta WEB-INF.
Neste exemplo, a metodologia aplicada foi a seguinte:


Tenho um servlet que pega vários dados de outra página e com alguns desses dados, chamo o construtor da classe que gera os dados do gráfico (passando os dados que você quiser pelo construtor). A Classe trata os dados do gráfico e retorna um Dataset que será lido pelas tags do cewolf no jsp.

Vamos ao que interessa... Após alocado os jars no seu projeto, devemos configurar o web.xml conforme abaixo:

web.xml
<servlet>

<servlet-name>CewolfServlet</servlet-name> 

<servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>CewolfServlet</servlet-name>

<url-pattern>/cewolf/*</url-pattern>

</servlet-mapping>

Uma vez configurado, criemos a classe de dados do gráfico...

Dataset.java
import java.io.Serializable;
import java.util.Date;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.jfree.data.category.CategoryDataset;
import org.jfree.data.time.Minute;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

import de.laures.cewolf.DatasetProduceException;
import de.laures.cewolf.DatasetProducer;

import de.laures.cewolf.links.CategoryItemLinkGenerator;
import de.laures.cewolf.tooltips.CategoryToolTipGenerator;

//Devemos implementar todos estas interfaces... 
public class Dataset implements DatasetProducer, CategoryToolTipGenerator, CategoryItemLinkGenerator, Serializable {

//A serie do gráfico é em TimeSeries
private TimeSeries series;

//Construtor que recebe como argumento um objeto vindo do servlet
//Para gráficos dinâmicos criei este construtor. O objeto passado pode ser o que quiser.
//No caso passei uma lista de um objeto com diversos valores de horas e dadas
public Dataset( List<MeuObjeto> listaDados  ){

// Instancia uma nova serie. O argumento é o nome da série
series = new TimeSeries( "nomeQueQuiserParaSerie" );


// Note que criamos UMA série apenas (acima), pois o gráfico só terá uma linha (série) de exibição. 
// Se quisermos mais linhas (séries), basta criarmos novos TimeSeries. 
// Ex. TimeSeries serie1 = new TimeSerie( "nomeDaSerie1" );
// Ex. TimeSeries serie2 = new TimeSerie( "nomeDaSerie2" );

// Percorre cada objeto da lista e adiciona os dados na série
for( MeuObjeto d : listaDados ){


//Adicionamos os dados do objeto na série 
series.add( new Minute( d.getMinuto(), d.getHora(), d.getDia(), d.getMes(), d.getAno(), d.getValor() ); 

// O Método acima "series.add( )" possui dois argumentos, um com RegularTimePeriod e outro com o valor *da série. 
//O RegularTimePeriod pode ser um "new Day(), new Hour(), new Minute(), etc" basta saber que 
//tipo de dados vai usa. Para saber mais acesse a API da classe RegularTimePeriod (jogue o nome no *google)

}
}

//Este é o método mais importante. Aqui é gerado o objeto Dataset para o jsp montar o grafico
public Object produceDataset(Map arg0) throws DatasetProduceException {

//TimeSeriesCollection é onde armazenamos todas as séries do nosso grafico.
//Todo tipo de gráfico, seja ele pizza, barra, etc, possui um dataset específico.
TimeSeriesCollection dataset = new TimeSeriesCollection();

dataset.addSeries( series );
return dataset;
}

private static final Log log = LogFactory.getLog(Dataset.class);


//Não utilizei este método
public String getProducerId() {
// TODO Auto-generated method stub
return null;
}

//Este método é apenas atualizar o gráfico a cada intervalo de X milisegundos
//No exemplo, utlizei 5 segundos (5000 milli)
public boolean hasExpired(Map arg0, Date since) {

log.debug(getClass().getName() + "hasExpired()");
return (System.currentTimeMillis() - since.getTime()) > 5000;

}

//Não utilizei este método

public String generateToolTip(CategoryDataset arg0, int arg1, int arg2) {

// TODO Auto-generated method stub
return null;
}

//Não utilizei este método

public String generateLink(Object arg0, int arg1, Object arg2) {
// TODO Auto-generated method stub
return null;
}
}

Construida a classe Dataset, chamaremos a jsp que exibira o gráfico. O código abaixo pode ser
inserido em qualquer parte da sua página.

exibeGrafico.jsp

<cewolf:chart id="line" title="Titulo do Grafico" type="timeseries" xaxislabel="Período" yaxislabel="Valor">

<cewolf:data> 

<cewolf:producer id="grafico"/> 

</cewolf:data>

</cewolf:chart>

<p>

<cewolf:img chartid="line" renderer="/cewolf" width="589" height="189"/> 


Agora exibirei a chamado que utlizei para exibir o gráfico.
Na minha servlet, em um determinado momento do código após tratar os dados chamo a classe Dataset ...

Servlet.java

//Códigos de servlet aqui...
//Mais alguns códigos aqui.... 

List<MeuObjeto> listaDados = // Aqui contém a lista de dados do objeto que quero passar...
Dataset dadosGrafico= new Dataset( listaDados );

//Envio para a jsp que vai exibir o gráfico o objeto dadosGrafico, onde dentro dele 
//possui o método que retorna um dataset já criado com os dados que o cewolf precisa.
request.setAttribute("grafico", dadosGrafico );
//Envio todos os objetos do request.setAttribute para a jsp /exibeGrafico.jsp....
RequestDispatcher dispatcher= request.getRequestDispatcher("/exibeGrafico.jsp");

dispatcher.forward( request, response );

Pronto.

sexta-feira, 7 de maio de 2010

Configurando JSF 1.2 + Tomahawk (Parte 2)

Seguindo com o tutorial de como Configurar o JSF 1.2 + Tomahawk:

Arquivo WEB.XML
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"
version="2.5">

<servlet>

<servlet-name>Faces Servlet</servlet-name>

<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>Faces Servlet</servlet-name>

<url-pattern>*.jsf</url-pattern>

</servlet-mapping>

<filter>

<filter-name>MyFacesExtensionsFilter</filter-name>

<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>

<init-param>

<param-name>uploadMaxFileSize</param-name>

<param-value>20m</param-value>

</init-param>

</filter>

<!-- extension mapping for adding <script/>, <link/>, and other 
resource tags to JSF-pages -->

<filter-mapping>

<filter-name>MyFacesExtensionsFilter</filter-name>

<!-- servlet-name must match the name of your
 javax.faces.webapp.FacesServlet entry -->

<servlet-name>Faces Servlet</servlet-name>

</filter-mapping>

<!-- extension mapping for serving page-independent resources
 (javascript, stylesheets, images, etc.) -->

<filter-mapping>

<filter-name>MyFacesExtensionsFilter</filter-name>

<url-pattern>/faces/myFacesExtensionResource/*</url-pattern>

</filter-mapping>

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

<welcome-file>index.html</welcome-file>

</welcome-file-list>

</web-app>
Notas do arquivo WEB.XML
A linha 19 é a extensão das páginas que serão chamadas. Você pode estar alterando isto. Neste modelo, você chamará as paginas com jsf com a extensão .jsf (ex. http://localhost:8080/MeuProjeto/ola.jsf)

Da linha 23 até a linha 59, são os Filtros de extensão (não são necessárias essas linhas caso use JSF puro, elas são necessárias para o uso do Tomahawk). Tive bastante problema com isso... não conseguia rodar minha aplicação, depois verifiquei no site http://myfaces.apache.org/tomahawk/extensionsFilter.html a necessidade dessa configuração no WEB.XML para o Tomahawk.

Inicie o servidor e pronto!

Configurando JSF 1.2 + Tomahawk (Parte 1)


Ambiente utilizado:
Eclipse Galileo
Tomcat v6.0 - ( A versão 5.5 do Tomcat foi inconsistente com JSF versão 1.2 )

Os downloads dos JARS necessários: (versão 1.2 do jsf)

Baixar arquivo mojarra-1.2_14-binary (Que são os jars do JSF)
https://javaserverfaces.dev.java.net/
Extraindo os arquivos deste, vá na pasta LIB e copie os jars: jsf-api.jar e jsf-impl.jar, para pasta WEB-INF/LIB do seu projeto.

Baixar arquivo myfaces-core-1.2.8-bin (Que são os 'commons')
http://www.apache.org/dyn/closer.cgi/myfaces/binaries/myfaces-core-1.2.8-bin.zip
Extraindo os arquivos deste, vá na pasta LIB e copie os 8 jars:
commons-beanutils-1.7.0
commons-codec-1.3
commons-collections-3.2
commons-digester-1.8
commons-discovery-0.4
commons-logging-1.1.1
myfaces-api-1.2.8
myfaces-impl-1.2.8
Para pasta WEB-INF/LIB do seu projeto.

Baixar a JSTL v1.2 copiar suas duas libs ( jstl-api-1.2.jar e jstl-impl-1.2 ) para WEB-INF/LIB do seu projeto

Baixar tomahawk12-1.1.9-bin no site (Atenção que é o Tomahawk para JSF 1.2!)
http://www.apache.org/dyn/closer.cgi/myfaces/binaries/tomahawk12-1.1.9-bin.tar.gz
Extraindo os arquivos deste, vá na pasta LIB e copie o jar tomahawk12-1.1.9, para pasta WEB-INF/LIB do seu projeto.

Baixar commons-fileupload-1.2.1-bin no site
http://commons.apache.org/fileupload/download_fileupload.cgi
Extraindo os arquivos deste, vá na pasta LIB e copie apenas o jar commons-fileupload-1.2.1, para pasta WEB-INF/LIB do seu projeto.

Baixar commons-lang-2.5-bin.tar no site
http://commons.apache.org/lang/download_lang.cgi
Extraindo os arquivos deste, copie apenas o jar commons-lang-2.5, para pasta WEB-INF/LIB do seu projeto.

Na pasta lib do meu projeto então ficaram 15 jars ao todo.

Na Parte 2 segue as configurações dos arquivos WEB.XML e FACES-CONFIG.XML

quinta-feira, 15 de abril de 2010

Transformar uma String em MD5

import java.math.BigInteger;
import java.security.MessageDigest;

public String convertMd5Passwd( String passwd ){
   try{
     MessageDigest md= MessageDigest.getInstance("MD5");
     md.update( passwd.getBytes() );
     BigInteger hash= new BigInteger(1, md.digest() );
     String passwordMd5= hash.toString(16);
     return passwordMd5;
   }catch(Exception e){
     e.printStackTrace();
     return null;
   }
}

quarta-feira, 7 de abril de 2010

Configurando o autocomplete do eclipse

Para configurar o autocompletar vá em: Window - Preferences2 - Nessa janela selecione a opção: Java - Editor - Advanced3 - Marque os quatro primeiros checkboxes das duas áreas que aparecerão na tela (parte superior e inferior) e clique em OK.