Session – Login – Logout – Timeout – Java

Publicado: 26 de novembro de 2014 em Java

Tarefas de gerenciamento de sessão típicas incluem manter o controle de quais aplicativos estão abertos e documentar cada aplicativo que abriu, para que o mesmo estado possa ser restaurado quando o usuário sair e entrar novamente mais tarde. Você também pode utilizar a Session para criar áreas restritas de um website que podem ser acessadas pela sessão de um usuário, você também pode definir um tempo para que esta sessão fique ativa no navegador do usuário autenticado.

Para um site, gerenciamento de sessão pode envolver e exigir que o usuário reinicie sessão se a sessão expirou ou seja, se um certo limite de tempo passou sem a atividade do usuário. A sessão também é usada para armazenar informações no lado do servidor entre solicitações HTTP. Este tipo de conceito básico é o principio do esquema de autenticação utilizado por vários websites, entretanto a partir deste esquema básico pode-se criar métodos mais eficientes para utilizar este conceito.

Criando uma Sessão

GetSession

Retorna a sessão atual associado a este pedido, ou se o pedido não tem uma sessão, cria uma.

https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html#getSession()

SetAttribute

Vincula um objeto para esta sessão, usando um nome especificado. Se um objeto do mesmo nome já está ligado à sessão, o objeto é substituído.

https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.html

Utilizando Sessions – Login, Logout e Timeout

1 – Crie um projeto web dinâmico e os Servlets chamados Autenticar, SairAreaComunitaria, utilize o código abaixo para cada respectivo arquivo e rode a aplicação. Você pode tentar chamar a pagina AreaComunitaria sem utilizar o usuário e senha, digitando o nome do Servlet na url do navegador e constatará que não pode acessar a pagina devido a inexistência da sessão para seu usuário. Efetue o Login para criar a sessão:

Session - Login

Session – Login

2 – Assim que efetuar o login você será direcionado a área comunitária podendo então acessar a pagina da comunidade, caso clique no link sair, a sessão será invalidada e você será redirecionado para a tela de login:

Session - Área Comunitária

Session – Área Comunitária

3 – Ao incluir as tags de configuração da sessão no arquivo web.xml você pode definir o tempo em minutos que deseja que sessão seja valida. Use o código do arquivo xml abaixo para fazer com que a sessão dure 1 minuto, efetue o login, aguarde um minuto e atualize a pagina, com a sessão expirada você será redirecionado novamente para a pagina de login:

Session - Timeout

Session – Timeout

Exemplo:

Neste exemplo criamos uma pagina de login com a funcionalidade de autenticar em uma pagina somente para membros da comunidade e utilizamos o recurso de timeout da sessão para que ela expire assim que o usuário estiver autenticado por 1 minuto.

Obs: usuário: DevAberto e a senha: 1234

Java

Servlet – Autenticar

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/Autenticar")
public class Autenticar extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public Autenticar() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// Mostra pagina HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto</h1>");
		html.println("<h2>Login: </h2>");

		// Formulário processa este mesmo Servlet e o método DoPost
		html.println("<form action='Autenticar' method='post'>");

		html.println("Nome  : <input type='text' name='nome' size ='40' /> <br>");
		html.println("Senha : <input type='password' name='senha' size ='40' /> ");
		html.println("<input type='submit' name='login' value='Login'/> <br>");

		html.println("</form>");
		html.println("</body>");
		html.println("</html>");

	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String usuario = request.getParameter("nome");
		String senha = request.getParameter("senha");

		// Verifica usuario e senha
		// provavelmente você utilizará um banco de dados
		// Neste exemplo utilizaremos valores fixos

		if (usuario.equals("DevAberto") && senha.equals("1234")) {
			request.getSession().setAttribute("usuario", usuario);
			response.sendRedirect("AreaComunidade");
		} 
		else {
			response.sendRedirect("Autenticar");
		}

	}

}

Servlet – Sair

package org.desenvolvimento.aberto;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/Sair")
public class Sair extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public Sair() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Invalida sessão e redireciona para login
		request.getSession().invalidate();
		response.sendRedirect("Autenticar");
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
	}

}

Servlet – AreaComunitaria

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/AreaComunidade")
public class AreaComunidade extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public AreaComunidade() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Mostra pagina HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		String usuario = (String) request.getSession().getAttribute("usuario");

		if (usuario != null) {
			html.println("<html>");
			html.println("<body>");
			html.println("<h1>Desenvolvimento Aberto</h1>");
			html.println("<h2>Area da Comunidade - Java  </h2>");
			html.println("<h3>Bem-vindo: " + usuario + "</h3>");
			html.println("<p><a href='Sair'>Sair</a></p>");
			html.println("</body>");
			html.println("</html>");
		}
		else
		{
			response.sendRedirect("Autenticar");
		}
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
	}

}

Config – web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>DACliente</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
	<session-config>
		<session-timeout>1</session-timeout>
	</session-config>
</web-app>

JSP – Cookie e Session Attribute – Java

Publicado: 25 de novembro de 2014 em Java

Em ciência da computação, uma sessão é um intercâmbio semipermanente de informações interativas, também conhecido como um diálogo, uma conversa ou uma reunião, entre dois ou mais dispositivos de comunicação, ou entre um computador e usuário. Uma sessão HTTP é uma sequência de transações de rede de requisição-resposta e se dá da seguinte forma, um cliente HTTP inicia uma requisição estabelecendo uma conexão Transmission Control Protocol (TCP) para uma porta particular de um servidor. Um servidor HTTP ouvindo naquela porta espera por uma mensagem de requisição de cliente. Recebendo a requisição, o servidor retorna uma linha de estado, como “HTTP/1.1 200 OK“, e uma mensagem particular própria. O corpo desta mensagem normalmente é o recurso solicitado, apesar de uma mensagem de erro ou outra informação também poder ser retornada.

Um identificador de sessão, ID da sessão ou token de sessão é um pedaço de dados que é usado em comunicações de rede  para identificar uma sessão, uma série de trocas de mensagens relacionadas. As sessões são identificadas por único identificador (ID) no qual é associado aos dados criados no servidor, este identificador é gerado aleatoriamente e de difícil falsificação. O rastreamento de sessões é efetuado por padrão através de cookies.

HTTP Session: https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.html

Utilizando Cookies e Sessions

1 – Crie um novo projeto web dinâmico e crie um novo Servlet chamado MeuCookie e MinhaSessao, utilize o código abaixo e rode sua aplicação, enquanto a aplicação está rodando na instancia do Tomcat do Eclipse, abra o seu navegador padrão e cole a url do navegador interno do Eclipse em seu browser, neste exemplo utilizamos o Firefox e logo após a pagina ser exibida digite seu nome no campo de texto e clique no botão da pagina:

Cria Cookie

Cookie

2 – Assim que o método do botão for executado, um cookie e um atributo para a sessão serão criados, a pagina seguinte não lerá o nome guardado no cookie e sim no atributo da sessão criada no servidor através de seu identificador, você pode abrir outras instancias do navegador e copiar e colar a url para que você brinque com a sessão.

Sessão

Sessão

3 – Para ver o cookie e a sessão criada no seu navegador, abra Opções no menu do Firefox e escolha a aba privacidade:

Firefox - Opções -  Privacidade

Firefox – Opções – Privacidade

4 – Clique no link excluir cookies em particular e digite no campo de busca, localhost. Selecione o cookie pelo seu nome e você pode ver os dados gravados no mesmo.

Firefox - Cookie

Firefox – Cookie

5 – Selecione a opção JSESSIONID e você verá o ID da sessão em você está conectado, assim que você fechar o browser o cookie e a sessão serão excluídos.

Session ID

Session ID

Exemplo:

Neste exemplo criamos um cookie e definimos um atributo para a sessão com o valor do cookie e logo recuperamos o atributo da sessão para que possamos exibir o valor gravado no cookie.

Java

Servlet – MeuCookie

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MeuCookie")
public class MeuCookie extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public MeuCookie() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Mostra pagina HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto</h1>");
		html.println("<h2>Cookies - Memoriza Dados</h2>");

		// Formulário processa este mesmo Servlet e o método DoPost
		html.println("<form action='MeuCookie' method='post'>");

		// Manipula cookie
		String nome = getDaCookieNome(request);
		if (nome != null)
			html.println("Nome: " + nome + " <br> ");
		else {
			html.println("Nome: <input type='text' name='nome' size ='55' /> ");
			html.println("<input type='submit' name='adiciona' value='Adicionar'/> <br>");
		}

		html.println("<a href='MinhaSessao'>testar Sessão</a>");
		html.println("</form>");
		html.println("</body>");
		html.println("</html>");
	}

	private String getDaCookieNome(HttpServletRequest request) {

		// Recupera cookie
		for (Cookie cookie : request.getCookies())
			if (cookie.getName().equals("DAname3"))
				return cookie.getValue();

		return null;
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Recupera cookie
		String nome = getDaCookieNome(request);

		if (nome == null) {

			// Recupera parâmetro
			nome = request.getParameter("nome");

			// Define sessão
			request.getSession().setAttribute("DAname3", nome);

			// Cria Cookie
			Cookie cookie = new Cookie("DAname3", nome);

			// Redireciona página
			response.addCookie(cookie);

			// Redireciona página
			response.sendRedirect("MinhaSessao");
		}
	}
}

 

Servlet – MinhaSessao

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MinhaSessao")
public class MinhaSessao extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public MinhaSessao() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Mostra pagina HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto</h1>");
		html.println("<h2>Cookies Sessão- Memoriza Dados Por Sessão</h2>");

		// Recupera sessão
		String nome = (String) request.getSession().getAttribute("DAname3");

		if (nome != null)
			html.println("Nome: " + nome + " <br> ");
		else {
			html.println("Nome: Não identificado  <br> ");
		}

		html.println("</form>");
		html.println("</body>");
		html.println("</html>");
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
	}

}

JSP – Cookies – Java

Publicado: 24 de novembro de 2014 em Java

Um cookie é um pequeno pedaço de dados enviado de a partir de um website e armazenado em um arquivo de texto criado no computador do usuário enquanto ele está navegando em um site. Cada vez que o usuário carrega o website, o navegador envia o cookie de volta ao servidor para notificar o site da atividade prévia do usuário. Os cookies foram projetados para serem um mecanismo confiável para sites recordarem informações de estado ou para registrar a atividade de navegação do usuário.

Cookie é um assunto que trouxe e ainda levanta muita controvérsia no universo da computação para web, devido a questões de segurança quanto a manipular informações no computador local, fazem com que todos os tipos de usuários se preocupe com as informações utilizadas em websites principalmente se utilizar computadores que são compartilhados com varias pessoas como em lan houses ou outros.

Java possui a classe Cookies que permite que o desenvolvedor manipule cookies em suas aplicações web seguindo as especificações do RFC 2109, está classe representa os valores de um cookie HTTP.

Cookies: https://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Cookie.html

Utilizando Cookies

1 – Crie um novo projeto web dinâmico e crie um novo Servlet chamado MeuCookie, utilize o código abaixo e rode sua aplicação, digite seu nome no campo de texto e clique no botão:

Cookie - Java

Cookie – Java

2 – Assim que o botão recebe o evento de clique o método doPost cria o cookie no computador local guardando em seu arquivo o nome do usuário, a pagina é recarregada e o cookie é lido automaticamente, toda vez que você tentar recarregar esta página o cookie será lido e o nome guardado automaticamente preenchido:

Cookie - Nome

Cookie – Nome

Exemplo:

Neste exemplo criamos uma página que grava e lê um cookie no computador local.

Java

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MeuCookie")
public class MeuCookie extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public MeuCookie() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Mostra pagina HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto</h1>");
		html.println("<h2>Cookies - Memoriza Dados</h2>");

		// Formulário processa este mesmo Servlet e o método DoPost
		html.println("<form action='MeuCookie' method='post'>");

		// Manipula cookie
		String nome = getDaCookieNome(request);
		if (nome != null)
			html.println("Nome: " + nome + " <br> ");
		else {
			html.println("Nome: <input type='text' name='nome' size ='55' /> ");
			html.println("<input type='submit' name='adiciona' value='Adicionar'/> <br>");
		}

		html.println("</form>");
		html.println("</body>");
		html.println("</html>");
	}

	private String getDaCookieNome(HttpServletRequest request) {
		
		// Recupera cookie
		for (Cookie cookie : request.getCookies())
			if (cookie.getName().equals("DAname1"))
				return cookie.getValue();

		return null;
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String nome = getDaCookieNome(request);
		if (nome == null) {

			nome = request.getParameter("nome");

			// Cria Cookie
			Cookie cookie = new Cookie("DAname1", nome);
			
			// Redireciona página
			response.addCookie(cookie);

			// Redireciona página
			response.sendRedirect("MeuCookie");
		}
	}

}

JSP – HTTP – Responses – Status Code – Java

Publicado: 20 de novembro de 2014 em Java

A cada solicitação do protocolo HTTP o servidor indica uma resposta provisória, consistindo somente da linha de status e cabeçalhos opcionaisencerrado por uma linha vazia. As respostas podem conter por exemplo erros de HTTP que são enviados para o navegador da Web pelo servidor se um problema for encontrado durante a tentativa de exibir uma página da Web. Se a página da Web não for exibida, o servidor exibirá a página de erro real enviada pelo site ou uma mensagem de erro amigável.

As vezes é útil criar uma pagina customizada para as paginas geradas automaticamente pelo servidor pois o mesmo pode mostrar nestas paginas informações que não queremos que o usuário remoto tenha conhecimento, além das boas praticas e uma mensagem esteticamente amigável, ainda temos entre os motivos, a segurança.

Para uma lista completa de todos os códigos de resposta enviados pelo servidor utilize o link abaixo:

Response Status Code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Customizando uma Página de Erro

1 – Crie um projeto Java Web dinâmico, crie uma nova pagina chamada de index.jsp, utilize o código abaixo para o XHTML da pagina e rode a aplicação:

Index.jsp

Index.jsp

2 – Clique no link “Java” para que você obtenha a pagina de erro com a resposta gerada pelo servidor:

Response - Erro - 404

Response – Erro – 404

3 – Para substituir a pagina automática por uma pagina mais amigável precisamos capturar a resposta do servidor e exibir uma pagina com informações customizadas, entretanto não queremos que o usuário tenha acesso a esta pagina via o navegador, então precisamos criar uma pagina chamada de 404.jsp na pasta chamada WEB-INF e alterar o web.xml localizado na mesma pasta, redirecionando a resposta 404 para a pagina 404.jsp. Crie a pagina 404.jsp e altere o arquivo web.xml utilizando os respectivos códigos abaixo, em seguida rode a aplicação e com ela rodando copie a URL e cole no seu navegador:

Aplicação - Firefox

Aplicação – Firefox

4 – Clique novamente na opção “Java” e sua pagina customizada será exibida sem que nenhuma informação do servidor e de sua aplicação seja apresentada para o usuário remoto:

Response 404 - Customizada

Response 404 – Customizada

Exemplo:

Neste exemplo utilizamos a resposta do servidor para substituir a mensagem de erro 404 por uma mensagem exibida em uma pagina customizada.

Java

index.jsp

<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Desenvolvimento Aberto - HTTP Respostas</title>
<style>
#header {
	background-color: Black;
	color: white;
	text-align: center;
	padding: 5px;
}

#nav {
	line-height: 30px;
	background-color: #eeeeee;
	height: 400px;
	width: 100px;
	float: left;
	padding: 5px;
}

#section {
	width: 450px;
	float: left;
	padding: 10px;
}

#footer {
	background-color: Black;
	color: white;
	clear: both;
	text-align: center;
	padding: 5px;
}
</style>

</head>
<body>
	<div id="header">
		<h1>Desenvolvimento Aberto</h1>
	</div>

	<div id="nav">

		<!-- HTTP Response: 

	     Este link referencia uma página que não existe,
	     deste modo o servidor nos enviará um erro 404  -->
		<p>
			<a href='nao-existe.jsp'>Java</a>
		</p>
		<p>JSP</p>
		<p>JavaBeans</p>
		<p>Servlet</p>

	</div>

	<div id="section">
		<h2>Desenvolvimento Aberto</h2>
		<p>Desenvolvimento Aberto é uma organização voltada para o
			aprendizado e discussão de técnicas de desenvolvimento focado em
			algumas linguagens de programação sendo parcialmente/totalmente
			abertas ou com licenças gratuitas para desenvolvedores de cada uma de
			suas respectivas marcas registradas.</p>
		<p>Desenvolvimento Aberto foi escrito e desenvolve utilizando
			ferramentas gratuitas disponibilizadas pelas melhores empresas de
			software da atualidade, incluindo a própria hospedagem e design deste
			site, sendo assim, também proporciona conteúdo gratuito, isso quer
			dizer que você não paga nada para aprender e utilizar as tecnologias
			de ponta que podem ser manuseadas através das linguagens de
			programação mais requisitadas pelas empresas no mercado atual.</p>
	</div>

	<div id="footer">Desenvolvimento Aberto ©
		desevolvimento.aberto@live.com</div>

</body>
</html>

404.jsp

<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Desenvolvimento Aberto - 404</title>
</head>
<body>
	<h1>Desenvolvimento Aberto:</h1>
	<h3>Desculpe! Não encontramos a página solicitada no servidor.</h3>
</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>DaRespostas</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
	<error-page>
		<error-code>404</error-code>
		<location>/WEB-INF/404.jsp</location>
	</error-page>
</web-app>

SAP MaxDB é um banco de dados estratégico criado para rodar em todas as soluções SAP e substituir os bancos de dados Oracle, IBM DB2 e MSSQL Server  tornando as soluções SAP mais acessíveis em termos de custo para clientes de grande e médio porte. O SAP MaxDB foi construído como uma solução open source baseado em MySQL sob a licença GNU GPL, as versão anteriores do MaxDB ainda são mantidas pela comunidade open source mas a SAP não contribui mais com estas versões.

Ao longo dos últimos anos, a tecnologia SAP MaxDB continuou a evoluir com investimentos muito significativos em inovações e essas inovações não são em código aberto. Assim o mais recente produto SAP MaxDB não é open source, entretanto ele é gratuito em sua versão comunitária para uso com aplicações não SAP e possui licença comercial para uso com aplicações SAP.

Com 40 anos de inovação atuando em mais de 130 países e com mais de 100 mil clientes que utilizam soluções SAP, o SAP MaxDB ainda é um banco de dados jovem mas conta com mais de 6.500 clientes em 15.000 instalações mais soluções que utilizam liveCache e Content Server.

SAP MaxDB: http://maxdb.sap.com/

SAP MaxDB e C++ MFC

O C++ MFC utiliza as classes de fundação Microsoft e é a linguagem padrão para se desenvolver aplicativos Desktop C++ para Windows, você precisa no mínimo de uma versão profissional do Visual Studio para utilizar este framework.

A SAP disponibiliza uma API para utilizar o MaxDB com a linguagem de programação C++ utilizando os sistemas operacionais Unix, Linux e Windows, possibilitando integrar soluções Enterprise SAP que utilizam o banco de dados MaxDB com aplicações escritas em C++ ou permite que aplicações C++ utilizem o SAP MaxDB gratuitamente também em soluções que não possuem o intuito de integrar dados com os sistemas SAP.

Softwares Requeridos

Para utilizar este walkthrough completo integrando uma solução C++ com a linguagem de programação ABAP, você precisa instalar vários software entres eles o NetWeaver Application Server ABAP no qual já possui uma instalação completa do ambiente de desenvolvimento SAP com uma instancia do banco de dados MaxDB, caso queira utilizar somente o lado C++ você pode baixar o SAP MaxDB diretamente da SAP Store:

NetWeaver Application Server ABAP: Mini SAP

Download SAP MaxDB sistemas não SAP: SAP Store

SAP MaxDB SQL Studio: Desenvolvimento Aberto walkthrough

API C++ e  Drivers ODBC

Microsoft Fundation Classes permite utilizar suas classes para conectar ao MaxDB de um modo simples através do protocolo padrão ODBC, no entanto os drivers ODBC disponibilizados pela SAP não possuem a mesma arquitetura para aplicativos win32 (código nativo)  x64, então precisamos utilizar o driver 32bit disponibilizado pelo SAP MaxDB SQL Studio.

Caso não queira utilizar as classes MFC, a instalação do SAP MaxDB incluída nos produtos SAP como o núcleo de desenvolvimento do sistema SAP R/3 chamado de NetWeaver Application Sever ABAP já comtempla uma API C++ para que você possa acessar o banco de dados MaxDB e se encontra no seguinte local:

C:\sapdb\clients\NSP\sdk\sqldbc\incl
C:\sapdb\NSP\db\doc\FirstSteps\SQLDBC

Conectando ao MaxDB NSP com C++

1 – Caso utilize este tutorial com o NetWeaver primeiro tenha certeza que servidor de aplicação e a instancia SAP do banco de dados está rodando, caso utilize apenas o MaxDb e C++ ignore este passo:

SAP - Servidor de Aplicação - e Banco de dados - NetWeaver/MaxDB

SAP – Servidor de Aplicação – e Banco de dados – NetWeaver/MaxDB

2 – Abra o SQL Studio utilizando o servidor MaxDB e o banco de dados NSP ou seu próprio banco de dados caso não utilize o sistema SAP:

NSP - NetWeaver Database

NSP – NetWeaver Database

3 – Crie uma tabela Z que significa uma tabela não SAP Standard que não será transparente no conceito do dicionário de dados do sistemas SAP para isto utilize o script logo abaixo, não se assuste para desenvolvedores não SAP isto é apenas uma tabela comum do banco de dados:

Tabela Não Transparente

Tabela Z Não Transparente

4 – Utilizaremos os drivers ODBC do SAP MaxDB SQL Studio. No painel de controle escolha ferramentas administrativas e fonte de dados ODBC de 32bit, em drivers verifique seu driver NSP:

ODBC 32bit

ODBC 32bit

5 – Crie uma nova fonte de dados do usuário escolha o driver NSP ou o driver apropriado e clique em concluir:

ODBC SQLSTUDIO

ODBC SQLSTUDIO

6 – Preencha os dados de conexão com o servidor e o banco de dados e finalize:

Dados Servidor

Dados Servidor

7 – No Visual Studio crie uma solução MFC Dialog Based e disponha na tela um Static Text, um List Control e um Button, utilize a figura abaixo para o design:

Design Time

Design Time

8 – Utilize o código abaixo para manipular dados utilizando o SAP MaxDB:

C++ - Programa

C++ – Programa

9 – Para utilizar o ABAP para ler ou gravar dados nesta mesma tabela não transparente utilizando uma Stored Procedure no MaxDB através de códigos Native SQL, utilize o link abaixo:

Stored Procedure - Abap

Stored Procedure – Abap

Programa SAP – ABAP Native SQL: MaxDB Stored Procedure parâmetros IN e OUT

 Caso conecte em um banco de dados MaxDB utilizando soluções SAP tenha em mente que você deve respeitar o conceito de dados dos sistemas SAP e verificar os termos de garantia de cada produto SAP, visto que este método ao contrario do RFC  ignora a camada de banco de dados SAP e o dicionário de dados ABAP.

Como você pode verificar na imagem acima no ambiente ABAP o valor flutuante não vem formatado por padrão como estão acostumados os desenvolvedores SAP que utilizam instruções Open SQL e o dicionário ABAP no entanto você pode utilizar campos criados no dicionário apenas para a manipulação do valor de saída da Stored Procedure neste caso você deve alinhar os tipos de dados entre as aplicações C++ e aplicações ABAP.

Exemplo:

Neste exemplo utilizamos a linguagem de programação C++ para conectar ao banco de dados SAP MaxDB em uma instancia do banco de dados do NetWeaver e integrar uma tabela não transparente que pode ser manipulada tanto do lado C++ como dentro do sistema SAP utilizando Native SQL.

SQL – SAP MaxDB

-- Cria tabela no schema SAPNSP
CREATE TABLE SAPNSP.ZFUNCIONARIO
(
            ID_FUNCIONARIO INT,
            NOME VARCHAR (30),
            SOBRENOME VARCHAR(70),
            CARGO VARCHAR(30),
            SALARIO DECIMAL(9,2)
)

-- Insere dados na tabela
Insert into SAPNSP.ZFUNCIONARIO values (1,'Steve','Gates','Programador',2550.56)
Insert into SAPNSP.ZFUNCIONARIO values (2,'Bill','Jobs','Diretor',5143.71)

CPP – arquivo h


// ConexaoSapMaxDBcppDlg.h : header file
//

#pragma once

// Inclui classe de banco de dados MFC
#include "afxdb.h"
#include "afxcmn.h"

// CConexaoSapMaxDBcppDlg dialog
class CConexaoSapMaxDBcppDlg : public CDialogEx
{

public:
	CConexaoSapMaxDBcppDlg(CWnd* pParent = NULL);	// standard constructor
	enum { IDD = IDD_CONEXAOSAPMAXDBCPP_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support


protected:
	HICON m_hIcon;

	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	
	// Cria métodos e objetos da classe
	CDatabase db;
	void conectarDB(CString dns, CString usuario, CString senha);
	afx_msg void OnBnClickedButton1();
	CListCtrl m_tabela;
};

CPP – arquivo cpp


// ConexaoSapMaxDBcppDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ConexaoSapMaxDBcpp.h"
#include "ConexaoSapMaxDBcppDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CConexaoSapMaxDBcppDlg dialog


CConexaoSapMaxDBcppDlg::CConexaoSapMaxDBcppDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CConexaoSapMaxDBcppDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CConexaoSapMaxDBcppDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_tabela);
}

BEGIN_MESSAGE_MAP(CConexaoSapMaxDBcppDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CConexaoSapMaxDBcppDlg::OnBnClickedButton1)
END_MESSAGE_MAP()


// CConexaoSapMaxDBcppDlg message handlers

BOOL CConexaoSapMaxDBcppDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// Inicializa dialogo
	// Cria o modelo de exibição de dados
	m_tabela.SetView(LV_VIEW_DETAILS);
	m_tabela.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES);


	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CConexaoSapMaxDBcppDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

HCURSOR CConexaoSapMaxDBcppDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CConexaoSapMaxDBcppDlg::OnBnClickedButton1()
{
	// campo de dado da tabela
	CString m_campo;

	// Abre conexão
         // O SAP MAXDB requer usuário e senha em caracteres UPPERCASE
       	conectarDB(L"SAPMAXDB32", L"SAPNSP", L"PASSWORD");	

	// Cria um set de dados
	CRecordset  dados(&db);

	// Executa instrução SQL
	dados.Open(CRecordset::forwardOnly, L"Select * From SAPNSP.ZFUNCIONARIO Order by 1 DESC");
	

	// Cria item
	LVITEM lvItem;

	// cria estrutura para inserir o item
	typedef struct _LVITEM
	{
		UINT mask;
		int iItem;
		int iSubItem;
		UINT state;
		UINT stateMask;
		LPTSTR pszText;
		int cchTextMax;
		int iImage;
		LPARAM lParam;
#if (_WIN32_IE >= 0x0300)
		int iIndent;
#endif
	} LVITEM, FAR *LPLVITEM;

	// Define variaveis de itens
	int InsertItem(const LVITEM* pItem);
	int nItem;

	// Converte CString para LPTSTR atraves de um TCHAR
	TCHAR sz[1024];

	// Verifica colunas
	short nFields = dados.GetODBCFieldCount();
	int colunas = m_tabela.GetHeaderCtrl()->GetItemCount();

	// Verifica colunas
	if (colunas == 0)
	{
		// Lê metadata da tabela
		CODBCFieldInfo field;
		for (UINT i = 0; i < nFields; i++)
		{
			dados.GetODBCFieldInfo(i, field);
			m_tabela.InsertColumn(i, field.m_strName, LVCFMT_LEFT, 100);
		}

	}

	// Deleta itens do controle de lista
	m_tabela.DeleteAllItems();

	// Recupera dados da tabela
	while (!dados.IsEOF())
	{
		for (short index = 0; index < nFields; index++)
		{
			dados.GetFieldValue(index, m_campo);

			// Retorna linha do banco de dados
			if (index == 0)
			{
				// Insere linha
				lvItem.mask = LVIF_TEXT;
				lvItem.iItem = 0;
				lvItem.iSubItem = 0;
				lvItem.pszText = lstrcpy(sz, m_campo);
				nItem = m_tabela.InsertItem(&lvItem);
			}

			// Retorna colunas da linha
			m_tabela.SetItemText(nItem, index, lstrcpy(sz, m_campo));

		}
		// Move o cursor para a proxima linha
		dados.MoveNext();
	}

	// Fecha o set de dados e a conexão
	dados.Close();
	db.Close();

	
}

void CConexaoSapMaxDBcppDlg::conectarDB(CString dns, CString usuario, CString senha)
{
	// Cria string de conexão ODBC
	CString conexao;

	// Cria string de conexão
	conexao = L"DSN=" + dns + L";UID=" + usuario + L";PWD=" + senha;

	// Abre conexão
	db.OpenEx(conexao, 0);
}

SAP MaxDB é um banco de dados estratégico criado para rodar em todas as soluções SAP e substituir os bancos de dados Oracle, IBM DB2 e MSSQL Server  tornando as soluções SAP mais acessíveis em termos de custo para clientes de grande e médio porte. O SAP MaxDB foi construído como uma solução open source baseado em MySQL sob a licença GNU GPL, as versão anteriores do MaxDB ainda são mantidas pela comunidade open source mas a SAP não contribui mais com estas versões.

Ao longo dos últimos anos, a tecnologia SAP MaxDB continuou a evoluir com investimentos muito significativos em inovações e essas inovações não são em código aberto. Assim o mais recente produto SAP MaxDB não é open source, entretanto ele é gratuito em sua versão comunitária para uso com aplicações não SAP e possui licença comercial para uso com aplicações SAP.

Com 40 anos de inovação atuando em mais de 130 países e com mais de 100 mil clientes que utilizam soluções SAP, o SAP MaxDB ainda é um banco de dados jovem mas conta com mais de 6.500 clientes em 15.000 instalações mais soluções que utilizam liveCache e Content Server.

SAP MaxDB: http://maxdb.sap.com/

SAP MaxDB e C#

A SAP disponibiliza provedores para utilizar o MaxDB com as linguagens de programação .NET utilizando os sistemas operacionais Unix, Linux e Windows, possibilitando integrar soluções Enterprise SAP que utilizam o banco de dados MaxDB com aplicações escritas em C# ou permite que aplicações C# utilizem o SAP MaxDB gratuitamente também em soluções que não possuem o intuito de integrar dados com os sistemas SAP.

SAP ADO.NETInterface ADO.NET

Para utilizar este walkthrough completo integrando uma solução C# com a linguagem de programação ABAP, você precisa instalar vários software entres eles o NetWeaver Application Server ABAP no qual já possui uma instalação completa do ambiente de desenvolvimento SAP com uma instancia do banco de dados MaxDB, caso queira utilizar somente o lado C# você pode baixar o SAP MaxDB diretamente da SAP Store:

NetWeaver Application Server ABAP: Mini SAP

Download SAP MaxDB sistemas não SAP: SAP Store

SAP MaxDB SQL Studio: Desenvolvimento Aberto walkthrough

MaxDB Data Provider ADO.NET e MONO

O provedor ADO.NET for MaxDB RDBMS foi desenvolvido pelo projeto MONO sob a licença GNU para as versões open Source do SAP MaxDB, caso queira utilizar provedores das versões disponibilizadas pela SAP, estas já acompanham a instalação do MaxDB.

Download: http://sourceforge.net/projects/maxdbprovider/

Projeto MaxDB Mono: http://www.mono-project.com/archived/maxdb/

Conectando ao MaxDB em instancia SAP com C#

1 – Caso utilize este tutorial com o NetWeaver primeiro tenha certeza que servidor de aplicação e a instancia SAP do banco de dados está rodando, caso utilize apenas o MaxDb e C# ignore este passo:

SAP - Servidor de Aplicação - e Banco de dados - NetWeaver/MaxDB

SAP – Servidor de Aplicação – e Banco de dados – NetWeaver/MaxDB

2 – Abra o SQL Studio utilizando o servidor MaxDB e o banco de dados NSP ou seu próprio banco de dados caso não utilize o sistema SAP:

NSP - NetWeaver Database

NSP – NetWeaver Database

3 – Crie uma tabela Z que significa uma tabela não SAP Standard que não será transparente no conceito do dicionário de dados do sistemas SAP para isto utilize o script logo abaixo, não se assuste para desenvolvedores não SAP isto é apenas uma tabela comum do banco de dados:

Tabela Não Transparente

Tabela Z Não Transparente

4 – Após efetuar o download do provedor ADO.NET para MaxDB clique com o botão direito do mouse, desbloqueie o arquivo baixado, pois o arquivo foi compilado no Linux, caso contrario o Windows Smart Screen tentara bloquear o arquivo. Clique em instalar:

SAP MaxDb Provider for .NET

SAP MaxDb Provider for .NET

5 – Crie um projeto Windows Forms e disponha na tela um Label, um DataGridView e um Button e alinhe os componentes como na figura abaixo:

Design Time

Design Time

6 – Compile o programa e clique em conectar para se conectar a instancia SAP NSP:

Programa C#

Programa C#

7 – Para utilizar o ABAP para ler ou gravar dados nesta mesma tabela não transparente utilizando uma Stored Procedure no MaxDB através de códigos Native SQL, utilize o link abaixo:

Stored Procedure - Abap

Stored Procedure – Abap

Programa SAP – ABAP Native SQL: MaxDB Stored Procedure parâmetros IN e OUT

 Caso conecte em um banco de dados MaxDB utilizando soluções SAP tenha em mente que você deve respeitar o conceito de dados dos sistemas SAP e verificar os termos de garantia de cada produto SAP, visto que este método ao contrario do RFC  ignora a camada de banco de dados SAP e o dicionário de dados ABAP.

Como você pode verificar na imagem acima no ambiente ABAP o valor flutuante não vem formatado por padrão como estão acostumados os desenvolvedores SAP que utilizam instruções Open SQL e o dicionário ABAP no entanto você pode utilizar campos criados no dicionário apenas para a manipulação do valor de saída da Stored Procedure neste caso você deve alinhar os tipos de dados entre as aplicações C# e aplicações ABAP.

Exemplo:

Neste exemplo utilizamos a linguagem de programação C# para se conectar ao banco de dados SAP MaxDB em uma instancia do banco de dados do NetWeaver e integrar uma tabela não transparente que pode ser manipulada tanto do lado C# como dentro do sistema SAP utilizando Native SQL.

SQL – SAP MaxDB

-- Cria tabela no schema SAPNSP
CREATE TABLE SAPNSP.ZFUNCIONARIO
(
            ID_FUNCIONARIO INT,
            NOME VARCHAR (30),
            SOBRENOME VARCHAR(70),
            CARGO VARCHAR(30),
            SALARIO DECIMAL(9,2)
)

-- Insere dados na tabela
Insert into SAPNSP.ZFUNCIONARIO values (1,'Steve','Gates','Programador',2550.56)
Insert into SAPNSP.ZFUNCIONARIO values (2,'Bill','Jobs','Diretor',5143.71)

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MaxDB.Data; // SAP MaxDB Data Provider for MONO 

namespace WindowsFormsApplication1
{
    public partial class FormMaxDB : Form
    {
        
        // Declara objetos
        private static MaxDBConnection connMaxDB;   // MaxDB Data Server Provider for MONO        
        private DataTable dataTable;
        string sql;
        
        // Conexão MaxDB
        void conexaoMaxDB(string Server, string Database,
                                    string Username, string Password)
        {
            try
            {
                // String de Conexao
                string connectionString =

                    // Servidor
                    "Server=" + Server +

                    // Banco de dados
                    ";Database=" + Database +

                    // Usuario
                    ";User ID=" + Username +

                    // Senha
                    ";Password=" + Password;

                //Conecta ao datasource usando a conexão SAP MaxDB
                connMaxDB = new MaxDBConnection(connectionString);

                //Abre a conexão com o banco de dados
                connMaxDB.Open();

            }
            // Retorna erro
            catch (Exception ex)
            {
                // Mostra menssagem de erro
                MessageBox.Show(ex.ToString());
            }
        }

        // Retorna um set de dados
        public DataTable retornaTabela(string sql)
        {
            FormMaxDB acesso = new FormMaxDB();

            // SAP MaxDB requer usuario e senha em caracteres UPPERCASE
            acesso.conexaoMaxDB("localhost", "NSP", "SAPNSP", "PASSWORD");

            // Cria comando SQL
            MaxDBCommand maxCmd = new MaxDBCommand(sql);
            maxCmd.Connection = connMaxDB;
            
            // Cria DataReader
            MaxDBDataReader maxDBreader = maxCmd.ExecuteReader();
            dataTable = new DataTable();
            dataTable.Load(maxDBreader);
            
            return dataTable;
        }

        public FormMaxDB()
        {
            InitializeComponent();
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            // Alimenta grade de dados
            FormMaxDB dados = new FormMaxDB();            
            dataGridView1.DataSource = dados.retornaTabela("Select * from SAPNSP.ZFUNCIONARIO");
        }
    }
}

SAP MaxDB – Soluções Enterprise com Java

Publicado: 13 de novembro de 2014 em Abap, Java

SAP MaxDB é um banco de dados estratégico criado para rodar em todas as soluções SAP e substituir os bancos de dados Oracle, IBM DB2 e MSSQL Server  tornando as soluções SAP mais acessíveis em termos de custo para clientes de grande e médio porte. O SAP MaxDB foi construído como uma solução open source baseado em MySQL sob a licença GNU GPL, as versão anteriores do MaxDB ainda são mantidas pela comunidade open source mas a SAP não contribui mais com estas versões.

Ao longo dos últimos anos, a tecnologia SAP MaxDB continuou a evoluir com investimentos muito significativos em inovações e essas inovações não são em código aberto. Assim o mais recente produto SAP MaxDB não é open source, entretanto ele é gratuito em sua versão comunitária para uso com aplicações não SAP e possui licença comercial para uso com aplicações SAP.

Com 40 anos de inovação atuando em mais de 130 países e com mais de 100 mil clientes que utilizam soluções SAP, o SAP MaxDB ainda é um banco de dados jovem mas conta com mais de 6.500 clientes em 15.000 instalações mais soluções que utilizam liveCache e Content Server.

SAP MaxDB: http://maxdb.sap.com/

Softwares Requeridos

Para utilizar este walkthrough completo integrando uma solução Java com a linguagem de programação ABAP, você precisa instalar vários software entres eles o NetWeaver Application Server ABAP no qual já possui uma instalação completa do ambiente de desenvolvimento SAP com uma instancia do banco de dados MaxDB, caso queira utilizar somente o lado Java você pode baixar o SAP MaxDB diretamente da SAP Store:

NetWeaver Application Server ABAP: Mini SAP

Download SAP MaxDB sistemas não SAP: SAP Store

SAP MaxDB SQL Studio: Desenvolvimento Aberto walkthrough

 SAP MaxDB JDBC Drivers

A instalação do SAP MaxDB incluída nos produtos SAP como o núcleo de desenvolvimento do sistema SAP R/3 chamado de NetWeaver Application Sever ABAP já comtempla os Drivers Java para que você possa acessar o banco de dados MaxDB.

C:\sapdb\NSP\db\runtime\jar
C:\sapdb\NSP\db\doc\FirstSteps\Java

SAP MaxDB JDBC Drivers: Documentação.

Conectando ao MaxDB em instancia SAP com Java

1 – Caso utilize este tutorial com o NetWeaver primeiro tenha certeza que servidor de aplicação e a instancia SAP do banco de dados está rodando, caso utilize apenas o MaxDb e Java ignore este passo:

SAP - Servidor de Aplicação - e Banco de dados - NetWeaver/MaxDB

SAP – Servidor de Aplicação – e Banco de dados – NetWeaver/MaxDB

2 – Abra o SQL Studio utilizando o servidor MaxDB e o banco de dados NSP ou seu próprio banco de dados caso não utilize o sistema SAP:

NSP - NetWeaver Database

NSP – NetWeaver Database

3 – Crie uma tabela Z que significa uma tabela não SAP Standard que não será transparente no conceito do dicionário de dados do sistemas SAP para isto utilize o script logo abaixo, não se assuste para desenvolvedores não SAP isto é apenas uma tabela comum do banco de dados:

Tabela Não Transparente

Tabela Z Não Transparente

4 – Utilize o Driver descrito acima, através da opção propriedades do seu projeto Java e adicione o arquivo sapdbc.jar nas bibliotecas externas do seu projeto:

Bibliotecas Externas

Bibliotecas Externas

5 – Utilize o código abaixo na IDE Eclipse:

Eclipse - SAPDBC

Eclipse – SAPDBC

 

6 – Compile o programa para manipular dados utilizando o SAP MaxDB:

MaxDB - Java - Programa

MaxDB – Java – Programa

7 – Para utilizar o ABAP para ler ou gravar dados nesta mesma tabela não transparente utilizando uma Stored Procedure no MaxDB através de códigos Native SQL, utilize o link abaixo para o procedimento ABAP:

Stored Procedure - Abap

Stored Procedure – Abap

Programa SAP – ABAP Native SQL: MaxDB Stored Procedure parâmetros IN e OUT

 Caso conecte em um banco de dados MaxDB utilizando soluções SAP tenha em mente que você deve respeitar o conceito de dados dos sistemas SAP e verificar os termos de garantia de cada produto SAP, visto que este método ao contrario do RFC  ignora a camada de banco de dados SAP e o dicionário de dados ABAP.

Como você pode verificar na imagem acima no ambiente ABAP o valor flutuante não vem formatado por padrão como estão acostumados os desenvolvedores SAP que utilizam instruções Open SQL e o dicionário ABAP no entanto você pode utilizar campos criados no dicionário apenas para a manipulação do valor de saída da Stored Procedure neste caso você deve alinhar os tipos de dados entre as aplicações Java e aplicações ABAP.

Exemplo:

Neste exemplo utilizamos a linguagem de programação Java para se conectar ao banco de dados SAP MaxDB em uma instancia do banco de dados do NetWeaver e integrar uma tabela não transparente que pode ser manipulada tanto do lado Java como dentro do sistema SAP utilizando Native SQL.

SQL – SAP MaxDB

-- Cria tabela no schema SAPNSP
CREATE TABLE SAPNSP.ZFUNCIONARIO
(
            ID_FUNCIONARIO INT,
            NOME VARCHAR (30),
            SOBRENOME VARCHAR(70),
            CARGO VARCHAR(30),
            SALARIO DECIMAL(9,2)
)
 
-- Insere dados na tabela
Insert into SAPNSP.ZFUNCIONARIO values (1,'Steve','Gates','Programador',2550.56)
Insert into SAPNSP.ZFUNCIONARIO values (2,'Bill','Jobs','Diretor',5143.71)

Java

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class ConectarMaxDB implements ActionListener, ItemListener {
	// Cria componentes
	private JTable tabela;
	private JRadioButton banco1;
	private JButton botao;

	// Declara objetos de conexão
	private static Connection conn;
	private static Statement query;
	private static String bancodedados;

	public void conectar(String login, String senha) {

		// Verifica strings de conexão
		// SAP MaxDB
		// Utilize senhas com caracteres UPPERCASE
		if (bancodedados == "maxdb") {
			try {
				// Define Driver de conexão JDBC SAP MaxDB
				Class.forName("com.sap.dbtech.jdbc.DriverSapDB");

				// Servidor / Banco de Dados
				conn = DriverManager.getConnection(
						"jdbc:sapdb://localhost/NSP", login, senha);

				// Executa pedido SQL
				query = conn.createStatement();

			}

			catch (ClassNotFoundException ex) {
				ex.printStackTrace();
			}

			catch (SQLException ex) {
				ex.printStackTrace();
			}
		}
	}

	public ResultSet retornaTabela() throws SQLException {
		// Cria uma nova conexão
		Statement query;
		query = conn.createStatement();
		String sql;

		sql = "Select * from SAPNSP.ZFUNCIONARIO";

		// Executa Script
		ResultSet dados = query.executeQuery(sql);

		// Retorna set de dados
		return dados;
	}

	// Modelo
	public static DefaultTableModel criaTableModel(ResultSet rs)
			throws SQLException {

		// Cria um modelo de tabela
		ResultSetMetaData metaData = rs.getMetaData();

		// Retorna as colunas
		Vector<String> colunas = new Vector<String>();

		int columnCount = metaData.getColumnCount();

		for (int column = 1; column <= columnCount; column++) {
			colunas.add(metaData.getColumnName(column));
		}

		// Retorna dados
		Vector<Vector<Object>> dados = new Vector<Vector<Object>>();

		while (rs.next()) {
			Vector<Object> vector = new Vector<Object>();

			for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
				vector.add(rs.getObject(columnIndex));
			}
			dados.add(vector);
		}

		return new DefaultTableModel(dados, colunas);

	}

	public void itemStateChanged(ItemEvent arg0) {

		// Verifica item banco de dados selecionado
		Object fonte = arg0.getItemSelectable();
		int estado = arg0.getStateChange();

		if (estado == arg0.SELECTED) {

			if (fonte == banco1) {
				bancodedados = "maxdb";
			}

		}

	}

	public void actionPerformed(ActionEvent arg0) {
		// Efetua login no banco de dados
		ConectarMaxDB acesso = new ConectarMaxDB();

		// SAP MaxDB utiliza senhas com caracteres maiusculos (UPPERCASE)
		if (bancodedados == "maxdb") {
			acesso.conectar("SAPNSP", "PASSWORD");
		}

		try {
			tabela.setModel(criaTableModel(acesso.retornaTabela()));
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

	public Container criaPainel() throws SQLException {
		// Cria painel principal
		JPanel painel = new JPanel();

		// Seleciona layout
		painel.setLayout(new BoxLayout(painel, BoxLayout.PAGE_AXIS));
		painel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

		// Cria painel de escolha de conexão
		JPanel pescolha = new JPanel();

		pescolha.setLayout(new BoxLayout(pescolha, BoxLayout.LINE_AXIS));
		pescolha.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

		ButtonGroup grupo = new ButtonGroup();

		// Cria componentes de radio
		banco1 = new JRadioButton("SAP MaxDB");

		// Agrupa botões de radio
		grupo.add(banco1);

		// Cria ouvinte dos botões
		banco1.addItemListener(this);

		// Seleciona primeira conexão
		banco1.setSelected(true);

		// Adiciona botões ao painel
		pescolha.add(banco1);

		// Efetua primeira conexão ao banco (SAP MAXDB)
		// SAP MaxDB utiliza senhas com caracteres maiusculos (UPPERCASE)
		ConectarMaxDB acesso = new ConectarMaxDB();
		acesso.conectar("SAPNSP", "PASSWORD");

		// Cria modelo de tabela
		tabela = new JTable(criaTableModel(acesso.retornaTabela()));

		// Adiciona um painel de rolagem
		JScrollPane rolar = new JScrollPane(tabela);

		// Cria painel do botão
		JPanel pbotao = new JPanel();

		// Seleciona layout
		pbotao.setLayout(new BoxLayout(pbotao, BoxLayout.PAGE_AXIS));

		// cria botão
		botao = new JButton("Ler dados");
		botao.addActionListener(this);

		// Adiciona botão ao painel
		pbotao.add(botao);

		// componentes ao painel principal
		painel.add(pescolha);
		painel.add(rolar);
		painel.add(Box.createVerticalStrut(10));
		painel.add(pbotao);

		return painel;
	}

	public static void criaGUI() {
		// Cria formulario
		JFrame formulario = new JFrame("SAP MaxDB - Acessando Dados");
		formulario.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// cria painel de conteudo
		ConectarMaxDB acesso = new ConectarMaxDB();

		try {
			formulario.setContentPane(acesso.criaPainel());
		}

		catch (SQLException e) {
			e.printStackTrace();
		}

		// Exibe o formulario
		formulario.pack();
		formulario.setVisible(true);
	}

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {

				// Cria e mostra a GUI
				criaGUI();

			}
		});
	}
}

SAP MaxDB é um banco de dados estratégico criado para rodar em todas as soluções SAP e substituir os bancos de dados Oracle, IBM DB2 e MSSQL Server  tornando as soluções SAP mais acessíveis em termos de custo para clientes de grande e médio porte. O SAP MaxDB foi construído como uma solução open source baseado em MySQL sob a licença GNU GPL, as versão anteriores do MaxDB ainda são mantidas pela comunidade open source mas a SAP não contribui mais com estas versões.

Ao longo dos últimos anos, a tecnologia SAP MaxDB continuou a evoluir com investimentos muito significativos em inovações e essas inovações não são em código aberto. Assim o mais recente produto SAP MaxDB não é open source, entretanto ele é gratuito em sua versão comunitária para uso com aplicações não SAP e possui licença comercial para uso com aplicações SAP.

Com 40 anos de inovação atuando em mais de 130 países e com mais de 100 mil clientes que utilizam soluções SAP, o SAP MaxDB ainda é um banco de dados jovem mas conta com mais de 6.500 clientes em 15.000 instalações mais soluções que utilizam liveCache e Content Server.

SAP MaxDB: http://maxdb.sap.com/

SAP MaxDB e Python

O Python é uma poderosa linguagem de scripts que já vem se destacando a algum tempo em aplicações para web e ambiente corporativos, a maior empresa de soluções corporativas não poderia deixar de integrar sua aplicações e utilizar os vários benéficos da linguagem de programação Python e da sua crescente comunidade de desenvolvedores.

A SAP disponibiliza módulos para utilizar o MaxDB com a linguagem de programação Python utilizando os sistemas operacionais Unix, Linux e Windows, possibilitando integrar soluções Enterprise SAP que utilizam o banco de dados MaxDB com aplicações escritas em Python ou permite que aplicações Python utilizem o SAP MaxDB gratuitamente também em soluções que não possuem o intuito de integrar dados com os sistemas SAP.

Wiki Python: Sap MaxDB

IMPORTANTE:  Para utilizar este walkthrough completo integrando uma solução Python com a linguagem de programação ABAP, você precisa instalar vários software entres eles o NetWeaver Application Server ABAP no qual já possui uma instalação completa do ambiente de desenvolvimento SAP com uma instancia do banco de dados MaxDB, caso queira utilizar somente o lado Python você pode baixar o SAP MaxDB diretamente da SAP Store:

NetWeaver Application Server ABAP: Mini SAP

Download SAP MaxDB sistemas não SAP: SAP Store

SAP MaxDB SQL Studio: Desenvolvimento Aberto walkthrough

Módulos Python e Drivers ODBC

A instalação do SAP MaxDB incluída nos produtos SAP como o núcleo de desenvolvimento do sistema SAP R/3 chamado de NetWeaver Application Sever ABAP já comtempla módulos Python para que você possa acessar o banco de dados MaxDB porem a instalação suporta apenas a versão Python 2.3 e se encontra no seguinte local:

C:\sapdb\clients\NSP\lib\python2.3
C:\sapdb\NSP\db\doc\FirstSteps\Python

No entanto o banco de dados possui drivers ODBC para que você se conecte com qualquer versão do Python, você encontra detalhes sobre os módulos Python mais recentes e vários exemplos neste link:

MaxDB Python Modules: SAP Manual Python

Conectando ao MaxDB em instancia SAP com Python

1 – Caso utilize este tutorial com o NetWeaver primeiro tenha certeza que servidor de aplicação e a instancia SAP do banco de dados está rodando, caso utilize apenas o MaxDb e Python ignore este passo:

SAP - Servidor de Aplicação - e Banco de dados - NetWeaver/MaxDB

SAP – Servidor de Aplicação – e Banco de dados – NetWeaver/MaxDB

2 – Abra o SQL Studio utilizando o servidor MaxDB e o banco de dados NSP ou seu próprio banco de dados caso não utilize o sistema SAP:

NSP - NetWeaver Database

NSP – NetWeaver Database

3 – Crie uma tabela Z que significa uma tabela não SAP Standard que não será transparente no conceito do dicionário de dados do sistemas SAP para isto utilize o script logo abaixo, não se assuste para desenvolvedores não SAP isto é apenas uma tabela comum do banco de dados:

Tabela Não Transparente

Tabela Z Não Transparente

4 – Como estamos utilizando uma versão mais recente do Python utilizaremos os drivers ODBC do MaxDB. No painel de controle escolha ferramentas administrativas e fonte de dados ODBC de 64bit, em drivers verifique seu driver NSP:

Driver SAP MaxDB ODBC 64bit

Driver SAP MaxDB ODBC 64bit

5 – Crie uma nova fonte de dados do usuário escolha o driver NSP ou o driver apropriado e clique em concluir:

Fonte de Dados do Usuário

Fonte de Dados do Usuário

6 – Preencha os dados de conexão com o servidor e o banco de dados:

Dados do DNS da conexão

Dados do DNS da conexão

7 – Clique em testar a conexão e alimente o usuário e senha para o banco de dados:

Testar Conexão - Usuário e Senha

Testar Conexão – Usuário e Senha

8 – Com tudo funcionando conclua a conexão:

Conexão OK

Conexão OK

9 – Utilize o código abaixo para manipular dados utilizando o SAP MaxDB:

MaxDB - Programa Python

MaxDB – Programa Python

10 – Para utilizar o ABAP para ler ou gravar dados nesta mesma tabela não transparente utilizando uma Stored Procedure no MaxDB através de códigos Native SQL, utilize o link abaixo para o procedimento ABAP:

Stored Procedure - Abap

Stored Procedure – Abap

Programa SAP – ABAP Native SQL: MaxDB Stored Procedure parâmetros IN e OUT

 Caso conecte em um banco de dados MaxDB utilizando soluções SAP tenha em mente que você deve respeitar o conceito de dados dos sistemas SAP e verificar os termos de garantia de cada produto SAP, visto que este método ao contrario do RFC  ignora a camada de banco de dados SAP e o dicionário de dados ABAP.

Como você pode verificar na imagem acima no ambiente ABAP o valor flutuante não vem formatado por padrão como estão acostumados os desenvolvedores SAP que utilizam instruções Open SQL e o dicionário ABAP no entanto você pode utilizar campos criados no dicionário apenas para a manipulação do valor de saída da Stored Procedure neste caso você deve alinhar os tipos de dados entre as aplicações Python e aplicações ABAP.

Exemplo:

Neste exemplo utilizamos a linguagem de programação Python para se conectar ao banco de dados SAP MaxDB em uma instancia do banco de dados do NetWeaver e integrar uma tabela não transparente que pode ser manipulada tanto do lado Python como dentro do sistema SAP utilizando Native SQL.

SQL – SAP MaxDB

-- Cria tabela no schema SAPNSP
CREATE TABLE SAPNSP.ZFUNCIONARIO
(
            ID_FUNCIONARIO INT,
            NOME VARCHAR (30),
            SOBRENOME VARCHAR(70),
            CARGO VARCHAR(30),
            SALARIO DECIMAL(9,2)
)

-- Insere dados na tabela
Insert into SAPNSP.ZFUNCIONARIO values (1,'Steve','Gates','Programador',2550.56)
Insert into SAPNSP.ZFUNCIONARIO values (2,'Bill','Jobs','Diretor',5143.71)

Python

#!/usr/bin/env python
# -*- coding: cp1252 -*-
# Desenvolvimento Aberto
# MeuSAPMaxDB.py

# importa modulos
from Tkinter import *
import tkMessageBox
import odbc

# Cria formulario
formulario = Tk(className='.::SAP MaxDB - Desenvolvimento Aberto')
formulario.geometry("550x300+300+300")

# Cria janela para menssagem
janela = Tk()
janela.wm_withdraw()

# Cria conexão com o banco de dados
def conectar():
    # Conexão SAPMaxDB
    # SAP MaxDb Drivers necessita que o password seja
    # convertido para letras maisculas (UPPERCASE)
    # Coloque somente caracteres maiusculos no exemplo
    # trate este requerimento no seu codigo fonte
    sconexao =  "SapMaxDB/SAPNSP/password"
    try:
        con = odbc.odbc(sconexao)
    except ValueError:
        tkMessageBox.showinfo(title="Menssagem", message="Erro de Conexão", parent=janela)
    return con

# Executa e retorna cursor
def retornaFuncionarioID(sql, con):
    cursor = con.cursor()
    cursor.execute(sql)
    return cursor

# Evento do botão
def on_Pesquisar():
    # Exibe banco de dados
    titulo['text'] = "Database: SAP MaxDB"

    # Cria conexão
    con = conectar()

    # Define e executa SQL
    sql = "Select * From SAPNSP.ZFUNCIONARIO Where  ID_FUNCIONARIO = " + tpesquisa.get()
    tabela = retornaFuncionarioID(sql, con)

    # Retorna dados
    dados = tabela.fetchone()

    # Exibe dados
    tcodigo.insert(0, str(dados[0]))
    tpnome.insert(0, dados[1])
    tsnome.insert(0, dados[2])
    tcargo.insert(0, dados[3])
    tsalario.insert(0, str(dados[4]))

# Cria componentes widgets
titulo = Label(formulario, text="Database: Nenhum")
separador1 = Frame(height=2, bd=1, relief=SUNKEN)
separador2 = Frame(height=2, bd=1, relief=SUNKEN)

# labels
lcodigo = Label(formulario, text="Codigo:")
lpnome = Label(formulario, text="Nome:")
lsnome = Label(formulario, text="Sobrenome:")
lcargo = Label(formulario, text="Cargo:")
lsalario = Label(formulario, text="Salario:")
# Entry
tcodigo = Entry(formulario)
tpnome = Entry(formulario, width=50)
tsnome = Entry(formulario, width=40)
tcargo = Entry(formulario, width=30)
tsalario = Entry(formulario)
# Pesquisa
lpesquisa = Label(formulario, text="Pesquisa:")
tpesquisa = Entry(formulario)
botao = Button(formulario, text = "Pesquisar", command=on_Pesquisar)

# Define Layout
titulo.grid(row=0, sticky=W+E+N+S, pady=20)
separador1.grid(row=1, sticky=W+E+N+S, pady=5, columnspan=4)
lcodigo.grid(row=2, sticky=W, padx=20)
tcodigo.grid(row=2, column=1, sticky=W, pady=5)
lpnome.grid(row=3, sticky=W, padx=20)
tpnome.grid(row=3, column=1, sticky=W, pady=5)
lsnome.grid(row=4, sticky=W, padx=20)
tsnome.grid(row=4, column=1, sticky=W, pady=5)
lcargo.grid(row=5, sticky=W, padx=20)
tcargo.grid(row=5, column=1, sticky=W, pady=5)
lsalario.grid(row=6, sticky=W, padx=20)
tsalario.grid(row=6, column=1, sticky=W, pady=5)
separador2.grid(row=7,sticky=W+E+N+S, pady=5, columnspan=4)
# Layout pesquisa
lpesquisa.grid(row=8, column=0, pady=20)
tpesquisa.grid(row=8, column=1, pady=20)
botao.grid(row=8, column=2,pady=20)

# loop do tcl
mainloop()

Sabendo que a tecnologia Java Server Pages proporcionada pelo servidor de aplicação Tomcat nos possibilita criar aplicações web dinâmicas utilizando JavaBeansServlets, vamos então criar um motor básico que utiliza o principio usado por quase todas as aplicações web para o mundo corporativo, ou seja manipulação de dados.

Em aplicações Enterprise os dados na grande maioria das vezes é manipulado através de um servidor de banco de dados relacional, entretanto neste primeiro exemplo vamos utilizar um objeto Java que possibilita a criação de listas para manipular os dados, ressaltando o que realmente nos interessa neste momento é apenas o esqueleto de uma simples aplicação que mostra, adiciona, edita e deleta dados através de uma interface com o usuário.

Java - Mostar - Adicionar - Editar e Apagar

Java – Mostar – Adicionar – Editar e Apagar

Exemplo:

Neste exemplo utilizaremos um JavaBean que manipula dados através de um objeto List do Java e usamos Servlets para criar a interface com o usuário e manipular as ações requisitadas de entrada, edição e exclusão de dados. Utilize os comentários nos códigos abaixo para entender os processos e técnicas utilizadas.

Java

MeuJavaBean – Manipula Dados

package org.desenvolvimento.aberto;

public class MeuJavaBean {
	// Declara atributo
	private String nome;
	private String comentario;

	// Construtor Default da classe
	public MeuJavaBean() {

	}

	// Construtor Overload
	public MeuJavaBean(String nome, String comentario) {
		this.nome = nome;
		this.comentario = comentario;
	}

	// Métodos Getter e Setter
	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getComentario() {
		return comentario;
	}

	public void setComentario(String comentario) {
		this.comentario = comentario;
	}

}

MeuJServlet – Mostra Dados (Página Principal)

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Ler Servlet ao iniciar
@WebServlet(urlPatterns="/MeuJServlet", loadOnStartup = 1)

public class MeuJServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public MeuJServlet() {
		super();
	}

	public void init(ServletConfig config) throws ServletException {		

		// Inicia configuração
		super.init(config);

		// Cria uma Lista com o objeto JavaBean
		List<MeuJavaBean> registros = new ArrayList<MeuJavaBean>();

		// Insere dados na lista
		registros.add(new MeuJavaBean("Ricardo", "Olá Pessoal"));
		registros.add(new MeuJavaBean("Mantovani",
				"Bem-vindos ao Desenvolvimento Aberto, adicione, altere e exclua dados desta tabela"));

		// Define um atributo para o contexto do servlet
		getServletContext().setAttribute("registros", registros);

	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Recupera contexto do JavaBean
		@SuppressWarnings("unchecked")
		List<MeuJavaBean> registros =  (List<MeuJavaBean>) getServletContext().getAttribute("registros");

		// Cria página HTML
		PrintWriter html = response.getWriter();

		html.println("<!DOCTYPE html>");
		html.println("<head><Title>Desenvolvimento Aberto</title>");

		// CSS
		html.println("<style>");
		html.println("td, th {");
		html.println("border: none;");
		html.println("background-color: #dddddd;");
		html.println("padding: 5px;");
		html.println("width: 200px; }");

		html.println("</style>");
		html.println("</head>");

		//  Corpo da página
		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto - Beans e Servlets</h1>");

		// Cria tabela
		html.println("<table>");
		html.println("<tr>");
		html.println("<th>Nome:</th>");
		html.println("<th>Comentário:</th>");
		html.println("<th>Ação:</th>");
		html.println("</tr>");

		for (int id = 0; id < registros.size(); id++) {

			// Recupera identificador
			MeuJavaBean reg = registros.get(id);

			html.println("<tr>");
			html.println("<td>" + reg.getNome() + "</td>");
			html.println("<td>" + reg.getComentario() + "</td>");

			// Link de edição
			html.println("<td><center>");
			html.println("<a href='MeuServletEditar?identificador=" + id + "'>Editar</a> | ");
			html.println("<a href='MeuServletApagar?identificador=" + id + "'>Apagar</a>");
			html.println("</center></td>");

			html.println("</tr>");
		}

		html.println("</table>");

		// Define link para formulario de adicionar dados (Servlet)
		html.println("<P> <a href='MeuServletAdd'>Adicione um comentário</a> </p>");

		html.println("</body>");
		html.println("</html>");
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Chama método GET
		doGet(request, response);
	}

}

MeuServletAdd – Adiciona Dados

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MeuServletAdd")
public class MeuServletAdd extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public MeuServletAdd() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Mostra pagina HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto</h1>");
		html.println("<h2>Servlet - Adiciona Dados</h2>");

		// Formulário processa este mesmo Servlet e o método DoPost
		html.println("<form action='MeuServletAdd' method='post'>");
		html.println("Nome: <input type='text' name='nome' size ='55' /> <br>");
		html.println("<textarea name='comentario' cols='50' rows='7'></textarea> <br>");
		html.println("<input type='submit' name='adiciona' value='Adicionar'/> <br>"); 

		html.println("</form>");
		html.println("</body>");
		html.println("</html>");
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Recupera parâmetros
		String nome = request.getParameter("nome");
		String comentario = request.getParameter("comentario");

		// Recupera Lista Registros
		@SuppressWarnings("unchecked")
		List<MeuJavaBean> registros =  (List<MeuJavaBean>) getServletContext().getAttribute("registros");

		// Adiciona dados ao Bean
		registros.add(new MeuJavaBean(nome, comentario));

		// Redireciona para o Servlet principal
		response.sendRedirect("MeuJServlet");

	}

}

MeuServletEditar – Edita Dados

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MeuServletEditar")
public class MeuServletEditar extends HttpServlet {
	private static final long serialVersionUID = 1L;

	// Cria identificador
	private static int id;

	public MeuServletEditar() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Recupera Lista Registros
		@SuppressWarnings("unchecked")
		List<MeuJavaBean> registros = (List<MeuJavaBean>) getServletContext()
				.getAttribute("registros");

		// Recupera registro por ID
		id = Integer.parseInt(request.getParameter("identificador"));

		MeuJavaBean reg = registros.get(id);

		// Mostra pagina HTML
		response.setContentType("text/html");

		PrintWriter html = response.getWriter();

		html.println("<html>");
		html.println("<body>");
		html.println("<h1>Desenvolvimento Aberto</h1>");
		html.println("<h2>Servlet - Editar Dados</h2>");

		// Formulário processa este mesmo Servlet e o método DoPost
		html.println("<form action='MeuServletEditar' method='post'>");
		html.println("Nome: <input type='text' name='nome' size ='55' value='"
				+ reg.getNome() + "'/> <br>");
		html.println("<textarea name='comentario' cols='50' rows='7'>"
				+ reg.getComentario() + "</textarea> <br>");
		html.println("<input type='submit' name='altera' value='Alterar'/> <br>");

		html.println("</form>");
		html.println("</body>");
		html.println("</html>");
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Recupera parâmetros
		String nome = request.getParameter("nome");
		String comentario = request.getParameter("comentario");

		// Recupera Lista Registros
		@SuppressWarnings("unchecked")
		List<MeuJavaBean> registros = (List<MeuJavaBean>) getServletContext()
				.getAttribute("registros");

		// Altera dados ao Bean
		registros.get(id).setNome(nome);
		registros.get(id).setComentario(comentario);

		// Redireciona para o Servlet principal
		response.sendRedirect("MeuJServlet");

	}

}

MeuServletApagar – Apaga Dados

package org.desenvolvimento.aberto;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/MeuServletApagar")
public class MeuServletApagar extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public MeuServletApagar() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		// Recupera Lista Registros
		@SuppressWarnings("unchecked")
		List<MeuJavaBean> registros = (List<MeuJavaBean>) getServletContext()
				.getAttribute("registros");

		// Recupera registro por ID
		int id = Integer.parseInt(request.getParameter("identificador"));

		// Remove identificador e redireciona Servlet
		registros.remove(id);

		// Redireciona para o Servlet principal
		response.sendRedirect("MeuJServlet");

	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
	}

}

 

O Document Object Model (DOM) ou modelo de objeto de documento é uma convenção multi-plataforma e independente de linguagem para representação e interação com objetos em documentos HTML, XHTML e XML. Os nós de cada documento são organizados em uma estrutura de árvore, chamada de árvore DOM. Os objetos na árvore DOM podem ser endereçados e manipulados pelo uso de métodos sobre os objetos. A interface pública de um DOM é especificada em sua interface de programação de aplicações (API). O JQuery possibilita através de seus métodos de manipulação a capacidade de manusear vários tipos de operações sobre os objetos DOM.

DOM: http://www.w3.org/DOM/

  • append() – Adiciona um elemento no parâmetro especificado no final do elemento.
  • remove() – Remove um elemento do DOM.

Você pode saber mais sobre manipulações DOM no seguinte link:

DOM: http://api.jquery.com/category/manipulation/

JQuery - DOM

JQuery – DOM

Exemplo:

Neste exemplo utilizamos métodos de manipulação para inserir e remover elementos  no modelo de objeto do documento .

JQuery


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="utf-8" />
    <title>Desenvolvimento Aberto</title>
    <style type="text/css">
     .imagem {
            border-style: double;
            border-width: 10px;
            width: 500px;
            height: 200px;

        }
    </style>

    <!-- Está é uma instalação do JQuery, você apenas precisa apontar
         para o respectivo script da versão que você deseja utilizar -->

   <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.0.min.js"> </script>

   <!-- Este é um script JQuery básico que manipula o CSS e um evento de clique.
        Todo o script roda no evento equivalent ao OnLoad da pagina html-->   

   <script>

   // Declara eventos de clique
   $( document ).ready(function() {

       $(".imagem").append("<p>Este é um elemento adicionado na arvore DOM</p>");
       // Manipulação de atributos

       $( "#bnt01" ).click(function() {
           $("div").addClass("imagem");
           });

       $( "#bnt02" ).click(function() {
           $("div").removeClass("imagem");
           });            

       $( "#bnt03" ).click(function() {
           $(".imagem").remove();
           });
    });       

   </script>
</head>

<body>

<h1>Desenvolvimento Aberto - DOM</h1>

    <div class="imagem"
         ></div>
<p>
    Escolha uma opção:
    </p>
<button id="bnt01">Adicionar Classe CSS</button>
<button id="bnt02">Remover Classe CSS</button>
<button id="bnt03">Remover Elemento DOM</button>

</body>
</html>