SlideShare une entreprise Scribd logo
1  sur  144
Workshop Microservices
Construindo APIs RESTful com
Spring Boot
Objetivos
• Ao final desta unidade você irá:
• Implementar a primeira aplicação utilizando Spring Boot
• Compreender as funcionalidades adicionais do Spring Boot
• Compreender como implementar serviços REST utilizando
Spring MVC
• Implementar persistência de dados utilizando Spring Data
• Expor os repositórios como serviços utilizando Spring Data
REST
• Implementar segurança utilizando Spring Security
• Explorar os demais projetos do ecossistema Spring
Agenda
• Spring Boot
• Spring MVC
• Spring REST
• Spring Data
• Spring Data REST
• Spring Security
• Demais projetos
• Batch, Cache, Messaging, Integration, WebSockets, …
Spring Ecosystem
Spring Boot
• Micro-framework para criação aplicações standalone
• Boot com embedded Java container
• Indicado para criação de micro-serviços
• Fornece várias funcionalidades por padrão
• Utiliza o conceito de configuração por “defaults”
• Ótima integração com toda plataforma Spring
• Spring MVC, Spring Data, Spring Security, …
• Suporta empacotamento JAR ou WAR
Spring Boot
• O que NÃO é:
• Plugins para IDE
• Você pode utilizar Spring Boot com qualquer IDE
• Ferramenta para geração de código
• Um novo container Java EE
• Arquitetura “ready” para Microservices
Spring Boot
Spring Boot (configuração inicial)
<project>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Spring Boot
• Como rodar a aplicação?
• IDE (Spring Tool Suite)
• Import… -> Existing Maven Projects
• Relaunch / Run
• Maven plugin
• mvn spring-boot:run
• export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M
• Standalone “fat JAR”
• java -jar target/myproject-0.0.1-SNAPSHOT.jar
• java -Xdebug -
Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n
-jar target/myproject-0.0.1-SNAPSHOT.jar
Spring Boot (deployment)
• Pode ser realizado via standalone “fat JAR”, ou por meio de
um WAR web package
• Suporta deployment em Java EE containers
• Tomcat, Jetty, Wildfly, TomEE, Glassfish, Weblogic
• Permite a configuração de “executable JARs”
• Podem ser configurados como serviços UNIX / Linux /
Windows
• UNIX/Linux services via init.d ou systemd
• Windows services via winsw
• Compatível com diferentes PaaS Cloud providers
• Cloud Foundry, Heroku, OpenShift, AWS, Boxfuse, Google App
Engine
Spring Boot (deployment)
• Configuração para deployment via WAR em um container
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
} <project>
<!-- ... -->
<packaging>war</packaging>
<!-- ... -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- ... -->
</dependencies>
</project>
Spring Boot (deployment)
• Configurando JAR executável no ambiente UNIX
• Fedora / CentOS
• sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp
• service myapp start
• Debian
• update-rc.d myapp defaults <priority>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
Spring Boot (containers)
Container Servlet Version Java Version
Tomcat 8 3.1 Java 7+
Tomcat 7 3.0 Java 6+
Jetty 9.3 3.1 Java 8+
Jetty 9.2 3.1 Java 7+
Jetty 8 3.0 Java 6+
Undertow 1.3 3.1 Java 7+
Spring Boot (containers)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!-- OR -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Laboratório 1 (boot-lab01)
• Criando uma primeira aplicação com Spring Boot
Spring Boot (starters)
• spring-boot-starter-web
• spring-boot-starter-data-jpa
• spring-boot-starter-data-rest
• spring-boot-starter-jdbc
• spring-boot-starter-websocket
• spring-boot-starter-cache
• spring-boot-starter-batch
• spring-boot-starter-hateoas
• spring-boot-starter-test
• spring-boot-starter-integration
• spring-boot-starter-validation
• spring-boot-starter-mobile…
Spring Boot (auto-configuration)
• AopAutoConfiguration
• JpaRepositoriesAutoConfiguration
• HibernateJpaAutoConfiguration
• DataSourceAutoConfiguration
• JmsTemplateAutoConfiguration
• MongoAutoConfiguration
• RedisAutoConfiguration
• WebMvcAutoConfiguration
• SecurityAutoConfiguration
• …
Spring Boot (configuration)
• Permite que você externalize as configurações da aplicação em arquivos
properties, YAML, variáveis de ambiente, argumentos de linha de comando
• Oferece uma lista bastante extensa de possíveis configurações
• https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-
properties.html
• Propriedades podem ser injetadas utilizando @Value ou acessadas via
Spring Environment
• Pode ser configurado também via @ConfigurationProperties
• Podem ser ativadas e alternadas utilizando profiles de aplicação
• application-{profile}.properties
• Suporta o uso de expressões e oferece recursos como
• Valores randômicos: ${random.long}
• Referências internas: ${anotherproperty.value}
• Variáveis de ambiente: ${VARIABLE}
Spring Boot (configuration)
• YAML file
• Properties file
spring:
application:
name: cruncher
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost/test
server:
port: 9000
my:
servers:
- dev.bar.com
- foo.bar.com
spring.application.name=cruncher
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/test
server.port=9000
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
Spring Boot (configuration)
email=test@email.com
thread-pool=12
@Component
public class GlobalProperties {
@Value("${thread-pool}")
private int threadPool;
@Value("${email}")
private String email;
@Autowired
private Environment env;
public String getEmail() {
return env.getProperty("email");
}
public int getThreadPool() {
return env.getProperty("thread-pool");
}
//getters and setters
}
• Exemplo utilizando @Value e Spring Environment
application.properties
Spring Boot (configuration)
@ConfigurationProperties(
locations = "classpath:mail.properties",
prefix = "mail")
public class MailProperties {
public static class Smtp {
private boolean auth;
private boolean starttlsEnable;
// ... getters and setters
}
@NotBlank
private String host;
private int port;
private String from;
private String username;
private String password;
@NotNull
private Smtp smtp;
// ... getters and setters
}
mail.host=localhost
mail.port=25
mail.smtp.auth=false
mail.smtp.starttls-enable=false
mail.from=me@localhost
mail.username=
mail.password=
• Exemplo utilizando @ConfigurationProperties
mail.properties
Spring Boot (profiles)
• Fornece uma maneira de segmentar a configuração da
aplicação por diferentes ambientes de execução
• Qualquer @Component, @Configuration por ser anotado
com @Profile
• Para sinalizar um profile, basta utilizar:
• Propriedade: spring.profiles.active=dev
• CLI: --spring.profiles.active=dev
• JVM: -Dspring.profiles.active=dev
• Java: SpringApplication.setAdditionalProfiles(…)
• Podem ser sobrescritos e/ou combinados utilizando uma regra
de maior prioridade
• spring.profiles.active=default,dev
Spring Boot (profiles)
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
server:
port: 9000
---
spring:
profiles: development
server:
port: 9001
---
spring:
profiles: production
server:
port: 0
@Configuration
@Profile(“!production")
public class NonProductionConfiguration {
// ...
}
• Exemplo de utilização @Profile
application.yml
Spring Boot (logging)
• Implementação interna via Commons Logging
• Por padrão utiliza Logback, mas suporta outros providers,
como Java Util Logging e Log4J
• Pode habilitar o level por execução
• java -jar myapp.jar --debug
• Formato padrão do log utilizado
• Date and Time, Log Level, Process ID, Thread Name, Logger Name, Log Message
2014-03-05 10:57:51.112 INFO 45469 --- [ main]
org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].
[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader
: Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1]
o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1]
o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to:
[/*]
Spring Boot (logging)
• Configuração customizada de níveis de log
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
application.properties
@Component
public class Service {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public void doSomething(String param) {
try {
logger.debug("Trying to do something using param {}", param);
// process something
} catch (Exception ex) {
logger.error("Error to do something", ex);
}
}
// other methods
}
Spring Boot (actuator)
• Ajuda gerenciar e monitorar as aplicações em produção
• Acessível via HTTP, JMX ou remote shell
• Fornece uma lista de endpoints para gerenciar Spring
Boot app
• Publica as propriedades e Spring Beans em formato
JSON view
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
Spring Boot (actuator)
• /info
• Informação da aplicação
• /health
• Status da aplicação (UP/DOWN)
• /beans
• Lista de Spring Beans na aplicação
• /env
• Propriedades externas configuradas
• /dump
• Realiza um thread dump
• /metrics
• Métricas da aplicação corrente (número de requests, consumo memória, etc)
• /mappings
• Lista de todos os @RequestMapping’s da aplicação
• /trace
• Demonstra o trace dos últimos 100 requests
• /autoconfig
• Relatório de auto-configuração da aplicação
• /shutdown
• Realiza o shutdown da aplicação (não ativado por padrão)
Spring Boot (actuator)
• Customizando health indicator
@Component
public class MyHealthIndicator implements HealthIndicator {
@Override
public Health health() {
int errorCode = check();
// perform some specific health check
if (errorCode != 0) {
return Health.down().withDetail(
"Error Code", errorCode).build();
}
return Health.up().build();
}
}
Spring Boot (dev tools)
• Conjunto de ferramentas para facilitar o processo de
desenvolvimento e deployment das apps
• Principais funcionalidades
• Property defaults
• Automatic restart
• Live reload
• Global settings
• Remote applications
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Laboratório 2 (boot-lab02)
• Explorando os recursos do Spring Boot
Spring Boot (testing)
• Fornece diversos utilitários e implementações para
implementação de testes unitários
• Habilitado via spring-boot-starter-test
• Módulos spring-boot-test (core), spring-boot-test-
autoconfigure (auto-configuração)
• Dependências
• JUnit - Biblioteca de unit testing em Java
• Spring Test - Utilitários para testes integração com Spring Boot
• AssertJ - Biblioteca para fluent assertion
• Hamcrest - Biblioteca para matcher objects (constraints / predicates)
• Mockito - Mock objects framework
• JSONassert - Biblioteca para JSON assertion
• JsonPath - Biblioteca para XPath para JOSN
Spring Boot (testing)
• Habilitado utilizando a anotação @SpringBootTest e via
JUnit SpringRunner
• Simula um webEnvironment que pode configurado como:
• MOCK, RANDON_PORT, DEFINED_PORT, NONE
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Import(MyTestsConfiguration.class)
public class MyTests {
@Test
public void exampleTest() {
...
}
}
Spring Boot (testing)
• Suporta a utilização de Mock objects via Mockito
• Basta injetar objetos com uso da anotação @MockBean
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {
@MockBean
private RemoteService remoteService;
@Autowired
private Reverser reverser;
@Test
public void exampleTest() {
// RemoteService has been injected into the reverser bean
given(this.remoteService.someCall()).willReturn("mock");
String reverse = reverser.reverseSomeCall();
assertThat(reverse).isEqualTo("kcom");
}
}
Spring Boot (testing)
• Oferece uma boa alternativa para testar conteúdo JSON
por meio da anotação @JsonTest
• Utiliza por padrão Jackson como parser, mas pode ser
configurado para suportar Gson
@RunWith(SpringRunner.class)
@JsonTest
public class MyJsonTests {
@Autowired
private JacksonTester<VehicleDetails> json;
@Test
public void testSerialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make")
.isEqualTo("Honda");
}
}
Laboratório 3 (boot-lab03)
• Testando uma aplicação Spring Boot
Spring MVC
• Web MVC action framework suportado pelo Spring Boot
• Utilizado para implementação de aplicações Web content
e também para REST APIs
Spring MVC
• DispatcherServlet
• Implementação do design
pattern FrontController
• Recebe todas as requisições
e delega para os controllers
respectivos
• Utiliza ViewResolver para
resolver qual a tela deverá
ser retornada
Spring MVC (controller)
• @Controller é o componente principal do Spring MVC
• Define os server endpoints da aplicação Web
• Aplicações REST pode ser utilizado @RestController
@Controller
public class GreetingController {
@RequestMapping("/greeting")
public String greeting(
@RequestParam(required=false) String name, Model model) {
model.addAttribute("name", name);
return "greeting";
}
}
Spring MVC (annotations)
• @RequestMapping
• Define os server endpoints à serem processados pela aplicação
@Controller
@RequestMapping("/appointments")
public class AppointmentsController {
@Autowired AppointmentBook appointmentBook;
@RequestMapping(method = RequestMethod.GET)
public Map<String, Appointment> get() {
return appointmentBook.getAppointmentsForToday();
}
@RequestMapping(method = RequestMethod.POST)
public String add(@Valid AppointmentForm appointment, BindingResult result) {
if (result.hasErrors()) {
return "appointments/new";
}
appointmentBook.addAppointment(appointment);
return "redirect:/appointments";
}
}
Spring MVC (annotations)
• RequestMapping possui variações para melhor suportar
as operações HTTP
• @GetMapping, @PostMapping, @PutMapping
@DeleteMapping, @PatchMapping
@Controller
@RequestMapping("/appointments")
public class AppointmentsController {
@Autowired AppointmentBook appointmentBook;
@GetMapping
public Map<String, Appointment> get() {
return appointmentBook.getAppointmentsForToday();
}
@PostMapping
public String add(@Valid AppointmentForm appointment, BindingResult result) {
if (result.hasErrors()) {
return "appointments/new";
}
appointmentBook.addAppointment(appointment);
return "redirect:/appointments";
}
}
Spring MVC (annotations)
• @RequestParam
• Recuperação de um parâmetro da requisição
• @RequestBody
• Define o acesso para o conteúdo do corpo da requisição (ex: JSON, XML, etc)
• @ResponseBody
• Define o retorno do conteúdo como corpo da resposta (ex; JSON, XML, etc)
• @PathVariable
• Recuperação de um atributo como parte do path da requisição
• @ModelAttribute
• Recuperação de um grupo de atributos submetidos na requisição
• @SessionAttribute
• Referência e/ou recuperação de um atributo da sessão (HttpSession)
• @RequestAttribute
• Referência e/ou recuperação de um atributo da requisição
• @CookieValue
• Recuperação de um cookie na requisição
• @RequestHeader
• Recuperação de um cabeçalho da requisição
Spring MVC (annotations)
@Controller
public class PetController {
@PostMapping(path = "/pets", consumes=“application/json”, produces="application/json")
@ResponseBody
public Pet addPet(@RequestBody Pet pet, Model model) {...}
@GetMapping(path = "/pets/setup")
public String setupForm(@RequestParam("petId") int petId, ModelMap model) {}
@PostMapping(path = "/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {...}
@GetMapping(path = "/display/cookie")
public void displayCookie(@CookieValue("JSESSIONID") String cookie) {...}
@GetMapping(path = "/display/header")
public void displayHeader(@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) {...}
@GetMapping(path = "/user")
public String handleUser(@SessionAttribute User user) {...}
}
• Exemplos de utilização das anotações
Spring MVC (error handling)
• Spring Boot oferece /error endpoint como página global
de erros, para tratar erros de maneira geral
• Oferece implementação de tratadores de execução
customizados via @ExceptionHandler
• Pode ser utilizado como método do @Controller ou por via
@ControllerAdvice
@Controller
public class SimpleController {
// @RequestMapping methods omitted ...
@ExceptionHandler(IOException.class)
@ResponseBody
public ResponseEntity<String> handleIOException(IOException ex) {
// prepare responseEntity
return responseEntity;
}
}
Spring MVC (error handling)
• Páginas de erros podem ser customizadas de maneira
estática ou utilizando templates
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftl
+- <other templates>
Spring MVC (static content)
• Por padrão Spring Boot irá buscar conteúdo estático nos
seguintes diretórios
• /static, /public, /resources ou /META-INF/resources
• A partir do diretório /src/main/resources (Maven)
• Não utilize o diretório /src/main/webapp
• Funciona apenas para empacotamento WAR
• Fornece LiveReload para browser refresh automático
• Apenas quando DevTools está habilitado no Spring Boot
• Suporta a utilização de WebJars
• http://www.webjars.org/
Spring MVC (view templates)
• Suporta uma variedade de ferramentas de view templates
para processamento conteúdo Web dinâmico
• FreeMaker
• Groovy
• Thymeleaf
• Mustache
• JSP
• Os templates serão buscados a partir do diretório template
na aplicação Spring Boot
• /src/main/resources/templates
Spring MVC (CORS)
• Pode ser customizado via configuração customizada
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
};
}
}
Spring MVC (CORS)
• Fornece a anotação @CrossOrigin para ser utilizada
diretamente nos controllers
@Controller
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@Controller
@RequestMapping("/account")
public class AccountController {...}
Spring MVC (testing)
• Oferece uma customização especial para testes utilizando a
anotação @WebMvcTest
• Possui integração com frameworks de teste funcional (HtmlUnit,
Selenium)
@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyControllerTests {
@Autowired MockMvc mvc;
@MockBean UserVehicleService userVehicleService;
@Test
public void testExample() throws Exception {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willReturn(new VehicleDetails("Honda", “Civic"));
this.mvc.perform(get("/sboot/vehicle")
.accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
}
}
Laboratório 4 (boot-lab04)
• Desenvolvimento Web com Spring MVC
Web Services APIs
Arquitetura REST
Arquitetura REST
• ︎Protocolo cliente/servidor sem estado (HTTP)
• ︎Operações bem definidas
• GET
• POST
• PUT
• DELETE, etc
• ︎Sintaxe universal para identificação de recursos
(URL)
• ︎Transferência de informações em formato padrão
(XML, HTML, JSON)
Richardson Maturity Model
RESTful Services
Spring REST
• @RestController
• Define uma anotação específica para controllers REST
@RestController
@RequestMapping(value="/users")
public class MyRestController {
@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
}
Spring REST
• Fornece flexibilidade para configuração na negociação de conteúdo
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
}
curl http://localhost:8080/spring-mvc-java/employee/10?mediaType=[json/xml]
<employee>
<contactNumber>999-999-9999</contactNumber>
<id>10</id>
<name>Test Employee</name>
</employee>
{
"id": 10,
"name": "Test Employee",
"contactNumber": "999-999-9999"
}
Spring REST
• Unit testing é implementado utilizando @WebMvcTest
@RunWith(SpringRunner.class)
@WebMvcTest(GreentingController.class)
public class GreetingControllerTests {
@Autowired
private MockMvc mvc;
@Test
public void givenGreetURIWithQueryParameter() {
this.mockMvc.perform(get("/greetWithQueryVariable")
.param("name", "John Doe")).andDo(print()).andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.message").value("Hello World John Doe!!!"));
}
@Test
public void givenGreetURIWithPost() {
this.mockMvc.perform(post("/greetWithPost")).andDo(print())
.andExpect(status().isOk()).andExpect(content()
.contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.message").value("Hello World!!!"));
}
}
Spring REST
• É possível utilizar especificação JAX-RS na implementação dos
REST endpoints
• Basta incluir a dependência spring-boot-starter-jersey
• Implementado via Jersey 2.x
• Para cada REST endpoint é necessário defini-los como um bean
gerenciado pelo Spring
• Configurado com a anotação @Component
@Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(Endpoint.class);
}
}
@Component
@Path("/hello")
public class Endpoint {
@GET
public String message() {
return "Hello";
}
}
HATEOAS
• Hypermedia As The Engine of Application State
• Descrevem o estado atual da aplicação e como navegar para
o próximo estado
Hypermedia
Spring HATEOAS
• Adiciona suporte HATEOAS para REST endpoints
• Basta incluir a dependência spring-boot-starter-hateoas
• Definida pelos componentes Links e Resources
Link link = new Link("http://localhost:8080/something");
assertThat(link.getHref(), is("http://localhost:8080/something"));
assertThat(link.getRel(), is(Link.SELF));
class PersonResource extends ResourceSupport {
String firstname;
String lastname;
}
PersonResource resource = new PersonResource();
resource.firstname = "Dave";
resource.lastname = "Matthews";
resource.add(new Link("http://myhost/people"));
{ firstname : "Dave",
lastname : "Matthews",
links : [
{ rel : "self",
href : "http://myhost/people" } ] }
Spring HATEOAS
public class Greeting {
String name;
// getters and setters
}
public class GreetingResource
extends Resource<Greeting> {
public GreetingResource(Greeting greeting,
Link... links) {
super(greeting, links);
}
}
public class GreetingResourceAssembler
extends ResourceAssemblerSupport<Greeting, GreetingResource> {
public GreetingResourceAssembler() {
super(Greeting.class, GreetingResource.class);
}
@Override
public GreetingResource toResource(Aluno aluno) {
return new GreetingResource(aluno,
linkTo(methodOn(GreetingController.class).get(greeting.getName())).withSelfRel());
}
@Override
protected GreetingResource instantiateResource(Greeting aluno) {
return new GreetingResource(greeting);
}
}
Spring HATEOAS
@RestController
public class GreetingController {
GreetingResourceAssembler assembler = new GreetingResourceAssembler();
@RequestMapping("/greeting")
public ResponseEntity<GreetingResource> greeting(
@RequestParam(value = "name", required = false) String name) {
Greeting greeting = new Greeting("Hello, " + name);
return new ResponseEntity<>(assembler.toResource(greeting), HttpStatus.OK);
}
}
{
"content":"Hello, User!",
"_links":{
"self":{
"href":"http://localhost:8080/greeting?name=User"
}
}
}
curl http://localhost:8080/greeting?name=User
Swagger
• Alternativa para documentação da REST API
• Possui ótima integração com Spring Boot
• SpringFox - https://springfox.github.io/springfox/
• Oferece uma ferramenta para navegação Web
• Swagger UI - http://swagger.io/swagger-ui/
• Possui também uma ferramenta para modelagem da API
• Swagger Editor - http://swagger.io/swagger-editor/
Swagger (spring boot)
• Basta adicionar as dependências Maven
• springfox-swagger-ui e springfox-swagger2
• Habilitar suporte Swagger na aplicação via @EnableSwagger2
• Documentar os REST controllers utilizando anotações
• @ApiOperation
• Documentação de um REST endpoint
• @ApiParam, @ApiImplicitParam
• Documentação dos parâmetros do REST endpoint
• @ApiResponse
• Documentação da resposta do REST endpoint
• @ApiModel, @ApiModelProperty
• Documentação do modelo de dados de resposta do REST endpoint
• @Authorization
• Documentação do modelo de autorização do REST endpoint
• @ResponseHeader
• Documentação dos headers de resposta do REST endpoint
Swagger (spring boot)
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
• Exemplo de integração Swagger com Spring Boot
Swagger (spring boot)
@RestController
public class GreetingController {
@ApiOperation(value = "getGreeting", nickname = "getGreeting")
@RequestMapping(method = RequestMethod.GET, path="/greeting",
produces = "application/json")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "User's name", required = false,
dataType = "string", paramType = "query")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success", response = Greeting.class),
@ApiResponse(code = 401, message = "Unauthorized"),
@ApiResponse(code = 403, message = "Forbidden"),
@ApiResponse(code = 404, message = "Not Found"),
@ApiResponse(code = 500, message = "Failure")})
public Greeting greeting(@RequestParam(value="name") String name) {
return new Greeting(new AtomicLong().incrementAndGet(),
String.format("Hello, %s!", name));
}
}
• Exemplo de documentação utilizando as anotações Swagger
Swagger UI
Laboratório 5 (boot-lab05)
• Implementando RESTful com Spring Boot
Spring Data
• Abstração para implementação de repositórios de
persistência de dados integrada ao Spring Boot
• Suporta diferentes modelos de persistência
• JDBC, JPA, MongoDB, LDAP, Redis, Gemfire, Cassandra
• DynamoDB, Couchbase, Solr, Elasticsearch, Neo4j,…
• Implementa ações de CRUD em repositórios abstratos
• Fornece queries dinâmicas criadas a partir nomes de
métodos dos repositórios
• Oferece flexibilidade para customização de repositórios
• Suporta configurações de auditoria
Spring Data
Spring Data
Spring Data
public interface CrudRepository<T, ID extends Serializable>
extends Repository<T, ID> {
<S extends T> S save(S entity);
T findOne(ID primaryKey);
Iterable<T> findAll();
Long count();
void delete(T entity);
boolean exists(ID primaryKey);
}
• Definição dos repositórios abstratos
public interface PagingAndSortingRepository<T, ID extends Serializable>
extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
interface Repository<T, ID> extends Serializable> {}
Spring Data
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
// other methods
}
• Utilização dos repositórios abstratos
@Component
public class SomeClient {
@Autowired
private UserRepository repository;
public void doSomething() {
PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = repository.findAll(new PageRequest(1, 20));
}
}
Spring Data
interface UserRepositoryCustom {
public void someCustomMethod(User user);
}
interface UserRepository extends CrudJpaRepository<User, Long>, UserRepositoryCustom {
// Declare query methods here
}
• Implementação de repositórios “customizados"
class UserRepositoryImpl implements UserRepositoryCustom {
public void someCustomMethod(User user) {
// Your custom implementation
}
}
Spring Data
• Mecanismo de geração de
consultas dinâmicas
• Definição por DSL
• Via nome dos métodos
• Suporta diferentes variações
• ByProperty
• ByPropertyAsc
• ByPropertyDesc
• ByProp1AndProp2
• ByProp1OrProp2
• ByPropertyContaining
• …
Spring Data (queries)
• Definição das consultas dinâmicas
public interface PersonRepository extends Repository<User, Long> {
List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
// Enables the distinct flag for the query
List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
// Enabling ignoring case for an individual property
List<Person> findByLastnameIgnoreCase(String lastname);
// Enabling ignoring case for all suitable properties
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
// Enabling static ORDER BY for a query
List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}
Spring Data (queries)
Logical keyword Keyword expressions
AND And
OR Or
AFTER After, IsAfter
BEFORE Before, IsBefore
CONTAINING Containing, IsContaining, Contains
BETWEEN Between, IsBetween
ENDING_WITH EndingWith, IsEndingWith, EndsWith
EXISTS Exists
FALSE False, IsFalse
GREATER_THAN GreaterThan, IsGreaterThan
GREATER_THAN_EQUALS GreaterThanEqual, IsGreaterThanEqual
IN In, IsIn
IS Is, Equals, (or no keyword)
IS_NOT_NULL NotNull, IsNotNull
Spring Data (queries)
Logical keyword Keyword expressions
IS_NULL Null, IsNull
LESS_THAN LessThan, IsLessThan
LESS_THAN_EQUAL LessThanEqual, IsLessThanEqual
LIKE Like, IsLike
NEAR Near, IsNear
NOT Not, IsNot
NOT_IN NotIn, IsNotIn
NOT_LIKE NotLike, IsNotLike
REGEX Regex, MatchesRegex, Matches
STARTING_WITH StartingWith, IsStartingWith, StartsWith
TRUE True, IsTrue
WITHIN Within, IsWithin
Spring Data (queries)
• Limitação nos resultados de consulta
public interface PersonRepository extends Repository<User, Long> {
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);
}
Spring Data JPA
• Oferece suporte à JPA
• Basta adicionar a dependência
• spring-boot-starter-data-jpa
• Habilitar por padrão Hibernate
como JPA provider
• Oferece integração QueryDSL
• Suporte à paginação, execução
dinâmica de consultas,
integração com repositórios
customizados, etc
Spring Data JPA
Spring Data JPA
public interface JpaRepository<T, ID> extends
PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
List<T> findAll();
List<T> findAll(Sort sort);
List<T> findAllById(Iterable<ID> ids);
<S extends T> List<S> saveAll(Iterable<S> entities);
void flush();
<S extends T> S saveAndFlush(S entity);
void deleteInBatch(Iterable<T> entities);
void deleteAllInBatch();
T getOne(ID id);
}
• Definição do repositório JPA abstrato
Spring Data JPA
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "username")
private String name;
private String password;
@OneToOne
private Person person;
// getters and setters
}
public interface UserRepository extends JpaRepository<User, Long> {
User findByName(String name);
List<User> findByNameContaining(String name);
}
• JPA Entity e repositório Spring Data JPA
Spring Data JPA
Keyword Sample JPQL snippet
And findByLastnameAndFirstnam
e
… where x.lastname = ?1 and
x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or
x.firstname = ?2
Is,Equals findByFirstname … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between
?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Spring Data JPA
@Entity
@NamedQuery(name = "User.findByEmailAddress",
query = "select u from User u where u.emailAddress = ?1")
public class User {
// Implementation
}
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByLastname(String lastname);
User findByEmailAddress(String emailAddress);
}
• Utilizando @NamedQuery's
Spring Data JPA
public interface UserRepository extends JpaRepository<User, Long> {
// JP-QL sample
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
// JP-QL with named parameters
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
// Native SQL query
@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
User findByEmailAddress(String emailAddress)
// Native SQL query for paging
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
nativeQuery = true)
Page<User> findByLastname(String lastname, Pageable pageable);
}
• Utilizando @Query’s customizadas
Spring Data JPA
public interface UserRepository extends JpaRepository<User, Long> {
// JP-QL sample with ordering
@Query("select u from User u where u.lastname like ?1%")
List<User> findByAndSort(String lastname, Sort sort);
// Delete query sample
@Modifying
@Query("delete from User u where user.role.id = ?1")
void deleteInBulkByRoleId(long roleId);
// Update query sample
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);
// Using query hints
@QueryHints(value = { @QueryHint(name = "name", value = "value")},
forCounting = false)
Page<User> findByLastname(String lastname, Pageable pageable);
}
• Utilizando @Query’s customizadas
Spring Data JPA
• Executando Stored Procedures
/;
DROP procedure IF EXISTS plus1inout
/;
CREATE procedure plus1inout (IN arg int, OUT res int)
BEGIN ATOMIC
set res = arg + 1;
END
/;
@Entity
@NamedStoredProcedureQuery(name = "User.plus1", procedureName = "plus1inout", parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) })
public class User {}
public interface UserRepository extends JpaRepository<User, Long> {
@Procedure("plus1inout")
Integer explicitlyNamedPlus1inout(Integer arg);
@Procedure(name = "User.plus1IO")
Integer entityAnnotatedCustomNamedProcedurePlus1IO(@Param("arg") Integer arg);
}
Spring Data JPA (specification)
public class CustomerSpecs {
public static Specification<Customer> isLongTermCustomer() {
return new Specification<Customer>() {
public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query,
CriteriaBuilder builder) {
LocalDate date = new LocalDate().minusYears(2);
return builder.lessThan(root.get(_Customer.createdAt), date);
}
};
}
}
public interface CustomerRepository extends JpaRepository<Customer, Long>,
JpaSpecificationExecutor<Customer> {...}
public interface Specification<T> {
Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
CriteriaBuilder builder);
}
List<Customer> customers = customerRepository.findAll(isLongTermCustomer());
Spring Data JPA (query by example)
public interface QueryByExampleExecutor<T> {
<S extends T> S findOne(Example<S> example);
<S extends T> Iterable<S> findAll(Example<S> example);
// … more functionality omitted.
}
public class PersonService {
@Autowired PersonRepository personRepository;
public List<Person> findPeople(Person probe) {
return personRepository.findAll(Example.of(probe));
}
}
public interface PersonRepository extends JpaRepository<Person, String> { … }
Person person = new Person();
person.setFirstname("Dave");
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnorePaths("lastname")
.withIncludeNullValues()
.withStringMatcherEnding();
Example<Person> example = Example.of(person, matcher);
Spring Data JPA (transactional)
public interface UserRepository extends JpaRepository<User, Long> {
// Transaction support
@Transactional(timeout = 10)
public List<User> findAll();
}
@Service
class UserManagementImpl implements UserManagement {
@Autowired UserRepository userRepository;
@Autowired RoleRepository roleRepository;
@Transactional
public void addRoleToAllUsers(String roleName) {
// Step 1
Role role = roleRepository.findByName(roleName);
// Step 2
for (User user : userRepository.findAll()) {
user.addRole(role);
userRepository.save(user);
}
}
• Suporte transacional
Spring Data JPA (auditing)
class Customer {
@CreatedBy
private User user;
@CreatedDate
private DateTime createdDate;
// … further properties omitted
}
• Controle de auditoria
class SpringSecurityAuditorAware implements AuditorAware<User> {
public User getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
return ((MyUserDetails) authentication.getPrincipal()).getUser();
}
}
@Configuration
@EnableJpaAuditing
class Config {
@Bean
public AuditorAware<AuditableUser> auditorProvider() {
return new AuditorAwareImpl();
}
}
Spring Data JPA (testing)
@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTests {
@Autowired TestEntityManager entityManager;
@Autowired UserRepository repository;
@Test
public void findByUsernameShouldReturnUser() {
this.entityManager.persist(new User("sboot", "123"));
User user = this.repository.findByUsername("sboot");
assertThat(user.getUsername()).isEqualTo("sboot");
assertThat(user.getVin()).isEqualTo("123");
}
}
• Unit testing com @DataJpaTest e TestEntityManager
Project Lombok
• Oferece anotações para substituir “boilerplate code” nos
beans da aplicação
• Fornece geração automática à diversas implementações
• Getters/setters, Constructors, Equals/hashcode
• ToString, Builder’s, Immutable classes, Synchronized,…
• Implementação por meio de anotações
• @Getter, @Setter, @EqualsAndHashCode, @ToString
• @NoArgsConstructor, @RequiredArgsConstructor
• @AllArgsContructor, @Data, @Builder, @Log
• @Synchronized, @Value, @NonNull, @Cleanup
Project Lombok
• Basta adicionar a dependência no projeto
• Implementar os beans utilizando as anotações
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
public class User implements Serializable {
Long id;
String name;
String password;
}
Spring Boot (datasources)
• Oferece suporte à diferentes RDBMS
• MySQL, PostgreSQL, Oracle, SQLServer, H2, …
• É necessário configurá-los via spring.datasource.*
• Suporta diferentes tipos de definição para data sources
• Hikari, Tomcat, C3P0, DBCP2, JNDI
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.hikari.maximum-pool-size=5
spring.datasource.hikari.connection-timeout=10
Spring Boot (H2)
• Embedded in-memory RDBMS
• Rápido, opensource e suporta 100% JDBC API
• Small footprint (cerca 1.5 MB de tamanho)
• Pode ser instalado como server, e persistência em arquivo
• Ideal para utilização em testes de integração
• Oferece uma aplicação Web para administração
• Para habilitá-lo, basta adicionar a dependência
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
Spring Boot (H2)
• Para habilitar no Spring Boot, basta adicionar a
dependência e habilitar interface Web, se desejado
• spring.h2.console.enabled = true
• http://boot/h2-console
Laboratório 6 (boot-lab06)
• Persistindo dados com Spring Data JPA
MongoDB
• NoSQL database orientado à documentos
• Persistência de dados no formato JSON
• Armazenamento em formato BSON (binary JSON)
• Suporte à full indexação, auto sharding, map reduce,
replicação e tolerância à falhas
db.createCollection('contato')
db.contato.insert({
name: 'Rodrigo',
email: 'rodrigo@email.com',
mensagem: 'Inserindo dados no MongoDB'
})
db.contato.find()
db.contato.update({name: 'Rodrigo'}, {$set: {email: 'rodrigo@new-email.com'}})
db.contato.remove({name: 'Rodrigo'})
db.contato.drop()
db.dropDatabase()
Spring Data MongoDB
• Suporte à persistência dados no MongoDB via Spring
• Basta adicionar a dependência no Spring Boot
• spring-boot-starter-data-mongodb
• Oferece helper classes para integração com MongoDB
• MongoTemplate, MongoOperations
• Anotações para mapeamento de entidades
• @Id, @Document, @DBRef, @Indexed,
• @CompoundIndex, @GeoSpatialIndexed, @Language
• @TextIndexed, @Transient, @Value, @Field
spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345/test
spring.data.mongodb.host=mongoserver
spring.data.mongodb.port=27017
Spring Data MongoDB
• Definição de repositório abstrato MongoRepository
public interface MongoRepository<T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
@Override
<S extends T> List<S> save(Iterable<S> entites);
@Override
List<T> findAll();
@Override
List<T> findAll(Sort sort);
<S extends T> S insert(S entity);
<S extends T> List<S> insert(Iterable<S> entities);
@Override
<S extends T> List<S> findAll(Example<S> example);
@Override
<S extends T> List<S> findAll(Example<S> example, Sort sort);
}
Spring Data MongoDB
@Document
public class Person {
@Id
private String id;
@Indexed
private Integer ssn;
private String firstName;
@Indexed
private String lastName;
// getters and setters
}
public interface PersonRepository extends MongoRepository<Person, String> {
List<Person> findByLastname(String lastname);
Page<Person> findByFirstname(String firstname, Pageable pageable);
Person findByShippingAddresses(Address address);
Stream<Person> findAllBy();
}
@Service
public class PersonService {
@Autowired PersonRepository repository;
public void doSomething() {
Page<Person> persons = repository.findAll(
new PageRequest(1, 20));
// do something
}
}
Spring Data MongoDB
Keyword Sample Logical result
After findByBirthdateAfter(Date date) {"birthdate" : {"$gt" : date}}
GreaterThan findByAgeGreaterThan(int age) {"age" : {"$gt" : age}}
GreaterThanEqual findByAgeGreaterThanEqual(int age) {"age" : {"$gte" : age}}
Before findByBirthdateBefore(Date date) {"birthdate" : {"$lt" : date}}
LessThan findByAgeLessThan(int age) {"age" : {"$lt" : age}}
LessThanEqual findByAgeLessThanEqual(int age) {"age" : {"$lte" : age}}
Between findByAgeBetween(int from, int to) {"age" : {"$gt" : from, "$lt" :
In findByAgeIn(Collection ages) {"age" : {"$in" : [ages… ]}}
NotIn findByAgeNotIn(Collection ages) {"age" : {"$nin" : [ages… ]}}
IsNotNull, findByFirstnameNotNull() {"firstname" : {"$ne" : null}}
IsNull, Null findByFirstnameNull() {"firstname" : null}
Spring Data MongoDB
• Suporte à JSON based @Query’s
public interface PersonRepository extends MongoRepository<Person, String>
@Query("{ 'firstname' : ?0 }")
List<Person> findByThePersonsFirstname(String firstname);
@Query(value="{ 'firstname': ?0 }", fields="{ 'firstname' : 1, 'lastname' : 1}")
List<Person> findByThePersonsFirstname(String firstname);
@Query("{ 'lastname': ?#{[0]} }")
List<Person> findByQueryWithExpression(String param0);
@Query("{'id': ?#{ [0] ? {$exists :true} : [1] }}")
List<Person> findByQueryWithExpressionAndNestedObject(boolean param0, String param1);
}
Spring Data MongoDB
• Exemplo utilizando MongoTemplate object
public class DomainRepositoryImpl implements DomainRepositoryCustom {
@Autowired
MongoTemplate mongoTemplate;
@Override
public int updateDomain(String domain, boolean displayAds) {
Query query = new Query(Criteria.where("domain").is(domain));
Update update = new Update();
update.set("displayAds", displayAds);
WriteResult result = mongoTemplate.updateFirst(query, update, Domain.class);
if(result!=null)
return result.getN();
else
return 0;
}
}
Laboratório 7 (boot-lab07)
• Persistindo NoSQL com Spring Data MongoDB
Spring Data REST
• Publica Spring Data Repo como RESTful API’s
• Expõe operações CRUD, consultas dinâmicas, paginação,
relacionamentos,…
• Incrementa o suporte HATEOAS
• HAL, ALPS, JSON Schema, URI templates, etc
• Permite
• Suporta
• JPA, MongoDB, GemFire, Neo4j, Solr, Cassandra
• Demais estão por vir
Spring Data REST
Spring Data REST
$ curl “http://localhost:8080/persons/1”
Spring Data REST
@CrossOrigin(origins = "http://domain2.com",
methods = { RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE },
maxAge = 3600)
@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {
@RestResource(path = "names")
List<Person> findByName(String name);
@RestResource(exported = false)
Person findByEmail(String email);
@Override
@RestResource(exported = false)
void delete(Person entity);
}
• Exemplo de customização dos REST endpoints
HAL
"Convenção para definição de REST hypermedia"
HAL Browser
• Utilitário para navegar nos REST endpoints gerados
Laboratório 8 (boot-lab08)
• Expondo os repositórios com Spring Data REST
Spring Security
• Solução de segurança para as aplicações Spring e/ou
Java EE-based
• Implementa os procedimentos autenticação e autorização
• Suporta autenticação em diferentes tecnologias
• HTTP BASIC, Digest, X.509, LDAP, Form-based, OpenID
• CAS, HttpInvoker, JAAS, Kerberos…
• Ótimo suporte aos protocolos OAuth2 e JWT
• Configuração facilitada por meio de anotações
• Oferece suporte à diferentes funcionalidades
• Remember-me, Run-as, CSRF, CORS, Crypto, ACL
Spring Security
• Basta adicionar a seguinte dependência no projeto
• Por padrão será habilitado a segurança HTTP BASIC
• Para acesso deve ser utilizando usuário user e a senha
gerada dinamicamente
• Caso queira customizar o usuário e senha, pode ser
definido via properties
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Using default security password: 12aa6b86-08a7-4894-b899-3b2ebb1de248
security.user.name=root
security.user.password=t0ps3cr3t
Spring Security
• É possível implementar uma tela de login customizada
• src/main/resources/templates/login.html
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().formLogin().loginPage("/login").permitAll()
.and().logout().permitAll();
}
}
<form th:action="@{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
Spring Security
• Autenticação pode ser configurada globalmente (In Memory)
• Ou pode ser configurada via JDBC datasource
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("barry").password("t0ps3cr3t").roles("USER");
}
}
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired DataSource dataSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.withDefaultSchema()
.withUser("barry").password("t0ps3cr3t").roles("USER");
}
}
Spring Security
• Autorização pode ser configurada globalmente
• Ou pode ser customizada via anotações @Secured,
@PreAuthorize
@Configuration
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/foo/**")
.authorizeRequests()
.antMatchers("/foo/bar").hasRole("BAR")
.antMatchers("/foo/spam").hasRole("SPAM")
.anyRequest().isAuthenticated();
}
}
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class Application {...}
Spring Security
• Exemplos de uso das anotações @Secured, @PreAuthorize
public interface BankService {
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account readAccount(Long id);
@Secured("ROLE_TELLER")
public Account post(Account account, double amount);
@PreAuthorize("isAnonymous()")
public Account readAccount(Long id);
@PreAuthorize("hasAuthority('ROLE_TELLER')")
public Account post(Account account, double amount);
@PreAuthorize("hasRole('ADMIN') AND hasRole('ROLE_TELLER')")
public void deleteAccount(Long id);
}
Laboratório 9 (boot-lab09)
• Habilitando segurança com Spring Boot
Spring Batch
• Lightweight Batch framework para desenvolvimento de
processos robustos com grande quantidade de dados
• Não é um scheduler, mas pode ser integrado
• Quartz, Spring Scheduler, Tivoli, CRON, Control-M
• Oferece diversas funcionalidades
• Logging/tracing, gerenciamento de transação, estatísticas, job
restart, skip, particionamento, gestão de concorrência,
gerenciamento de recursos (memória, cpu)
• Forte integração com demais projetos Spring
• Utilizado geralmente em use cases particulares
• ETL, exportação/importação de dados, cálculos,…
Spring Batch
• Basta adicionar a seguinte dependência no projeto
• Para habilitar processamento batch na aplicação Spring
Boot deve-ser utilizar @EnableBatchProcessing
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
@SpringBootApplication
@EnableBatchProcessing
public class SpringBatchApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBatchApplication.class, args);
}
}
Spring Batch
• Chunk vs. Tasklet
• Implementam step dentro do job
• Chunk
• Encapsula padrão ETL
• Single Reader, Processor e Writer
• Executado por pedaços de dados (chunk)
• Chunk output é escrito unitariamente
• Tasklet
• Promove a execução de um único e simples processo
• Executado até o fim produzindo um código de retorno
Spring Batch
Chunk Tasklet
Spring Batch
• ItemReader
• ItemWriter
• ItemProcessor
public interface ItemReader<T> {
T read() throws Exception, UnexpectedInputException, ParseException;
}
public interface ItemWriter<T> {
void write(List<? extends T> items) throws Exception;
}
public interface ItemProcessor<I, O> {
O process(I item) throws Exception;
}
Spring Batch
• Exemplo de configuração do job na aplicação
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired JobBuilderFactory jobBuilderFactory;
@Autowired StepBuilderFactory stepBuilderFactory;
@Bean
public Job job() {
return jobBuilderFactory.get("job")
.incrementer(new RunIdIncrementer())
.flow(step1()).end().build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1").chunk(1)
.reader(new Reader())
.processor(new Processor())
.writer(new Writer()).build();
}
}
Spring Batch
• Exemplo de execução job na aplicação
@RestController
public class JobLauncherController {
@Autowired JobLauncher jobLauncher;
@Autowired Job job;
@RequestMapping("/launchjob")
public String handle() throws Exception {
Logger logger = LoggerFactory.getLogger(this.getClass());
try {
JobParameters jobParameters = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(job, jobParameters);
} catch (Exception e) {
logger.info(e.getMessage());
}
return "Done";
}
}
Spring Cache
• Oferece uma abstração para implementação de cache de
dados nas aplicações Spring
• Suporta diferente cache providers
• Generic, JCache, EhCache, Hazelcast, Infinitspan, Couchbase,
Redis, Caffeine, Guava, Simple
• Possui integração com Spring Data e JPA
• Ativação simples e fácil nas aplicações Spring Boot
• Basta adicionar a dependência spring-boot-starter-cache
• Ativar o sistema de cache com a anotação @EnableCaching
• Utilizar os objetos CacheManager e Cache
• Utilizar a anotação @Cachable
Spring Cache
• Exemplo de implementação de cache na aplicação
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Component
public class SimpleBookRepository implements BookRepository {
@Override
@Cacheable("books")
public Book getByIsbn(String isbn) {
simulateSlowService();
return new Book(isbn, "Some book");
}
}
Spring Messaging
• Processamento mensagens assíncronas na aplicação Spring Boot
• Suporta diferentes tipos de protocolos mensagens
• JMS, AMQP, STOMP
• Suporte também diferentes providers de mensagens
• ActiveMQ, Artemis, RabbitMQ, Apache Kafka, …
• Oferece anotações e propriedades customizadas para trabalhar
com provedores de mensagens
• @JmsListener, @RabbitListener, @KafkaListener
• Basta adicionar a dependência desejada
• spring-boot-starter-activemq
• spring-boot-starter-amqp
• spring-boot-starter-kafka
Spring Messaging
@SpringBootApplication
@EnableRabbit
public class MessagingApplication {
@Bean
public Queue fooQueue() {
return new Queue("foo");
}
}
@Service
public class CustomService {
@RabbitListener(queues = "foo")
public void process(@Payload String foo) {
System.out.println(new Date() + ": " + foo);
}
}
public class Sender {
@Autowired RabbitTemplate rabbitTemplate;
public void send() {
this.rabbitTemplate.convertAndSend("foo", "hello");
}
}
• Exemplo de consumo e envio de mensagens RabbitMQ
Spring Integration
• Implementação de design patterns de integração (EIP)
• Endpoint, Channel, Aggregator, Filter, Transformer, Bus,…
• http://www.enterpriseintegrationpatterns.com/
• Oferece integração com diversos protocolos e sistemas
• FTP, sFTP, Twitter, Web Services (SOAP/REST), MQTT
• Feed, JMS, AMQP, Email, TCP/UDP, XMPP, WebSocket,…
• Expões objetos via JMX para monitoramento
• Para configurar, basta adicionar a dependência
• spring-boot-starter-integration
• Oferece anotações para facilitar a implementação
• @MessagingGateway, @Gateway, @ServiceActivator,
@MessageEndpoint, @InboundChannelAdapter,
@OutboundChannelAdapter
Spring Integration
@SpringBootApplication
public class Application {
@Bean
@InboundChannelAdapter(value = "feedChannel",
poller = @Poller(maxMessagesPerPoll = "100", fixedRate = "10000"))
public MessageSource<SyndEntry> feedAdapter() throws MalformedURLException {
return new FeedEntryMessageSource(
new URL("http://feeds.abcnews.com/abcnews/topstories"), "feedAdapter");
}
@MessageEndpoint
public static class Endpoint {
@ServiceActivator(inputChannel = "feedChannel")
public void log(Message<SyndEntry> message) {
SyndEntry payload = message.getPayload();
logger.info(payload.getPublishedDate() + " - " + payload.getTitle());
}
}
@Bean
public MessageChannel feedChannel() {
return new QueueChannel(500);
}
}
• Exemplo de consumo de dados via feed RSS
Spring WebSockets
• Fornece suporte ao protocolo WebSockets aos web
containers auto-contidos
• Tomcat, Jetty, Undertow
• Suportado pelos protocolos STOMP e SockJS
• http://stomp.github.io/stomp-specification-1.2.html
• https://github.com/sockjs/sockjs-protocol
• Integrado aos controllers Spring MVC
• Para configurar na aplicação
• Adicionar a configuração spring-boot-starter-websocket
• Habilitar @EnableWebSocketMessageBroker
Spring WebSockets
• Exemplo de configuração endpoint via WebSocket
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").withSockJS();
}
}
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + message.getName() + "!");
}
}
Spring WebSockets
• Exemplo de cliente WebSocket em Javascript
function connect() {
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendName() {
stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}
Laboratório 10 (boot-lab10)
• Explorando recursos adicionais no Spring Boot
Conclusões
• Spring Boot fornece diversos utilitários e facilitadores
para implementação com Microservices
• Spring Data e Data REST são projetos que aceleram a
implementação e exposição na camada de persistência
como serviços REST
• Spring Security tem um ótima infra-estrutura para lidar
com requisitos de segurança em aplicações Web
• Existem diversos outros projetos que podem ser
incorporados no boot da aplicação Spring, como Batch,
Cache, Messaging, Integration, WebSockets, etc
• Enjoy it ;)
Revisão
Nessa unidade você teve a oportunidade de compreender
como:
• Implementar a primeira aplicação utilizando Spring Boot
• Compreender as funcionalidades adicionais do Spring Boot
• Compreender como implementar serviços REST utilizando
Spring MVC
• Implementar persistência de dados utilizando Spring Data
• Expor os repositórios como serviços utilizando Spring Data
REST
• Implementar segurança utilizando Spring Security
• Explorar os demais projetos do ecossistema Spring
Referências
• https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
• https://github.com/eugenp/tutorials/tree/master/spring-mvc-java
• http://www.restapitutorial.com/httpstatuscodes.html
• https://spring.io/guides/tutorials/bookmarks/
• http://docs.spring.io/spring-hateoas/docs/current/reference/html/
• http://docs.spring.io/spring-data/jpa/docs/current/reference/html/
• https://docs.spring.io/spring-data/rest/docs/current/reference/html/
• https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/
• https://spring.io/guides/gs/securing-web/
• https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-messaging.html
• https://spring.io/guides/gs/messaging-rabbitmq/
• http://docs.spring.io/spring-integration/reference/html/index.html
• https://spring.io/guides/gs/integration/
• http://docs.spring.io/spring-batch/reference/html/index.html
• https://spring.io/guides/gs/batch-processing/
• https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
• https://spring.io/guides/gs/caching/
• https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
• https://spring.io/guides/gs/messaging-stomp-websocket/

Contenu connexe

Tendances

AWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp VaultAWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp VaultGrzegorz Adamowicz
 
Introdução a testes unitários com jUnit
Introdução a testes unitários com jUnitIntrodução a testes unitários com jUnit
Introdução a testes unitários com jUnitLeonardo Soares
 
Pengenalan Git
Pengenalan GitPengenalan Git
Pengenalan Gitfajran
 
Treinamento de SQL Básico
Treinamento de SQL BásicoTreinamento de SQL Básico
Treinamento de SQL BásicoIgor Alves
 
Julien Maitrehenry - Docker, ça mange quoi au printemps
Julien Maitrehenry - Docker, ça mange quoi au printempsJulien Maitrehenry - Docker, ça mange quoi au printemps
Julien Maitrehenry - Docker, ça mange quoi au printempsWeb à Québec
 
Docker Security Overview
Docker Security OverviewDocker Security Overview
Docker Security OverviewSreenivas Makam
 
Boas práticas técnica para um código limpo (Clean Code)
Boas práticas técnica para um código limpo (Clean Code)Boas práticas técnica para um código limpo (Clean Code)
Boas práticas técnica para um código limpo (Clean Code)Rodrigo Kono
 
Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...
Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...
Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...Felipe Blini
 
Don't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using MocksDon't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using MocksVictor Rentea
 
Curso ITIL 4 Foundation - Singulares IT Training - In Company.pdf
Curso ITIL 4 Foundation - Singulares IT Training - In Company.pdfCurso ITIL 4 Foundation - Singulares IT Training - In Company.pdf
Curso ITIL 4 Foundation - Singulares IT Training - In Company.pdfJonathanRuver
 
Docker Container Security
Docker Container SecurityDocker Container Security
Docker Container SecuritySuraj Khetani
 
Kubernetes in Docker
Kubernetes in DockerKubernetes in Docker
Kubernetes in DockerDocker, Inc.
 

Tendances (20)

Github in Action
Github in ActionGithub in Action
Github in Action
 
AWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp VaultAWS DevOps - Terraform, Docker, HashiCorp Vault
AWS DevOps - Terraform, Docker, HashiCorp Vault
 
Introdução a testes unitários com jUnit
Introdução a testes unitários com jUnitIntrodução a testes unitários com jUnit
Introdução a testes unitários com jUnit
 
Pengenalan Git
Pengenalan GitPengenalan Git
Pengenalan Git
 
clean code
clean codeclean code
clean code
 
Treinamento de SQL Básico
Treinamento de SQL BásicoTreinamento de SQL Básico
Treinamento de SQL Básico
 
Julien Maitrehenry - Docker, ça mange quoi au printemps
Julien Maitrehenry - Docker, ça mange quoi au printempsJulien Maitrehenry - Docker, ça mange quoi au printemps
Julien Maitrehenry - Docker, ça mange quoi au printemps
 
Spring boot
Spring bootSpring boot
Spring boot
 
Docker Security Overview
Docker Security OverviewDocker Security Overview
Docker Security Overview
 
Integração Contínua
Integração ContínuaIntegração Contínua
Integração Contínua
 
JAVA - Herança
JAVA - HerançaJAVA - Herança
JAVA - Herança
 
Boas práticas técnica para um código limpo (Clean Code)
Boas práticas técnica para um código limpo (Clean Code)Boas práticas técnica para um código limpo (Clean Code)
Boas práticas técnica para um código limpo (Clean Code)
 
Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...
Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...
Monitoramento de serviços com Zabbix + Grafana + Python - Marcelo Santoto - D...
 
Curso de Node JS Básico
Curso de Node JS BásicoCurso de Node JS Básico
Curso de Node JS Básico
 
Tutorial struts
Tutorial strutsTutorial struts
Tutorial struts
 
Don't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using MocksDon't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using Mocks
 
Curso ITIL 4 Foundation - Singulares IT Training - In Company.pdf
Curso ITIL 4 Foundation - Singulares IT Training - In Company.pdfCurso ITIL 4 Foundation - Singulares IT Training - In Company.pdf
Curso ITIL 4 Foundation - Singulares IT Training - In Company.pdf
 
CSS
CSSCSS
CSS
 
Docker Container Security
Docker Container SecurityDocker Container Security
Docker Container Security
 
Kubernetes in Docker
Kubernetes in DockerKubernetes in Docker
Kubernetes in Docker
 

Similaire à Workshop Microservices - Construindo APIs RESTful com Spring Boot

CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeRafael Benevides
 
PDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NETPDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NETslides_teltools
 
TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?Rafael Benevides
 
Ecosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javEcosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javJulio Viegas
 
Testes em aplicações JEE: Montando sua infra de testes automatizados
Testes em aplicações JEE: Montando sua infra de testes automatizadosTestes em aplicações JEE: Montando sua infra de testes automatizados
Testes em aplicações JEE: Montando sua infra de testes automatizadosDiego Santos
 
De a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIDe a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIElias Nogueira
 
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EEJavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EERodrigo Cândido da Silva
 
Criando uma arquitetura para seus testes de API com RestAssured
Criando uma arquitetura para seus testes de API com RestAssuredCriando uma arquitetura para seus testes de API com RestAssured
Criando uma arquitetura para seus testes de API com RestAssuredElias Nogueira
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Rafael Benevides
 
Path to the future #2 - Internet das coisas com AWS IoT
Path to the future #2 - Internet das coisas com AWS IoTPath to the future #2 - Internet das coisas com AWS IoT
Path to the future #2 - Internet das coisas com AWS IoTAmazon Web Services LATAM
 
Integrando o dev com o ops - Marcelo Castellani
Integrando o dev com o ops - Marcelo CastellaniIntegrando o dev com o ops - Marcelo Castellani
Integrando o dev com o ops - Marcelo CastellaniiMasters
 
Introdução à Internet das Coisas com AWS IoT
Introdução à Internet das Coisas com AWS IoTIntrodução à Internet das Coisas com AWS IoT
Introdução à Internet das Coisas com AWS IoTAlexandre Santos
 
Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Elton Minetto
 

Similaire à Workshop Microservices - Construindo APIs RESTful com Spring Boot (20)

CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpike
 
PDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NETPDC - Engenharia - Plataforma Microsoft .NET
PDC - Engenharia - Plataforma Microsoft .NET
 
TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?
 
Ecosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javEcosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_jav
 
Precisamos falar sobre Gradle
Precisamos falar sobre GradlePrecisamos falar sobre Gradle
Precisamos falar sobre Gradle
 
Framework web 01 - Aula UTFPR 2018
Framework web 01 - Aula UTFPR 2018Framework web 01 - Aula UTFPR 2018
Framework web 01 - Aula UTFPR 2018
 
Testes em aplicações JEE: Montando sua infra de testes automatizados
Testes em aplicações JEE: Montando sua infra de testes automatizadosTestes em aplicações JEE: Montando sua infra de testes automatizados
Testes em aplicações JEE: Montando sua infra de testes automatizados
 
De a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIDe a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de API
 
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EEJavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
 
Criando uma arquitetura para seus testes de API com RestAssured
Criando uma arquitetura para seus testes de API com RestAssuredCriando uma arquitetura para seus testes de API com RestAssured
Criando uma arquitetura para seus testes de API com RestAssured
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007
 
Path to the future #2 - Internet das coisas com AWS IoT
Path to the future #2 - Internet das coisas com AWS IoTPath to the future #2 - Internet das coisas com AWS IoT
Path to the future #2 - Internet das coisas com AWS IoT
 
De 0 a DevOps
De 0 a DevOpsDe 0 a DevOps
De 0 a DevOps
 
API Apontador
API ApontadorAPI Apontador
API Apontador
 
Integrando o dev com o ops - Marcelo Castellani
Integrando o dev com o ops - Marcelo CastellaniIntegrando o dev com o ops - Marcelo Castellani
Integrando o dev com o ops - Marcelo Castellani
 
Java Seminar
Java SeminarJava Seminar
Java Seminar
 
Java e Cloud Computing
Java e Cloud ComputingJava e Cloud Computing
Java e Cloud Computing
 
PHP no Google AppEngine
PHP no Google AppEnginePHP no Google AppEngine
PHP no Google AppEngine
 
Introdução à Internet das Coisas com AWS IoT
Introdução à Internet das Coisas com AWS IoTIntrodução à Internet das Coisas com AWS IoT
Introdução à Internet das Coisas com AWS IoT
 
Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2
 

Plus de Rodrigo Cândido da Silva

Protegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de ImplementaçãoProtegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de ImplementaçãoRodrigo Cândido da Silva
 
Protecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and StrategiesProtecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and StrategiesRodrigo Cândido da Silva
 
Workshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e KubernetesWorkshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e KubernetesRodrigo Cândido da Silva
 
TDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com JavaTDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com JavaRodrigo Cândido da Silva
 
GUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOpsGUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOpsRodrigo Cândido da Silva
 
GUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com JavaGUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com JavaRodrigo Cândido da Silva
 
JavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EEJavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EERodrigo Cândido da Silva
 
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data RESTJavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data RESTRodrigo Cândido da Silva
 
TDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring CloudTDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring CloudRodrigo Cândido da Silva
 
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...Rodrigo Cândido da Silva
 
QCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EEQCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EERodrigo Cândido da Silva
 
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2Rodrigo Cândido da Silva
 
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...Rodrigo Cândido da Silva
 
TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2Rodrigo Cândido da Silva
 
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EEConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EERodrigo Cândido da Silva
 

Plus de Rodrigo Cândido da Silva (20)

Java 9, 10 e ... 11
Java 9, 10 e ... 11Java 9, 10 e ... 11
Java 9, 10 e ... 11
 
Cloud Native Java EE
Cloud Native Java EECloud Native Java EE
Cloud Native Java EE
 
Protegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de ImplementaçãoProtegendo Microservices: Boas Práticas e Estratégias de Implementação
Protegendo Microservices: Boas Práticas e Estratégias de Implementação
 
Protecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and StrategiesProtecting Java Microservices: Best Practices and Strategies
Protecting Java Microservices: Best Practices and Strategies
 
As novidades da nova versão do Java 9
As novidades da nova versão do Java 9As novidades da nova versão do Java 9
As novidades da nova versão do Java 9
 
Workshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e KubernetesWorkshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
Workshop Microservices - Distribuindo os Microservices com Docker e Kubernetes
 
GUJavaSC - Protegendo Microservices em Java
GUJavaSC - Protegendo Microservices em JavaGUJavaSC - Protegendo Microservices em Java
GUJavaSC - Protegendo Microservices em Java
 
TDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com JavaTDC Floripa 2017 - Criando Microservices Reativos com Java
TDC Floripa 2017 - Criando Microservices Reativos com Java
 
GUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOpsGUJavaSC - Combinando Micro-serviços com Práticas DevOps
GUJavaSC - Combinando Micro-serviços com Práticas DevOps
 
GUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com JavaGUJavaSC - Criando Micro-serviços Reativos com Java
GUJavaSC - Criando Micro-serviços Reativos com Java
 
JavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EEJavaOne 2016 - Reactive Microservices with Java and Java EE
JavaOne 2016 - Reactive Microservices with Java and Java EE
 
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data RESTJavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
JavaOne LATAM 2016 - RESTful Services Simplificado com Spring Data REST
 
TDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring CloudTDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
TDC Floripa 2016 - Decolando seus micro-serviços na Spring Cloud
 
GUJavaSC - Combinando AngularJS com Java EE
GUJavaSC - Combinando AngularJS com Java EEGUJavaSC - Combinando AngularJS com Java EE
GUJavaSC - Combinando AngularJS com Java EE
 
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
QCon SP 2016 - Construindo Microservices Auto-curáveis com Spring Cloud e Net...
 
QCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EEQCon 2015 - Combinando AngularJS com Java EE
QCon 2015 - Combinando AngularJS com Java EE
 
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
JavaOne LATAM 2015 - Segurança em Recursos RESTful com OAuth2
 
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
JavaOne LATAM 2015 - Batch Processing: Processamento em Lotes no Mundo Corpor...
 
TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2TDC 2015 - Segurança em Recursos RESTful com OAuth2
TDC 2015 - Segurança em Recursos RESTful com OAuth2
 
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EEConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
ConFoo 2015 - Supporting Multi-tenancy Applications with Java EE
 

Workshop Microservices - Construindo APIs RESTful com Spring Boot

  • 1. Workshop Microservices Construindo APIs RESTful com Spring Boot
  • 2. Objetivos • Ao final desta unidade você irá: • Implementar a primeira aplicação utilizando Spring Boot • Compreender as funcionalidades adicionais do Spring Boot • Compreender como implementar serviços REST utilizando Spring MVC • Implementar persistência de dados utilizando Spring Data • Expor os repositórios como serviços utilizando Spring Data REST • Implementar segurança utilizando Spring Security • Explorar os demais projetos do ecossistema Spring
  • 3. Agenda • Spring Boot • Spring MVC • Spring REST • Spring Data • Spring Data REST • Spring Security • Demais projetos • Batch, Cache, Messaging, Integration, WebSockets, …
  • 5.
  • 6. Spring Boot • Micro-framework para criação aplicações standalone • Boot com embedded Java container • Indicado para criação de micro-serviços • Fornece várias funcionalidades por padrão • Utiliza o conceito de configuração por “defaults” • Ótima integração com toda plataforma Spring • Spring MVC, Spring Data, Spring Security, … • Suporta empacotamento JAR ou WAR
  • 7. Spring Boot • O que NÃO é: • Plugins para IDE • Você pode utilizar Spring Boot com qualquer IDE • Ferramenta para geração de código • Um novo container Java EE • Arquitetura “ready” para Microservices
  • 9. Spring Boot (configuração inicial) <project> <!-- Inherit defaults from Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <!-- Add typical dependencies for a web application --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <!-- Package as an executable jar --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
  • 10. Spring Boot • Como rodar a aplicação? • IDE (Spring Tool Suite) • Import… -> Existing Maven Projects • Relaunch / Run • Maven plugin • mvn spring-boot:run • export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M • Standalone “fat JAR” • java -jar target/myproject-0.0.1-SNAPSHOT.jar • java -Xdebug - Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -jar target/myproject-0.0.1-SNAPSHOT.jar
  • 11. Spring Boot (deployment) • Pode ser realizado via standalone “fat JAR”, ou por meio de um WAR web package • Suporta deployment em Java EE containers • Tomcat, Jetty, Wildfly, TomEE, Glassfish, Weblogic • Permite a configuração de “executable JARs” • Podem ser configurados como serviços UNIX / Linux / Windows • UNIX/Linux services via init.d ou systemd • Windows services via winsw • Compatível com diferentes PaaS Cloud providers • Cloud Foundry, Heroku, OpenShift, AWS, Boxfuse, Google App Engine
  • 12. Spring Boot (deployment) • Configuração para deployment via WAR em um container @SpringBootApplication public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } } <project> <!-- ... --> <packaging>war</packaging> <!-- ... --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <!-- ... --> </dependencies> </project>
  • 13. Spring Boot (deployment) • Configurando JAR executável no ambiente UNIX • Fedora / CentOS • sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp • service myapp start • Debian • update-rc.d myapp defaults <priority> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <executable>true</executable> </configuration> </plugin>
  • 14. Spring Boot (containers) Container Servlet Version Java Version Tomcat 8 3.1 Java 7+ Tomcat 7 3.0 Java 6+ Jetty 9.3 3.1 Java 8+ Jetty 9.2 3.1 Java 7+ Jetty 8 3.0 Java 6+ Undertow 1.3 3.1 Java 7+
  • 16. Laboratório 1 (boot-lab01) • Criando uma primeira aplicação com Spring Boot
  • 17. Spring Boot (starters) • spring-boot-starter-web • spring-boot-starter-data-jpa • spring-boot-starter-data-rest • spring-boot-starter-jdbc • spring-boot-starter-websocket • spring-boot-starter-cache • spring-boot-starter-batch • spring-boot-starter-hateoas • spring-boot-starter-test • spring-boot-starter-integration • spring-boot-starter-validation • spring-boot-starter-mobile…
  • 18. Spring Boot (auto-configuration) • AopAutoConfiguration • JpaRepositoriesAutoConfiguration • HibernateJpaAutoConfiguration • DataSourceAutoConfiguration • JmsTemplateAutoConfiguration • MongoAutoConfiguration • RedisAutoConfiguration • WebMvcAutoConfiguration • SecurityAutoConfiguration • …
  • 19. Spring Boot (configuration) • Permite que você externalize as configurações da aplicação em arquivos properties, YAML, variáveis de ambiente, argumentos de linha de comando • Oferece uma lista bastante extensa de possíveis configurações • https://docs.spring.io/spring-boot/docs/current/reference/html/common-application- properties.html • Propriedades podem ser injetadas utilizando @Value ou acessadas via Spring Environment • Pode ser configurado também via @ConfigurationProperties • Podem ser ativadas e alternadas utilizando profiles de aplicação • application-{profile}.properties • Suporta o uso de expressões e oferece recursos como • Valores randômicos: ${random.long} • Referências internas: ${anotherproperty.value} • Variáveis de ambiente: ${VARIABLE}
  • 20. Spring Boot (configuration) • YAML file • Properties file spring: application: name: cruncher datasource: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost/test server: port: 9000 my: servers: - dev.bar.com - foo.bar.com spring.application.name=cruncher spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost/test server.port=9000 my.servers[0]=dev.bar.com my.servers[1]=foo.bar.com
  • 21. Spring Boot (configuration) email=test@email.com thread-pool=12 @Component public class GlobalProperties { @Value("${thread-pool}") private int threadPool; @Value("${email}") private String email; @Autowired private Environment env; public String getEmail() { return env.getProperty("email"); } public int getThreadPool() { return env.getProperty("thread-pool"); } //getters and setters } • Exemplo utilizando @Value e Spring Environment application.properties
  • 22. Spring Boot (configuration) @ConfigurationProperties( locations = "classpath:mail.properties", prefix = "mail") public class MailProperties { public static class Smtp { private boolean auth; private boolean starttlsEnable; // ... getters and setters } @NotBlank private String host; private int port; private String from; private String username; private String password; @NotNull private Smtp smtp; // ... getters and setters } mail.host=localhost mail.port=25 mail.smtp.auth=false mail.smtp.starttls-enable=false mail.from=me@localhost mail.username= mail.password= • Exemplo utilizando @ConfigurationProperties mail.properties
  • 23. Spring Boot (profiles) • Fornece uma maneira de segmentar a configuração da aplicação por diferentes ambientes de execução • Qualquer @Component, @Configuration por ser anotado com @Profile • Para sinalizar um profile, basta utilizar: • Propriedade: spring.profiles.active=dev • CLI: --spring.profiles.active=dev • JVM: -Dspring.profiles.active=dev • Java: SpringApplication.setAdditionalProfiles(…) • Podem ser sobrescritos e/ou combinados utilizando uma regra de maior prioridade • spring.profiles.active=default,dev
  • 24. Spring Boot (profiles) @Configuration @Profile("production") public class ProductionConfiguration { // ... } server: port: 9000 --- spring: profiles: development server: port: 9001 --- spring: profiles: production server: port: 0 @Configuration @Profile(“!production") public class NonProductionConfiguration { // ... } • Exemplo de utilização @Profile application.yml
  • 25. Spring Boot (logging) • Implementação interna via Commons Logging • Por padrão utiliza Logback, mas suporta outros providers, como Java Util Logging e Log4J • Pode habilitar o level por execução • java -jar myapp.jar --debug • Formato padrão do log utilizado • Date and Time, Log Level, Process ID, Thread Name, Logger Name, Log Message 2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat]. [localhost].[/] : Initializing Spring embedded WebApplicationContext 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms 2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
  • 26. Spring Boot (logging) • Configuração customizada de níveis de log logging.level.root=WARN logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR application.properties @Component public class Service { private final Logger logger = LoggerFactory.getLogger(this.getClass()); public void doSomething(String param) { try { logger.debug("Trying to do something using param {}", param); // process something } catch (Exception ex) { logger.error("Error to do something", ex); } } // other methods }
  • 27. Spring Boot (actuator) • Ajuda gerenciar e monitorar as aplicações em produção • Acessível via HTTP, JMX ou remote shell • Fornece uma lista de endpoints para gerenciar Spring Boot app • Publica as propriedades e Spring Beans em formato JSON view <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>
  • 28. Spring Boot (actuator) • /info • Informação da aplicação • /health • Status da aplicação (UP/DOWN) • /beans • Lista de Spring Beans na aplicação • /env • Propriedades externas configuradas • /dump • Realiza um thread dump • /metrics • Métricas da aplicação corrente (número de requests, consumo memória, etc) • /mappings • Lista de todos os @RequestMapping’s da aplicação • /trace • Demonstra o trace dos últimos 100 requests • /autoconfig • Relatório de auto-configuração da aplicação • /shutdown • Realiza o shutdown da aplicação (não ativado por padrão)
  • 29. Spring Boot (actuator) • Customizando health indicator @Component public class MyHealthIndicator implements HealthIndicator { @Override public Health health() { int errorCode = check(); // perform some specific health check if (errorCode != 0) { return Health.down().withDetail( "Error Code", errorCode).build(); } return Health.up().build(); } }
  • 30. Spring Boot (dev tools) • Conjunto de ferramentas para facilitar o processo de desenvolvimento e deployment das apps • Principais funcionalidades • Property defaults • Automatic restart • Live reload • Global settings • Remote applications <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
  • 31. Laboratório 2 (boot-lab02) • Explorando os recursos do Spring Boot
  • 32. Spring Boot (testing) • Fornece diversos utilitários e implementações para implementação de testes unitários • Habilitado via spring-boot-starter-test • Módulos spring-boot-test (core), spring-boot-test- autoconfigure (auto-configuração) • Dependências • JUnit - Biblioteca de unit testing em Java • Spring Test - Utilitários para testes integração com Spring Boot • AssertJ - Biblioteca para fluent assertion • Hamcrest - Biblioteca para matcher objects (constraints / predicates) • Mockito - Mock objects framework • JSONassert - Biblioteca para JSON assertion • JsonPath - Biblioteca para XPath para JOSN
  • 33. Spring Boot (testing) • Habilitado utilizando a anotação @SpringBootTest e via JUnit SpringRunner • Simula um webEnvironment que pode configurado como: • MOCK, RANDON_PORT, DEFINED_PORT, NONE @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @Import(MyTestsConfiguration.class) public class MyTests { @Test public void exampleTest() { ... } }
  • 34. Spring Boot (testing) • Suporta a utilização de Mock objects via Mockito • Basta injetar objetos com uso da anotação @MockBean @RunWith(SpringRunner.class) @SpringBootTest public class MyTests { @MockBean private RemoteService remoteService; @Autowired private Reverser reverser; @Test public void exampleTest() { // RemoteService has been injected into the reverser bean given(this.remoteService.someCall()).willReturn("mock"); String reverse = reverser.reverseSomeCall(); assertThat(reverse).isEqualTo("kcom"); } }
  • 35. Spring Boot (testing) • Oferece uma boa alternativa para testar conteúdo JSON por meio da anotação @JsonTest • Utiliza por padrão Jackson como parser, mas pode ser configurado para suportar Gson @RunWith(SpringRunner.class) @JsonTest public class MyJsonTests { @Autowired private JacksonTester<VehicleDetails> json; @Test public void testSerialize() throws Exception { VehicleDetails details = new VehicleDetails("Honda", "Civic"); // Assert against a `.json` file in the same package as the test assertThat(this.json.write(details)).isEqualToJson("expected.json"); // Or use JSON path based assertions assertThat(this.json.write(details)).hasJsonPathStringValue("@.make"); assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make") .isEqualTo("Honda"); } }
  • 36. Laboratório 3 (boot-lab03) • Testando uma aplicação Spring Boot
  • 37. Spring MVC • Web MVC action framework suportado pelo Spring Boot • Utilizado para implementação de aplicações Web content e também para REST APIs
  • 38. Spring MVC • DispatcherServlet • Implementação do design pattern FrontController • Recebe todas as requisições e delega para os controllers respectivos • Utiliza ViewResolver para resolver qual a tela deverá ser retornada
  • 39. Spring MVC (controller) • @Controller é o componente principal do Spring MVC • Define os server endpoints da aplicação Web • Aplicações REST pode ser utilizado @RestController @Controller public class GreetingController { @RequestMapping("/greeting") public String greeting( @RequestParam(required=false) String name, Model model) { model.addAttribute("name", name); return "greeting"; } }
  • 40. Spring MVC (annotations) • @RequestMapping • Define os server endpoints à serem processados pela aplicação @Controller @RequestMapping("/appointments") public class AppointmentsController { @Autowired AppointmentBook appointmentBook; @RequestMapping(method = RequestMethod.GET) public Map<String, Appointment> get() { return appointmentBook.getAppointmentsForToday(); } @RequestMapping(method = RequestMethod.POST) public String add(@Valid AppointmentForm appointment, BindingResult result) { if (result.hasErrors()) { return "appointments/new"; } appointmentBook.addAppointment(appointment); return "redirect:/appointments"; } }
  • 41. Spring MVC (annotations) • RequestMapping possui variações para melhor suportar as operações HTTP • @GetMapping, @PostMapping, @PutMapping @DeleteMapping, @PatchMapping @Controller @RequestMapping("/appointments") public class AppointmentsController { @Autowired AppointmentBook appointmentBook; @GetMapping public Map<String, Appointment> get() { return appointmentBook.getAppointmentsForToday(); } @PostMapping public String add(@Valid AppointmentForm appointment, BindingResult result) { if (result.hasErrors()) { return "appointments/new"; } appointmentBook.addAppointment(appointment); return "redirect:/appointments"; } }
  • 42. Spring MVC (annotations) • @RequestParam • Recuperação de um parâmetro da requisição • @RequestBody • Define o acesso para o conteúdo do corpo da requisição (ex: JSON, XML, etc) • @ResponseBody • Define o retorno do conteúdo como corpo da resposta (ex; JSON, XML, etc) • @PathVariable • Recuperação de um atributo como parte do path da requisição • @ModelAttribute • Recuperação de um grupo de atributos submetidos na requisição • @SessionAttribute • Referência e/ou recuperação de um atributo da sessão (HttpSession) • @RequestAttribute • Referência e/ou recuperação de um atributo da requisição • @CookieValue • Recuperação de um cookie na requisição • @RequestHeader • Recuperação de um cabeçalho da requisição
  • 43. Spring MVC (annotations) @Controller public class PetController { @PostMapping(path = "/pets", consumes=“application/json”, produces="application/json") @ResponseBody public Pet addPet(@RequestBody Pet pet, Model model) {...} @GetMapping(path = "/pets/setup") public String setupForm(@RequestParam("petId") int petId, ModelMap model) {} @PostMapping(path = "/owners/{ownerId}/pets/{petId}/edit") public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {...} @GetMapping(path = "/display/cookie") public void displayCookie(@CookieValue("JSESSIONID") String cookie) {...} @GetMapping(path = "/display/header") public void displayHeader(@RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive") long keepAlive) {...} @GetMapping(path = "/user") public String handleUser(@SessionAttribute User user) {...} } • Exemplos de utilização das anotações
  • 44. Spring MVC (error handling) • Spring Boot oferece /error endpoint como página global de erros, para tratar erros de maneira geral • Oferece implementação de tratadores de execução customizados via @ExceptionHandler • Pode ser utilizado como método do @Controller ou por via @ControllerAdvice @Controller public class SimpleController { // @RequestMapping methods omitted ... @ExceptionHandler(IOException.class) @ResponseBody public ResponseEntity<String> handleIOException(IOException ex) { // prepare responseEntity return responseEntity; } }
  • 45. Spring MVC (error handling) • Páginas de erros podem ser customizadas de maneira estática ou utilizando templates src/ +- main/ +- java/ | + <source code> +- resources/ +- public/ +- error/ | +- 404.html +- <other public assets> src/ +- main/ +- java/ | + <source code> +- resources/ +- templates/ +- error/ | +- 5xx.ftl +- <other templates>
  • 46. Spring MVC (static content) • Por padrão Spring Boot irá buscar conteúdo estático nos seguintes diretórios • /static, /public, /resources ou /META-INF/resources • A partir do diretório /src/main/resources (Maven) • Não utilize o diretório /src/main/webapp • Funciona apenas para empacotamento WAR • Fornece LiveReload para browser refresh automático • Apenas quando DevTools está habilitado no Spring Boot • Suporta a utilização de WebJars • http://www.webjars.org/
  • 47. Spring MVC (view templates) • Suporta uma variedade de ferramentas de view templates para processamento conteúdo Web dinâmico • FreeMaker • Groovy • Thymeleaf • Mustache • JSP • Os templates serão buscados a partir do diretório template na aplicação Spring Boot • /src/main/resources/templates
  • 48. Spring MVC (CORS) • Pode ser customizado via configuração customizada @Configuration public class MyConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://domain2.com") .allowedMethods("PUT", "DELETE") .allowedHeaders("header1", "header2") .exposedHeaders("header1", "header2") .allowCredentials(false).maxAge(3600); } }; } }
  • 49. Spring MVC (CORS) • Fornece a anotação @CrossOrigin para ser utilizada diretamente nos controllers @Controller @RequestMapping("/account") public class AccountController { @CrossOrigin @RequestMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } } @CrossOrigin(origins = "http://domain2.com", maxAge = 3600) @Controller @RequestMapping("/account") public class AccountController {...}
  • 50. Spring MVC (testing) • Oferece uma customização especial para testes utilizando a anotação @WebMvcTest • Possui integração com frameworks de teste funcional (HtmlUnit, Selenium) @RunWith(SpringRunner.class) @WebMvcTest(UserVehicleController.class) public class MyControllerTests { @Autowired MockMvc mvc; @MockBean UserVehicleService userVehicleService; @Test public void testExample() throws Exception { given(this.userVehicleService.getVehicleDetails("sboot")) .willReturn(new VehicleDetails("Honda", “Civic")); this.mvc.perform(get("/sboot/vehicle") .accept(MediaType.TEXT_PLAIN)) .andExpect(status().isOk()) .andExpect(content().string("Honda Civic")); } }
  • 51. Laboratório 4 (boot-lab04) • Desenvolvimento Web com Spring MVC
  • 54. Arquitetura REST • ︎Protocolo cliente/servidor sem estado (HTTP) • ︎Operações bem definidas • GET • POST • PUT • DELETE, etc • ︎Sintaxe universal para identificação de recursos (URL) • ︎Transferência de informações em formato padrão (XML, HTML, JSON)
  • 57. Spring REST • @RestController • Define uma anotação específica para controllers REST @RestController @RequestMapping(value="/users") public class MyRestController { @RequestMapping(value="/{user}", method=RequestMethod.GET) public User getUser(@PathVariable Long user) { // ... } @RequestMapping(value="/{user}/customers", method=RequestMethod.GET) List<Customer> getUserCustomers(@PathVariable Long user) { // ... } @RequestMapping(value="/{user}", method=RequestMethod.DELETE) public User deleteUser(@PathVariable Long user) { // ... } }
  • 58. Spring REST • Fornece flexibilidade para configuração na negociação de conteúdo @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorPathExtension(false). favorParameter(true). parameterName("mediaType"). ignoreAcceptHeader(true). useJaf(false). defaultContentType(MediaType.APPLICATION_JSON). mediaType("xml", MediaType.APPLICATION_XML). mediaType("json", MediaType.APPLICATION_JSON); } } curl http://localhost:8080/spring-mvc-java/employee/10?mediaType=[json/xml] <employee> <contactNumber>999-999-9999</contactNumber> <id>10</id> <name>Test Employee</name> </employee> { "id": 10, "name": "Test Employee", "contactNumber": "999-999-9999" }
  • 59. Spring REST • Unit testing é implementado utilizando @WebMvcTest @RunWith(SpringRunner.class) @WebMvcTest(GreentingController.class) public class GreetingControllerTests { @Autowired private MockMvc mvc; @Test public void givenGreetURIWithQueryParameter() { this.mockMvc.perform(get("/greetWithQueryVariable") .param("name", "John Doe")).andDo(print()).andExpect(status().isOk()) .andExpect(content().contentType("application/json;charset=UTF-8")) .andExpect(jsonPath("$.message").value("Hello World John Doe!!!")); } @Test public void givenGreetURIWithPost() { this.mockMvc.perform(post("/greetWithPost")).andDo(print()) .andExpect(status().isOk()).andExpect(content() .contentType("application/json;charset=UTF-8")) .andExpect(jsonPath("$.message").value("Hello World!!!")); } }
  • 60. Spring REST • É possível utilizar especificação JAX-RS na implementação dos REST endpoints • Basta incluir a dependência spring-boot-starter-jersey • Implementado via Jersey 2.x • Para cada REST endpoint é necessário defini-los como um bean gerenciado pelo Spring • Configurado com a anotação @Component @Component public class JerseyConfig extends ResourceConfig { public JerseyConfig() { register(Endpoint.class); } } @Component @Path("/hello") public class Endpoint { @GET public String message() { return "Hello"; } }
  • 61. HATEOAS • Hypermedia As The Engine of Application State • Descrevem o estado atual da aplicação e como navegar para o próximo estado
  • 63. Spring HATEOAS • Adiciona suporte HATEOAS para REST endpoints • Basta incluir a dependência spring-boot-starter-hateoas • Definida pelos componentes Links e Resources Link link = new Link("http://localhost:8080/something"); assertThat(link.getHref(), is("http://localhost:8080/something")); assertThat(link.getRel(), is(Link.SELF)); class PersonResource extends ResourceSupport { String firstname; String lastname; } PersonResource resource = new PersonResource(); resource.firstname = "Dave"; resource.lastname = "Matthews"; resource.add(new Link("http://myhost/people")); { firstname : "Dave", lastname : "Matthews", links : [ { rel : "self", href : "http://myhost/people" } ] }
  • 64. Spring HATEOAS public class Greeting { String name; // getters and setters } public class GreetingResource extends Resource<Greeting> { public GreetingResource(Greeting greeting, Link... links) { super(greeting, links); } } public class GreetingResourceAssembler extends ResourceAssemblerSupport<Greeting, GreetingResource> { public GreetingResourceAssembler() { super(Greeting.class, GreetingResource.class); } @Override public GreetingResource toResource(Aluno aluno) { return new GreetingResource(aluno, linkTo(methodOn(GreetingController.class).get(greeting.getName())).withSelfRel()); } @Override protected GreetingResource instantiateResource(Greeting aluno) { return new GreetingResource(greeting); } }
  • 65. Spring HATEOAS @RestController public class GreetingController { GreetingResourceAssembler assembler = new GreetingResourceAssembler(); @RequestMapping("/greeting") public ResponseEntity<GreetingResource> greeting( @RequestParam(value = "name", required = false) String name) { Greeting greeting = new Greeting("Hello, " + name); return new ResponseEntity<>(assembler.toResource(greeting), HttpStatus.OK); } } { "content":"Hello, User!", "_links":{ "self":{ "href":"http://localhost:8080/greeting?name=User" } } } curl http://localhost:8080/greeting?name=User
  • 66. Swagger • Alternativa para documentação da REST API • Possui ótima integração com Spring Boot • SpringFox - https://springfox.github.io/springfox/ • Oferece uma ferramenta para navegação Web • Swagger UI - http://swagger.io/swagger-ui/ • Possui também uma ferramenta para modelagem da API • Swagger Editor - http://swagger.io/swagger-editor/
  • 67. Swagger (spring boot) • Basta adicionar as dependências Maven • springfox-swagger-ui e springfox-swagger2 • Habilitar suporte Swagger na aplicação via @EnableSwagger2 • Documentar os REST controllers utilizando anotações • @ApiOperation • Documentação de um REST endpoint • @ApiParam, @ApiImplicitParam • Documentação dos parâmetros do REST endpoint • @ApiResponse • Documentação da resposta do REST endpoint • @ApiModel, @ApiModelProperty • Documentação do modelo de dados de resposta do REST endpoint • @Authorization • Documentação do modelo de autorização do REST endpoint • @ResponseHeader • Documentação dos headers de resposta do REST endpoint
  • 68. Swagger (spring boot) @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } } <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency> • Exemplo de integração Swagger com Spring Boot
  • 69. Swagger (spring boot) @RestController public class GreetingController { @ApiOperation(value = "getGreeting", nickname = "getGreeting") @RequestMapping(method = RequestMethod.GET, path="/greeting", produces = "application/json") @ApiImplicitParams({ @ApiImplicitParam(name = "name", value = "User's name", required = false, dataType = "string", paramType = "query") }) @ApiResponses(value = { @ApiResponse(code = 200, message = "Success", response = Greeting.class), @ApiResponse(code = 401, message = "Unauthorized"), @ApiResponse(code = 403, message = "Forbidden"), @ApiResponse(code = 404, message = "Not Found"), @ApiResponse(code = 500, message = "Failure")}) public Greeting greeting(@RequestParam(value="name") String name) { return new Greeting(new AtomicLong().incrementAndGet(), String.format("Hello, %s!", name)); } } • Exemplo de documentação utilizando as anotações Swagger
  • 71. Laboratório 5 (boot-lab05) • Implementando RESTful com Spring Boot
  • 72. Spring Data • Abstração para implementação de repositórios de persistência de dados integrada ao Spring Boot • Suporta diferentes modelos de persistência • JDBC, JPA, MongoDB, LDAP, Redis, Gemfire, Cassandra • DynamoDB, Couchbase, Solr, Elasticsearch, Neo4j,… • Implementa ações de CRUD em repositórios abstratos • Fornece queries dinâmicas criadas a partir nomes de métodos dos repositórios • Oferece flexibilidade para customização de repositórios • Suporta configurações de auditoria
  • 75. Spring Data public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { <S extends T> S save(S entity); T findOne(ID primaryKey); Iterable<T> findAll(); Long count(); void delete(T entity); boolean exists(ID primaryKey); } • Definição dos repositórios abstratos public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); } interface Repository<T, ID> extends Serializable> {}
  • 76. Spring Data public interface UserRepository extends PagingAndSortingRepository<User, Long> { // other methods } • Utilização dos repositórios abstratos @Component public class SomeClient { @Autowired private UserRepository repository; public void doSomething() { PagingAndSortingRepository<User, Long> repository = // … get access to a bean Page<User> users = repository.findAll(new PageRequest(1, 20)); } }
  • 77. Spring Data interface UserRepositoryCustom { public void someCustomMethod(User user); } interface UserRepository extends CrudJpaRepository<User, Long>, UserRepositoryCustom { // Declare query methods here } • Implementação de repositórios “customizados" class UserRepositoryImpl implements UserRepositoryCustom { public void someCustomMethod(User user) { // Your custom implementation } }
  • 78. Spring Data • Mecanismo de geração de consultas dinâmicas • Definição por DSL • Via nome dos métodos • Suporta diferentes variações • ByProperty • ByPropertyAsc • ByPropertyDesc • ByProp1AndProp2 • ByProp1OrProp2 • ByPropertyContaining • …
  • 79. Spring Data (queries) • Definição das consultas dinâmicas public interface PersonRepository extends Repository<User, Long> { List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname); // Enables the distinct flag for the query List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname); List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname); // Enabling ignoring case for an individual property List<Person> findByLastnameIgnoreCase(String lastname); // Enabling ignoring case for all suitable properties List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname); // Enabling static ORDER BY for a query List<Person> findByLastnameOrderByFirstnameAsc(String lastname); List<Person> findByLastnameOrderByFirstnameDesc(String lastname); }
  • 80. Spring Data (queries) Logical keyword Keyword expressions AND And OR Or AFTER After, IsAfter BEFORE Before, IsBefore CONTAINING Containing, IsContaining, Contains BETWEEN Between, IsBetween ENDING_WITH EndingWith, IsEndingWith, EndsWith EXISTS Exists FALSE False, IsFalse GREATER_THAN GreaterThan, IsGreaterThan GREATER_THAN_EQUALS GreaterThanEqual, IsGreaterThanEqual IN In, IsIn IS Is, Equals, (or no keyword) IS_NOT_NULL NotNull, IsNotNull
  • 81. Spring Data (queries) Logical keyword Keyword expressions IS_NULL Null, IsNull LESS_THAN LessThan, IsLessThan LESS_THAN_EQUAL LessThanEqual, IsLessThanEqual LIKE Like, IsLike NEAR Near, IsNear NOT Not, IsNot NOT_IN NotIn, IsNotIn NOT_LIKE NotLike, IsNotLike REGEX Regex, MatchesRegex, Matches STARTING_WITH StartingWith, IsStartingWith, StartsWith TRUE True, IsTrue WITHIN Within, IsWithin
  • 82. Spring Data (queries) • Limitação nos resultados de consulta public interface PersonRepository extends Repository<User, Long> { User findFirstByOrderByLastnameAsc(); User findTopByOrderByAgeDesc(); Page<User> queryFirst10ByLastname(String lastname, Pageable pageable); Slice<User> findTop3ByLastname(String lastname, Pageable pageable); List<User> findFirst10ByLastname(String lastname, Sort sort); List<User> findTop10ByLastname(String lastname, Pageable pageable); }
  • 83. Spring Data JPA • Oferece suporte à JPA • Basta adicionar a dependência • spring-boot-starter-data-jpa • Habilitar por padrão Hibernate como JPA provider • Oferece integração QueryDSL • Suporte à paginação, execução dinâmica de consultas, integração com repositórios customizados, etc
  • 85. Spring Data JPA public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { List<T> findAll(); List<T> findAll(Sort sort); List<T> findAllById(Iterable<ID> ids); <S extends T> List<S> saveAll(Iterable<S> entities); void flush(); <S extends T> S saveAndFlush(S entity); void deleteInBatch(Iterable<T> entities); void deleteAllInBatch(); T getOne(ID id); } • Definição do repositório JPA abstrato
  • 86. Spring Data JPA @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name = "username") private String name; private String password; @OneToOne private Person person; // getters and setters } public interface UserRepository extends JpaRepository<User, Long> { User findByName(String name); List<User> findByNameContaining(String name); } • JPA Entity e repositório Spring Data JPA
  • 87. Spring Data JPA Keyword Sample JPQL snippet And findByLastnameAndFirstnam e … where x.lastname = ?1 and x.firstname = ?2 Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2 Is,Equals findByFirstname … where x.firstname = ?1 Between findByStartDateBetween … where x.startDate between ?1 and ?2 LessThan findByAgeLessThan … where x.age < ?1 LessThanEqual findByAgeLessThanEqual … where x.age <= ?1 GreaterThan findByAgeGreaterThan … where x.age > ?1 GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1 After findByStartDateAfter … where x.startDate > ?1
  • 88. Spring Data JPA @Entity @NamedQuery(name = "User.findByEmailAddress", query = "select u from User u where u.emailAddress = ?1") public class User { // Implementation } public interface UserRepository extends JpaRepository<User, Long> { List<User> findByLastname(String lastname); User findByEmailAddress(String emailAddress); } • Utilizando @NamedQuery's
  • 89. Spring Data JPA public interface UserRepository extends JpaRepository<User, Long> { // JP-QL sample @Query("select u from User u where u.emailAddress = ?1") User findByEmailAddress(String emailAddress); // JP-QL with named parameters @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname") User findByLastnameOrFirstname(@Param("lastname") String lastname, @Param("firstname") String firstname); // Native SQL query @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true) User findByEmailAddress(String emailAddress) // Native SQL query for paging @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1", countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1", nativeQuery = true) Page<User> findByLastname(String lastname, Pageable pageable); } • Utilizando @Query’s customizadas
  • 90. Spring Data JPA public interface UserRepository extends JpaRepository<User, Long> { // JP-QL sample with ordering @Query("select u from User u where u.lastname like ?1%") List<User> findByAndSort(String lastname, Sort sort); // Delete query sample @Modifying @Query("delete from User u where user.role.id = ?1") void deleteInBulkByRoleId(long roleId); // Update query sample @Modifying @Query("update User u set u.firstname = ?1 where u.lastname = ?2") int setFixedFirstnameFor(String firstname, String lastname); // Using query hints @QueryHints(value = { @QueryHint(name = "name", value = "value")}, forCounting = false) Page<User> findByLastname(String lastname, Pageable pageable); } • Utilizando @Query’s customizadas
  • 91. Spring Data JPA • Executando Stored Procedures /; DROP procedure IF EXISTS plus1inout /; CREATE procedure plus1inout (IN arg int, OUT res int) BEGIN ATOMIC set res = arg + 1; END /; @Entity @NamedStoredProcedureQuery(name = "User.plus1", procedureName = "plus1inout", parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class), @StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class) }) public class User {} public interface UserRepository extends JpaRepository<User, Long> { @Procedure("plus1inout") Integer explicitlyNamedPlus1inout(Integer arg); @Procedure(name = "User.plus1IO") Integer entityAnnotatedCustomNamedProcedurePlus1IO(@Param("arg") Integer arg); }
  • 92. Spring Data JPA (specification) public class CustomerSpecs { public static Specification<Customer> isLongTermCustomer() { return new Specification<Customer>() { public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder builder) { LocalDate date = new LocalDate().minusYears(2); return builder.lessThan(root.get(_Customer.createdAt), date); } }; } } public interface CustomerRepository extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {...} public interface Specification<T> { Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder); } List<Customer> customers = customerRepository.findAll(isLongTermCustomer());
  • 93. Spring Data JPA (query by example) public interface QueryByExampleExecutor<T> { <S extends T> S findOne(Example<S> example); <S extends T> Iterable<S> findAll(Example<S> example); // … more functionality omitted. } public class PersonService { @Autowired PersonRepository personRepository; public List<Person> findPeople(Person probe) { return personRepository.findAll(Example.of(probe)); } } public interface PersonRepository extends JpaRepository<Person, String> { … } Person person = new Person(); person.setFirstname("Dave"); ExampleMatcher matcher = ExampleMatcher.matching() .withIgnorePaths("lastname") .withIncludeNullValues() .withStringMatcherEnding(); Example<Person> example = Example.of(person, matcher);
  • 94. Spring Data JPA (transactional) public interface UserRepository extends JpaRepository<User, Long> { // Transaction support @Transactional(timeout = 10) public List<User> findAll(); } @Service class UserManagementImpl implements UserManagement { @Autowired UserRepository userRepository; @Autowired RoleRepository roleRepository; @Transactional public void addRoleToAllUsers(String roleName) { // Step 1 Role role = roleRepository.findByName(roleName); // Step 2 for (User user : userRepository.findAll()) { user.addRole(role); userRepository.save(user); } } • Suporte transacional
  • 95. Spring Data JPA (auditing) class Customer { @CreatedBy private User user; @CreatedDate private DateTime createdDate; // … further properties omitted } • Controle de auditoria class SpringSecurityAuditorAware implements AuditorAware<User> { public User getCurrentAuditor() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || !authentication.isAuthenticated()) { return null; } return ((MyUserDetails) authentication.getPrincipal()).getUser(); } } @Configuration @EnableJpaAuditing class Config { @Bean public AuditorAware<AuditableUser> auditorProvider() { return new AuditorAwareImpl(); } }
  • 96. Spring Data JPA (testing) @RunWith(SpringRunner.class) @DataJpaTest public class UserRepositoryTests { @Autowired TestEntityManager entityManager; @Autowired UserRepository repository; @Test public void findByUsernameShouldReturnUser() { this.entityManager.persist(new User("sboot", "123")); User user = this.repository.findByUsername("sboot"); assertThat(user.getUsername()).isEqualTo("sboot"); assertThat(user.getVin()).isEqualTo("123"); } } • Unit testing com @DataJpaTest e TestEntityManager
  • 97. Project Lombok • Oferece anotações para substituir “boilerplate code” nos beans da aplicação • Fornece geração automática à diversas implementações • Getters/setters, Constructors, Equals/hashcode • ToString, Builder’s, Immutable classes, Synchronized,… • Implementação por meio de anotações • @Getter, @Setter, @EqualsAndHashCode, @ToString • @NoArgsConstructor, @RequiredArgsConstructor • @AllArgsContructor, @Data, @Builder, @Log • @Synchronized, @Value, @NonNull, @Cleanup
  • 98. Project Lombok • Basta adicionar a dependência no projeto • Implementar os beans utilizando as anotações <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> </dependency> @Data @Builder @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode @ToString public class User implements Serializable { Long id; String name; String password; }
  • 99. Spring Boot (datasources) • Oferece suporte à diferentes RDBMS • MySQL, PostgreSQL, Oracle, SQLServer, H2, … • É necessário configurá-los via spring.datasource.* • Suporta diferentes tipos de definição para data sources • Hikari, Tomcat, C3P0, DBCP2, JNDI spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=dbuser spring.datasource.password=dbpass spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.hikari.maximum-pool-size=5 spring.datasource.hikari.connection-timeout=10
  • 100. Spring Boot (H2) • Embedded in-memory RDBMS • Rápido, opensource e suporta 100% JDBC API • Small footprint (cerca 1.5 MB de tamanho) • Pode ser instalado como server, e persistência em arquivo • Ideal para utilização em testes de integração • Oferece uma aplicação Web para administração • Para habilitá-lo, basta adicionar a dependência <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>runtime</scope> </dependency>
  • 101. Spring Boot (H2) • Para habilitar no Spring Boot, basta adicionar a dependência e habilitar interface Web, se desejado • spring.h2.console.enabled = true • http://boot/h2-console
  • 102. Laboratório 6 (boot-lab06) • Persistindo dados com Spring Data JPA
  • 103. MongoDB • NoSQL database orientado à documentos • Persistência de dados no formato JSON • Armazenamento em formato BSON (binary JSON) • Suporte à full indexação, auto sharding, map reduce, replicação e tolerância à falhas db.createCollection('contato') db.contato.insert({ name: 'Rodrigo', email: 'rodrigo@email.com', mensagem: 'Inserindo dados no MongoDB' }) db.contato.find() db.contato.update({name: 'Rodrigo'}, {$set: {email: 'rodrigo@new-email.com'}}) db.contato.remove({name: 'Rodrigo'}) db.contato.drop() db.dropDatabase()
  • 104. Spring Data MongoDB • Suporte à persistência dados no MongoDB via Spring • Basta adicionar a dependência no Spring Boot • spring-boot-starter-data-mongodb • Oferece helper classes para integração com MongoDB • MongoTemplate, MongoOperations • Anotações para mapeamento de entidades • @Id, @Document, @DBRef, @Indexed, • @CompoundIndex, @GeoSpatialIndexed, @Language • @TextIndexed, @Transient, @Value, @Field spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345/test spring.data.mongodb.host=mongoserver spring.data.mongodb.port=27017
  • 105. Spring Data MongoDB • Definição de repositório abstrato MongoRepository public interface MongoRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { @Override <S extends T> List<S> save(Iterable<S> entites); @Override List<T> findAll(); @Override List<T> findAll(Sort sort); <S extends T> S insert(S entity); <S extends T> List<S> insert(Iterable<S> entities); @Override <S extends T> List<S> findAll(Example<S> example); @Override <S extends T> List<S> findAll(Example<S> example, Sort sort); }
  • 106. Spring Data MongoDB @Document public class Person { @Id private String id; @Indexed private Integer ssn; private String firstName; @Indexed private String lastName; // getters and setters } public interface PersonRepository extends MongoRepository<Person, String> { List<Person> findByLastname(String lastname); Page<Person> findByFirstname(String firstname, Pageable pageable); Person findByShippingAddresses(Address address); Stream<Person> findAllBy(); } @Service public class PersonService { @Autowired PersonRepository repository; public void doSomething() { Page<Person> persons = repository.findAll( new PageRequest(1, 20)); // do something } }
  • 107. Spring Data MongoDB Keyword Sample Logical result After findByBirthdateAfter(Date date) {"birthdate" : {"$gt" : date}} GreaterThan findByAgeGreaterThan(int age) {"age" : {"$gt" : age}} GreaterThanEqual findByAgeGreaterThanEqual(int age) {"age" : {"$gte" : age}} Before findByBirthdateBefore(Date date) {"birthdate" : {"$lt" : date}} LessThan findByAgeLessThan(int age) {"age" : {"$lt" : age}} LessThanEqual findByAgeLessThanEqual(int age) {"age" : {"$lte" : age}} Between findByAgeBetween(int from, int to) {"age" : {"$gt" : from, "$lt" : In findByAgeIn(Collection ages) {"age" : {"$in" : [ages… ]}} NotIn findByAgeNotIn(Collection ages) {"age" : {"$nin" : [ages… ]}} IsNotNull, findByFirstnameNotNull() {"firstname" : {"$ne" : null}} IsNull, Null findByFirstnameNull() {"firstname" : null}
  • 108. Spring Data MongoDB • Suporte à JSON based @Query’s public interface PersonRepository extends MongoRepository<Person, String> @Query("{ 'firstname' : ?0 }") List<Person> findByThePersonsFirstname(String firstname); @Query(value="{ 'firstname': ?0 }", fields="{ 'firstname' : 1, 'lastname' : 1}") List<Person> findByThePersonsFirstname(String firstname); @Query("{ 'lastname': ?#{[0]} }") List<Person> findByQueryWithExpression(String param0); @Query("{'id': ?#{ [0] ? {$exists :true} : [1] }}") List<Person> findByQueryWithExpressionAndNestedObject(boolean param0, String param1); }
  • 109. Spring Data MongoDB • Exemplo utilizando MongoTemplate object public class DomainRepositoryImpl implements DomainRepositoryCustom { @Autowired MongoTemplate mongoTemplate; @Override public int updateDomain(String domain, boolean displayAds) { Query query = new Query(Criteria.where("domain").is(domain)); Update update = new Update(); update.set("displayAds", displayAds); WriteResult result = mongoTemplate.updateFirst(query, update, Domain.class); if(result!=null) return result.getN(); else return 0; } }
  • 110. Laboratório 7 (boot-lab07) • Persistindo NoSQL com Spring Data MongoDB
  • 111. Spring Data REST • Publica Spring Data Repo como RESTful API’s • Expõe operações CRUD, consultas dinâmicas, paginação, relacionamentos,… • Incrementa o suporte HATEOAS • HAL, ALPS, JSON Schema, URI templates, etc • Permite • Suporta • JPA, MongoDB, GemFire, Neo4j, Solr, Cassandra • Demais estão por vir
  • 113. Spring Data REST $ curl “http://localhost:8080/persons/1”
  • 114. Spring Data REST @CrossOrigin(origins = "http://domain2.com", methods = { RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE }, maxAge = 3600) @RepositoryRestResource(path = "people") interface PersonRepository extends CrudRepository<Person, Long> { @RestResource(path = "names") List<Person> findByName(String name); @RestResource(exported = false) Person findByEmail(String email); @Override @RestResource(exported = false) void delete(Person entity); } • Exemplo de customização dos REST endpoints
  • 115. HAL "Convenção para definição de REST hypermedia"
  • 116. HAL Browser • Utilitário para navegar nos REST endpoints gerados
  • 117. Laboratório 8 (boot-lab08) • Expondo os repositórios com Spring Data REST
  • 118. Spring Security • Solução de segurança para as aplicações Spring e/ou Java EE-based • Implementa os procedimentos autenticação e autorização • Suporta autenticação em diferentes tecnologias • HTTP BASIC, Digest, X.509, LDAP, Form-based, OpenID • CAS, HttpInvoker, JAAS, Kerberos… • Ótimo suporte aos protocolos OAuth2 e JWT • Configuração facilitada por meio de anotações • Oferece suporte à diferentes funcionalidades • Remember-me, Run-as, CSRF, CORS, Crypto, ACL
  • 119. Spring Security • Basta adicionar a seguinte dependência no projeto • Por padrão será habilitado a segurança HTTP BASIC • Para acesso deve ser utilizando usuário user e a senha gerada dinamicamente • Caso queira customizar o usuário e senha, pode ser definido via properties <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> Using default security password: 12aa6b86-08a7-4894-b899-3b2ebb1de248 security.user.name=root security.user.password=t0ps3cr3t
  • 120. Spring Security • É possível implementar uma tela de login customizada • src/main/resources/templates/login.html @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated() .and().formLogin().loginPage("/login").permitAll() .and().logout().permitAll(); } } <form th:action="@{/login}" method="post"> <div><label> User Name : <input type="text" name="username"/> </label></div> <div><label> Password: <input type="password" name="password"/> </label></div> <div><input type="submit" value="Sign In"/></div> </form>
  • 121. Spring Security • Autenticação pode ser configurada globalmente (In Memory) • Ou pode ser configurada via JDBC datasource @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("barry").password("t0ps3cr3t").roles("USER"); } } @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired DataSource dataSource; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource) .withDefaultSchema() .withUser("barry").password("t0ps3cr3t").roles("USER"); } }
  • 122. Spring Security • Autorização pode ser configurada globalmente • Ou pode ser customizada via anotações @Secured, @PreAuthorize @Configuration public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.antMatcher("/foo/**") .authorizeRequests() .antMatchers("/foo/bar").hasRole("BAR") .antMatchers("/foo/spam").hasRole("SPAM") .anyRequest().isAuthenticated(); } } @SpringBootApplication @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) public class Application {...}
  • 123. Spring Security • Exemplos de uso das anotações @Secured, @PreAuthorize public interface BankService { @Secured("IS_AUTHENTICATED_ANONYMOUSLY") public Account readAccount(Long id); @Secured("ROLE_TELLER") public Account post(Account account, double amount); @PreAuthorize("isAnonymous()") public Account readAccount(Long id); @PreAuthorize("hasAuthority('ROLE_TELLER')") public Account post(Account account, double amount); @PreAuthorize("hasRole('ADMIN') AND hasRole('ROLE_TELLER')") public void deleteAccount(Long id); }
  • 124. Laboratório 9 (boot-lab09) • Habilitando segurança com Spring Boot
  • 125. Spring Batch • Lightweight Batch framework para desenvolvimento de processos robustos com grande quantidade de dados • Não é um scheduler, mas pode ser integrado • Quartz, Spring Scheduler, Tivoli, CRON, Control-M • Oferece diversas funcionalidades • Logging/tracing, gerenciamento de transação, estatísticas, job restart, skip, particionamento, gestão de concorrência, gerenciamento de recursos (memória, cpu) • Forte integração com demais projetos Spring • Utilizado geralmente em use cases particulares • ETL, exportação/importação de dados, cálculos,…
  • 126. Spring Batch • Basta adicionar a seguinte dependência no projeto • Para habilitar processamento batch na aplicação Spring Boot deve-ser utilizar @EnableBatchProcessing <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency> @SpringBootApplication @EnableBatchProcessing public class SpringBatchApplication { public static void main(String[] args) { SpringApplication.run(SpringBatchApplication.class, args); } }
  • 127. Spring Batch • Chunk vs. Tasklet • Implementam step dentro do job • Chunk • Encapsula padrão ETL • Single Reader, Processor e Writer • Executado por pedaços de dados (chunk) • Chunk output é escrito unitariamente • Tasklet • Promove a execução de um único e simples processo • Executado até o fim produzindo um código de retorno
  • 129. Spring Batch • ItemReader • ItemWriter • ItemProcessor public interface ItemReader<T> { T read() throws Exception, UnexpectedInputException, ParseException; } public interface ItemWriter<T> { void write(List<? extends T> items) throws Exception; } public interface ItemProcessor<I, O> { O process(I item) throws Exception; }
  • 130. Spring Batch • Exemplo de configuração do job na aplicação @Configuration @EnableBatchProcessing public class BatchConfig { @Autowired JobBuilderFactory jobBuilderFactory; @Autowired StepBuilderFactory stepBuilderFactory; @Bean public Job job() { return jobBuilderFactory.get("job") .incrementer(new RunIdIncrementer()) .flow(step1()).end().build(); } @Bean public Step step1() { return stepBuilderFactory.get("step1").chunk(1) .reader(new Reader()) .processor(new Processor()) .writer(new Writer()).build(); } }
  • 131. Spring Batch • Exemplo de execução job na aplicação @RestController public class JobLauncherController { @Autowired JobLauncher jobLauncher; @Autowired Job job; @RequestMapping("/launchjob") public String handle() throws Exception { Logger logger = LoggerFactory.getLogger(this.getClass()); try { JobParameters jobParameters = new JobParametersBuilder() .addLong("time", System.currentTimeMillis()) .toJobParameters(); jobLauncher.run(job, jobParameters); } catch (Exception e) { logger.info(e.getMessage()); } return "Done"; } }
  • 132. Spring Cache • Oferece uma abstração para implementação de cache de dados nas aplicações Spring • Suporta diferente cache providers • Generic, JCache, EhCache, Hazelcast, Infinitspan, Couchbase, Redis, Caffeine, Guava, Simple • Possui integração com Spring Data e JPA • Ativação simples e fácil nas aplicações Spring Boot • Basta adicionar a dependência spring-boot-starter-cache • Ativar o sistema de cache com a anotação @EnableCaching • Utilizar os objetos CacheManager e Cache • Utilizar a anotação @Cachable
  • 133. Spring Cache • Exemplo de implementação de cache na aplicação @SpringBootApplication @EnableCaching public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @Component public class SimpleBookRepository implements BookRepository { @Override @Cacheable("books") public Book getByIsbn(String isbn) { simulateSlowService(); return new Book(isbn, "Some book"); } }
  • 134. Spring Messaging • Processamento mensagens assíncronas na aplicação Spring Boot • Suporta diferentes tipos de protocolos mensagens • JMS, AMQP, STOMP • Suporte também diferentes providers de mensagens • ActiveMQ, Artemis, RabbitMQ, Apache Kafka, … • Oferece anotações e propriedades customizadas para trabalhar com provedores de mensagens • @JmsListener, @RabbitListener, @KafkaListener • Basta adicionar a dependência desejada • spring-boot-starter-activemq • spring-boot-starter-amqp • spring-boot-starter-kafka
  • 135. Spring Messaging @SpringBootApplication @EnableRabbit public class MessagingApplication { @Bean public Queue fooQueue() { return new Queue("foo"); } } @Service public class CustomService { @RabbitListener(queues = "foo") public void process(@Payload String foo) { System.out.println(new Date() + ": " + foo); } } public class Sender { @Autowired RabbitTemplate rabbitTemplate; public void send() { this.rabbitTemplate.convertAndSend("foo", "hello"); } } • Exemplo de consumo e envio de mensagens RabbitMQ
  • 136. Spring Integration • Implementação de design patterns de integração (EIP) • Endpoint, Channel, Aggregator, Filter, Transformer, Bus,… • http://www.enterpriseintegrationpatterns.com/ • Oferece integração com diversos protocolos e sistemas • FTP, sFTP, Twitter, Web Services (SOAP/REST), MQTT • Feed, JMS, AMQP, Email, TCP/UDP, XMPP, WebSocket,… • Expões objetos via JMX para monitoramento • Para configurar, basta adicionar a dependência • spring-boot-starter-integration • Oferece anotações para facilitar a implementação • @MessagingGateway, @Gateway, @ServiceActivator, @MessageEndpoint, @InboundChannelAdapter, @OutboundChannelAdapter
  • 137. Spring Integration @SpringBootApplication public class Application { @Bean @InboundChannelAdapter(value = "feedChannel", poller = @Poller(maxMessagesPerPoll = "100", fixedRate = "10000")) public MessageSource<SyndEntry> feedAdapter() throws MalformedURLException { return new FeedEntryMessageSource( new URL("http://feeds.abcnews.com/abcnews/topstories"), "feedAdapter"); } @MessageEndpoint public static class Endpoint { @ServiceActivator(inputChannel = "feedChannel") public void log(Message<SyndEntry> message) { SyndEntry payload = message.getPayload(); logger.info(payload.getPublishedDate() + " - " + payload.getTitle()); } } @Bean public MessageChannel feedChannel() { return new QueueChannel(500); } } • Exemplo de consumo de dados via feed RSS
  • 138. Spring WebSockets • Fornece suporte ao protocolo WebSockets aos web containers auto-contidos • Tomcat, Jetty, Undertow • Suportado pelos protocolos STOMP e SockJS • http://stomp.github.io/stomp-specification-1.2.html • https://github.com/sockjs/sockjs-protocol • Integrado aos controllers Spring MVC • Para configurar na aplicação • Adicionar a configuração spring-boot-starter-websocket • Habilitar @EnableWebSocketMessageBroker
  • 139. Spring WebSockets • Exemplo de configuração endpoint via WebSocket @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/gs-guide-websocket").withSockJS(); } } @Controller public class GreetingController { @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(1000); // simulated delay return new Greeting("Hello, " + message.getName() + "!"); } }
  • 140. Spring WebSockets • Exemplo de cliente WebSocket em Javascript function connect() { var socket = new SockJS('/gs-guide-websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/greetings', function (greeting) { showGreeting(JSON.parse(greeting.body).content); }); }); } function disconnect() { if (stompClient != null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } function sendName() { stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()})); }
  • 141. Laboratório 10 (boot-lab10) • Explorando recursos adicionais no Spring Boot
  • 142. Conclusões • Spring Boot fornece diversos utilitários e facilitadores para implementação com Microservices • Spring Data e Data REST são projetos que aceleram a implementação e exposição na camada de persistência como serviços REST • Spring Security tem um ótima infra-estrutura para lidar com requisitos de segurança em aplicações Web • Existem diversos outros projetos que podem ser incorporados no boot da aplicação Spring, como Batch, Cache, Messaging, Integration, WebSockets, etc • Enjoy it ;)
  • 143. Revisão Nessa unidade você teve a oportunidade de compreender como: • Implementar a primeira aplicação utilizando Spring Boot • Compreender as funcionalidades adicionais do Spring Boot • Compreender como implementar serviços REST utilizando Spring MVC • Implementar persistência de dados utilizando Spring Data • Expor os repositórios como serviços utilizando Spring Data REST • Implementar segurança utilizando Spring Security • Explorar os demais projetos do ecossistema Spring
  • 144. Referências • https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/ • https://github.com/eugenp/tutorials/tree/master/spring-mvc-java • http://www.restapitutorial.com/httpstatuscodes.html • https://spring.io/guides/tutorials/bookmarks/ • http://docs.spring.io/spring-hateoas/docs/current/reference/html/ • http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ • https://docs.spring.io/spring-data/rest/docs/current/reference/html/ • https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/ • https://spring.io/guides/gs/securing-web/ • https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-messaging.html • https://spring.io/guides/gs/messaging-rabbitmq/ • http://docs.spring.io/spring-integration/reference/html/index.html • https://spring.io/guides/gs/integration/ • http://docs.spring.io/spring-batch/reference/html/index.html • https://spring.io/guides/gs/batch-processing/ • https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html • https://spring.io/guides/gs/caching/ • https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html • https://spring.io/guides/gs/messaging-stomp-websocket/