Web Service no ambiente escolar: um estudo de caso

Propaganda
ISSN 2316-2872
T.I.S. São Carlos, v. 1, n. 1, p. 35-53, jul. 2012
©Tecnologias, Infraestrutura e Software
Web Service no ambiente escolar:
um estudo de caso
Alberto René Zanetti, Valter Vieira de Camargo
Abstract: This paper proposes the development of a Web Service destined to the school environment whose main function is to provide
information about students’ grades (transcripts) to other schools in an integrated way. So every institution can access the Web Service and
request transcripts of any student registered through an access key. Also it is provided the possibility of registered institutions update their
students’ information by sending them directly to the Web Service. A case study is presented to illustrate the ideas proposed in this paper.
Keywords: web service, framework, web application
Resumo: Neste artigo propõe-se o desenvolvimento de um Web Service destinado ao ambiente escolar cuja principal função é fornecer
informações sobre as notas dos alunos (histórico escolar) para outros estabelecimentos de ensino de uma forma integrada. Assim toda instituição pode acessar o Web Service e solicitar o histórico escolar de qualquer aluno cadastrado por meio de uma chave de acesso. Também foi
previsto a possibilidade das instituições cadastradas atualizarem as informações de seus alunos enviando-as diretamente para o Web Service.
Um estudo de caso é apresentado para ilustrar as idéias propostas neste artigo.
Palavras-chave: web service, framework, aplicação web
I. INTRODUÇÃO
No ambiente escolar o histórico dos alunos é de extrema
importância, mas infelizmente a sua disponibilização está, na
maior parte das vezes, restrita à instituição de origem do aluno,
dade de se ter acesso a um histórico on-line agilizaria o trabalho
das instituições. Pensando nisso, teve-se a ideia de desenvolver
um Web Service para suprir essa necessidade.
O Web Service em questão possui uma base de dados que
mantêm instituições, alunos, disciplinas e suas respectivas notas. Quando uma instituição precisar do histórico escolar de um
aluno que não faça parte de seu corpo discente, a mesma envia uma solicitação para o Web Service fornecendo a chave de
acesso para aquele aluno. O Web Service prontamente fornece
os dados necessários para a montagem do histórico escolar desejado. Esses dados estão no formato XML.
Para manter a base de dados do Web Service, este pode receber solicitações de inclusão/alteração de dados provenientes
das instituições cadastradas. No decorrer deste artigo será apresentada a estrutura em que os dados deverão ser enviados e
sugerido que isso seja feito automaticamente quando ocorrer
alguma alteração nas notas no sistema da instituição.
Todo o processo de desenvolvimento é abordado passo-a-passo, bem como um exemplo de utilização é apresentado
para que o Web Service possa ser incorporado em outras aplicações.
O restante do artigo está organizado da seguinte maneira. Na
seção II são apresentados conceitos básicos utilizados no restante do artigo. Na seção III é apresentado um estudo de caso e
II. CONCEITOS BÁSICOS
Nesta seção são descritos os conceitos utilizados no desenvolvimento do web service descrito neste artigo.
A. XML
XML (eXtensible Markup Language) é uma linguagem simples capaz de descrever diversos tipos de dados, baseada em
arquivo texto e composta por tags (palavras demarcadas por
ta um exemplo de um documento XML.
demos enfatizar sua representação estruturada e hierárquica,
separação clara do conteúdo da formatação, simplicidade e fácil entendimento, possibilidade de criação de tags próprias e
ênfase na estrutura e não na aparência.
Departamento de Computação – Universidade Federal de São Carlos (UFSCar)
Caixa Postal 676 – 13.565-905 – São Carlos – SP – Brasil
Autor para correspondência: [email protected], [email protected]
B. HTTP
atributos: mustUnderstand, actor, e encodingStyle. O atributo
mustUndestand valor “1” obriga o receptor a processar essa
entrada do Header e actor
sagem.
O elemento Body possui a chamada dos métodos da aplicação e seus respectivos parâmetros de requisição e resposta.
O elemento Fault é opcional, e é utilizado para indicar mensagens de erro. Ele pode ser utilizado apenas uma vez no Envelope. Possui os seguintes sub-elementos: faultcode, faultstring,
faultactor e detail
HTTP (HyperText Transfer Protocol) é um padrão de comunicação “requisição-resposta” amplamente utilizado pela Internet. O cliente envia uma requisição ao servidor que envia uma
mensagem de resposta ao cliente.
C. Web Services
Web Services são aplicações criadas para receber e dar
portanto não são acessadas diretamente pelos usuários, sendo desenvolvidas para serem acessadas por outras aplicações.
Web Services trabalham basicamente com XML para os dados e
HTTP para a comunicação.
A independência de linguagem e plataforma dos Web Services tornou-os excepcionalmente úteis na integração de sistemas. O único requisito para um sistema se comunicar a um Web
Service é interpretar uma mensagem XML.
do erro.
III ESTUDO DE CASO
Nesta seção é apresentado todos os passos do desenvolvimento do Web Service em questão.
D. SOAP
A. Documento de requisitos
SOAP (Simple Object Access Protocol) é o protocolo utilizado para comunicação com os Web Services. É basicamente
um documento XML composto por um elemento Envelope, um
Header, um Body e um Fault (Header e Fault são opcionais).
No Quadro 2 temos um modelo da estrutura de um documento SOAP com seus principais elementos:
XML é um
O elemento Envelope
encodingStyle,
SOAP, o atributo xmlns
as regras de serialização do elemento (este atributo pode ser
utilizado em todos os elementos).
O elemento Header é opcional, mas se utilizado deve ser o
primeiro elemento dentro do Envelope. Ele serve para man-
No Quadro 3 é apresentado o documento de requisitos, onde
sárias para o seu desenvolvimento.
B. Casos de uso
guras as funcionalidades propostas para o Sistema.
atorAluno se relaciona com o
caso de uso SolicitarHistorico, que por sua vez inclui os casos
de uso ValidarChave e GerarHistórico. No caso do atorInstituicao, este se relaciona com o caso de uso CadastrarNota
Figura 1. Diagrama de Casos de Uso
T.I.S. 2012; 1 (1): 35-53
36
Web Service no ambiente escolar: um estudo de caso
que inclui, se necessário, os casos de uso ValidarChave, CadastrarInstituicao, CadastrarAluno e CadastrarDisciplina. Os
estereótipos <<include>> e <<extend>> representam, respectivamente, uma ação obrigatória e uma ação opcional.
Complementando o diagrama de casos de uso, no Quadro 4
atribuição de permissões de Select, Insert, Update e Delete em
todas as tabelas necessárias.
Foram criadas quatro tabelas assim como o diagrama de
classes indicou, mas com alguns detalhes: em todas as tabelas
foi adicionado um campo id chave primária e auto-incremento; na tabela disciplina foi adicionado o campo id_instituicao
chave estrangeira para a tabela instituicao; na tabela nota foi
adicionado o campo id_aluno chave estrangeira para a tabela
aluno e id_disciplina chave estrangeira para a tabela disciplina;
UNIQUE nos campos cpf
e cnpj das tabelas aluno e instituição para garantir a unicidade
dos registros.
No Quadro 5 é apresentado o script completo utilizado nesta
aplicação.
No NetBeans, para criar a conexão do banco de dados com o
projeto, foram realizados os passos abaixo:
a) Aba Serviços, botão direito em Banco de dados, Nova conexão;
b) Modo de entrada de dados: Entrada direta de URL, Nome do driver: PostgreSQL, Nome do usuário: postgres, Senha: (senha do usuário postgres), marque Lembrar senha,
URL JDBC: jdbc:postgresql://localhost:5432/ WSHistorico,
Ok;
c) Selecione um esquema: public, Ok.
passo a passo as ações realizadas em cada caso de uso. Essas
Alternativo.
onde as condições (se-então) são sempre verdadeiras e os dados
GerarHistorico temos
os passos 2. Enquanto houver notas e 2.1 Carregar nota. Nesses
passos é previsto que existam notas para serem carregadas. Des2a.
Não existem notas, 2a.1 Gerar mensagem de erro e 2a.2 Abandonar caso de uso
butos, métodos e relações entre elas.
C. Implementação
O sistema foi implementado utilizando Java EE 5 no NetBeans IDE 6.8 em uma máquina com Ubuntu 9.04, banco de
dados PostgreSQL 8.3.11 e servidor Apache Tomcat 6.0.20.
Projeto no NetBeans
O projeto foi criado como uma Aplicação Web e chamado de
WSHistorico, segundo os seguintes passos:
a) Menu Arquivo, Novo projeto, Categorias: Java Web, Projetos:
Aplicação Web, Próximo;
b) Nome do projeto: WSHistorico, Próximo;
Banco de Dados
No PostgreSQL foi criado o banco de dados WSHistorico,
foi mantido o usuário postgres
-
Figura 2. Diagrama de Classes
37
T.I.S. 2012; 1 (1): 35-53
c) Servidor: Apache Tomcat 6.0.20
EE 5, Finalizar.
DAO
Java EE: Java
Outro padrão utilizado é o DAO (Data Access Object), ele
propõe a criação de uma camada de persistência, para isolar a
aplicação da comunicação com o banco de dados.
Seguindo esse padrão foram criados as classes DAO referentes a cada uma das entidades, como abaixo:
a) Aba Projetos, botão direito em WSHistorico, Novo, Classe java
(ou Outro, Categorias: Java, Tipos de arquivos: Classe java);
b) Nome da classe: InstituicaoDAO, Pacote: persistencia, Finalizar;
c) Esses procedimentos foram repetidos para as classes DisciplinaDAO, AlunoDAO e NotaDAO.
Unidade de persistência
Para que o banco de dados relacional “converse” com os
objetos java, foi criado uma Unidade de persistência:
a) Aba Projetos, botão direito em WSHistorico, Novo, Unidade
de persistência (ou Outro, Categorias: Persistence, Tipos de
arquivos: Unidade de persistência), Próximo;
b) Nome da unidade de persistência: WSHistoricoPU, Biblioteca de persistência: TopLink, Conexão de banco de dados:
jdbc:postgresql: //localhost:5432/WSHistorico, Estratégia de
geração de tabela: Nenhum, Finalizar.
O corpo da classe InstituicaoDAO, AlunoDAO e NotaDAO
são apresentados pelos Quadros 8 a 10, respectivamente.
Entidades
Façade
As entidades foram criadas automaticamente pelo NetBeans
a partir do banco de dados, como segue:
a) Aba Projetos, botão direito em WSHistorico, Novo, Classes
de entidade do banco de dados (ou Outro, Categorias: Persistence, Tipos de arquivos: Classes de entidade do banco de
dados), Próximo;
b) Conexão de banco de dados: jdbc:postgresql://localhost:5432/
WSHistorico, Adicionar todos, Próximo;
c) Pacote: negocio.entidade, Finalizar.
O padrão de projeto Façade cria a camada de negócio, a qual
desacoplamento requerido pelo MVC.
As classes Façades foram criadas seguindo os passos abaixo:
a) Aba Projetos, botão direito em WSHistorico, Novo, Classe java
(ou Outro, Categorias: Java, Tipos de arquivos: Classe java);
c) Nome da classe: InstituicaoFacade, Pacote: negocio.facade,
Finalizar;
d) Esses procedimentos foram repetidos para as classes DisciplinaFacade, AlunoFacade e NotaFacade.
Alguns atributos das entidades foram refatorados para facilitar o seu entendimento: em Aluno, notaCollection foi refatorado para notas; em Disciplina, idInstituicao para instituicao e
notaCollection para notas; em Instituicao, disciplinaCollection
para disciplinas; e em Nota, idAluno para aluno e idDisciplina
para disciplina.
Refatorar é simples, clique com o botão direito no atributo desejado, escolha Refatorar, Renomear, digite o novo nome e o clique no botão Refatorar. Não podemos esquecer que ao refatorar os
atributos, o NetBeans não refatora automaticamente os métodos
O corpo das classes InstituicaoFacade, DisciplinaFacade,
AlunoFacade e NotaFacade é apresentado no quadro 11:
Os Quadros 12,13 e 14 apresentam os corpos das classes DisciplinaFacade, AlunoFacade e NotaFacade, respectivamente.
Classe Chave
Foi criada a classe de persistência Chave, responsável pela
geração da chave de acesso, utilizada no cadastro de alunos e
ma de classes por se tratar de uma classe de persistência e não
de negócio como as demais.
a) Aba Projetos, botão direito em WSHistorico, Novo, Classe java
(ou Outro, Categorias: Java, Tipos de arquivos: Classe java);
b) Nome da classe: Chave, Pacote: persistencia, Finalizar;
O NetBeans não mapeia corretamente os auto-incrementos,
por isso as anotações apresentadadas no Quadro 6 foram inseridas nas entidades, entre os atributo @Column(name = «id»);
e private Integer id;
MVC
O corpo da classe Chave é apresentado no Quadro 15.
padronização ao software. MVC (Model-View-Controller) propõe dividir a aplicação em 3 camadas distintas e independentes:
Model representa as classes, objetos e a lógica de acesso ao
banco de dados; View representa a interface que exibe os dados
dos objetos; e Controller recebe as requisições dos usuários e
as converte em ações para o Model
View mais
apropriada para cada resposta.
Utilizando o MVC, as classes foram divididas da seguinte
forma: as entidades e os DAOs representam a camada Model
enquanto os Façades e a classe Historico.java representam a
camada Controller. A camada View não é utilizada visto que os
Web Services não possuem interface com o usuário.
T.I.S. 2012; 1 (1): 35-53
Web Service
mentação do Web Service. Foi criado um Web Service, chamado Historico, seguindo os passos abaixo:
a) Aba Projetos, botão direito em WSHistorico, Novo, Serviço
Web (ou Outro, Categorias: Web Services, Tipos de arquivos:
Serviço Web);
b) Nome do serviço web: Historico, Pacote: webservices, Finalizar.
38
Web Service no ambiente escolar: um estudo de caso
O Web Service possui dos métodos: solicitarHistorico e cadastrarNota. O método solicitarHistorico recebe CPF e chave
de um aluno e retorna a lista de disciplinas cursadas em uma
string XML apresentada no Quadro 16 ou uma mensagem de
erro apresentada no Quadro 17, sendo que o código do método
solicitarHistorico é apresentado no Quadro 18.
O método cadastrarNota recebe CNPJ da instituição, nome
da instituição, chave da instituição, disciplina, CPF do aluno,
nome do aluno, chave do aluno, nota, data da nota e status e
retorna os dados cadastrados em uma string XML apresentada
no Quadro 19 ou uma mensagem de erro semelhante ao método
anterior.
sário passar o CNPJ e o nome, a chave de acesso será gerada e
devolvida no retorno. E para uma instituição existente, apenas
o CNPJ e a chave de acesso, o nome não será atualizado. O
mesmo se aplica para o aluno.
O código do método cadastrarNota é apresentado no Quadro
20:
Agora que o Web Service está pronto, apresenta-se um
exemplo simples de utilização:
a) Aba Projetos, botão direito no seu projeto, Novo, Cliente para
serviço Web (ou Outro, Categorias: Web Services, Tipos de
arquivos: Cliente para serviço Web), Próximo;
b) WSDL URL: http://localhost:8080/WSHistorico/
HistoricoService?wsdl, Pacote: infraestrutura, Finalizar;
IV. CONCLUSÃO
Levando-se em conta o que foi apresentado neste artigo,
observa-se que o Web Service
cumpre os objetivos pretendidos: fornecer um histórico escolar
on-line mediante dados previamente cadastrados.
Sobre os Web Services, conclui-se que a sua implementação
é uma tarefa consideravelmente simples e muito útil para os
desenvolvedores. Os Web Services podem desempenhar com
elegância desde tarefas simples, como a geração de um histórico escolar, até as mais complexas, como a integração de
sistemas de grande porte.
Deve-se ressaltar que o Web Service
cado pois não ha necessidade de complexidade computacional
para expor a ideia apresentada, e que para a completa utilização
deste Web Service, algumas funcionalidade devem ser implementadas, tais como: recuperação da chave-de-acesso e alteração/exclusão dos registros.
REFERÊNCIAS
FOSCHINI, Ivan J. Frameworks para Desenvolvimento Web.
São Carlos: UFSCar/DC, 2010. Apostila.
JOSUTTIS, Nicolai M. SOA na Prática. Rio de Janeiro: Alta
Books, 2008.
Web
Services. São Carlos: UFSCar/DC, 2010. Apostila.
Exemplo de utilização
O trecho de código no Quadro 21 instancia o Web Service,
passa as informações necessárias para o cadastro e recebe como
resultado uma string XML com os dados fornecidos ou o erro
ocorrido. Além disso instancia duas variáveis para receber a
chave de acesso da instituição e do aluno (caso a instituição e/
ou o aluno não existam na base do Web Service).
w3schools.com/soap/>. Acesso em: 04 ago. 2010.
W3SCHOOLS. Web Services
www.w3schools.com/webservices/>. Acesso em: 01 jun.
2010.
w3schools.com/xml/>. Acesso em: 08 jul. 2010.
39
T.I.S. 2012; 1 (1): 35-53
Quadro 1. Exemplo de arquivo XML
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don’t forget me this weekend!</body>
</note>
Quadro 2. Estrutura do documento SOAP
<?xml version=”1.0”?>
<soap:Envelope xmlns:soap=”http://www.w3.org/2001/12/soap-envelope”
soap:encodingStyle=”http://www.w3.org/2001/12/soap-encoding”>
<soap:Header> . . . </soap:Header>
<soap:Body>
. . .
<soap:Fault> . . . </soap:Fault>
</soap:Body>
</soap:Envelope>
Quadro 3. Descrição dos Casos de Uso
O sistema possui dois atores: aluno e instituição. Qualquer um deles pode
solicitar um histórico escolar fornecendo o CPF e a chave de acesso de um
aluno. O histórico é composto pelo nome do aluno, nome da instituição,
disciplinas, notas, datas e status das notas. A instituição pode cadastrar as
notas de seus alunos, fornecendo CNPJ, nome e chave de acesso da instituição,
CPF, nome e chave de acesso do aluno, disciplina, nota, data e status. Caso
a instituição não exista, esta será cadastrada e uma chave de acesso será
gerada e devolvida. Caso o aluno não exista, este será cadastrado e uma chave
de acesso será gerada e devolvida. Caso a disciplina não exista, está será
data) não exista, está será cadastrada, e caso exista, está terá sua nota e
status atualizados.
T.I.S. 2012; 1 (1): 35-53
40
Web Service no ambiente escolar: um estudo de caso
SolicitarHistórico
Fluxo Normal:
1. Usuário informa cpf e chave de acesso.
2. Chamar ValidarChave.
3. Chave válida.
4. Chamar GerarHistórico.
5. Encerrar caso de uso.
ValidarChave
Fluxo normal:
1. Recebe cpf/cnpj e chave de acesso.
2. Chave válida.
3. Encerrar caso de uso.
Fluxo alternativo:
2a. Chave inválida.
2a.1 Gerar mensagem de erro.
2a.2 Abandonar caso de uso .
GerarHistórico
Fluxo normal:
1. Recebe cpf.
2. Enquanto houver notas
2.1 Carregar nota.
3. Montar histórico escolar.
4. Encerrar caso de uso.
Fluxo alternativo:
2a. Não existem notas.
2a.1 Gerar mensagem de erro.
2a.2 Abandonar caso de uso.
CadastrarInstituição
Fluxo normal:
1. Recebe cnpj e nome da instituição.
2. Chamar GerarChave.
3. Cadastrar instituição.
4. Retornar chave.
5. Encerrar caso de uso.
GerarChave
Fluxo normal:
1. Recebe cpf/cnpj.
2. Gerar chave.
3. Retornar chave.
4. Encerrar caso de uso.
CadastrarNota
Fluxo normal:
1. A instituição fornece dados.
2. Instituição cadastrada.
3. Chamar ValidarChave.
4. Aluno cadastrado.
5. Chamar ValidarChave.
6. Disciplina cadastrada.
7. Nota não existe.
8. Cadastrar nota.
9. Encerrar caso de uso.
Fluxos alternativos:
2a. Instituição não cadastrada.
2a.1 Chamar CadastrarInstituição.
2a.2 Retornar ao passo 4.
4a. Aluno não cadastrado.
4a.1 Chamar CadastrarAluno.
4a.2 Retornar ao passo 6.
6a. Disciplina não cadastrada.
6a.1 Chamar CadastrarDisciplina.
6a.2 Retornar ao passo 7.
7a. Nota existe.
7a.1 Alterar nota.
7a.2 Retornar ao passo 9.
CadastrarAluno
Fluxo normal:
1. Recebe cpf e nome do aluno.
2. Chamar GerarChave.
3. Cadastrar aluno.
4. Retornar chave.
5. Encerrar caso de uso.
CadastrarDisciplina
Fluxo normal:
1. Recebe instituição e nome disciplina.
2. Cadastrar disciplina.
3. Encerrar caso de uso.
41
T.I.S. 2012; 1 (1): 35-53
Quadro 5. Script de criação do banco de dados
CREATE TABLE aluno
( id serial PRIMARY KEY,
cpf character varying(11) NOT NULL UNIQUE,
nome character varying(100) NOT NULL,
chave character varying(9) NOT NULL
)
CREATE TABLE instituicao
( id serial PRIMARY KEY,
cnpj character varying(14) NOT NULL UNIQUE,
nome character varying(100) NOT NULL,
chave character varying(9) NOT NULL
)
CREATE TABLE disciplina
( id serial PRIMARY KEY,
id_instituicao integer NOT NULL,
nome character varying(100) NOT NULL,
FOREIGN KEY (id_instituicao) REFERENCES instituicao (id)
)
CREATE TABLE nota
( id serial PRIMARY KEY,
id_aluno integer NOT NULL,
id_disciplina integer NOT NULL,
nota double precision NOT NULL,
data date NOT NULL,
status character varying(11) NOT NULL,
FOREIGN KEY (id_aluno) REFERENCES aluno (id),
FOREIGN KEY (id_disciplina) REFERENCES disciplina (id)
)
Quadro 6. Anotações para os auto-incrementos nas entidades
Aluno.java
@SequenceGenerator(name=”aluno_id_seq”, sequenceName=”aluno_id_seq”,
allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator=”aluno_id_seq”)
Instituicao.java
@SequenceGenerator(name=”instituicao_id_seq”,
sequenceName=”instituicao_id_seq”,allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator=”instituicao_id_seq”)
Disciplina.java
@SequenceGenerator(name=”disciplina_id_seq”,
sequenceName=”disciplina_id_seq”, allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator=”disciplina_id_seq”)
Nota.java
@SequenceGenerator(name=”nota_id_seq”, sequenceName=”nota_id_seq”,
allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator=”nota_id_seq”)
T.I.S. 2012; 1 (1): 35-53
42
Web Service no ambiente escolar: um estudo de caso
Quadro 7. Métodos do classe InstituicaoDAO
private static EntityManagerFactory emf;
private static EntityManager em;
private static void conectar() {
emf = Persistence.createEntityManagerFactory(“WSHistorico2PU”);
em = emf.createEntityManager();
}
private static void desconectar() {
em.close();
emf.close();
}
public static void inserir(Instituicao instituicao) {
conectar();
try {
em.getTransaction().begin();
em.persist(instituicao);
em.getTransaction().commit();
desconectar();
}
}
public static Instituicao recuperarPorCnpj(String cnpj) {
conectar();
try {
Instituicao instituicao = (Instituicao) em.createNamedQuery(“Instituicao.
setParameter(“cnpj”, cnpj).getSingleResult();
return instituicao;
} catch (Exception e) {
return null;
desconectar();
}
}
public static boolean validarChave(Instituicao instituicao, String chave) {
try {
return chave.equals(instituicao.getChave());
} catch (Exception e) {
return false;
}
}
43
T.I.S. 2012; 1 (1): 35-53
Quadro 8. Métodos da classe DisciplinaDAO
private static EntityManagerFactory emf;
private static EntityManager em;
private static void conectar() {
emf = Persistence.createEntityManagerFactory(“WSHistorico2PU”);
em = emf.createEntityManager();
}
private static void desconectar() {
em.close();
emf.close();
}
public static void inserir(Disciplina disciplina) {
conectar();
try {
em.getTransaction().begin();
em.persist(disciplina);
em.getTransaction().commit();
desconectar();
}
}
public static Disciplina recuperarPorInstituicaoENome(Instituicao instituicao,
String nome) {
conectar();
try {
Disciplina disciplina = (Disciplina) em.createQuery(“SELECT d FROM Disciplina AS
d
WHERE (d.instituicao.cnpj = ‘” + instituicao.getCnpj() + “’) AND (d.nome = ‘” +
nome +
“’)”).getSingleResult();
return disciplina;
} catch (Exception e) {
return null;
desconectar();
}
}
T.I.S. 2012; 1 (1): 35-53
44
Web Service no ambiente escolar: um estudo de caso
Quadro 9. Métodos da classe AlunoDAO
private static EntityManagerFactory emf;
private static EntityManager em;
private static void conectar() {
emf = Persistence.createEntityManagerFactory(“WSHistorico2PU”);
em = emf.createEntityManager();
}
private static void desconectar() {
em.close();
emf.close();
}
public static void inserir(Aluno aluno) {
conectar();
try {
em.getTransaction().begin();
em.persist(aluno);
em.getTransaction().commit();
desconectar();
}
}
public static Aluno recuperarPorCpf(String cpf) {
conectar();
try {
setParameter(“cpf”, cpf)
.getSingleResult();
return aluno;
} catch (Exception e) {
return null;
desconectar();
}
}
public static boolean validarChave(Aluno aluno, String chave) {
try {
return chave.equals(aluno.getChave());
} catch (Exception e) {
return false;
}
}
45
T.I.S. 2012; 1 (1): 35-53
Quadro 10. Métodos da classe NotaDAO
private static EntityManagerFactory emf;
private static EntityManager em;
private static void conectar() {
emf = Persistence.createEntityManagerFactory(“WSHistorico2PU”);
em = emf.createEntityManager();
}
private static void desconectar() {
em.close();
emf.close();
}
public static void inserir(Nota nota) {
conectar();
try {
em.getTransaction().begin();
em.persist(nota);
em.getTransaction().commit();
desconectar();
}
}
public static void alterar(Nota nota) {
conectar();
try {
em.getTransaction().begin();
em.merge(nota);
em.getTransaction().commit();
desconectar();
}
}
public static Nota recuperarPorDisciplinaAlunoEData(Disciplina disciplina,
Aluno aluno, Date data) {
SimpleDateFormat dataMascara = new SimpleDateFormat(“yyyy-MM-dd”);
conectar();
try {
Nota nota = (Nota) em.createQuery(“SELECT n FROM Nota AS n WHERE
(n.disciplina.nome = ‘” +
disciplina.getNome() + “’) AND (n.aluno.cpf = ‘” + aluno.getCpf() + “’) AND
(n.data = ‘” +
dataMascara.format(data) + “’)”).getSingleResult();
return nota;
} catch (Exception e) {
return null;
desconectar();
}
}
public static List<Nota> recuperarTodosPorAluno(Aluno aluno) {
conectar();
try {
List<Nota> notas = em.createQuery(“SELECT n FROM Nota AS n WHERE (n.aluno.
cpf = ‘” +
aluno.getCpf() + “’) ORDER BY n.data ASC”).getResultList();
return notas;
} catch (Exception e) {
return null;
desconectar();
}
}
T.I.S. 2012; 1 (1): 35-53
46
Web Service no ambiente escolar: um estudo de caso
Quadro 11. Métodos da classe InstituicaoFacade
public static void inserir(Instituicao instituicao) {
InstituicaoDAO.inserir(instituicao);
}
public static Instituicao recuperarInstituicaoPorCnpj(String cnpj) {
return InstituicaoDAO.recuperarPorCnpj(cnpj);
}
public static boolean validarChaveInstituicao(Instituicao instituicao,
String chave) {
return InstituicaoDAO.validarChave(instituicao, chave);
}
Quadro 12. Métodos da classe DisciplinaFacade
public static void inserir(Disciplina disciplina) {
DisciplinaDAO.inserir(disciplina);
}
public static Disciplina recuperarDisciplinaPorInstituicaoENome(Instituicao
instituicao, String nome) {
return DisciplinaDAO.recuperarPorInstituicaoENome(instituicao, nome);
}
Quadro 13. Métodos da classe AlunoFacade
public static void inserir(Aluno aluno) {
AlunoDAO.inserir(aluno);
}
public static Aluno recuperarAlunoPorCpf(String cpf) {
return AlunoDAO.recuperarPorCpf(cpf);
}
public static boolean validarChaveAluno(Aluno aluno, String chave) {
return AlunoDAO.validarChave(aluno, chave);
}
Quadro 14. Métodos da classe NotaFacade
public static void inserir(Nota nota) {
NotaDAO.inserir(nota);
}
public static void alterar(Nota nota) {
NotaDAO.alterar(nota);
}
public static Nota recuperarNotaPorDisciplinaAlunoEData(Disciplina
disciplina, Aluno aluno, Date data) {
return NotaDAO.recuperarPorDisciplinaAlunoEData(disciplina, aluno, data);
}
public static List<Nota> recuperarTodosNotaPorAluno(Aluno aluno) {
return NotaDAO.recuperarTodosPorAluno(aluno);
}
47
T.I.S. 2012; 1 (1): 35-53
Quadro 15. Métodos da classe Chave
static Random random = new Random();
public static String gerar() {
String chave = “”;
for (int i = 0; i < 8; i++)
chave += Integer.toHexString(random.nextInt(16));
return chave.substring(0, 4) + “-” + chave.substring(4);
}
solicitarHistorico
<aluno>
<nome>...</nome>
<instituicao>
<nome>...</nome>
<disciplina>
<nota>
<nota>...</nota>
<data>...</data>
<status>...</status>
</nota>
</disciplina>
</instituicao>
</aluno>
Quadro 17. Erro do método solicitarHistorico
<erro>...</erro>
T.I.S. 2012; 1 (1): 35-53
48
Web Service no ambiente escolar: um estudo de caso
Quadro 18. Método solicitarHistorico
@WebMethod(operationName = “solicitarHistorico”)
public String solicitarHistorico(@WebParam(name = “cpf”) String cpf,
@WebParam(name = “chave”) String chave) {
SimpleDateFormat dataMascara = new SimpleDateFormat(“dd-MM-yyyy”);
try {
String lista = “”;
// validações de entrada
if(cpf == null) {
throw new Exception(“CPF não fornecido!”);
}
if(chave == null) {
throw new Exception(“Chave de acesso não fornecida!”);
}
Aluno aluno = AlunoFacade.recuperarAlunoPorCpf(cpf);
if(aluno != null) {
if(AlunoFacade.validarChaveAluno(aluno, chave)) {
// recuperar as notas
List<Nota> notas = NotaFacade.recuperarTodosNotaPorAluno(aluno);
lista += “<aluno>” +
“<nome>” + aluno.getNome() + “</nome>”;
Instituicao instituicaoTMP = null;
for (Nota nota : notas) {
if(!nota.getDisciplina().getInstituicao().equals(instituicaoTMP)) {
if(instituicaoTMP != null) {
lista += “</instituicao>”;
}
instituicaoTMP = nota.getDisciplina().getInstituicao();
lista += “<instituicao>” +
“<nome>” + instituicaoTMP.getNome() + “</nome>”;
}
lista += “<disciplina>” +
“<nome>” + nota.getDisciplina().getNome() + “</nome>” +
“<nota>” +
“<nota>” + nota.getNota() + “</nota>” +
“<status>” + nota.getStatus() + “</status>” +
“<data>” + dataMascara.format(nota.getData()) + “</data>” +
“</nota>” + “</disciplina>”;
}
if(instituicaoTMP != null) {
lista += “</instituicao>”;
}
lista += “</aluno>”;
}
else {
throw new Exception(“Chave inválida!”);
}
}
else {
throw new Exception(“Aluno inválido!”);
}
return lista;
}
catch (Exception e) {
return “<erro>” + e.getMessage() + “</erro>”;
}
}
49
T.I.S. 2012; 1 (1): 35-53
cadastrarNota
<instituicao>
<cnpj>...</cnpj>
<nome>...</nome>
<chave>...</chave>
</instituicao>
<disciplina>
<nome>...</nome>
</disciplina>
<aluno>
<cpf>...</cpf>
<nome>...</nome>
<chave>...</chave>
</aluno>
<nota>
<nota>...</nota>
<data>...</data>
<status>...</status>
</nota>
Quadro 20. Método cadastrarNota
@WebMethod(operationName = “cadastrarNota”)
public String cadastrarNota(@WebParam(name = “insCnpj”) String insCnpj,
@WebParam(name = “insNome”) String insNome,
@WebParam(name = “insChave”) String insChave,
@WebParam(name = “disNome”) String disNome,
@WebParam(name = “aluCpf”) String aluCpf,
@WebParam(name = “aluNome”) String aluNome,
@WebParam(name = “aluChave”) String aluChave,
@WebParam(name = “ntNota”) String ntNota,
@WebParam(name = “ntData”) String ntData,
@WebParam(name = “ntStatus”) String ntStatus) {
SimpleDateFormat dataMascara = new SimpleDateFormat(“dd-MM-yyyy”);
dataMascara.setLenient(false);
try {
if(insCnpj == null) {
throw new Exception(“CPNJ da instituição não fornecido!”);
}
// recuperar a instituição (se existir)
Instituicao instituicao =
InstituicaoFacade.recuperarInstituicaoPorCnpj(insCnpj);
if(instituicao == null) {
// instituição não existe
if(insNome == null) {
throw new Exception(“Nome da instituição não fornecido!”);
}
if(insNome.length() > 100) {
throw new Exception(“Nome da instituição maior que 100 caracteres!”);
}
}
else {
if(!InstituicaoFacade.validarChaveInstituicao(instituicao, insChave)) {
throw new Exception(“Chave de acesso da instituição inválida!”);
}
}
if(disNome == null) {
throw new Exception(“Nome da disciplina não fornecido!”);
}
// recuperar a disciplina (se existir)
T.I.S. 2012; 1 (1): 35-53
50
Web Service no ambiente escolar: um estudo de caso
Disciplina disciplina = DisciplinaFacade.
recuperarDisciplinaPorInstituicaoENome(instituicao, disNome);
if(disciplina == null) {
// disciplina não existe
if(disNome.length() > 100) {
throw new Exception(“Nome da instituição maior que 100 caracteres!”);
}
}
if(aluCpf == null) {
throw new Exception(“CPF do aluno não fornecido!”);
}
// recuperar o aluno (se existir)
Aluno aluno = AlunoFacade.recuperarAlunoPorCpf(aluCpf);
if(aluno == null) {
// aluno não existe
if(aluNome == null) {
throw new Exception(“Nome do aluno não fornecido!”);
}
if(aluNome.length() > 100) {
throw new Exception(“Nome do aluno maior que 100 caracteres!”);
}
}
else {
if(!AlunoFacade.validarChaveAluno(aluno, aluChave)) {
throw new Exception(“Chave de acesso do aluno inválida!”);
}
}
if(ntNota == null) {
throw new Exception(“Nota não fornecida!”);
}
try {
Double.parseDouble(ntNota);
}
catch (Exception e) {
throw new Exception(“Nota inválida!”);
}
if((Double.parseDouble(ntNota) < 0) || (Double.parseDouble(ntNota) > 10))
{
throw new Exception(“Nota fora da faixa permitida (0..10)!”);
}
if(ntData == null) {
throw new Exception(“Data da nota não fornecida!”);
}
try {
dataMascara.parse(ntData);
}
catch (Exception e) {
throw new Exception(“Data da nota inválida (dd-mm-aaaa)!”);
}
if(ntStatus == null) {
throw new Exception(“Status da nota não fornecido!”);
}
if(ntStatus.length() > 100) {
}
if(instituicao == null) {
// instituição não existe - inserir a instituição
instituicao = new Instituicao();
instituicao.setCnpj(insCnpj);
instituicao.setNome(insNome);
insChave = Chave.gerar();
instituicao.setChave(insChave);
InstituicaoFacade.inserir(instituicao);
51
T.I.S. 2012; 1 (1): 35-53
}
if(disciplina == null) {
// disciplina não existe - inserir a disciplina
disciplina = new Disciplina();
disciplina.setInstituicao(instituicao);
disciplina.setNome(disNome);
DisciplinaFacade.inserir(disciplina);
}
if(aluno == null) {
// aluno não existe - inserir o aluno
aluno = new Aluno();
aluno.setCpf(aluCpf);
aluno.setNome(aluNome);
aluChave = Chave.gerar();
aluno.setChave(aluChave);
AlunoFacade.inserir(aluno);
}
// recuperar a nota (se existir)
Nota nota = NotaFacade.recuperarNotaPorDisciplinaAlunoEData(disciplina,
aluno,dataMascara.parse(ntData));
if(nota == null) {
// nota não existe - inserir nota
nota = new Nota();
nota.setDisciplina(disciplina);
nota.setAluno(aluno);
nota.setNota(Double.parseDouble(ntNota));
nota.setData(dataMascara.parse(ntData));
nota.setStatus(ntStatus);
NotaFacade.inserir(nota);
}
else {
// nota existe - atualizar
nota.setNota(Double.parseDouble(ntNota));
nota.setStatus(ntStatus);
NotaFacade.alterar(nota);
}
return “<instituicao>” +
“<cnpj>” + instituicao.getCnpj() + “</cnpj>” +
“<nome>” + instituicao.getNome() + “</nome>” +
“<chave>” + instituicao.getChave() + “</chave>” +
“</instituicao>” +
“<disciplina>” +
“<nome>” + disciplina.getNome() + “</nome>” +
“</disciplina>” +
“<aluno>” +
“<cpf>” + aluno.getCpf() + “</cpf>” +
“<nome>” + aluno.getNome() + “</nome>” +
“<chave>” + aluno.getChave() + “</chave>” +
“</aluno>” +
“<nota>” +
“<nota>” + nota.getNota() + “</nota>” +
“<data>” + dataMascara.format(nota.getData()) + “</data>” +
“<status>” + nota.getStatus() + “</status>” +
“</nota>”;
}
catch (Exception e) {
return “<erro>” + e.getMessage() + “</erro>”;
}
}
T.I.S. 2012; 1 (1): 35-53
52
Web Service no ambiente escolar: um estudo de caso
Quadro 21. Teste do cadastrarNota
webservices.HistoricoService servico = new webservices.HistoricoService();
webservices.Historico porta = servico.getHistoricoPort();
String resultado = porta.cadastrarNota(“55732312000181”, “Escola de teste”,
null, “Disciplina de teste”, “73548738966”, “Aluno de teste”, null, “9.0”,
“27-09-2010”, “Aprovado”);
String instituicaoChave = null;
String alunoChave = null;
if(resultado.indexOf(“<erro>”) < 0) {
String instituicao = resultado.substring(resultado.
indexOf(“<instituicao>”),
resultado.indexOf(“</instituicao>”));
if(instituicao.indexOf(“<chave>”) >= 0)
instituicaoChave = instituicao.substring(instituicao.indexOf(“<chave>”) +
7,
instituicao.indexOf(“</chave>”));
String aluno = resultado.substring(resultado.indexOf(“<aluno>”),
resultado.indexOf(“</aluno>”));
if(aluno.indexOf(“<chave>”) >= 0)
alunoChave = aluno.substring(aluno.indexOf(“<chave>”) + 7, aluno.
indexOf(“</chave>”));
// gravar as chaves no banco da aplicação
}
else {
// tratar o erro aqui
}
53
T.I.S. 2012; 1 (1): 35-53
Download