spring-boot
Spring Boot + Spring Data Elasticsearch
Recherche…
Introduction
Spring Data Elasticsearch est une implémentation Spring Data pour Elasticsearch qui permet l'intégration au moteur de recherche Elasticsearch .
Intégration Spring Boot et Spring Data Elasticsearch
Dans cet exemple, nous allons implémenter le projet spring-data-elasticsearch pour stocker POJO dans elasticsearch. Nous verrons un exemple de projet Maven qui fait les choses suivantes:
- Insérez un élément de
Greeting(id, username, message)
sur elasticsearch. - Obtenez tous les articles de voeux qui ont été insérés.
- Mettre à jour un élément de message d'accueil.
- Supprimer un élément de message.
- Obtenez un objet de salutation par identifiant.
- Obtenez tous les articles de vœux par nom d'utilisateur.
Intégration printanière des données d'amorçage et de données printanières
Dans cet exemple, nous allons voir une application de démarrage à ressort basée sur maven qui intègre spring-data-elasticsearch. Ici, nous allons faire les choses suivantes et voir les segments de code respectifs.
- Insérez un élément de
Greeting(id, username, message)
sur elasticsearch. - Obtenez tous les articles de elasticsearch
- Mettre à jour un élément spécifique.
- Supprimer un élément spécifique.
- Obtenez un article spécifique par identifiant.
- Obtenez un article spécifique par nom d'utilisateur.
Fichier de configuration du projet (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springdataes</groupId>
<artifactId>springdataes</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Nous utiliserons Spring Boot de la version 1.5.6.RELEASE
et Spring Data Elasticsearch de cette version respective. Pour ce projet, nous devons exécuter elasticsearch-2.4.5 pour tester nos apis.
Fichier de propriétés
Nous allons mettre le fichier de propriétés du projet (nommé applications.properties
) dans le dossier resources
qui contient:
elasticsearch.clustername = elasticsearch
elasticsearch.host = localhost
elasticsearch.port = 9300
Nous utiliserons le nom, l’hôte et le port du cluster par défaut. Par défaut, le port 9300
est utilisé comme port de transport et le port 9200
est appelé port http. Pour voir le nom du cluster par défaut, cliquez sur http: // localhost: 9200 / .
Classe principale (Application.java)
package org.springdataes;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String []args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication
est une combinaison des @Configuration
, @EnableAutoConfiguration
, @EnableWebMvc
et @ComponentScan
. La méthode main()
utilise la méthode SpringApplication.run()
Spring Boot pour lancer une application. Là, nous n'avons besoin d'aucune configuration xml, cette application est une pure application java spring.
Classe de configuration Elasticsearch (ElasticsearchConfig.java)
package org.springdataes.config;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import java.net.InetAddress;
@Configuration
@PropertySource(value = "classpath:applications.properties")
@EnableElasticsearchRepositories(basePackages = "org.springdataes.dao")
public class ElasticsearchConfig {
@Value("${elasticsearch.host}")
private String EsHost;
@Value("${elasticsearch.port}")
private int EsPort;
@Value("${elasticsearch.clustername}")
private String EsClusterName;
@Bean
public Client client() throws Exception {
Settings esSettings = Settings.settingsBuilder()
.put("cluster.name", EsClusterName)
.build();
return TransportClient.builder()
.settings(esSettings)
.build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(EsHost), EsPort));
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() throws Exception {
return new ElasticsearchTemplate(client());
}
}
ElasticsearchConfig
classe ElasticsearchConfig
configure elasticsearch pour ce projet et établit une connexion avec elasticsearch. Ici, @PropertySource
est utilisé pour lire le fichier application.properties
où sont @PropertySource
le nom du cluster, l'hôte elasticsearch et le port. @EnableElasticsearchRepositories
permet d'activer les référentiels Elasticsearch qui analyseront par défaut les packages de la classe de configuration annotée pour les référentiels Spring Data. @Value
est utilisé ici pour lire les propriétés du fichier application.properties
.
La méthode Client()
crée une connexion de transport avec elasticsearch. La configuration ci-dessus configure un serveur Elasticsearch intégré qui est utilisé par ElasticsearchTemplate
. Le bean ElasticsearchTemplate
utilise le Elasticsearch Client
et fournit une couche personnalisée pour la manipulation des données dans Elasticsearch.
Classe de modèle (Greeting.java)
package org.springdataes.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import java.io.Serializable;
@Document(indexName = "index", type = "greetings")
public class Greeting implements Serializable{
@Id
private String id;
private String username;
private String message;
public Greeting() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Ici, nous avons annoté nos objets de données d' Greeting
avec une annotation @Document que nous pouvons également utiliser pour déterminer les paramètres d'index tels que le nom, le nombre de fragments ou le nombre de répliques. L'un des attributs de la classe doit être un id
, soit en l'annotant avec @Id
soit en utilisant l'un des id
ou documentId
trouvés automatiquement. Ici, la valeur du champ id
sera automatiquement générée si nous ne définissons aucune valeur du champ id
.
Classe de référentiel Elasticsearch (GreetingRepository.class)
package org.springdataes.dao;
import org.springdataes.model.Greeting;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface GreetingRepository extends ElasticsearchRepository<Greeting, String> {
List<Greeting> findByUsername(String username);
}
Ici, nous avons étendu ElasticsearchRepository
qui nous fournit de nombreux apis que nous n'avons pas besoin de définir en externe. Ceci est la classe de référentiel de base pour les classes de domaine basées sur elasticsearch
. Comme il étend les classes de référentiels basées sur Spring
, nous avons l'avantage d'éviter le code passe-partout requis pour implémenter les couches d'accès aux données pour différents magasins de persistance.
Ici, nous avons déclaré une méthode findByUsername(String username)
qui convertira en une requête de correspondance qui correspond au nom d'utilisateur avec le champ username
des objets de Greeting
d' Greeting
et renvoie la liste des résultats.
Services (GreetingService.java)
package org.springdataes.service;
import org.springdataes.model.Greeting;
import java.util.List;
public interface GreetingService {
List<Greeting> getAll();
Greeting findOne(String id);
Greeting create(Greeting greeting);
Greeting update(Greeting greeting);
List<Greeting> getGreetingByUsername(String username);
void delete(String id);
}
Bean de service (GreetingServiceBean.java)
package org.springdataes.service;
import com.google.common.collect.Lists;
import org.springdataes.dao.GreetingRepository;
import org.springdataes.model.Greeting;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GreetingServiceBean implements GreetingService {
@Autowired
private GreetingRepository repository;
@Override
public List<Greeting> getAll() {
return Lists.newArrayList(repository.findAll());
}
@Override
public Greeting findOne(String id) {
return repository.findOne(id);
}
@Override
public Greeting create(Greeting greeting) {
return repository.save(greeting);
}
@Override
public Greeting update(Greeting greeting) {
Greeting persitedGreeting = repository.findOne(greeting.getId());
if(persitedGreeting == null) {
return null;
}
return repository.save(greeting);
}
@Override
public List<Greeting> getGreetingByUsername(String username) {
return repository.findByUsername(username);
}
@Override
public void delete(String id) {
repository.delete(id);
}
}
Dans la classe ci-dessus, nous avons @Autowired
le GreetingRepository
. Nous pouvons simplement appeler les méthodes CRUDRepository
et la méthode que nous avons déclarée dans la classe de référentiel avec l'objet GreetingRepository
.
Dans la méthode getAll()
, vous pouvez trouver une ligne Lists.newArrayList(repository.findAll())
. Nous l'avons fait pour convertir repository.findAll()
en élément List<>
car il retourne une liste Iterable
.
Classe de contrôleur (GreetingController.java)
package org.springdataes.controller;
import org.springdataes.model.Greeting;
import org.springdataes.service.GreetingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
public class GreetingController {
@Autowired
private GreetingService greetingService;
@ResponseBody
@RequestMapping(value = "/greetings", method = RequestMethod.GET)
public ResponseEntity<List<Greeting>> getAll() {
return new ResponseEntity<List<Greeting>>(greetingService.getAll(), HttpStatus.OK);
}
@ResponseBody
@RequestMapping(value = "/greetings", method = RequestMethod.POST)
public ResponseEntity<Greeting> insertGreeting(@RequestBody Greeting greeting) {
return new ResponseEntity<Greeting>(greetingService.create(greeting), HttpStatus.CREATED);
}
@ResponseBody
@RequestMapping(value = "/greetings", method = RequestMethod.PUT)
public ResponseEntity<Greeting> updateGreeting(@RequestBody Greeting greeting) {
return new ResponseEntity<Greeting>(greetingService.update(greeting), HttpStatus.MOVED_PERMANENTLY);
}
@ResponseBody
@RequestMapping(value = "/greetings/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Greeting> deleteGreeting(@PathVariable("id") String idd) {
greetingService.delete(idd);
return new ResponseEntity<Greeting>(HttpStatus.NO_CONTENT);
}
@ResponseBody
@RequestMapping(value = "/greetings{id}", method = RequestMethod.POST)
public ResponseEntity<Greeting> getOne(@PathVariable("id") String idd) {
return new ResponseEntity<Greeting>(greetingService.findOne(idd), HttpStatus.OK);
}
@ResponseBody
@RequestMapping(value = "/greetings/{name}", method = RequestMethod.GET)
public ResponseEntity<List<Greeting>> getByUserName(@PathVariable("name") String name) {
return new ResponseEntity<List<Greeting>>(greetingService.getGreetingByUsername(name), HttpStatus.OK);
}
}
Construire
Pour construire cette application maven exécutée
mvn clean install
Au-dessus de la commande, commencez par supprimer tous les fichiers du dossier target
et créez le projet. Après la construction du projet, nous obtiendrons le fichier exécutable .jar nommé springdataes-1.0-SNAPSHOT.jar
. Nous pouvons exécuter la classe principale ( Application.java
) pour démarrer le processus ou simplement exécuter le fichier jar ci-dessus en tapant:
java -jar springdataes-1.0-SNAPSHOT.jar
Vérification des API
Pour insérer un élément de message d'accueil dans elasticsearch, exécutez la commande ci-dessous
curl -H "Content-Type: application/json" -X POST -d '{"username":"sunkuet02","message": "this is a message"}' http://localhost:8080/api/greetings
Vous devriez obtenir le résultat ci-dessous comme
{"id":"AV2ddRxBcuirs1TrVgHH","username":"sunkuet02","message":"this is a message"}
Vous pouvez également vérifier l’api get en exécutant:
curl -H "Content-Type: application/json" -X GET http://localhost:8080/api/greetings
Tu devrais obtenir
[{"id":"AV2ddRxBcuirs1TrVgHH","username":"sunkuet02","message":"this is a message"}]
Vous pouvez vérifier d'autres apis en suivant les processus ci-dessus.
Documentations Officielles: