CONTEÚDO TECNOLOGIA EM INFORMÁTICA PARA NEGÓCIOS JAVA CONCEITOS Prof. Dr. Henrique Dezani dezani@fatecriopreto.edu.br Arquitetura de uma aplicação Web HTTP (HyperText Transfer Protocol) Métodos HTTP GET & HTTP POST Request & Response O que é? O que ele oferece? Como ele trata as solicitações? J2EE, como ele entra nesse assunto? Descritor XML ARQUITETURA DE UMA APLICAÇÃO WEB HTTP (HyperText Transfer Protocol) é um protocolo de transporte e um sistema de mensagem, porque solicitações e respostas HTTP são mensagens. O conteúdo das mensagem HTTP pode ser classificado, usando o sistema de Fpo MIME (Mul4purpose Internet Mail Extensions). HTTP também fornece códigos de status de resposta para informar ao solicitante se a solicitação obteve sucesso e, se não, porque. ARQUITETURA DE UMA APLICAÇÃO WEB O HTTP possui verbos bem conhecidos, oficilamente conhecidos como métodos, os quais são dados na tabela abaixo: Método Descrição Significado * GET Pede para recuperar algum recurso na URL Lê (Read) POST Pede que o servidor aceitar o conteúdo anexado Cria (Create) PUT Pede para adicionar alguma informação. Edita(Update) TRACE Pede para voltar ao início da mensagem de solicitação, para que o cliente possa ver o que está sendo recebido do outro lado (utilizado em geral para testes). DELETE Pede para apagar um determinado recurso Apaga (Delete) * CRUD (Create, Read, Update and Delete) ARQUITETURA DA APLICAÇÃO WEB ARQUITETURA DA APLICAÇÃO WEB http://www.google.com.br 1
ARQUITETURA DA APLICAÇÃO WEB HTTP ARQUITETURA DA APLICAÇÃO WEB (Get/Post) GET POST Perguntas!! 1 Como é processada a solicitação? 2 Como é definida a resposta? 3 Quando uma solicitação é feita por GET e quando é feita por POST? 4 Como saberemos qual classe será executada? CONTAINER O QUE ELE OFERECE? Os servlets não possuem um método main(). Eles estão sob o controle de outra aplicação Java chamada. Exemplos: Glassfish e Apache Tomcat ( ) Quando uma aplicação web recebe uma solicitação para uma servlet, o servidor entrega a solicitação não ao servlet em si, mas para o no qual o servlet é distribuído. O então entrega ao servlet a solicitação e a resposta HTTP e, dependendo do tipo de solicitação, chama o método servlet adequado (doget, dopost etc). Suporte para comunicações O container já trata as requisições e redireciona para o servlet correto (veremos adiante), portanto não precisamos nos preocupar com a criação de tráfego, escuta de porta, assim como é feito em aplicações ServerSocket. Foco na lógica do negócio! Gerenciamento do ciclo de vida O container controla a vida e a morte dos seus servlets, ou seja, ele é responsável por carregar as classes, instânciar, inicializar os servlets e chamar os métodos adequados (Get/Post). E, no final, o próprio container trata de coletar o lixo (Garbage Collector) Não é necessário se preocupar com o gerenciamento de recursos. O QUE ELE OFERECE? Suporte a Multithread O container cria automaticamente uma nova thread em Java para cada solicitação do servlet recebida. Ao finalizar a execução do método do serviço HTTP (Get/Post), a thread é finalizada. Poupa tempo de trabalho. Certeza de Segurança Utilizando o Deployment Descriptor XML (web.xml) você pode configurar a segurança sem ter que alterar (e recompilar) qualquer classe. Poupa tempo e facilita a manutenção Suporte ao JSP O container é responsável por interpretar os códigos escrtios no JSP e criar as páginas visualizadas pelo cliente final. 1 O usuário clica em um link que contém uma URL para um servlet. HTTP GET 2
2 O container vê que a solicitação é para um servlet e então cria dois objetos: HttpRequest e HttpResponse 3 O container encontra o servlet correto baseado na URL da solicitação, cria um thread para essa solicitação e passa os objetos de solicitação e resposta para a thread do servlet. (HttpRequest) (HttpResponse) Thread 4 O container chama o método service() do servlet. De acordo com o tipo de solicitação (Get ou Post), o método service chama o método correspondente (doget ou dopost). Neste exemplo consideramos o uso da solicitação por HTTP Get. 5 O método doget gera uma página dinamicamente e a insere no objeto resposta (HttpResponse). É importante ressaltar que o container ainda tem uma referência do objeto resposta. service() <html> </html> doget() service() 6 O thread é finalizado, o container converte o objeto resposta em uma resposta HTTP e envia de volta para o cliente. Por último, o container apaga os objetos solicitação e resposta. CICLO DE VIDA DA SERVLET Web Class Object Load class <html> </html> HTTP A.class Instancia a servlet (construtor) init() O Construtor padrão é executa. NÃO sobrescreva o construtor padrão. Executado uma única vez no ciclo de vida da servlet e deve ser completado antes do container invocar o método service(). service() destroy() Iniciada Iniciada Trata solicitações dos clientes. (doget(), dopost() etc.) Cada solicitação é tratada em um thread separada. Permite finalizar a servlet antes dela ser eliminada pelo Garbage Collector. Assim como o método init(), este é executado apenas uma vez. 3
J2EE (JAVA TO ENTERPRISE EDITION) O QUE É E COMO ELE ENTRA NESSE ASSUNTO J2EE incorpora especificações tais como o s e a JSP. A especificação J2EE também inclui a especificação Enterprise JavaBean para o EJB. O container web é para componentes web (s e JSP) e o container EJB é para componentes de negócios. Um servidor de aplicação totalmente compatível com J2EE deve ter tanto um container web como um container EJB. O Apache Tomcat é apenas um container web! VAMOS PROGRAMAR! Mas antes, vamos estudar quais é a estrutura de classes utilizada Interface (javax.servlet.) Generic class (javax.servlet.generic) <<interface>> service(request, Response) init(config) destroy() getconfig() getinfo() Generic service(request, Response) init(config) init() destroy() getconfig() getinfo() getinitparameter() getinitparameternames() getcontext() log(string) log(string, Throwable) public class extends Http { Http class (javax.servlet.http.http) class (br.edu.fatecriopreto.controller) doget(httprequest, HttpResponse) Http service(httprequest, HttpResponse) service(request, Response) doget(httprequest, HttpResponse) dopost(httprequest, HttpResponse) dohead(httprequest, HttpResponse) doput(httprequest, HttpResponse) dotrace(httprequest, HttpResponse) dodelete(httprequest, HttpResponse) getlastmodified(httprequest) Http public class extends Http { public class extends Http { 4
(POST) public class extends Http { public class extends Http { public class extends Http { out.println( <HTML><BODY>Hello World</BODY></HTML> ); DESCRITOR XML <web-app> <servlet> <servlet-name></servlet-name> <servlet-class></servlet-class> </servlet> <servlet-mapping> <servlet-name></servlet-name> <url-pattern>/cliente</url-pattern> </servlet-mapping> </web-app> DESCRITOR XML <web-app> <servlet> <servlet-name></servlet-name> <servlet-class></servlet-class> </servlet> <servlet-mapping> <servlet-name></servlet-name> <url-pattern>/cliente</url-pattern> </servlet-mapping> </web-app> DESCRITOR XML <web-app> <servlet> <servlet-name></servlet-name> <servlet-class></servlet-class> </servlet> <servlet-mapping> <servlet-name></servlet-name> <url-pattern>/cliente</url-pattern> </servlet-mapping> </web-app> http://localhost/pedidoweb/cliente 5
INDEX.JSP <!DOCTYPE html> <HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY> <A HREF= cliente?nome=fulano >Exibir</A> </BODY> INDEX.JSP <!DOCTYPE html> <HTML> <HEAD> <TITLE></TITLE> </HEAD> Símbolo para indicar que parâmetros serão enviados <BODY> <A HREF= cliente?nome=fulano >Exibir</A> </BODY> </HTML> </HTML> Parâmetros passados para o servidor URL da (<url-pattern>/cliente</url-pattern>) <A HREF= cliente?nome=fulano >Exibir</A> MENSAGEM HTTP MÉTODO GET Método HTTP Cabeçalho da solicitação Não há corpo da mensagem O caminho do recurso no servidor web GET /localhost/cliente?nome=fulano HTTP/1.1 Host: localhost User- Agent: Chrome (Macintosh; PPC Mac OS X) Accept: text/xml,application/xml,text/plain Accept- Language: en- us, en Accept- Encoding: gzip Accept- Charset: ISO- 8859-1,utf- 8 Keep- Alive:300 Connection: keep- alive Nas requisições GET, os parâmetros, caso haja algum, são adicionados à URL da solicitação A versão do protocolo que o navegador está solicitando INDEX.JSP <!DOCTYPE html> <HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY> <A HREF= cliente?nome=fulano&idade=35 >Exibir</A> </BODY> String idade = request.getparameter( idade ); </HTML> Símbolo utilizado na concatenação de parâmetros <A HREF= cliente?nome=fulano&idade=20 >Exibir</A> 6
<<interface>> Request getattribute(string) getcontentlength() getinputstream() getlocalport() getparameter() getparameternames() // E MUITOS OUTROS <<interface>> HttpRequest getcontextpath() getcookies() getheader(string) getquerystring() getsession() getmethod() // E MUITOS OUTROS String idade = request.getparameter( idade ); Mas idade é um número inteiro int idade = request.getparameter( idade ); Agora sim está correto! Mas não compila!!! int idade = request.getparameter( idade ); Como armazenar uma String como número inteiro? Parâmetros são sempre do tipo String!!! String sidade = request.getparameter( idade ); int idade = Integer.parseInt(sIdade); <!DOCTYPE html> <HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY> <FORM ACTION= cliente METHOD= POST > <INPUT TYPE= TEXT NAME= nome /> <INPUT TYPE= SUBMIT VALUE= Enviar /> </FORM> </BODY> </HTML> 7
MENSAGEM HTTP MÉTODO POST Método HTTP Cabeçalho da solicitação Corpo da mensagem O caminho do recurso no servidor web POST /localhost/cliente HTTP/1.1 Host: localhost User- Agent: Chrome (Macintosh; PPC Mac OS X) Accept: text/xml,application/xml,text/plain Accept- Language: en- us, en Accept- Encoding: gzip Accept- Charset: ISO- 8859-1,utf- 8 Keep- Alive:300 Connection: keep- alive nome=fulano A versão do protocolo que o navegador está solicitando Nas solicitações por POST, os parâmetros são passados no corpo da mensagem e, portanto, não são limitados como o GET. <!DOCTYPE html> <HTML> <HEAD> <TITLE></TITLE> </HEAD> URL da (<url-pattern>/cliente</url-pattern>) <BODY> <FORM ACTION= cliente METHOD= POST > <INPUT TYPE= TEXT NAME= nome /> <INPUT TYPE= SUBMIT VALUE= Enviar /> </FORM> </BODY> </HTML> (POST) E se os parâmetros tiverem o mesmo nome? <FORM ACTION= Minha METHOD= post > <INPUT TYPE= TEXT NAME= nome /> <INPUT TYPE= CHECKBOX NAME= modulo value= Java /> <INPUT TYPE= CHECKBOX NAME= modulo value= Net /> <INPUT TYPE= SUBMIT VALUE= Enviar /> </FORM> (POST) String[] nome = request.getparametervalues( modulo ); <INPUT TYPE= CHECKBOX NAME= modulo value= Java /> <INPUT TYPE= CHECKBOX NAME= modulo value= Net /> E se eu não souber o nome dos parâmetros? E se eu quisesse obter informações sobre o cabeçalho da solicitação? Como eu faria para obter a quantidade de saltos de roteadores realizadas? E para recuperar a sessão do cliente? E para recuperar os cookies? Como é possível identificar o método que será executado (GET/POST)? 8
Existem muitos outros métodos E se eu não souber o nome dos parâmetros? request.getparameternames() E se eu quisesse obter informações sobre o cabeçalho da solicitação? request.getheader( User-Agent ) Como eu faria para obter a quantidade de saltos de roteadores realizadas? request.getheader( Max-Forwards ) E para recuperar a sessão do cliente? request.getsession() E para recuperar os cookies? request.getcookies() Como é possível identificar o método que será executado (GET/POST)? request.getmethod() public class extends Http { <<interface>> Response getbuffersize() setcontenttype() getoutputstream() getwriter() // E MUITOS OUTROS <<interface>> HttpResponse addcookie() addheader() encoderedirecturl() senderror() setstatus() // E MUITOS OUTROS A resposta para o cliente pode ser: Caracteres (PrintWriter) Byes (OutputStream) Podemos definir o MIME (tipo do conteúdo), por exemplo text/html utilizando o método setcontenttype(); response.setcontenttype( text/html ); Alguns tipos: text/html application/pdf video/quicktime image/jpeg application/x-zip application/java application/jar public class extends Http { public class extends Http { out.println( Algum texto ou HTML ); out.println( Algum texto ou HTML ); 9
public class extends Http { public class extends Http { OutputStream out = response.getoutputstream(); out.write(abytearray); OutputStream out = response.getoutputstream(); out.write(abytearray); public class extends Http { response.setcontenttype( text/html ); public class extends Http { response.setcontenttype( application/txt ); out.println( <HTML><BODY>Teste</BODY></HTML> ); out.println( Hello World ); public class extends Http { response.setcontenttype( application/txt ); response.setheader("content-disposition","attachment; filename=teste.txt"); Além de retornar uma resposta para o cliente a partir de uma, é possível que você passe para outra coisa lidar com a resposta. Para isso podemos utilizar tanto Redirecionamento quanto RequestDispatch. Qual a diferença entre eles? out.println( Hello World ); 10
REDIRECIONAMENTO REDIRECIONAMENTO Quando uma servlet faz um redirecionamento, é como se pedíssemos que o cliente digitasse outra URL. Nesse caso o cliente é o Navegador. O usuário vê a nova URL no navegador!! public class extends Http { response.sendredirect( http://www.google.com.br ); REDIRECIONAMENTO public class extends Http { REQUEST DISPATCH Quando um servlet faz o request dispatch, é como se pedíssemos que um colega de trabalho cuidasse de um cliente. O colega de trabalho acaba respondendo ao cliente, mas o cliente não sabe disso, e também pouco se importa. O usuário NÃO vê a nova URL no navegador!! response.sendredirect( cliente?nome=pedro ); Podemos utilizar o redirecionamento para chamar outras classes dentro da aplicação. REQUEST DISPATCH REQUEST DISPATCH public class extends Http { throws IOException, Exception { RequestDispatcher view = request.getrequestdispatcher( index.jsp ); public class extends Http { Página que continuará a execução RequestDispatcher view = request.getrequestdispatcher( index.jsp ); view.forward(request, response); view.forward(request, response); Passamos a solicitação e a resposta, para que quem continuar a execução saiba para onde retornar os dados 11