quinta-feira, 16 de julho de 2015

Lendo o mesmo arquivo duas vezes

Parece fácil ler um arquivo de texto linha por linha até o fim, para validá-lo por exemplo, e depois voltar ao começo para aí sim processá-lo, mas não foi fácil encontrar a solução! Na documentação do java, eles comentam dos métodos mark e reset do Reader pra voltar a um determinado ponto marcado no arquivo, mas eles não são implementados por todos os tipos de reader e só funcionam quando o arquivo não é muito grande. Veja como você poderia fazer:


import java.io.BufferedReader;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.ParseException;
import org.apache.commons.io.IOUtils;

public class LineFileReader {
 
   private BufferedReader in;
   private byte[] bytes;
   private int lineNumber;
 
   public LineFileReader(Reader reader) throws IOException {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      IOUtils.copy(reader, baos);
      bytes = baos.toByteArray();
      in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)));  
      lineNumber = 0;
   }
 
   public final String readLine() throws IOException {
      lineNumber++;
      return in.readLine();
   }
 
   public int getLineNumber() {
      return lineNumber;
   }

   public void reset() throws ParseException {
      in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes)));
      lineNumber = 0; 
   }

   public static void main(String[] args) throws Exception {
      FileInputStream fileInputStream = new FileInputStream(new File("/home/rafael", "teste.txt"));
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
      LineFileReader reader = new LineFileReader(bufferedReader);
      String line = reader.readLine();

      while(line != null){
         System.out.println(reader.getLineNumber() + " " + line);
         line = reader.readLine();
      }

      reader.reset();

      line = reader.readLine();
      while(line != null){
         System.out.println(reader.getLineNumber() + " " + line);
         line = reader.readLine();
      }
   }
}

domingo, 29 de julho de 2012

Configurando o Maven

Abaixo seguem alguns passos necessários para configurar o Maven em sua máquina e utilizá-lo no Eclipse.


1 - Baixar o zip do maven 2.2.1 (http://maven.apache.org/download.html)
2 - Configurar a variável de ambiente JAVA_HOME (por exemplo, C:\Program Files\Java\jdk16)
3 - Configurar a variável de ambiente M2_HOME (por exemplo, C:\Program Files\apache-maven-2.2.1)
4 - No Eclipse, instalar o plugin do maven para o eclipse, conforme esse site diz: http://m2eclipse.sonatype.org/installing-m2eclipse.html
5 - Ainda no Eclilpse, em Window -> Preferences -> Maven -> Installations -> Add, adicione a instalação do maven informando a pasta em que ele foi instalado. Em Window -> Preferences -> Maven -> User Settings, coloque o local do settings.xml (por exemplo, C:\Program Files\Apache Software Foundation\apache-maven-2.2.1\conf). Verifique se a pasta do repository realmente existe (por exemplo, C:\Documents and Settings\Owner\.m2\repository)

sábado, 9 de junho de 2012

Consumindo Web Services REST

Se você precisa consumir Web Services REST que utilizam JSON na requisição e na resposta, abaixo tem um exemplo de classe completa em Java que realiza GETs e POSTs em um determinado serviço. Também utilizei os métodos de transformação em JSON que mostrei em outro post.

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.MappingJsonFactory;
import org.codehaus.jackson.map.ObjectMapper;

public class ClientWS {

   public static Object getObjeto(Class tipoObjetoRetorno, String urlWebService, String... parametros) {
      Object objetoRetorno = null;
	
      try {
         for(String parametro: parametros){
            urlWebService = urlWebService + "/" + parametro.replaceAll(" ", "%20");
         }
		
         URL url = new URL(urlWebService);
         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
         connection.setRequestMethod("GET");
         connection.setConnectTimeout(15000);
         connection.setRequestProperty("login", "teste");
         connection.setRequestProperty("senha", "teste");
         connection.connect();

         String responseJson = inputStreamToString(connection.getInputStream());
         connection.disconnect();
		
         return fromJson(responseJson, tipoObjetoRetorno);

      } catch (Exception e) {
         e.printStackTrace();
      }	
      return objetoRetorno;
   }

   public static Object postObjeto(Object objetoEnvio, Class tipoObjetoRetorno, String urlWebService) {
      Object objetoRetorno = null;
	
      try {
         String requestJson = toJson(objetoEnvio);
		
         URL url = new URL(urlWebService);
         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
         connection.setRequestMethod("POST");
         connection.setDoOutput(true);
         connection.setUseCaches(false);
	 connection.setConnectTimeout(15000);
         connection.setRequestProperty("login", "teste");
         connection.setRequestProperty("senha", "teste");
         connection.setRequestProperty("Content-Type", "application/json");
         connection.setRequestProperty("Accept", "application/json");
         connection.setRequestProperty("Content-Length", Integer.toString(requestJson.length()));
			
         DataOutputStream stream = new DataOutputStream(connection.getOutputStream());
         stream.write(requestJson.getBytes("UTF-8"));
         stream.flush();
         stream.close();
         connection.connect();

         String responseJson = inputStreamToString(connection.getInputStream());
         connection.disconnect();
         objetoRetorno = fromJson(responseJson, tipoObjetoRetorno);

      } catch (Exception e) {
         e.printStackTrace();
      }
      return objetoRetorno;
   }


   public static String inputStreamToString(InputStream is) throws IOException {
      if (is != null) {
         Writer writer = new StringWriter();

         char[] buffer = new char[1024];
         try {
            Reader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
            int n;
            while ((n = reader.read(buffer)) != -1) {
               writer.write(buffer, 0, n);
            }
         } finally {
            is.close();
         }
         return writer.toString();
      } else {
         return "";
      }
   }

   public static String toJson(Object objeto) throws Exception {
      ObjectMapper mapper = new ObjectMapper();
      StringWriter jsonValue = new StringWriter();
      mapper.writeValue(new PrintWriter(jsonValue), objeto);
      return jsonValue.toString();
   }


   public static Object fromJson(String json, Class objectClass) throws Exception {
      JsonFactory f = new MappingJsonFactory();
      JsonParser jp = f.createJsonParser(json);
      Object obj = jp.readValueAs(objectClass);
      return obj;
   }

}


Manipulação de Strings

Uma forma fácil de formatar strings em java é utilizando a classe MaskFormatter.

import javax.swing.text.MaskFormatter;

public static String formatarString(String texto, String mascara) {
    if(texto == null){
        return null;
    }
    try {
        MaskFormatter mf = new MaskFormatter(mascara);
        mf.setValueContainsLiteralCharacters(false);
        return mf.valueToString(texto);
    } catch(Exception e){
        return texto;
    }
}

public static String desformatarString(String texto, String mascara) {
    if(texto == null){
        return null;
    }
    try {
        MaskFormatter mf = new MaskFormatter(mascara);
        mf.setValueContainsLiteralCharacters(false);
        return mf.stringToValue(texto).toString();
    } catch(Exception e){
        return "";
    }
}
Um exemplo de utilização é se você precisa formatar um CNPJ. Imagine que você receba o valor do CNPJ sem pontos e traços, mas precisa mostrá-lo corretamente formatado...você poderia fazer assim:

public static void main(String[] args) {
    try{
        System.out.println(formatarString("54555499869655", "##.###.###/####-##"));
    }catch(Exception e){
        e.printStackTrace();
    }
}
Agora, se você recebe o CNPJ formatado e precisa gravá-lo no banco somente com os números, você poderia fazer:

public static void main(String[] args) {
    try{
        System.out.println(desformatarString("54.555.499/869-655", "##.###.###/####-##"));
    }catch(Exception e){
        e.printStackTrace();
    }
}
Imagine agora que você ainda precisa guardar alguma informação (sem qualquer formatação) que foi formatada mas você não sabe que formato foi utilizado. Utilize então esse método:

public static String somenteNumerosLetras(String texto) {
    if(texto == null){
        return null;
    }
    return texto.replaceAll("[^0-9a-z0-9A-Z]", "");
}
Ele retira tudo o que não for letra e número da string...fácil né!

JSON em Java

Um framework bastante conhecido para trabalhar com JSON em Java é o Jackson. Tudo que vocë precisa fazer é importar 2 jars para o seu projeto e comecar a utilizá-lo. Eles podem ser encontrados em:

http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl
http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl

Para transformar objetos comuns Java em JSON, basta fazer:

import java.io.PrintWriter;
import java.io.StringWriter;
import org.codehaus.jackson.map.ObjectMapper;

public static String toJson(Object obj) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    StringWriter jsonValue = new StringWriter();
    mapper.writeValue(new PrintWriter(jsonValue), obj);
    return jsonValue.toString();
}
Para transformar um objeto representado em JSON para um objeto em java, basta fazer:

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.MappingJsonFactory;

public static Object fromJson(String json, Class objectClass) throws Exception {
    JsonFactory f = new MappingJsonFactory();
    JsonParser jp = f.createJsonParser(json);
    Object obj = jp.readValueAs(objectClass);
    return obj;
}
Criando uma classe Pagina, teríamos o seguinte:

public class Pagina {

    private Long id;
    private int numero;

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    public int getNumero() {
        return numero;
    }
    public void setNumero(int numero) {
        this.numero = numero;
    }

    public String toString() {
        return "Pagina [" id=" + id + " ,numero=" + numero + "]";
    }
}
A representação de um objeto Pagina poderia ser:

{"numero" : 1,"id" : 1}
Agora, executando o método:

public static void main(String[] args) {
    try{
        System.out.println(fromJson("{\"numero\" : 1,\"id\" : 1}", Pagina.class));
    }catch(Exception e){
        e.printStackTrace();
    }
}
Imaginando outra situação, talvez você não tenha a classe que representa o conteúdo de determinado JSON. Nesse caso, a melhor forma é tratar o JSON como ele realmente é, ou seja, como um Mapa de String com objeto.

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

public static Map fromJson(String json) throws Exception {
   ObjectMapper jsonMapper = new ObjectMapper();
   Map meta = jsonMapper.readValue(json, new TypeReference>() { });	    		
   return meta;
}

segunda-feira, 30 de novembro de 2009

Enviando Mensagem Instatânea (MSN) com JAVA

Depois de sofrer bastante para fazer meu programa funcionar, finalmente consegui! E é realmente simples mandar uma mensagem para o MSN de alguém usando Java...

Primeiro, baixe a lib Java MSN Messenger Library (JML) em http://jml.blathersource.org/

Você precisará criar 2 classes.
Primeiro, crie a classe MSNListener, desse jeito:


import net.sf.jml.MsnContact;
import net.sf.jml.MsnMessenger;
import net.sf.jml.MsnSwitchboard;
import net.sf.jml.event.MsnAdapter;
import net.sf.jml.message.MsnControlMessage;
import net.sf.jml.message.MsnDatacastMessage;
import net.sf.jml.message.MsnInstantMessage;
import net.sf.jml.message.MsnSystemMessage;
import net.sf.jml.message.MsnUnknownMessage;

public class MsnListener extends MsnAdapter {

public void exceptionCaught(
MsnMessenger messenger,
Throwable throwable) {
}

public void loginCompleted(
MsnMessenger messenger) {
}

public void logout(
MsnMessenger messenger) {
}

public void instantMessageReceived(
MsnSwitchboard switchboard,
MsnInstantMessage message,
MsnContact friend) {
switchboard.sendMessage(message, false);
}

public void systemMessageReceived(
MsnMessenger messenger,
MsnSystemMessage message) {
}

public void controlMessageReceived(
MsnSwitchboard switchboard,
MsnControlMessage message,
MsnContact contact) {
switchboard.sendMessage(message, false);
}

public void datacastMessageReceived(
MsnSwitchboard switchboard,
MsnDatacastMessage message,
MsnContact friend) {
switchboard.sendMessage(message, false);
}

public void unknownMessageReceived(
MsnSwitchboard switchboard,
MsnUnknownMessage message,
MsnContact friend) {
}

public void contactListInitCompleted(
MsnMessenger messenger) {
}

public void contactListSyncCompleted(
MsnMessenger messenger) {
}

public void contactStatusChanged(
MsnMessenger messenger,
MsnContact friend) {
}

public void ownerStatusChanged(
MsnMessenger messenger) {
}

public void contactAddedMe(
MsnMessenger messenger,
MsnContact friend) {
}

public void contactRemovedMe(
MsnMessenger messenger,
MsnContact friend) {
}

public void switchboardClosed(
MsnSwitchboard switchboard) {
}

public void switchboardStarted(
MsnSwitchboard switchboard) {
}

public void contactJoinSwitchboard(
MsnSwitchboard switchboard,
MsnContact friend) {
}

public void contactLeaveSwitchboard(
MsnSwitchboard switchboard,
MsnContact friend) {
}

}


Agora, crie a classe MSNSender, desse jeito:


import java.util.Properties;
import net.sf.jml.Email;
import net.sf.jml.MsnMessenger;
import net.sf.jml.MsnProtocol;
import net.sf.jml.MsnUserStatus;
import net.sf.jml.impl.MsnMessengerFactory;

public class MSNSender {

private String username;
private String password;
private String proxyHost;
private String proxyPort;

public MSNSender(
String username,
String password,
String proxyHost,
String proxyPort) {

this.username = username;
this.password = password;
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;

}

public void send(
String msg,
String to) {

if (proxyHost != null && proxyHost.trim().length() > 0) {
Properties systemSettings = System.getProperties();
systemSettings.put("https.proxySet", "true");
systemSettings.put("https.proxyHost", proxyHost);
systemSettings.put("https.proxyPort", proxyPort);
systemSettings.put("http.proxySet", "true");
systemSettings.put("http.proxyHost", proxyHost);
systemSettings.put("http.proxyPort", proxyPort);
}

MsnMessenger messenger = MsnMessengerFactory.createMsnMessenger(username, password);
messenger.setSupportedProtocol(new MsnProtocol[] { MsnProtocol.MSNP11 });
messenger.getOwner().setInitStatus(MsnUserStatus.ONLINE);
messenger.setLogIncoming(false);
messenger.setLogOutgoing(true);
messenger.addListener(new MsnListener());
messenger.login();

// Tempo de espera para completar o login
try {
Thread.sleep(16000);
} catch (InterruptedException e) {
e.printStackTrace();
}

messenger.sendText(Email.parseStr(to), msg);
messenger.logout();
}

public static void main(String args[]){
MSNSender sender = new MSNSender("rafael@hotmail.com","senha","","");
sender.send("Oi! Tudo bem?", "maria@hotmail.com");
}
}