terça-feira, 26 de julho de 2016

Spring Tutorial parte II - Consumindo o Web Service Rest com Angularjs

Anteriormente vimos dois tópicos que visam a integração do Spring com Web Service Rest (no back-end) e com Angularjs (no front-end). Considerando que já sabemos como criar um Web Service com Spring e que faça um databind em XML/JSON para retornar um objeto para a camada view, conforme os links abaixo, Vamos então para o consumo do serviço.

http://toxinavirtual.blogspot.com.br/2016/07/databind-com-jackson-e-com-google-json.html

http://toxinavirtual.blogspot.com.br/2016/07/spring-tutorial-parte-i-injecao-de_25.html


Segundo o manual do Spring, temos um exemplo em que uma URL fornece um JSON. O serviço roda na URL abaixo:

http://rest-service.guides.spring.io/greeting

E devolve o seguinte JSON:

{"id":1,"content":"Hello, World!"}

Para criar o projeto no Eclipse, vamos novamente em File>>New>>Other>>Dynamic Web Service e vamos criar um projeto com o nome WSAngularjsRest com a opção de criar web.xml selecionada.

Clicando com o botão direito do mouse sobre o projeto Configure>>Convert to Maven Project e deverá aparecer o arquivo pom.xml.

Vamos adicionar no arquivo as dependências embaixo da tag </build>.

  1.  <properties>
  2.         <spring.version>4.2.1.RELEASE</spring.version>
  3.     </properties>
  4.     <dependencies>
  5.         <!-- javax: XML binding -->
  6.         <dependency>
  7.             <groupId>javax.xml</groupId>
  8.             <artifactId>jaxb-api</artifactId>
  9.             <version>2.1</version>
  10.         </dependency>
  11.         <!-- RESTful web service: Jersey -->
  12.         <dependency>
  13.             <groupId>com.sun.jersey</groupId>
  14.             <artifactId>jersey-server</artifactId>
  15.             <version>1.17.1</version>
  16.         </dependency>
  17.         <dependency>
  18.             <groupId>com.sun.jersey</groupId>
  19.             <artifactId>jersey-servlet</artifactId>
  20.             <version>1.17.1</version>
  21.         </dependency>
  22.         <dependency>
  23.             <groupId>com.sun.jersey</groupId>
  24.             <artifactId>jersey-json</artifactId>
  25.             <version>1.17.1</version>
  26.         </dependency>
  27.         <!-- Unit testing -->
  28.         <dependency>
  29.             <groupId>junit</groupId>
  30.             <artifactId>junit</artifactId>
  31.             <version>3.8.1</version>
  32.             <scope>test</scope>
  33.         </dependency>
  34.         <!-- DEPENDÊNCIAS DO SPRING -->
  35.         <dependency>
  36.             <groupId>org.springframework</groupId>
  37.             <artifactId>spring-core</artifactId>
  38.             <version>${spring.version}</version>
  39.         </dependency>
  40.         <dependency>
  41.             <groupId>org.springframework</groupId>
  42.             <artifactId>spring-web</artifactId>
  43.             <version>${spring.version}</version>
  44.         </dependency>
  45.         <dependency>
  46.             <groupId>org.springframework</groupId>
  47.             <artifactId>spring-webmvc</artifactId>
  48.             <version>${spring.version}</version>
  49.         </dependency>
  50.     </dependencies>


Vamos criar o arquivo index.html dentro da pasta WebContent.

  1. <!doctype html>
  2. <html ng-app>
  3.     <head>
  4.         <title>Hello AngularJS</title>
  5.         <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
  6.         <script src="hello.js"></script>
  7.     </head>
  8.     <body>
  9.         <div ng-controller="Hello">
  10.             <p>The ID is {{greeting.id}}</p>
  11.             <p>The content is {{greeting.content}}</p>
  12.         </div>
  13.     </body>
  14. </html>

Repare que o arquivo importa uma biblioteca do Angularjs e importa também um arquivo hello.js que deverá conter o código com o objeto que será impresso na div ng-controller.

Dentro da mesma pasta vamos criar o arquivo hello.js.


  1. function Hello($scope, $http) {
  2.     $http.get('http://rest-service.guides.spring.io/greeting').
  3.         success(function(data) {
  4.             $scope.greeting = data;
  5.         });
  6. }

Repare que existe uma solicitação GET para o Web Service Rest do manual do Spring. Embaixo o objeto é recebido em uma variável que será impresso no index.html.


Vamos agora configurar o arquivo web.xml com o arquivo de chamada.

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  3.   <display-name>WSAngularjsRest</display-name>
  4.   <welcome-file-list>
  5.     <welcome-file>index.html</welcome-file>
  6.    
  7.   </welcome-file-list>
  8.   <!-- . <welcome-file>index.htm</welcome-file>
  9.     <welcome-file>index.jsp</welcome-file>
  10.     <welcome-file>default.html</welcome-file>
  11.     <welcome-file>default.htm</welcome-file>
  12.     <welcome-file>default.jsp</welcome-file>. -->
  13. <servlet>
  14.     <servlet-name>jersey-serlvet</servlet-name>
  15.     <servlet-class>
  16.         com.sun.jersey.spi.container.servlet.ServletContainer
  17.     </servlet-class>
  18.     <init-param>
  19.         <param-name>com.sun.jersey.config.property.packages</param-name>
  20.         <param-value>ngdemo.rest</param-value>
  21.     </init-param>
  22.     <init-param>
  23.         <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
  24.         <param-value>true</param-value>
  25.     </init-param>
  26.     <load-on-startup>1</load-on-startup>
  27. </servlet>
  28. <servlet-mapping>
  29.     <servlet-name>jersey-serlvet</servlet-name>
  30.     <url-pattern>/rest/*</url-pattern>
  31. </servlet-mapping>
  32. <!-- .. -->
  33. </web-app>

Basta rodar o arquivo agora no Tomcat clicando no projeto com o direito Run as>>Tomcat8>>OK.

A página deverá exibir algo como:




Repare que a página retornou os dados do JSON em formato de um objeto numa única variável. Este objeto poderia ser qualquer objeto e poderia ser invocado por diferentes URL. Por exemplo ser fosse um carro ou dados de uma pessoa:

http://rest-service.guides.spring.io/carro

http://rest-service.guides.spring.io/pessoa


Referencias:




segunda-feira, 25 de julho de 2016

Spring Tutorial parte I - Injeção de Dependência e Web Service Rest

Continuando a bateria de testes com o objetivo de estudar algumas arquiteturas interessantes e bastante utilizadas em projetos Java vamos testar um projeto com Spring e Web Service Rest.

O Spring é um framework largamente utilizado. Existem soluções Spring para diversos tipos de cenários. Pode ser utilizado para controle de sessão, para facilitar a divisão de camadas, pode ser utilizado com outras tecnologias como Hibernate e ultimamente tem sido utilizado como um atalho para os Web Services Rest.

O que o Spring faz? Basicamente o que o Spring faz Injeção de Dependência. Muito se fala hoje sobre Injeção de Dependência, mas neste contexto a Injeção de Dependência é apenas um atalho, uma forma de instanciar uma classe ou objeto.

Quando criamos uma nova instância geralmente utilizamos o comando abaixo para alocar o objeto em um novo espaço de memória do computador dentro de uma variável.

  1. Object nomeObjeto = new Object();

Sendo que este objeto pode ser qualquer tipo de classe como um carro:

  1. Carro carro = new Carro();

Quando utilizamos a Injeção de Dependência esse comando se faz desnecessário porque a chamada está ocorrendo em outro lugar. E no caso do Spring do Java esta instância é substituída por alguma anotação "annotation" que é caracterizado por um @ + palavra chave reservada, que é interpretada como um comando. Por exemplo o comando abaixo que é um comando de mapeamento:

  1. @RequestMapping("/")

Quando ocorre este tipo de "chamada", dizemos que ocorre uma Inversão de Controle, isso porque o controle vem de uma classe "mais interna". Diferente de como se fazia antes ao criar uma instância numa classe "mais externa". Em muitos casos onde havia uma chamada de função o objeto é lançado dentro da função para retornar o parâmetro numa variável de escopo mais externo.


Interessante que a annotation acima é importada da API do Java:

  1. import org.springframework.web.bind.annotation.RequestMapping;

Existem outras annotations que podem ser importadas de outras API's do Java, como pacotes Hibernate ou JAX-WS, e é aqui que parece ficar mais claro o limite entre uma tecnologia e outra. Apensar do Spring fazer Injeção de Dependência através de annotations, as annotations não se limitam ao Spring.

Em posts posteriores voltaremos a falar sobre Injeção de Dependência. Segue um artigo do próprio Martin Fowler falando sobre o tema:

http://martinfowler.com/articles/injection.html

Vamos aos testes agora.

Abra o Eclipse e crie um novo projeto Java em File>>New>>Other>>Dynamic Web Project com o nome de SistemaSpringMVC.

Clique com o direito do mouse sobre o projeto e Configure>>Convert to Maven Project e deverá aparecer o arquivo pom.xml dentro do projeto. Dentro do arquivo e abaixo da tag </build> vamos adicionar as API's.

  1. <properties>
  2.   <spring.version>4.2.1.RELEASE</spring.version>
  3.  </properties>
  4.  <dependencies>  
  5.  <!-- DEPENDÊNCIAS DO SPRING -->
  6.  <dependency>
  7.   <groupId>org.springframework</groupId>
  8.   <artifactId>spring-core</artifactId>
  9.   <version>${spring.version}</version>
  10.  </dependency>
  11.   <dependency>
  12.   <groupId>org.springframework</groupId>
  13.   <artifactId>spring-web</artifactId>
  14.   <version>${spring.version}</version>
  15.  </dependency>
  16.   <dependency>
  17.   <groupId>org.springframework</groupId>
  18.   <artifactId>spring-webmvc</artifactId>
  19.   <version>${spring.version}</version>
  20.  </dependency>
  21.  </dependencies>





Novamente com o botão direito sobre o projeto clique em Maven>>Update Project e as bibliotecas deverão aparecer em Java Resourcers>>Libraries>>Maven Dependences.

Vamos criar o index.jsp dentro de WebContent com o conteúdo abaixo.


  1. <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  2.  pageEncoding="ISO-8859-1"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  7. <title>Página Inicial</title>
  8. <script type="text/javascript">
  9.  function Redirecionar() {
  10.    var nomeInformado = prompt("Favor informar um nome: ", "");
  11.    window.location.href = "sistema/boasvindas?nome=" + nomeInformado;
  12.  }
  13. </script>
  14. </head>
  15. <body>
  16.   <center>
  17.   <h2>INICIANDO O SISTEMA EM SPRING MVC</h2>
  18.   <h3>
  19.    <a href="#" onclick="Redirecionar();">Click aqui para informar o
  20.     nome</a>
  21.   </h3>
  22.  </center>
  23. </body>
  24. </html>



Para que o index.jsp seja carregado temos que configurar o arquivo web.xml dentro de WEB-INF. Vamos colocar um dispatcher em web.xml que deverá carregar um outro arquivo.


  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  3.   <display-name>SistemaSpringMVC</display-name>
  4.   <welcome-file-list>
  5.     <welcome-file>index.html</welcome-file>
  6.     <welcome-file>index.htm</welcome-file>
  7.     <welcome-file>index.jsp</welcome-file>
  8.     <welcome-file>default.html</welcome-file>
  9.     <welcome-file>default.htm</welcome-file>
  10.     <welcome-file>default.jsp</welcome-file>
  11.   </welcome-file-list>
  12.   <servlet>
  13.  <servlet-name>dispatcher</servlet-name>
  14.  <servlet-class>
  15.   org.springframework.web.servlet.DispatcherServlet
  16.  </servlet-class>
  17.  <load-on-startup>1</load-on-startup>
  18. </servlet>
  19. <servlet-mapping>
  20.  <servlet-name>dispatcher</servlet-name>
  21.  <url-pattern>/</url-pattern>
  22. </servlet-mapping>
  23. <context-param>
  24.  <param-name>contextConfigLocation</param-name>
  25.  <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
  26. </context-param>
  27. <listener>
  28.  <listener-class>
  29.   org.springframework.web.context.ContextLoaderListener
  30.  </listener-class>
  31. </listener>
  32. </web-app>

Vamos criar agora o arquivo apontado WEB-INF/dispatcher-servlet.xml com o conteúdo abaixo.

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2.  xmlns:context="http://www.springframework.org/schema/context"
  3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6.       http://www.springframework.org/schema/context
  7.       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  8.   <context:component-scan base-package="br.marcelo.rosa.controller"/>
  9.   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  10.   <property name="prefix">
  11.    <value>/WEB-INF/views/</value>
  12.   </property>
  13.   <property name="suffix">
  14.    <value>.jsp</value>
  15.   </property>
  16.  </bean>
  17. </beans>

Repare que neste arquivo existe uma tag context apontando para o pacote br.marcelo.rosa.controller. Existem também duas tags properties apontantando para um arquivo .jsp dentro da pasta /WEB-INF/views/. Vamos criar os dois arquivos. Primeiro clicamos com o direito na pasta Java Resources criando uma nova classe em New>>Class e preenchemos da forma abaixo:





Inserimos o conteúdo abaixo:

  1. package br.marcelo.rosa.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RequestMethod;
  5. import org.springframework.web.bind.annotation.RequestParam;
  6. import org.springframework.web.servlet.ModelAndView;
  7. @Controller
  8. @RequestMapping("/sistema")
  9. public class SistemaController {
  10.  @RequestMapping(value = "/boasvindas", method = RequestMethod.GET)
  11.  public ModelAndView boasVindas(@RequestParam(value = "nome", required = false, defaultValue = "Cicero Ednilson") String nome) {
  12.    System.out.println("nome="+nome);
  13.   ModelAndView modelAndView = new ModelAndView("boasVindas");
  14.   modelAndView.addObject("mensagem", "Olá " + nome);
  15.    return modelAndView;
  16.  }
  17. }


Repare que este arquivo está mapeado pelo seguinte endereço:

/sistema/boasvindas/

A arquivo recebe ainda um parâmetro nomedo tipo String via GET.


Vamos criar o arquivo boasVindas.jsp em /views/. Se a pasta não existe é necessário criar a pasta primeiro e em seguida inserir o conteúdo.


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boas Vindas</title>
</head>
<body>
 <center>
  <h2>${mensagem}</h2>
  <h2>Nesse post aprendemos a configurar o Spring MVC</h2>
 </center>
</body>
</html>


Segue a estrutura do projeto para melhor visualização:



Para executar o projeto é necessário o Tomcat instalado, no meu caso estou usando o Tomcat8. Para que o Web Service funcione dentro do Tomcat é necessário instalar as API's de JAX-WS dentro de lib da pasta Tomcat.

Baixe o JAX-WS RI em https://jax-ws.java.net/ e descompacte.



As arquivos utilizados estão dentro da pasta lib. São utilizados apenas algumas libs:

jaxb-impl.jar
jaxws-api.jar
jaxws-rt.jar
gmbal-api-only.jar
management-api.jar
stax-ex.jar
streambuffer.jar
policy.jar

Feito isso é possível testar o arquivo com o direito em Run as >> Run on Server >> Tomcat8.

O aplicativo pode ser acessado pelo endereço:

http://localhost:8080/SistemaSpringMVC/




Ao clicar no link e preencher a janela aberta, ao dar OK o serviço será redirecionado com a palavra digitada para o endereço:

http://localhost:8080/SistemaSpringMVC/sistema/boasvindas?nome=Teste

E no Console deverá ser impresso o nome:
nome=Teste


Repare que apesar do Spring estar configurado, tecnicamente a parte do Rest ainda não foi complettamente implementada já que a característica do Web Service é receber um XML/JSON para devolver outro XML/JSON. Temos apenas a impressão de uma variável via GET, apesar do GET ser característica de chamada de Web Sevice. O objetivo inicial do Rest seria a comunicação entre sistemas distribuídos:

https://spring.io/understanding/REST



Referencias:
Os arquivos testados foram retirados do site abaixo:
http://www.ciceroednilson.com.br/configurando-um-projeto-java-com-spring-mvc-e-maven/

Um teste ainda mais simples pode ser encontrado no link abaixo. Considero este Tutorial excelente:
http://www.javatpoint.com/spring-3-mvc-tutorial

Manual do Spring:
http://projects.spring.io/spring-framework/

Para Deploy:
http://www.mkyong.com/webservices/jax-ws/deploy-jax-ws-web-services-on-tomcat/

Design Patterns:
http://www.tutorialspoint.com/design_pattern/