Hier erstellen wir ein Spring Boot-Webanwendungsbeispiel mit der Hibernate Search Thymeleaf-Vorlagen-Engine und stellen es als WAR für Wildfly 10.1 bereit.
Verwendete Technologien:
-
Spring Boot 1.5.6. FREIZEIT
-
Java 8
-
Hibernate-Suche 5.6.1.Ende
-
Embedded Tomcat, Wildfly 8.1 Finale
1. Projektstruktur
Eine Standard-Maven-Projektstruktur
1. Projektabhängigkeiten
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. Modell
Für diese Beispielanwendung erstellen wir eine Website, auf der Sie nach seltenen Baseballkarten suchen können. Also machen wir unser Modell zur Baseballkarte und kommentieren die durchsuchbaren Felder.
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. Repository
Hier haben wir ein Spring Data
CrudRepository
für das BaseballCard-Modell, mit dem wir die erforderlichen Erstellungs- und Lesefunktionen ausführen können.
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. Suche im Ruhezustand
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; } }
Dadurch wird der
HibernateSearchService
so konfiguriert, dass auf ihn zugegriffen werden kann.
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 für das Modell
Dies ist ein einfacher Service, der unserem Repository drei Karten hinzufügt. Zur Veranschaulichung der SOLID-Programmierprinzipien gibt es eine separate Schnittstelle für den Dienst.
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. Controller
Der Controller ist für die Verbindung der Backend-Services mit unserer Thymeleaf-Vorlage für das Frontend verantwortlich.
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. Konfiguration
Jetzt müssen wir unsere Thymeleaf- und Hibernate-Suche konfigurieren.
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. Thymeleaf-Vorlage
Für unsere Thymeleaf-Vorlage haben wir zwei Zwecke: Erlauben Sie dem Benutzer, die Suchergebnisse zu suchen und anzuzeigen, sobald eine Suche abgeschlossen ist.
Glücklicherweise hat Thymeleaf bedingte Anweisungen, die es uns ermöglichen, Ergebnisse anzuzeigen, wenn die Suche eines Benutzers Elemente zurückgibt.
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. Demo
Starten Sie Spring Boot Application mit dem eingebetteten Tomcat-Standardcontainer.
$ mvn spring-boot:run
Zugriff auf http://localhost : 8080/
Ich habe nach "Ted" gesucht und die Ergebnisse werden in der Tabelle http://localhost : 8080/? Search = ted angezeigt
11. Stellen Sie die WAR-Datei für Wildfly bereit
Der Wildfly ist ein JBoss-Open-Source-Anwendungsserver. Wildfly kann von% E2% 80% heruntergeladen werden 9Chttp://wildfly.org/downloads/%E2%80%9C[offizielle Website]
11.1 Schließen Sie den eingebetteten Tomcat-Container aus.
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 Erweitert
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 erstellt und kopiert die WAR-Datei in JBoss Wildfly und startet sie.
Terminal
$ mvn package
11.4 Überlegungen zu Wildfly 10
Für Wildfly 10 müssen wir aufgrund der vorinstallierten Technologien zusätzliche Änderungen vornehmen. In unserem Fall verwenden wir die Hibernate-Suche, die in Wildfly 10 verpackt ist.
Für Benutzer von Wildfly 10 müssen Sie eine persistence.xml -Datei erstellen und Folgendes eingeben:
persistence.xml
wildfly.jpa.hibernate.search.module = none
Erledigt.
Quellcode herunterladen
Download es - spring-boot-hibernate-search-example.zip (24 KB)
Referenzen
5.6 Dokumentation suchen]. https://spring.io/blog/2014/03/07/deploying-spring-boot-applications [Deploying
Spring Boot-Anwendungen]. http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html [Thymeleaf
+ Frühling]. link://spring-boot/spring-boot-deploy-war-datei zu tomcat/
-
Bereitstellen der WAR-Datei für Tomcat]
Link://Tag/Hibernate-Suche/[Hibernate-Suche] springboot wildfly