O que é Java?
Java é uma linguagem de programação de alto nível, compilada e multiplataforma. Quando uma arquivo *.java passa pelo processo de compilação é criado um novo arquivo de mesmo nome com a extensão .class, este arquivo não é um executável nativo de um sistema operacional mas sim bytecodes que serão executados por uma maquina virtual (JVM) instalada no sistema operacional.
We can't promise you fame, fortune, or even a job if you learn the Java programming language. (by Oracle)
Criando uma classe em Java.
Para criar um classe java precisamos apenas de um editor de texto simples (Notepad++), conforme a imagem assim criei o arquivo HelloWorldApp.java dentro do diretório “C:\tmp”, com o conteúdo abaixo e salvei.
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
Compilar/Rodar uma classe Java.
Pré-requisitos
Instalação do Java Development Kit (JDK) - Instruções
Compilar
Para compilarmos um classe Java usamos o comando javac, usando nosso exemplo de classe acima a linha de comando ficara assim “javac HelloWorldApp.java”, execute-a dentro do prompt de comando do sistema operacional, no nosso caso o windows, a mesma vai criar o arquivo “.class”
Rodar
Agora já podemos rodar nossa classe com a comando “java HelloWorldApp”.
Exercícios
- Cria um classe usando apenas um editor de texto, que imprima seu nome, compilar e rodar.
Console
Saída
Como vimos em nossa classe de “HelloWorldApp” usamos a console do sistema para imprimir a uma saída com a valor “Hello World” usando o System.out.println, toda execução de uma classe Java terá um System, o System.out é um instancia da classe “java.io.PrintStream” que nos disponibiliza alguns métodos para a saída na console.
System.out
Métodos mais usados.
System.out.print
Escreve a saída na console.
System.out.print("Java");
System.out.println
O memso que o print mas coloca após a saída “\n”.
System.out.println("Java");
System.out.format
Recebe uma string e parâmetros formatando a saída.
System.out.format("%s - Hello World", "Java");
System.console
Outra possibilidade é usar a Console para escreve suas saídas.
Métodos mais usandos.
System.console().printf
Recebe uma string e parametros formatando a saída.
System.console().printf("Java");
System.console().format -
Similar ao printf.
System.console().format("Java");
Entrada
Para entrada de dados pela console utilizamos o System.in, que é uma instancia de “java.io.InputStream”.
BufferedReader
Para usar o BufferedReader, vamos precisar também de leitor de stream (Reader), usando a classe InputStreamReader podemos iniciar nosso BufferedReader conforme o código abaixo.
import java.io.BufferedReader;
import java.io.InputStreamReader;
class HelloWorldApp {
public static void main(String[] args) {
try (final InputStreamReader inputStreamReader = new InputStreamReader(System.in)) {
try (final BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
System.out.println("Hello World! - " + bufferedReader.readLine());
} catch (Exception e) {
//...
}
} catch (Exception e) {
//...
}
}
}
Scanner
Scanner é um implementação Java que veio a partir da versão 5 facilita a vida para esse tarefa de capturar entradas da console.
import java.util.Scanner;
class HelloWorldApp {
public static void main(String[] args) {
try (final Scanner scanner = new Scanner(System.in)) {
System.out.println("Hello World! - " + scanner.nextLine());
} catch (Exception e) {
//...
}
}
}
System.console
Não podia faltar a Console que surgiu na versão 6 do Java.
import java.io.Console;
class HelloWorldApp {
public static void main(String[] args) {
final Console console = System.console();
System.out.println("Hello World! - " + console.readLine());
}
}
Exercícios
- Crie um classe que receba um número é informe se o mesmo é par ou impar.
Netbeans
https://netbeans.org/downloads/
Criando um Projeto
String
Usada para manipular strings, elas são imutáveis uma vez criadas no pool.
class StringRun {
public static void main(String[] args) {
if ("A" == new String("A")) {
System.out.println("0");
} else {
System.out.println("1");
}
}
}
Exemplo mostra que quando é usada uma nova instância de String o seu valor não vai para o pool.
“”.compareTo
Compara o valor da string com o parâmetro.
"".compareTo("");
“”.compareToIgnoreCase
Igual a compareTo porém sem o case-sensitive.
"".compareToIgnoreCase("");
“”.contains
Valida se contêm o parâmetro dentro da string.
"".contains("");
“”.isEmpty
Retona true se a string está vazia.
"".isEmpty();
“”.split
Cria um array de string conforme o delimitador.
"a,b,c".split(",");
“”.toLowerCase e “”.toUpperCase
"".toLowerCase();
"".toUpperCase();
“”.substring
Retorna uma nova string conforme os indíces informados.
"abc".substring(1);
“”.replace
Retorna uma nova string aplicando o modificador passado.
"".replace("", "");
Exercícios
- Solicitar que o usuário informe um frase, e retorna a quantidade de vogais.
- Solicitar que o usuário informe valores e inverter string de entrada.
StringBuilder / StringBuffer
StringBuilder
É um modificador de string, geramente usado quando manipulas muitas string (ex. carregamento de texto de um arquivo);
StringBuilder().append
Adicionar o valor do parâmetro ao conteudo da string.
new StringBuilder("Hello ").append("World");
StringBuilder().insert
Adicionar o valor na posição informada.
new StringBuilder("ello World").insert(0, "H");
StringBuffer
Igual a StringBuilder porem é sincronizado (Thread Safe);
Exercícios
- Usando o enum descrito abaixo, utilize o StringBuffer para concatenar os nomes do estados separados por virgula, e exiba-os na console. Se conseguir ordenado melhor.
enum Estados {
AC("Acre"), AL("Alagoas"), ES("EspíritoSanto"), AP("Amapá"),
BA("Bahia"), CE("Ceará"), DF("DistritoFederal"), GO("Goiás"),
MA("Maranhão"), SC("SantaCatarina"), MG("MinasGerais"),
MT("MatoGrosso"), MS("MatoGrossodoSul"), PA("Pará"),
RS("RioGrandedoSul"), PE("Pernambuco"), PI("Piauí"),
AM("Amazonas"), PR("Paraná"), RJ("RiodeJaneiro"),
RN("RioGrandedoNorte"), PB("Paraíba"), RO("Rondônia"),
RR("Roraima"), SE("Sergipe"), SP("SãoPaulo"), TO("Tocantins");
private String nome;
private Estados(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Date
A classe Date representa um instante específico no tempo, com uma precisão de milissegundos.
new java.util.Date();
SimpleDateFormat
Classe para fazer parsing de datas para texto e texto para data.
SimpleDateFormat simpleDateFormat;
simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
Calendar
Classe abstrata para manipulação de tempo.
Calendar calendar = Calendar.getInstance();
Calendar.setTime
Recebe a data que o calendar deve trabalhar.
calendar.setTime(new Date());
Calendar.getTime
Retorna a data após a manipulação.
calendar.getTime();
Calendar.add
Adiciona ou subtrai valor da data interna do calendar.
// + 1 mês
calendar.add(Calendar.MONTH, 1);
// -1 mês
calendar.add(Calendar.MONTH, -1);
// +1 dia
calendar.add(Calendar.DAY_OF_MONTH, 1);
// -1 dia
calendar.add(Calendar.DAY_OF_MONTH, -1);
Exercícios
- Exibir na console a data atual do sistema.
- Informe a data de nascimento e devolva o dia da semana.
File
Classe responsável pela manipulação de arquivo (criar, mover excluir …)
import java.io.File;
public class Run {
public static void main(String[] args) {
final File file = new File("aula2.txt");
}
}
createNewFile
Quando não existe o arquivo informado o mesmo é criado.
try {
final boolean b = new File("aula2.txt").createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
delete
Quando existir o arquivo, o mesmo será excluido.
final boolean b = new File("aula2.txt").delete();
getAbsolutePath
Retorna o caminho absoluto do arquivo, muito útil para identificar se estamos manipulando o arquivo correto.
final String path = new File("aula2.txt").getAbsolutePath();
list
Devolve um array com o nome dos arquivos.
final String[] list = new File(".").list();
listFiles
Retonar um array com Files.
final File[] list = new File(".").listFiles();
FileFilter
Interface onde é implementados uma restrição para o listFiles.
final File file = new File(".");
final File[] list = file.listFiles(new FileFilter() {
@Override
public boolean accept(final File pathname) {
return pathname.getName().contains(".txt");
}
});
isDirectory e isFile
Para a classe file diretório e arquivo são diferenciados pelo metodos acima.
final File file = new File(".");
if (file.isDirectory()) {
//...
}
if (file.isFile()) {
//...
}
Reader
Classe abstrata utilizada na leitura do streams.
FileReader
Classe utilitária para ler um arquivo, e criar um Reader.
try {
final Reader reader = new FileReader("aula2.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedReader
Classe utilizada para ler Strings do stream.
try {
final Reader reader = new FileReader("aula2.txt");
final BufferedReader bufferReader = new BufferedReader(reader);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Writer
Como no Reader, é um classe abstrata agora para a escrita em streams
FileWriter
Similar ao FileReader mas para escrita.
try {
final Writer writer = new FileWriter("aula2.txt");
} catch (IOException e) {
e.printStackTrace();
}
BufferedWriter
Classe utilizada para escrever Strings em stream.
try {
final Writer writer = new FileWriter("aula2.txt");
final BufferedWriter bufferReader = new BufferedWriter(writer);
} catch (IOException e) {
e.printStackTrace();
}
JDBC
JDBC é uma API Java que nos permite interagir com a maioria dos bancos de dados relacionais existentes através de um driver (Driver Manager).
DriverManager
Classe java.sql.DriverManager é responsável por utilizar o driver (no nosso caso o “ojdbc6” da oracle) para criar a conexão.
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3.0</version>
</dependency>
// Oracle Thin
// jdbc:oracle:thin:@<HOST>:<PORT>:<SID>
// oracle.jdbc.driver.OracleDriver
final String url = "jdbc:oracle:thin:@<HOST>:<PORT>:<SID>";
final String user = "xa";
final string pass = "xa";
try (final Connection connection = DriverManager.getConnection(url, user, pass)) {
// ...
} catch (SQLException e) {
System.err.format("SQLException: %s", e);
}
Connection
É a representação da conexão criada com o banco de dados, por default a conexão cria um transação com auto comitê, o que significa que toda instrução executada é ACID (Atomicidade, Consistência, Isolamento e Durabilidade).
final String insert = "INSERT INTO PESSOA("
+ "ID_PESSOA, NM_PESSOA ) "
+ "VALUES (?, ?)";
Connection c = null;
PreparedStatement ps = null;
try {
c = ConnectionUtil.getConnection();
c.setAutoCommit(false); // não permite o autocomit
ps = c.prepareStatement(insert);
for (int i = 1; i <= 10; i++) {
ps.setInt(1, i);
ps.setString(2, String.format("Nº %d", i));
ps.executeUpdate();
}
c.commit();
} catch (final SQLException e) {
System.err.format("SQLException: %s", e);
try {
if (ps != null) {
ps.close();
}
if (c != null) {
c.rollback();
c.close();
}
throw e;
} catch (final SQLException ex) {
System.err.format("SQLException: %s", ex);
}
}
Statement
Classe usada para executar uma instrução SQL estática.
try (final Connection connection = DriverManager.getConnection(url, user, pass)) {
try (final Statement statement = connection.createStatement()) {
// ...
} catch (final SQLException e) {
System.err.format("SQLException: %s", e);
}
} catch (SQLException e) {
System.err.format("SQLException: %s", e);
}
executeUpdade
Executa a instrução SQL fornecida, que pode ser um INSERT, UPDATE, ou DELETE ou uma instrução SQL que não retorna nada, como uma instrução SQL DDL.
final String ddl = "CREATE TABLE PESSOA ("
+ " ID_PESSOA NUMBER(19,0) NOT NULL, "
+ " NM_PESSOA VARCHAR2(50) NOT NULL, "
+ " PRIMARY KEY (ID_PESSOA) "
+ ")";
try (final Connection connection = DriverManager.getConnection(url, user, pass)) {
try (final Statement statement = connection.createStatement()) {
statement.executeUpdate(ddl);
} catch (final SQLException e) {
System.err.format("SQLException: %s", e);
}
} catch (SQLException e) {
System.err.format("SQLException: %s", e);
}
Statement.executeQuery
final String query = "SELECT 1 FROM PESSOA";
try (final Statement statement = connection.createStatement()) {
try (final ResultSet resultSet = statement.executeQuery(query)) {
//..
} catch (final SQLException e) {
System.err.format("SQLException: %s", e);
}
} catch (final SQLException e) {
System.err.format("SQLException: %s", e);
}
ResultSet
É uma representação tabular do resultado da execução passada.
// Pegando o nº da linha
while (resultSet.next()) {
System.out.println(resultSet.getRow());
}
PreparedStatement
Classe usada para executar para criar um instrução SQL com parâmetros.
final String insert = "INSERT INTO PESSOA("
+ "ID_PESSOA, NM_PESSOA ) "
+ "VALUES (?, ?)";
try (final PreparedStatement preparedStatement = connection.prepareStatement(insert)) {
for (int i = 1; i <= 10; i++) {
preparedStatement.setInt(1, i);
preparedStatement.setString(2, String.format("%s pessoa de 10", i));
preparedStatement.executeUpdate();
}
} catch (final SQLException e) {
System.err.format("SQLException: %s", e);
}
JPA
É uma especificação de API de persistência definida pela Oracle, orientada a Pojos Abaixo utilizaremos a o eclipselink (implementação de JPA).
<!-- Dependências -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.1.0.3.0</version>
</dependency>
Mapear Entidade
Usando a tabela PESSOA que criamos na aula, criaremos seu mapeamento.
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "PESSOA")
public class Pessoa implements Serializable {
@Id // Identifica a PK
@Basic(optional = false)
@Column(name = "ID_PESSOA")
private Long idPessoa;
@Basic(optional = false)
@Column(name = "NM_PESSOA")
private String nmPessoa;
// GETTER AND SETTER
persistence.xml
Arquivo de configuração onde é definido acesso ao banco e a lista de classes mapeadas.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" >
<persistence-unit name="localPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>br.com.cwi.entity.Pessoa</class>
<properties>
<property name="javax.persistence.jdbc.url"
value="jdbc:oracle:thin:@<HOST>:<PORT>:XE"/>
<property name="javax.persistence.jdbc.user"
value="<USER>"/>
<property name="javax.persistence.jdbc.driver"
value="oracle.jdbc.OracleDriver"/>
<property name="javax.persistence.jdbc.password"
value="<PASS>"/>
</properties>
</persistence-unit>
</persistence>
@ManyToOne
Mapeando entidade com relacionamento muitos pra um.
@Entity
@Table(name = "FILHO")
public class Filho implements Serializable {
@Id
@Basic(optional = false)
@Column(name = "ID_FILHO")
private Long idFilho;
@ManyToOne
@JoinColumn(name = "ID_PESSOA")
private Pessoa pessoa;
@OneToMany
@Entity
@Table(name = "PESSOA")
public class Pessoa implements Serializable {
@Id // Identifica a PK
@Basic(optional = false)
@Column(name = "ID_PESSOA")
private Long idPessoa;
@Basic(optional = false)
@Column(name = "NM_PESSOA")
private String nmPessoa;
@OneToMany(mappedBy="pessoa")
private List<Filhos> filhos;
@Temporal
Define o tipo que será convertido para o banco quando temos uma data
@Temporal(TemporalType.DATE)
@Column(name = "data")
private Date data;
@Temporal(TemporalType.TIME)
@Column(name = "hora")
private Date hora;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "data_hora")
private Date dataHora;
@GeneratedValue
Define a forma que será gerada a PK, quando usamos um sequence é usada também a anotação
@SequenceGenerator onde temos o nome da mesma.
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "SEQ_PESSOA")
@SequenceGenerator(name = "SEQ_PESSOA", sequenceName = "SEQ_PESSOA")
"strategy = SEQUENCE" é forma mais utilizada para a geração, mas existem outras. GenerationType
@Enumerated
Quando definimos um enum como atributo de um entidade podemos mapear o seu valor usando o enumerated.
enum TipoPessoa { PF, PJ};
@Enumerated(EnumType.STRING)
@Column(name = "TP_PESSOA")
private TipoPessoa tipoPessoa
EntityManager
É a classe principal do JPA, ela provem diversos métodos para ações como consulta, inclusão, alteração e exclusão. Existe uma diferença entre o JPA na arquitetura EE e SE onde o na EE o contêiner é o responsável pelo seu gerenciamento.
// Criando um EntityManager
final EntityManagerFactory emf;
emf = Persistence.createEntityManagerFactory("localPU");
final EntityManager em;
em = emf.createEntityManager();
find
Método que carrega a entidade definida pelo seu ID.
entityManager.find(Pessoa.class, ID);
createQuery
Método que usamos para construir um instrução usando JPQL.
entityManager.createQuery("SELECT p FROM Pessoa p");
createNativeQuery
Aqui podemos usar instruções nativas do nosso banco de dados.
//
String s = "SELECT NVL(NM_PESSOA, '...') FROM PESSOA";
entityManager.createNativeQuery(s);
//
createNamedQuery
Query estática definida na entidade, é uma boa prática.
// Mapeamento da Entidade
@Entity
@NamedQueries({
@NamedQuery(name = "Pessoa.findAll",
query = "SELECT p FROM Pessoa p")
})
public class Pessoa implements Serializable {
//
// Usando a namedQuery
entityManager.createNamedQuery("Pessoa.findAll");
persist
Método persiste a entidade na base de dados, caso o mesmo já exista devo uma EntityExistsException.
//
entityManager.persist(pessoa);
//
merge
Similar ao persiste, porem caso a entidade já exista ele mescla suas alterações.
//
entityManager.merge(pessoa);
//
Hibernate
O Hibernate ao meu ver é o mais famoso ORM Java existente no mercado, conforme vimos a especificação do JPA também é implementada por ele permitindo usarmos todos os itens acima.
<!-- Dependências -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.1.Final</version>
</dependency>
<!--
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.2</version>
</dependency>
-->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3.0</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="CRESCER16" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--<class>br.com.crescer.aula4.entity.Pessoa</class>-->
<class>br.com.crescer.aula4.entity.Usuario</class>
<class>br.com.crescer.aula4.entity.Amigo</class>
<class>br.com.crescer.aula4.entity.Publicacao</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="javax.persistence.jdbc.user" value="CWI"/>
<property name="javax.persistence.jdbc.password" value="CWI"/>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<!--<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Session
Similar ao EntityManager no JPA, a Session é um interface que dispõem de vários métodos para persistência de dados.
Session session = entityManager.unwrap(Session.class);
load
Carrega a entidade por seu ID.
Session session = entityManager.unwrap(Session.class);
session.load(Pessoa.class, <ID>);
save
Persiste a entidade passada.
Session session = entityManager.unwrap(Session.class);
session.save(pessoa);
update
Atualiza a entidade.
Session session = entityManager.unwrap(Session.class);
session.update(pessoa);
saveOrUpdate
Executa os métodos save ou update.
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(pessoa);
Criteria
Interface que provem diversas restrições e funções para utilizar nas consultas.
Session session = entityManager.unwrap(Session.class);
Criteria criteria = session.createCriteria(Pessoa.class);
add
Adicionar uma restrição usando Restrictions.
Session session = entityManager.unwrap(Session.class);
Criteria criteria = session.createCriteria(Pessoa.class);
criteria.add(Restrictions.like("nome", ".."));
uniqueResult
Retorna uma entidade.
Session session = entityManager.unwrap(Session.class);
Criteria criteria = session.createCriteria(Pessoa.class);
criteria.add(Restrictions.like("nome", ".."));
Pessoa pessoa = criteria.uniqueResult();
list
Retorna um lista de entidades.
Session session = entityManager.unwrap(Session.class);
Criteria criteria = session.createCriteria(Pessoa.class);
criteria.add(Restrictions.like("nome", ".."));
List<Pessoa> pessoas = criteria.list();
Servlet
São classes java que representam o conceito um de um servidor HTTP de requeste e response.
public class PessoaServlet extends HttpServlet {
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
// ...
}
}
web.xml
Arquivo de definições do projeto web.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>Pessoa</servlet-name>
<servlet-class>br.com.crescer.aula5.PessoaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Pessoa</servlet-name>
<url-pattern>/pessoa</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
HttpServletRequest
Representa a requisição de entrada no servidor.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final String remoteHost = request.getRemoteHost();
getParameter
Retorna os parâmetros passados na requisição.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String nome = request.getParameter("pessoa.nome");
getSession
Retorna a httpSession criada para aquela requisição, para o jsession.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
HttpServletRequest
Representa a saída do servidor.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setStatus(200);
getWriter
Retorna o printWriter, que possibilita escrever a saída do html.
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
try (final PrintWriter out = response.getWriter();) {
out.append("<!DOCTYPE html>");
out.append("<html>");
out.append("<head>");
out.append("<title>Java - aula5</title>");
out.append("<meta charset=\"UTF-8\">");
out.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
out.append("</head>");
out.append("<body>");
out.append("<h1>Pessoa</h1>");
out.append("</body>");
out.append("</html>");
}
}
setContentType
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
JSP
JavaServer Pages, é uma forma de escrever conteúdo HTML de forma dinámica.
<!DOCTYPE html>
<html>
<head>
<title>Java - aula5</title>
<meta charset="UTF-8">
</head>
<body>
<%
String title = "Pessoa";
%>
<h1><% out.println(title); %></h1>
</body>
</html>
out
Assim como no servlet o jsp pode escrever direto no HTML usando o out.print.. ou pode ser usada o <%= %>
<!DOCTYPE html>
<html>
<head>
<title>Java - aula5</title>
<meta charset="UTF-8">
</head>
<body>
<%
String title = "Pessoa";
%>
<h1><%= title %></h1>
</body>
</html>
import
É possível usar nossas classes dentro do nosso scriptlet.
<%@ page import="java.util.*,
br.com.crescer.aula1.*,
br.com.crescer.aula2.*,
br.com.crescer.aula3.*,
br.com.crescer.aula4.*" %>
JSF
Tecnologia JavaServer Faces é um framework de componentes do lado do servidor para a construção de aplicações web.
Configuração
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<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>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
@ManagedBean
É a anotação que registra a classe como um ManagedBean.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class Hello {
private String helloWorld = "Hello World!";
public String getHelloWorld() {
return helloWorld;
}
public void setHelloWorld(String helloWorld) {
this.helloWorld = helloWorld;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Aula 6</title>
</h:head>
<h:body>
#{hello.helloWorld}
</h:body>
</html>
Tipo de escopo de um ManagedBean.
- NoneScoped
- RequestScoped
- ViewScoped
- SessionScoped
- ApplicationScoped,
Ciclo de vida
Abaixo a imagem explica como funciona um requisição do JSF.
Facelets
É o gerenciador de templates usado no JSF, com ele é possível criar nosso proprios templates e componentes.
- JavaServer Faces Facelets Tag Library (Tags for templating)
- JavaServer Faces HTML Tag Library (JavaServer Faces component tags for all UIComponent objects)
- JavaServer Faces Core Tag Library (Tags for JavaServer Faces custom actions that are independent of any particular render kit)
- JSTL Core Tag Library (JSTL 1.2 Core Tags)
- JSTL Functions Tag Library (JSTL 1.2 Functions Tags)
Template
Usando o facelets para criar um template.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Aula 6</title>
</h:head>
<h:body>
<ui:insert name="body"></ui:insert>
</h:body>
</html>
form
Todo o envio de informação para o nosso bean deve ser feito de dentro de um form
<h:form>
<h:panelGrid>
<h:outputText id="out" value="#{hello.helloWorld}"/>
<h:inputText value="#{hello.helloWorld}"/>
</h:panelGrid>
</h:form>
faces-config.xml
É o arquivo de configurações para o JSF.
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
</faces-config>
Internacionlização
O JSF nos permite internacionalizar nossa aplicação conforme usando um bundle apenas configurando o mesmo no faces-config.xml.
<application>
<resource-bundle>
<base-name>messages</base-name>
<var>bundle</var>
</resource-bundle>
<locale-config>
<default-locale>pt_BR</default-locale>
<supported-locale>en_US</supported-locale>
</locale-config>
</application>
Criando um arquivo de properties (messages_pt_BR.properties).
hello=Hello World!
Navegação
O JSF nos permite usar sua navegação definida no faces-config.xml.
<navigation-rule>
<from-view-id>/index.xhtml</from-view-id>
<navigation-case>
<from-outcome>hello</from-outcome>
<to-view-id>/hello.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
No arquivo .xml
<h:commandLink value="hello" action="hello"/>
Filter
Filtros são definidos para processar as requisições antes que entre no ciclo de vida do JSF. O Filter tem varias aplicações, com validador de sessão, manipular a entrada e saída da requisição, etc.
@WebFilter(filterName = "MyFilter", urlPatterns = {"*.xhtml"})
public class MyFilter implements Filter {
Converter
Converter classes que definimos para converter tanto entrada como saída de valores em requisições JSF
@FacesConverter
public class DateConverter implements Converter {
private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy");
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
try {
return value != null ? SIMPLE_DATE_FORMAT.parse(value) : null;
} catch (ParseException ex) {
return null;
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return SIMPLE_DATE_FORMAT.format((Date) value);
}
}
Validator
Podemos implementar nossa propria validação.
@FacesValidator("emailValidator")
public class EmailValidator implements Validator{
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
//...
}
}
Spring Boot
É um framework que engloba o spring framework com um direcionamento a convenções para facilitar a configuração e o start do desenvolvimento.
Configuração
Para configurarmos um projeto devemos tem um pom.xml conforme o descrito abaixo.
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<groupId>br.com.crescer</groupId>
<artifactId>spring-crescer-web</artifactId>
<version>1.0.0.0</version>
<!--<packaging>war</packaging>-->
<name>spring-crescer-web</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
</repositories>
</project>
Criando uma classe para iniciar o projeto.
package br.com.crescer.aula7;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Carlos H. Nonnemacher
*/
@SpringBootApplication
public class Run {
public static void main(String[] args) throws Exception {
SpringApplication.run(AppRun.class, args);
}
}
br.com.crescer.aula7.Run.java
@Controller
É um esteriótipo do spring para criar um bean, similar ao managedBean que vimos no JSF.
package br.com.crescer.aula7.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @author Carlos H. Nonnemacher
*/
@Controller
public class Example {
@RequestMapping(value = "/")
String toIndex(Model model) {
model.addAttribute("name", "Carlos H. Nonnemacher");
return "index";
}
}
@RequestMapping
Define a quel URL aquele metodo irá responde.
@RequestMapping(value = "/", method = RequestMethod.GET)
method
é um atributo que definie o tipo assim como os metodos doGet do Servlet, abaixo outras formas de abreviar o mapeamento.
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
@RequestParam
Passa um parametro para o metodo conforme URL
@RequestMapping(value = "/", method = RequestMethod.GET)
String toIndex(@RequestParam String name) {
}
@PathVariable
Utilizado para definir rotas dinamicas
@RequestMapping(value = "/pessoa/{id}", method = RequestMethod.GET)
Pessoa getPessoa(@PathVariable Long id) {
}
@ResponseBody
Anotação defini que nosso retorno será um JSON
@ResponseBody
@RequestMapping(value = "/current_date_time")
public Date date() {
return new Date();
}
// "yyyy-MM-dd HH:mm:ss"
@RequestBody
No corpo da requisição estou enviando um JSON.
@ResponseBody
@RequestMapping(value = "/pessoa.json", method = RequestMethod.POST)
public List<Pessoa> list(@RequestBody Pessoa p) {
p.setNascimento(new Date());
return Stream.of(p).collect(Collectors.toList());
}
@RestController
Quando utilizo uma RestController digo que todos os meus retornos serão JSON.
@RestController
public class PessoaRest {
@RequestMapping(value = "/current_date_time")
public Date date() {
return new Date();
}
@RequestMapping("/pessoa")
public List<Pessoa> list() {
Pessoa p = new Pessoa();
p.setNome("Carlos H. Nonnemacher");
p.setNascimento(new Date());
return Stream.of(p).collect(Collectors.toList());
}
}
@Autowired
O autowired é a anotação usada no core do spring pra sinalizar um injeção de dependencia.
@RestController
public class PessoaRest {
@Autowired
PessoaService service;
5 @Service
É outro esteriótipo do spring que no permite criar classes para definir nelas regras do negocio.
@Service
public class PessoaService {
public List<Pessoa> list() {
Pessoa p = new Pessoa();
p.setNome("Carlos H. Nonnemacher");
p.setNascimento(new Date());
return Stream.of(p).collect(Collectors.toList());
}
}
@Component
É outro esteriótipo do spring que no permite criar classes para definir nelas regras do negocio.
@Component
public class DateUtils {
//...
}
application.properties
Arquivo de configuração onde temos todas as definições da nossa aplicação.
# definições do servidor
server.port=9090
# spring debug out
#debug=true
# definições do datasource
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.username=cwi
spring.datasource.password=cwi
# definições do hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.show_sql=true
spring.jpa.hibernate.format_sql=true
# JSON format
#spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#spring.jackson.time-zone=America/Sao_Paulo
/src/main/resources/application.properties
messages.properties
Arquivo contem as definições da internacionalização, similar ao do JSF.
Thymeleaf
É uma das varias e a mais adotada template engine que podem ser usadas com Spring.
/src/main/resources/templates/index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>thymeleaf</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<h1 th:text="'Hello World! ' + ${name}"/>
</body>
</html>
Spring Data
Spring Data assim como o MVC é um framework incorporado ao boot, facilita muito a manipulação de entidades de banco.
Repository
Repository é um interface que por magia cria mantem um transação para cada metódo definido.
import br.com.crescer.entity.Pessoa;
import org.springframework.data.repository.Repository;
/**
* @author Carlos H. Nonnemacher
*/
public interface PessoaRepository extends Repository<Pessoa, Long> {
}
CrudRepository
Assim com o Repository o crud também é uma interface mas que nos traz métodos basicos para inclusão, exclusão, listar
import br.com.crescer.entity.Pessoa;
import org.springframework.data.repository.CrudRepository;
/**
* @author Carlos H. Nonnemacher
*/
public interface PessoaRepository extends CrudRepository<Pessoa, Long> {
}
9.3 @Query
Anotação onde podemos definir nossa query.
import br.com.crescer.entity.Pessoa;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
/**
* @author Carlos H. Nonnemacher
*/
public interface PessoaRepository extends CrudRepository<Pessoa, Long> {
@Override
@Query("select p from Pessoa p where p.nome ...")
public List<Pessoa> findAll();
}
PagingAndSortingRepository
Para usarmos paginação assim como um repositório o spring data prove uma interface que estende o CrudRepository.
import br.com.crescer.entity.Pessoa;
import org.springframework.data.repository.PagingAndSortingRepository;
/**
* @author Carlos H. Nonnemacher
*/
public interface PessoaRepository extends PagingAndSortingRepository<Pessoa, Long> {
}
Pageable - Controllers + Paginação
Para usarmos a paginação dentro do MVC nossas controllers deveram receber em seus (os que terão paginação) um novo parametro Pageable.
@RequestMapping(value="/listAll", method = RequestMethod.GET)
public String listAll(Model model, Pageable pageable) {
Page<Pessoa> pessoas = service.findAll(pageable);
model.addAttribute("pessoas", pessoas);
return "pessoa";
}
// Implementação do service.
public Page<Pessoa> findAll(Pageable pageable) {
return repository.findAll(pageable);
}
Thymeleaf
th:if
Caso a expressão retorne true vai exibir a tag.
<a th:if="${not pessoas.first}"
th:class
Caso a expressão retorne true vai colocar a class na tag
<li th:class="${pessoas.first} ? 'disabled' : ''">
th:each
Exemplo de uso de for
th:each="i : ${#numbers.sequence(0, pessoas.totalPages -1)}"
th:href
Cria um link, onde pode ser adicionado parâmetros
th:href="@{${'/pessoa'}(page=${i},size=${pessoas.size})}"
th:fragment
Defini um fragmento que poderemos utilizar com o th:replace
th:fragment="navbar"
th:replace
O replace como o nome diz vai pegar substituir por seu conteudo.
th:replace="fragments :: paginator(${pessoas}, '/pessoa')"
Spring Security
Essa api é bem ampla, onde podemos usar de tokens a single single on, o que veremos a seguir é um custom para autenticação usando um estrutura própria.
Aditivos do pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
WebSecurityConfigurerAdapter
Classe abstrata usada para a configuração do spring security
package br.com.crescer.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* @author Carlos H. Nonnemacher
*/
@Configuration
public class CrescerWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
CrescerUserDetailsService crescerUserDetailsService;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.permitAll();
}
@Autowired
public void setDetailsService(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(crescerUserDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
}
UserDetailsService
É a interface que retorna o usuário (userdetails) conforme o logon.
package br.com.crescer.security;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
/**
* @author Carlos H. Nonnemacher
*/
@Service
public class CrescerUserDetailsService implements UserDetailsService {
private static final String CRESCER = "crescer";
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username.isEmpty()) {
throw new UsernameNotFoundException(String.format("User with username=%s was not found", username));
}
return new User(username, new BCryptPasswordEncoder().encode(CRESCER), Roles.valuesToList());
}
}
Roles
O spring vai trabalhar com rules ou seja, toda url pode exigir uma role para acesso.
package br.com.crescer.security;
import java.util.Arrays;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
/**
* @author Carlos H. Nonnemacher
*/
public enum Roles implements GrantedAuthority {
USER;
@Override
public String getAuthority() {
return toString();
}
public static List<Roles> valuesToList() {
return Arrays.asList(Roles.values());
}
}