Nous allons ici créer un exemple d’application Web Spring Boot avec le moteur de gabarit Hibernate Search Thymeleaf et le déployer en tant que WAR pour Wildfly 10.1.
Technologies utilisées:
-
Spring Boot 1.5.6.LELEASE
-
Java 8
-
Recherche Hibernate 5.6.1.Final
-
Tomcat intégré, Wildfly 8.1 Final
1. Structure du projet
Une structure de projet Maven standard
1. Dépendances 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>com.techfou</groupId> <artifactId>spring-boot-web-wildfly-search</artifactId> <version>0.0.1</version> <packaging>war</packaging> <name>techfou-wildfly-spring-boot</name> <description>Spring Boot Web Hibernate Search Example</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <logback.version>1.1.9</logback.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- Comment out if deploy as WAR file <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-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-search-engine --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-search-engine</artifactId> <version>5.6.1.Final</version> <exclusions> <exclusion> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-search-orm --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-search-orm</artifactId> <version>5.6.1.Final</version> <exclusions> <exclusion> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.3.0.Final</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.9</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <layout>WAR</layout> <executable>true</executable> <mainClass>com.mkyong.WildflySpringBootApplication</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
2. Modèle
Pour cet exemple d’application, nous créons un site Web qui vous permet de rechercher des cartes de baseball rares. Nous faisons donc de notre modèle la carte de baseball et annotons les champs interrogeables.
BaseballCard.java
package com.mkyong.model; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.Indexed; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Indexed @Entity public class BaseballCard { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Field private String name; @Field private String rarityLevel; @Field private int year; //getters n setters }
3. Référentiel
Nous avons ici un
CrudRepository
de Spring Data pour le modèle BaseballCard qui nous permettra d’effectuer les fonctions de création et de lecture nécessaires.
BaseballCardRepository.java
package com.mkyong.dao; import org.springframework.data.repository.CrudRepository; import com.mkyong.model.BaseballCard; public interface BaseballCardRepository extends CrudRepository<BaseballCard,Long> { }
4. Recherche Hibernate
HibernateSearchService.java
package com.mkyong.service; import com.mkyong.model.BaseballCard; import org.apache.lucene.search.Query; import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.Search; import org.hibernate.search.query.dsl.QueryBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import java.util.List; @Service public class HibernateSearchService { @Autowired private final EntityManager centityManager; @Autowired public HibernateSearchService(EntityManager entityManager) { super(); this.centityManager = entityManager; } public void initializeHibernateSearch() { try { FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(centityManager); fullTextEntityManager.createIndexer().startAndWait(); } catch (InterruptedException e) { e.printStackTrace(); } } @Transactional public List<BaseballCard> fuzzySearch(String searchTerm) { FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(centityManager); QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(BaseballCard.class).get(); Query luceneQuery = qb.keyword().fuzzy().withEditDistanceUpTo(1).withPrefixLength(1).onFields("name") .matching(searchTerm).createQuery(); javax.persistence.Query jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, BaseballCard.class); //execute search List<BaseballCard> BaseballCardList = null; try { BaseballCardList = jpaQuery.getResultList(); } catch (NoResultException nre) { ;//do nothing } return BaseballCardList; } }
Ceci configure le
HibernateSearchService
pour qu’il soit accessible.
HibernateSearchConfiguration.java
package com.mkyong; import javax.persistence.EntityManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.mkyong.service.HibernateSearchService; @EnableAutoConfiguration @Configuration public class HibernateSearchConfiguration { @Autowired private EntityManager bentityManager; @Bean HibernateSearchService hibernateSearchService() { HibernateSearchService hibernateSearchService = new HibernateSearchService(bentityManager); hibernateSearchService.initializeHibernateSearch(); return hibernateSearchService; } }
5. Service pour le modèle
C’est un service simple qui ajoute trois cartes au référentiel pour notre exemple. Pour une démonstration des principes de programmation SOLID, il existe une interface distincte pour le service.
CardService.java
package com.mkyong.service; public interface CardService { void addCards(); }
CardServiceImpl.java
package com.mkyong.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.mkyong.dao.BaseballCardRepository; import com.mkyong.model.BaseballCard; @Service public class CardServiceImpl implements CardService { @Autowired BaseballCardRepository cardrepository; BaseballCard TedWilliams = new BaseballCard(); BaseballCard BobGibson = new BaseballCard(); BaseballCard HonusWagner = new BaseballCard(); public void addCards() { TedWilliams.setName("Ted Williams"); TedWilliams.setYear(1954); TedWilliams.setRarityLevel("Very Rare"); cardrepository.save(TedWilliams); BobGibson.setName("Bob Gibson"); BobGibson.setYear(1959); BobGibson.setRarityLevel("Very Rare"); cardrepository.save(BobGibson); HonusWagner.setName("Honus Wagner"); HonusWagner.setYear(1909); HonusWagner.setRarityLevel("Rarest"); cardrepository.save(HonusWagner); System.out.println("Cards have been added : " + cardrepository.findAll()); } }
6. Contrôleur
Le contrôleur est responsable de la connexion des services principaux à notre modèle Thymeleaf frontal.
CardController.java
package com.mkyong.controller; import com.mkyong.model.BaseballCard; import com.mkyong.service.CardService; import com.mkyong.service.HibernateSearchService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; @Controller public class CardController { @Autowired private HibernateSearchService searchservice; @Autowired private CardService cardservice; @RequestMapping(value = "/", method = RequestMethod.GET) public String search(@RequestParam(value = "search", required = false) String q, Model model) { List<BaseballCard> searchResults = null; try { cardservice.addCards(); searchResults = searchservice.fuzzySearch(q); } catch (Exception ex) { //here you should handle unexpected errors //... //throw ex; } model.addAttribute("search", searchResults); return "index"; } }
7. Configuration
Nous devons maintenant configurer notre recherche Thymeleaf et Hibernate.
application.properties
#================================== # = Thymeleaf configurations #================================== spring.thymeleaf.check-template-location=true spring.thymeleaf.prefix=classpath:/templates/spring.thymeleaf.suffix=.html spring.thymeleaf.content-type=text/html spring.thymeleaf.cache=false server.contextPath=/#=================================== #= # Specify the Lucene Directory spring.jpa.properties.hibernate.search.default.directory__provider = filesystem # Using the filesystem DirectoryProvider you also have to specify the default # base directory for all indexes spring.jpa.properties.hibernate.search.default.indexBase = indexpath
8. Modèle Thymeleaf
Pour notre modèle Thymeleaf, nous avons deux objectifs: permettre à l’utilisateur de rechercher et d’afficher les résultats de recherche une fois la recherche terminée.
Heureusement, Thymeleaf a des instructions conditionnelles nous permettant d’afficher les résultats si la recherche d’un utilisateur renvoie des éléments.
index.html
<!DOCTYPE html> <html lang="en"> <head> <!-- META SECTION --> <title>Mkyong Wildfly Example</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <!-- END META SECTION --> <!-- BEGIN STYLE --> <style> table, th, td { border: 1px solid black; padding: 1px; } </style> <!-- END STYLE --> </head> <body> <form action="#" th:action="@{/}" th:object="${search}"> <label for="search__input">Search:</label> <input name="search" id="search"> </input> <div th:if="${not #lists.isEmpty(search)}"> <h2>Search Results</h2> <table> <thead> <tr> <th>ID</th> <th>name</th> <th>rarity level</th> <th>year</th> </tr> </thead> <tbody> <tr th:each="search : ${search}"> <td th:text="${search.id}">Text ...</td> <td th:text="${search.name}">Text ...</td> <td th:text="${search.rarityLevel}">Text ...</td> <td th:text="${search.year}">Text...</td> </tr> </tbody> </table> </div> </form> </body> </html>
9. SpringBootApplication
WildflySpringBootApplication.java
package com.mkyong; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class WildflySpringBootApplication { public static void main(String[]args) { SpringApplication.run(WildflySpringBootApplication.class, args); } }
10. Démo
Démarrez Spring Boot Application avec le conteneur Tomcat intégré par défaut.
$ mvn spring-boot:run
Accédez à http://localhost : 8080/
J’ai cherché «Ted» et les résultats sont affichés dans le tableau, http://localhost : 8080/? Search = ted
image://wp-content/uploads/1717/fr
11. Déployer le fichier WAR sur Wildfly
Wildfly est un serveur d’applications open source JBoss. Wildfly peut être téléchargé à partir de leur% E2% 80% 9Chttp://wildfly.org/downloads/%E2%80%9C[site web officiel]
11.1 Exclure le conteneur Tomcat intégré.
pom.xml
<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>
11.2 étend
SpringBootServletInitializer
WildflySpringBootApplication.java
package com.mkyong; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; @SpringBootApplication public class WildflySpringBootApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(WildflySpringBootApplication.class); } public static void main(String[]args) { SpringApplication.run(WildflySpringBootApplication.class, args); } }
11.3 Maven crée et copie le fichier WAR dans JBoss Wildfly et le démarre.
Terminal
$ mvn package
11.4 Considérations pour Wildfly 10
Pour Wildfly 10, nous devons apporter des modifications supplémentaires à cause des technologies fournies avec son emballage. Dans notre cas, nous utilisons Hibernate Search et cela est fourni dans Wildfly 10.
Pour les utilisateurs de Wildfly 10, vous devez créer un fichier
persistence.xml
et entrer:
persistence.xml
wildfly.jpa.hibernate.search.module = none
Terminé.
Télécharger le code source
Téléchargez le - lien://wp-content/uploads/2017/09/spring-boot-hibernate-search-example.zip[spring-boot-hibernate-search-example.zip](24 KB)
Références
Rechercher 5.6 Documentation]. https://spring.io/blog/2014/03/07/deploying-spring-boot-applications [Deploying
Applications d’amorçage de printemps]. http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html [Thymeleaf
Printemps]. lien://printemps-boot/printemps-boot-deploy-war-fichier-à-tomcat/[Spring Boot
-
Déployer un fichier WAR sur Tomcat]
recherche hibernate lien://tag/spring-boot/[botte de printemps]lien://tag/wildfly/[wildfly]