martes, 2 de febrero de 2010

Conectarse con el puerto Serie/paralelo desde Java

Bien pues para esta tarea existe una librería llamada Java Comunication API. Pero hay que tener en cuenta que para comunicarte a través de algo físico de la máquina Java nos proporciona una fachada de métodos que por debajo se conectan con diferentes drivers según si estamos corriendo el programa en un windows, macos o linux. Esto quiere decir que además de tener la máquina virtual de java instalada tendrás que instalar un driver en el sistema operativo. Yo empece a trabajar con la implementación de Sun pero me dió muchos problemas y no conseguía que me detectara los drivers instalados, así que finalmente opte por usar una implementación de Java Comunication API open source llamada RXTX. Con ella fue todo rodado por lo que os recomiendo que la useís.

Su página web es http://rxtx.qbang.org/

La instalación es muy simple os bajais la librería en la que os viene:

- RXTXcomm.jar (librería que implementa la especificación de Java Comunication API)
- Directorio con drivers para Linux
- Directorio con drivers para Solaris
- Directorio con drivers para Mac_OS_X
- Directorio con drivers para Windows


Añadis RXTXcomm.jar como librería a vuestro proyecto java y el driver lo meteis en la instalación del jre\bin

Ahora la implementación de una conexión al puerto serie.


public class EjemploRXTX {
    static CommPortIdentifier portId;
    static CommPortIdentifier saveportId;
    static Enumeration  portList;
    static InputStream inputStream;
    static OutputStream outputStream;
    static BufferedInputStream bufferedInputStream;
    static SerialPort  serialPort;
   
   
    public static void main(String[] args){
        boolean gotPort = false;
        String port;
        portList = CommPortIdentifier.getPortIdentifiers();
       
        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement(); //get next port to check
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                if ( portId.getName().equals("COM4") ) {
                    port = portId.getName();
                    gotPort = true;
                }
               
                if (gotPort == true) {
                    try {
                        serialPort = (SerialPort)portId.open("SMSSender", 2000);
                    } catch (PortInUseException ex) {
                        ex.printStackTrace();
                    }
                    try {
                        outputStream = serialPort.getOutputStream();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    try {
                        serialPort.setSerialPortParams(19200,
                                SerialPort.DATABITS_8,
                                SerialPort.STOPBITS_2,
                                SerialPort.PARITY_NONE
                                );
                    } catch (UnsupportedCommOperationException ex) {
                        ex.printStackTrace();
                    }
                   
                    try {
                        inputStream = serialPort.getInputStream();
                        bufferedInputStream = new BufferedInputStream(inputStream);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                   
                    serialPort.notifyOnDataAvailable(true);
                }
            }
        }
       
       //Escribir en el puerto serie
       try {
            if (!(outputStream == null))
                outputStream.write("array de váis que queremos enviar");
           
            byte[] readBuffer = new byte[1];
            boolean read = false;
            while(!read) {
                try {
                    String getInfo = "";
                    Thread.sleep(100);
                    while (bufferedInputStream.available() > 0) {
                        int numBytes = bufferedInputStream.read(readBuffer);
                        getInfo += new String(readBuffer);
                        read = true;
                    }
                    feedback += getInfo;
                    int length = getInfo.length();
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        } catch (IOException e){
            e.printStackTrace();
        }
    }



En este ejemplo se usa por debajo una plataforma windows como podéis ver en el nombre del puerto "COM4" en un linux por ejemplo este sería algo como "/dev/ttyS0".

Tambíen para cada caso teneis que tener en cuenta que los datos de conexión con el dispositivo son particulares a cada dispositivo:


serialPort.setSerialPortParams(19200,
                                SerialPort.DATABITS_8,
                                SerialPort.STOPBITS_2,
                                SerialPort.PARITY_NONE
                                );


El dispositivo de este ejemplo trabajaba a 19200 baudios, tamaño de mensaje 8 bits, sin paridad y con el bit de parada 2.

Si ajustais estas cosas ya os debe funcionar para cualquier dispositivo.

Enviar email desde Java 2º parte

Para usar el SMTP de google y nuestra cuenta de gmail tendremos que modificar el ejemplo anterior ya que google usa encriptación por SSL para la autenticación. A continuación el como se haría:


public class Main {
    
    private static final String SMTP_HOST_NAME = "smtp.gmail.com";
    private static final String SMTP_PORT = "465";
    private static final String emailMsgTxt = "Esto sería el mensaje";
    private static final String emailSubjectTxt = "Aqui el asunto";
    private static final String emailFromAddress = "micuenta@gmail.com";
    private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
    private static final String[] sendTo = { "Email destino"};
    
    
    public static void main(String args[]) throws Exception {
        
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        
        new Main().sendSSLMessage(sendTo, emailSubjectTxt,emailMsgTxt, emailFromAddress);
        System.out.println("Sucessfully Sent mail to All Users");
    }
    
    public void sendSSLMessage(String recipients[], String subject,String message, String from) throws MessagingException {
        boolean debug = true;
        
        Properties props = new Properties();
        props.put("mail.smtp.host", SMTP_HOST_NAME);
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "true");
        props.put("mail.smtp.port", SMTP_PORT);
        props.put("mail.smtp.socketFactory.port", SMTP_PORT);
        props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.put("mail.smtp.socketFactory.fallback", "false");
        
        Session session = Session.getDefaultInstance(props,new javax.mail.Authenticator() {
            
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("micuenta@gmail.com", "micontraseñadegmail");
            }
        });
        
        session.setDebug(debug);
        
        Message msg = new MimeMessage(session);
        InternetAddress addressFrom = new InternetAddress(from);
        msg.setFrom(addressFrom);
        
        InternetAddress[] addressTo = new InternetAddress[recipients.length];
        for (int i = 0; i < recipients.length; i++) {
            addressTo[i] = new InternetAddress(recipients[i]);
        }
        msg.setRecipients(Message.RecipientType.TO, addressTo);
        
        
        msg.setSubject(subject);
        
        msg.setText(message);
        Transport.send(msg);
    }
}

Como enviar emails desde Java

Hace ya un tiempo que no escribo en el blog, pero es que últimamente he estado muy muy liado, lo bueno es que he tenido que trabajar en muchos proyectos lo cuál me permitirá escribir unos cuantos tutoriales este més.

Para este primer tutorial he decidido poner un ejemplo de algo que puede parecer una tontería "enviar un correo electrónico desde Java" pero si no encuentra un buen ejemplo en la red puedes pegarte un buen rato.

Lo primero debemos bajarnos la librería JavaMail.jar y activation.jar y añadirlos a nuestro proyecto.


Nota. No preocuparse son dos jar de poco peso.


En principio creamos una clase para el envío de emails:



public class SendMail {
    
    private String from;
    private String to;
    private String subject;
    private String text;
    private ITracer tracer;
    
    public SendMail(String from, String to, String subject, String text){
        this.from = from;
        this.to = to;
        this.subject = subject;
        this.text = text;
        tracer = FileTracer.getInstance();
    }
    
    public void send(){
        
        Properties props = new Properties();
        props.put("mail.smtp.host", "ServidorSMTP");
        props.put("mail.smtp.port", "25"); //Suele ser este puerto
        props.put("mail.smtp.auth", "true");
                
        Session mailSession = Session.getDefaultInstance(props,new javax.mail.Authenticator() {
            
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("UsuarioSMTP",
                                                  "PasswordSMTP");
            }
        });
        
        Message simpleMessage = new MimeMessage(mailSession);
        
        InternetAddress fromAddress = null;
        InternetAddress toAddress = null;
        try {
            fromAddress = new InternetAddress(from);
            toAddress = new InternetAddress(to);
        } catch (AddressException e) {
            tracer.send(ITracer.INFO,e.getMessage());
        }
        
        try {
            simpleMessage.setFrom(fromAddress);
            simpleMessage.setRecipient(RecipientType.TO, toAddress);
            simpleMessage.setSubject(subject);
            simpleMessage.setText(text);
            
            Transport.send(simpleMessage);
            
            tracer.send(ITracer.INFO,"Email enviado a "+toAddress);
        } catch (MessagingException e) {
            tracer.send(ITracer.INFO,e.getMessage());
        }
    }
    
    public void setSubject(String subject)
    {
        this.subject = subject;
    }
    
    public void setText(String message)
    {
        this.text = message;
    }
}



Y por último sólo nos queda usarlo:



SendMail mail = new SendMail("FromEmail",
                                             "ToEmail",
                                             "Asunto",
                                             "Mensaje");
mail.send();



Un saludo y espero que os sea útil ;)