O que é Spring Boot?

Sabe o que é Spring Boot?

Spring Boot é um conjuntos de configurações padrões que aceleram o processo de desenvolvimento no Spring, resumindo um ambiente semi pronto para iniciar o desenvolvimento.

Funcionalidades disponíveis:

  • Servidor de aplicação embarcado
  • Cria aplicação autônoma do Spring
  • Fornece poms mais intuitivos para a configuração do MAVEN
    Sempre que possível, automaticamente configura o Spring
  • Pré fornecer recursos para produção, como verificação de integridade, configurações externas e métricas
  • Nenhuma geração de código e nenhum requisito para configuração de XMLs

Para Startups é um modelo ideal para pegar a ideia e começar a implementar.

Pretendo começar a escrever uma série de artigos utilizando o Spring Boot e uma aplicação Web simples, demonstrando os passos para colocar uma aplicação em pouco tempo no ar.

O modelo adotado para aplicação deverá ter divisão clara de camadas e usar o máximo de recursos que o Spring permite.

A aplicação irá implementar uma lista de contatos, onde cada contato deverá possuir os seguintes atributos:

  • Nome (String)
  • Email (String)
  • Telefone (String), opcional
  • CEP (String)
  • UF (String)
  • Cidade (String)
  • Endereco (String)
  • Número (String), opcional

A tela principal ser responsiva em HTML5, utilizar Bootstrap e Thymeleaf. deverá ter dois botões. Um botão para salvar o contato e outro para realizar pesquisa.

A tela principal deverá ter a listagem dos contatos paginada por 50 contatos por página.

Em cada linha da grade de listagem deverá ter a opção de visualizar, excluir ou editar o contato.

Na listagem somente trazer informações de Nome, email, Telefone e Cidade.

O código estará disponibilizado no Github em: https://github.com/andremrezende/agenda

Nos próximos posts já teremos a configuração do projeto e download do mesmo.

Como ignorar erro de certificado no envio de email em Java

Lembra aquela situação que está na correria para criar um programa que envia e-mail, testa-lo e então garantir que o e-mail foi enviado a pessoa correta, com o assunto correto, com o corpo do email correto, certificar que o email está “responsivo” e o cliente ou gerente businando na sua orelha para entregar rápido?

Então cria um programa rápido, porém ao executar aparece o erro:

PKIX path building failed:

Essas situação não lhe proverá muito tempo para importar ou criar um certificado daquele provedor de email.

Caso se encontre em situação semelhante a descrita acima, segue as propriedades para adicionar no seu programa Java e ingorar.

Em SMTP:

props.put("mail.smtp.ssl.trust", "*");

Em IMAP:

prop.put("mail.imaps.ssl.trust", "*");

Lembrando sempre que estas propriedade deverá ser usada com cautela, pois irá comprometer a segurança.

Java broadcast message websocket

websocketAcredito que possa ser útil dar uma olhada no WebSockets, que é uma tecnologia relativamente nova que promete tornar sites mais reativos, permitindo menor latência entre os usuários e o servidor.
Neste artigo vou mostrar um simples exemplos de envio de mensagem a todos conectado no servidor utilizando Websocket e Java.

O que é WebSocket?

Antes de começar com o código fonte, mas descobrir o que é a tecnologia.
O WebSocket é um protocolo que permite a comunicação entre o cliente e o servidor / nó de extremidade usando uma única conexão TCP.
Parecido com o http. A vantagem que o WebSocket tem sobre o HTTP é que o protocolo é full-duplex (permite a comunicação simultânea em dois sentidos) e seu cabeçalho é muito menor que o de um cabeçalho HTTP,
permitindo uma comunicação mais eficiente mesmo em pequenos pacotes de dados.

O ciclo de vida de um WebSocket é fácil de entender também:

O cliente envia ao servidor uma solicitação de handshake na forma de um cabeçalho de atualização HTTP com dados sobre o WebSocket ao qual está tentando se conectar.
O servidor responde à solicitação com outro cabeçalho HTTP, esta é a última vez que um cabeçalho HTTP é usado na conexão WebSocket. Se o handshake foi bem sucedido, o servidor envia um
cabeçalho HTTP dizendo ao cliente que está mudando para o protocolo WebSocket.
Agora uma conexão constante é aberta e o cliente eo servidor podem enviar qualquer número de mensagens umas às outras até que a conexão seja fechada. Essas mensagens têm apenas cerca de 2 bytes de sobrecarga.

Um Exemplo

A API do WebSocket foi introduzida com o Java EE7, neste exemplo vamos criar dois clientes, uma aplicação web e outra standalone, que enviará uma mensagem para o servidor e o servidor deverá espalhar a mensagem e responder a quem enviou a mensagem.

Neste exemplo, usarei o Eclipse, servidor Tomcat 8 e a biblioteca do nv-websocket-client para o cliente standalone.
Para o seu servidor, crie um aplicação Web.
Converta para um projeto Maven e adicione as seguintes linhas no pom.xml:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>br.com.tsystems</groupId>
<artifactId>webSocket-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<properties>
<java-version>1.8</java-version>
<tomcat.version>8.0.30</tomcat.version>
<debug.code>true</debug.code>
</properties>

<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>

<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>

<dependency>
<groupId>com.neovisionaries</groupId>
<artifactId>nv-websocket-client</artifactId>
<version>1.30</version>
</dependency>

<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Crie seu EndPoint, classe Java responsável por receber as mensagens e espalha:


/**
* @ServerEndpoint poderá ser acessado por ws://localhost:8080/webSocket-example/echo
*/
@ServerEndpoint("/echo")
public class WebSocketDemo {
private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());

@OnOpen
public void onOpen(final Session session) {
// Adicionar sessão
sessions.add(session);
}

@OnMessage
public String echo(Session currentSession, String message) {
synchronized (sessions) {
for (Session session : sessions) {
// enviar mensagens para todos os clientes com essão daquele que enviou.
if (session.isOpen() && !session.equals(currentSession)) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
return message;
}

@OnError
public void onError(Session session, Throwable thr) {
//Ocorrer erro
thr.printStackTrace();
}

@OnClose
public void onClose(final Session session) {
// remover a sessão
sessions.remove(session);
}
}

Crie o index.html com o código abaixo:

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>

<body>
<meta charset="utf-8">
<title>Web Socket JavaScript Echo Client</title>
<script language="javascript" type="text/javascript">
 var wsUri = getRootUri() + "/webSocket-example/echo";

function getRootUri() {
 return "ws://" + (document.location.hostname == "" ? "localhost" : document.location.hostname) + ":" +
 (document.location.port == "" ? "8080" : document.location.port);
 }

function init() {
 output = document.getElementById("output");
 }

function send_echo() {

websocket = new WebSocket(wsUri);
 websocket.onopen = function (evt) {
 onOpen(evt)
 };
 websocket.onmessage = function (evt) {
 onMessage(evt)
 };
 websocket.onerror = function (evt) {
 onError(evt)
 };

}

function onOpen(evt) {
 writeToScreen("CONNECTED");
 doSend(textID.value);

}

function onMessage(evt) {
 writeToScreen("RECEIVED: " + evt.data);
 }

function onError(evt) {
 writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
 }

function doSend(message) {
 writeToScreen("SENT: " + message);
 websocket.send(message);
 }

function writeToScreen(message) {
 var pre = document.createElement("p");
 pre.style.wordWrap = "break-word";
 pre.innerHTML = message;
 //alert(output);
 output.appendChild(pre);
 }

window.addEventListener("load", init, false);

</script>
<h2 style="text-align: center;">WebSocket Echo Client</h2>
</br>
<div style="text-align: center;">
<form action="">
<input onclick="send_echo()" value="Press me" type="button">
<input id="textID" name="message" value="Hello WebSocket!" type="text">

</form>
</div>
<div id="output"></div>
</body>
</html>

Por fim, crie o código do cliente stantalone:


/**
* @author Andre Rezende
*/
public class EchoClient {
private static final String SERVER = "ws://localhost:8443/cms/app/echo";
private static final int TIMEOUT = 5000;

public static void main(String[] args) throws Exception {
EchoClient echoClient = new EchoClient();
WebSocket ws = null;
try {
ws = echoClient.connect();
ws.sendText(new Date() + " teste->1");
} finally {
// Close the WebSocket.
ws.disconnect();
}
}

/**
* Conectar no servidor de websocket.
*/
public WebSocket connect() throws IOException, WebSocketException {
return new WebSocketFactory().setConnectionTimeout(TIMEOUT).createSocket(SERVER)
.addListener(new WebSocketAdapter() {
// A text message arrived from the server.
public void onTextMessage(WebSocket websocket, String message) {
System.out.println(message);
}
}).addExtension(WebSocketExtension.PERMESSAGE_DEFLATE).connect();
}
}

Para testar primeiro realize o deploy do seu war no tomcat. Talvez o tomcat requisite a biblioteca tomcat-juli.jar. Ela poderá ser obtida pelo endereço http://www.java2s.com/Code/Jar/t/Downloadtomcatjulijar.htm.
Após realizar o download, descompacte-a no diretório lib do seu tomcat.
Servidor de aplicação (Tomcat) em execução, realizado o deploy sem qualquer erro no tomcat, está na hora de iniciarmos os testes.
Para executar o cliente standalone, basta executar a classe EchoClient. A classe enviará a mensagem “Data corrente ” + test->1.
Abra a aplicação WEB no seu browser pela URL: localhost:8080/webSocket-example/
Por último abra o site: http://www.websocket.org/echo.html. Ele permite realizar testes por web em seu servidor de Websocket. Em location adicione ws://localhost:8080/websocket-example/echo
Clique no botão Connect, escreva em Message a mensagem que deseja compartilhar e por fim clique em Send para enviar a mensagem. Instruções em inglês e um exemplo em HTML está disponível no mesmo link.
Sua aplicação web deverá receber a mesma mensagem enviada pelo último site.

Concluindo

Webscoket permite envio de mensagem de forma assincrona e com segurança.
Substitui a antiga abordagem de consultas aos dados através de refresh de tela ou de tempos em tempos, o que particularmente é ineficiente na maior parte dos casos. Torna a vida do desenvolvedor mais fácil.
É baseado no TCP, bi-derecional e full-duplex. Part do HTML5 e a W3C define a API Jscript. Suportador pela maior parte dos browsers e suas respectivas versões.
Sugestão, comece fazendo um teste simples e vá aumentando a complexidade de seu websocket. Adicione recursos de reconexão e mensagens do mais variados tipos como textos ou binários.
Boa diversão.
O código está disponível para download no Github 

Project Lombok

Cansado de ficar fazendo Gets/Sets em seu código java?
Veja o Project Lombok.
Uma simples anotação em seu código @Data (gerar ate hashCode, equals e toString()) ou @Getter / @Setter poderá obter facilitar essa vida de gerador. Sei que se usar uma IDE tem teclas de atalhos para gerar, mas nada melhor que somente anotar a classe e aguardar o resto.

Na página tem alguns videos explicativos.

Problemas de Upload de arquivos com Primefaces?

Problemas de Upload de arquivos com Primefaces?

Verifique se adicionou em seu web.xml:

    <!-- Muito importante -->
	<context-param>
		<param-name>primefaces.UPLOADER</param-name>
		<param-value>commons</param-value>
	</context-param>	
	
	<filter>
	 <filter-name>PrimeFaces FileUpload Filter</filter-name>
	 <filter-class>
	  org.primefaces.webapp.filter.FileUploadFilter
	 </filter-class>
	</filter>
	<filter-mapping>
	 <filter-name>PrimeFaces FileUpload Filter</filter-name>
	 <servlet-name>Faces Servlet</servlet-name>
	</filter-mapping>
	
	<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>/faces/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <context-param>
        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <context-param>
        <param-name>primefaces.UPLOADER</param-name>
        <param-value>auto</param-value>
    </context-param>
    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>	
  

A dependencias para upload de arquivos são:

		
		<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <!-- Faces Implementation -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.2.4</version>
        </dependency>
        <!-- Faces Library -->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.2.4</version>
        </dependency>
        <!-- Primefaces Version 5 -->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>5.0</version>
        </dependency>
		<!-- File uploads -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.2.1</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.4</version>
		</dependency>  
		
        <!-- JSP Library -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <!-- JSTL Library -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.1.2</version>
        </dependency>		
	

index.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Journaldev Tutorial</title>
    </h:head>
    <h:body>
        <h:form enctype="multipart/form-data">
                <p:fileUpload value="#{fileUploadManagedBean.file}"  mode="simple"></p:fileUpload>
                <p:separator/>
                <h:commandButton value="Dummy Action" action="#{fileUploadManagedBean.dummyAction}"></h:commandButton>
        </h:form>
    </h:body>
</html>		

FileUploadManagedBean.java:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
import org.primefaces.model.UploadedFile;
 
@ManagedBean
@SessionScoped
public class FileUploadManagedBean {
    UploadedFile file;
 
    public UploadedFile getFile() {
        return file;
    }
 
    public void setFile(UploadedFile file) {
        this.file = file;
    }
 
    public String dummyAction(){
        System.out.println("O nome do arquivo é "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
        return "";
    }
}

Conclusão
Este artigo tem intenção de prover uma explicação da utilização do FileUpload do Primefaces. Caso não esteja conseguindo realizar upload, tente verificar se todos os passos estão realizados e não falta nenhum detalhe. O componente FileUpload tem muitas funcionalidades e permite que o programador mantenha o foco do trabalho nas regras de negócio ao invés de ficar reinventando a roda.

Java 8 e StringJoiner

Na ultima versão do Java 8 foi adicionado o StringJoiner no pacote java.util.
É uma implementação juntar as pedaços em comparação, um facilitador da antiga abordagem usando StringBuffer / StringBuilder.
Vamos ver o uso do StringJoiner e como funciona a implementação.

Por exemplo, tenho duas cadeias como “Andre” e “Rezende” e eu quero juntar essas cadeias como [Andre, Rezende]. Neste caso, eu tenho o prefixo como “[“, o sufixo como “]” e o delimitador como “,”. StringJoiner tem dois construtores como dado abaixo.
StringJoiner (CharSequence delimitador)
StringJoiner (CharSequence delimitador, CharSequence prefixo, sufixo CharSequence)
Queremos ter prefixo e sufixo, portanto, vamos usar o segundo construtor para o nosso exemplo.

StringJoiner sjr = new StringJoiner(",", "[", "]");
sjr.add("Andre").add("Rezende");
System.out.println("A string final é " + sjr);

Resultado será a saída no console: A string final é [Andre,Rezende]

Se não quiser adicionar o prefixo e sufixo, então:

StringJoiner sjr1 = new StringJoiner(",");
sjr1.add("Andre").add("Rezende");
System.out.println("A string final é " + sjr1);

Resultado será a saída no console: A string final é [Andre,Rezende]

Conclusão, não é uma baita implementação, ainda pode-se utilizar a StringBuilder ou StringBuffer, mas ele facilita um pouco a vida do desenvolvedor.

Exemplo JDBI

Como já comentado no artigo anterior, JDBI é uma forma de implementar seu DAO com mais produtividade, uma biblioteca para se trabalhar SQL e banco de dados relacionais.
Então vamos criar um simples DAO para realizar operações CRUD(Create, Read, Update e Delete).
Para esse exemplo é necessário possuir o MySQL em execução na sua máquina com o esquema teste criado.

No maven (pom.xml) de seu projeto Java, adicione as dependências do JDBI versão 2.73 , do MYSQL 5.1.38 e Junit versão 4.12 para nossos testes unitários.

                <!-- JDBI-->
		<dependency>
			<groupId>org.jdbi</groupId>
			<artifactId>jdbi</artifactId>
			<version>${jdbi.version}</version>
		</dependency>

                <!-- MySQL -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>

                <!-- JUNIT -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>

Criaremos uma interface de nome MyDAO:

public interface MyDAO {}

Agora que temos nossa classe criada, podemos então criar nossos métodos CRUD, vamos implementar uma INSERT, SELECT, UDPATE e DELETE para tabela do MySQL TBLEXEMPLO conforme métodos abaixo:

public interface MyDAO
{
	//Cria tabela TBLEXEMPLO no banco
	@SqlUpdate("CREATE TABLE IF NOT EXISTS TBLEXEMPLO (ID int NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, PRIMARY KEY (ID))")
	void createTable();

	//Insere registro no banco na tabela TBLEXEMPLO
	@SqlUpdate("insert into TBLEXEMPLO (name) values (:name)")
	void insert(@Bind("name") String name);

	//filtra no banco da tabela TBLEXEMPLO
	@SqlQuery("select ID from TBLEXEMPLO where name = :name")
	int findIdByName(@Bind("name") String name);

	//filtra no banco da tabela TBLEXEMPLO
	@SqlQuery("select name from TBLEXEMPLO where id = :id")
	String findNameById(@Bind("id") int id);

	//Altera registro no banco na tabela TBLEXEMPLO
	@SqlUpdate("update TBLEXEMPLO set name = :name where id = :id")
	int updateNameById(@Bind("id") int id, @Bind("name") String name);

	//Apaga registro no banco na tabela TBLEXEMPLO
	@SqlUpdate("delete from TBLEXEMPLO where id = :id")
	int deleteById(@Bind("id") int id);

	//Apaga tabela após conclusão de testes
	@SqlUpdate("drop table TBLEXEMPLO")
	void dropTable();

	//Finaliza conexão
	void close();
}

As anotações @SqlUpdate servem para realizar operações de escrita no branco de dados, em quanto as anotações @SqlQuery para leitura, como SELECT.

Abaixo o código que realiza os testes unitários.

public class MyDAOTest {

	@Test
	public void testJdbi() {
		MyDAO dao = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			//Realiza conexão com o mysql
			DBI dbi = new DBI("jdbc:mysql://localhost/test", "usuario", "senha");
			//Abra conexão com o MySQL
			dao = dbi.open(MyDAO.class);
			//Cria tabela
			dao.createTable();
			//Insere Registro com nome Rezebde
			dao.insert("Rezende");
			int id = dao.findIdByName("Rezende");
			//Nome retornado da consulta deve ser Rezende
			assertEquals(1, id);
			//Altera nome de Rezende para Rezende2
			dao.updateNameById(id, "Rezende2");
			String name2 = dao.findNameById(id);
			//Nome retornado deve ser Rezende2
			assertEquals("Rezende2", name2);

			//Apaga registro criado
			dao.deleteById(id);
			String name3 = dao.findNameById(id);
			//Valor retornado deve ser nulo, pois registro foi apagado acima
			assertNull(name3);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			fail("Error");
		} finally {
			if (dao != null) {
				// Apaga tabela
				dao.dropTable();
				dao.close();
			}
		}
	}
}

Executando os testes acima, não deverá retornar erro.

O download do projeto pode ser feito em meu github: https://github.com/andremrezende/jdbi-example.git

Como visto no post, é muito rápido implementar a camada de persistência utilizando o JDBI e chamadas nativas no banco de dados desejado.