GVKun编程网logo

在Spring WebApp中使用Elasticsearch客户端时发生链接错误(spring.data.elasticsearch)

25

在本文中,我们将给您介绍关于在SpringWebApp中使用Elasticsearch客户端时发生链接错误的详细内容,并且为您解答spring.data.elasticsearch的相关问题,此外,我

在本文中,我们将给您介绍关于在Spring WebApp中使用Elasticsearch客户端时发生链接错误的详细内容,并且为您解答spring.data.elasticsearch的相关问题,此外,我们还将为您提供关于006-spring-data-elasticsearch 3.0.0.0 使用【四】-spring-data 之 Elasticsearch Repositories、Dockerized elasticsearch和fscrawler:无法创建Elasticsearch客户端,禁用了搜寻器…连接被拒绝、elasticsearch java api 使用elasticsearch 6.x.x版本,客户端使用5.6.10版本、elasticsearch 结合 spring springmvc jest 使用做成 web 架构的知识。

本文目录一览:

在Spring WebApp中使用Elasticsearch客户端时发生链接错误(spring.data.elasticsearch)

在Spring WebApp中使用Elasticsearch客户端时发生链接错误(spring.data.elasticsearch)

尝试在我的WebApp中包含Elasticsearch Java客户端时遇到问题。我有所需的依赖关系,我正在初始化/销毁Spring
bean中创建客户端(作为简单测试),如下所示:

    @Overridepublic void afterPropertiesSet() throws Exception {    try {        client = new TransportClient();        InetSocketTransportAddress addr = new InetSocketTransportAddress("localhost", 9300);        ((TransportClient) client).addTransportAddress(addr);    }     catch(Exception e){        System.out.println(e.toString());    }}

相应的destroy()将关闭客户端。

一切看起来正常,上下文开始正常,但是访问JSP时,我收到以下异常:

SEVERE: Servlet.service() for servlet [jsp] in context with path [/Fountain] threw           exception [Filter execution threw an exception] with root causejava.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "javax.servlet.ServletResponseWrapper.getOutputStream()Ljavax/servlet/ServletOutputStream;" the class loader (instance of org/apache/catalina/loader/WebappClassLoader) of the current class, javax/servlet/ServletResponseWrapper, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for interface javax/servlet/ServletResponse have different Class objects for the type vlet/ServletOutputStream; used in the signature    at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:186)at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:181)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at java.lang.Thread.run(Thread.java:722)Jan 10, 2014 10:44:46 AM org.apache.catalina.core.ApplicationDispatcher invokeSEVERE: Servlet.service() for servlet jsp threw exceptionjava.lang.LinkageError: loader constraint violation: when resolving method "javax.servlet.jsp.JspFactory.getPageContext(Ljavax/servlet/Servlet;Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext;" the class loader (instance of org/apache/jasper/servlet/JasperLoader) of the current class, org/apache/jsp/jsp/ajaxerror_jsp, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, javax/servlet/jsp/JspFactory, have different Class objects for the type t/ServletRequest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext; used in the signatureat org.apache.jsp.jsp.ajaxerror_jsp._jspService(ajaxerror_jsp.java:59)at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:489)at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467)at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:412)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:201)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at java.lang.Thread.run(Thread.java:722)Jan 10, 2014 10:44:46 AM org.apache.catalina.core.StandardHostValve customSEVERE: Exception Processing ErrorPage[exceptionType=java.lang.Throwable,      location=/jsp/ajaxerror.jsp]org.apache.jasper.JasperException: javax.servlet.ServletException: java.lang.LinkageError: loader constraint violation: when resolving method "javax.servlet.jsp.JspFactory.getPageContext(Ljavax/servlet/Servlet;Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext;" the class loader (instance of org/apache/jasper/servlet/JasperLoader) of the current class, org/apache/jsp/jsp/ajaxerror_jsp, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, javax/servlet/jsp/JspFactory, have different Class objects for the type t/ServletRequest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext; used in the signatureat org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:549)at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:455)at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:489)at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:467)at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:412)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:201)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at java.lang.Thread.run(Thread.java:722)Caused by: javax.servlet.ServletException: java.lang.LinkageError: loader constraint violation: when resolving method    "javax.servlet.jsp.JspFactory.getPageContext(Ljavax/servlet/Servlet;Ljavax/servlet/ServletR equest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext;" the class loader (instance of org/apache/jasper/servlet/JasperLoader) of the current class, org/apache/jsp/jsp/ajaxerror_jsp, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, javax/servlet/jsp/JspFactory, have different Class objects for the type t/ServletRequest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext; used in the signatureat org.apache.jsp.jsp.ajaxerror_jsp._jspService(ajaxerror_jsp.java:130)at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)... 22 moreCaused by: java.lang.LinkageError: loader constraint violation: when resolving method "javax.servlet.jsp.JspFactory.getPageContext(Ljavax/servlet/Servlet;Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext;" the class loader (instance of org/apache/jasper/servlet/JasperLoader) of the current class, org/apache/jsp/jsp/ajaxerror_jsp, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, javax/servlet/jsp/JspFactory, have different Class objects for the type t/ServletRequest;Ljavax/servlet/ServletResponse;Ljava/lang/String;ZIZ)Ljavax/servlet/jsp/PageContext; used in the signatureat org.apache.jsp.jsp.ajaxerror_jsp._jspService(ajaxerror_jsp.java:59)... 25 more

没有这种情况,上下文将启动并且将正确服务JSP。

有谁知道这可能是什么原因?我假设elasticsearch客户端使用的是网络应用所需的类,但在其他类加载器中将其实例化。

我尝试通过使用ImmutableSettings显式设置elasticsearch使用的类加载器,但这似乎没有任何区别:

    ClassLoader contextClassLoader = thread.getContextClassLoader();    try {        //thread.setContextClassLoader(ClassLoader.getSystemClassLoader());        Settings s = ImmutableSettings.settingsBuilder()                .classLoader(contextClassLoader)                .build();

任何帮助,将不胜感激!谢谢!

答案1

小编典典

好了,设法解决了这个问题:

获取对tomcat’common’类加载器的引用,并将其传递给Elasticsearch客户端:

ClassLoader contextClassLoader = thread.getContextClassLoader();try {        Settings settings = ImmutableSettings.settingsBuilder().classLoader(contextClassLoader.getParent()).build();                    client = new TransportClient(settings);

这样做的副作用是必须将names.txt文件从elasticSearch jar中移到“通用”类路径上的某个位置。

我仍然没有找到为什么这个问题会影响我的特定堆栈而不是其他堆栈的原因,但希望这样做并在此处进行更新。

006-spring-data-elasticsearch 3.0.0.0 使用【四】-spring-data 之 Elasticsearch Repositories

006-spring-data-elasticsearch 3.0.0.0 使用【四】-spring-data 之 Elasticsearch Repositories

二、Elasticsearch Repositories

2.1、简介

2.1.1、Spring 命名空间

  Spring Data Elasticsearch 模块包含一个允许定义存储库 bean 的自定义名称空间以及用于实例化 ElasticsearchServer 的元素。使用 repositories 元素查找 Spring Data 存储库

示例、使用名称空间设置 Elasticsearch 存储库

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">

    <elasticsearch:repositories base-package="com.acme.repositories" />

</beans>
View Code

使用传输客户端或节点客户端元素在上下文中注册 Elasticsearch 服务器的实例。

传输客户端使用命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">

    <elasticsearch:transport-client id="client" cluster-nodes="localhost:9300,someip:9300" />

</beans>
View Code

节点客户端使用命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd">

    <elasticsearch:node-client id="client" local="true"" />

</beans>
View Code

2.1.2、基于注释的配置

  Spring Data Elasticsearch 存储库支持不仅可以通过 XML 命名空间激活,还可以通过 JavaConfig 使用注释。

示例、使用 JavaConfig 激活 Elasticsearch 数据储存库

@Configuration
@EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories")
static class Config {

    @Bean
    public ElasticsearchOperations elasticsearchTemplate() {
        return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
    }
}
View Code

上面的配置设置了 ElasticsearchTemplate 使用的嵌入式 Elasticsearch 服务器。Spring Data Elasticsearch Repositories 使用 @EnableElasticsearchRepositories 注释来激活,它本质上具有与 XML 名称空间相同的属性。如果没有配置基础软件包,它将使用配置类所在的软件包。

2.1.3、Elasticsearch 使用 CDI 进行存储

  Spring Data Elasticsearch 存储库也可以使用 CDI 功能进行设置。

示例

class ElasticsearchTemplateProducer {

    @Produces
    @ApplicationScoped
    public ElasticsearchOperations createElasticsearchTemplate() {
        return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
    }
}

class ProductService {

    private ProductRepository repository;

    public Page<Product> findAvailableBookByName(String name, Pageable pageable) {
        return repository.findByAvailableTrueAndNameStartingWith(name, pageable);
    }

    @Inject
    public void setRepository(ProductRepository repository) {
        this.repository = repository;
    }
}
View Code

2.2、查询方法

2.2.1、查询策略

  Elasticsearch 模块支持所有基本的查询构建功能,如 String,Abstract,Criteria 或从方法名派生。

声明的查询

  从方法名称派生查询并不总是足够的和 / 或可能导致不可读的方法名称。在这种情况下,可以使用 @Query 注解(请参阅使用 @Query 注释)。

2.2.2、query 创建

示例

public interface BookRepository extends Repository<Book, String>{
    List<Book> findByNameAndPrice(String name, Integer price);
}

上面的方法名称将被转换为以下 Elasticsearch json 查询

{ "bool" :
    { "must" :
        [
            { "field" : {"name" : "?"} },
            { "field" : {"price" : "?"} }
        ]
    }
}

下面显示了 Elasticsearch 支持的关键字列表。

Keyword Sample Elasticsearch Query String

And

findByNameAndPrice

{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}

Or

findByNameOrPrice

{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}

Is

findByName

{"bool" : {"must" : {"field" : {"name" : "?"}}}}

Not

findByNameNot

{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}

Between

findByPriceBetween

{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

LessThanEqual

findByPriceLessThan

{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

GreaterThanEqual

findByPriceGreaterThan

{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}

Before

findByPriceBefore

{"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

After

findByPriceAfter

{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}

Like

findByNameLike

{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}

StartingWith

findByNameStartingWith

{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}

EndingWith

findByNameEndingWith

{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}

Contains/Containing

findByNameContaining

{"bool" : {"must" : {"field" : {"name" : {"query" : "?","analyze_wildcard" : true}}}}}

In

findByNameIn(Collection<String>names)

{"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}

NotIn

findByNameNotIn(Collection<String>names)

{"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}

Near

findByStoreNear

Not Supported Yet !

True

findByAvailableTrue

{"bool" : {"must" : {"field" : {"available" : true}}}}

False

findByAvailableFalse

{"bool" : {"must" : {"field" : {"available" : false}}}}

OrderBy

findByAvailableTrueOrderByNameDesc

{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

2.2.3、使用 @Query 注解

public interface BookRepository extends ElasticsearchRepository<Book, String> {
    @Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")
    Page<Book> findByName(String name,Pageable pageable);
}

三、其他 Elasticsearch 操作支持

无法通过存储库接口直接访问的 Elasticsearch 操作的额外支持。建议将这些操作添加为自定义实现,如 Spring Data 存储库的自定义实现中所述。

3.1、Filter Builder

private ElasticsearchTemplate elasticsearchTemplate;

SearchQuery searchQuery = new NativeSearchQueryBuilder()
    .withQuery(matchAllQuery())
    .withFilter(boolFilter().must(termFilter("id", documentId)))
    .build();

Page<SampleEntity> sampleEntities =
    elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
View Code

3.2、使用 Scan And Scroll 查看大结果集

Elasticsearch 具有扫描和滚动功能,可以获取大块结果集。 ElasticsearchTemplate 具有可用于以下的扫描和滚动方法。

SearchQuery searchQuery = new NativeSearchQueryBuilder()
    .withQuery(matchAllQuery())
    .withIndices("test-index")
    .withTypes("test-type")
    .withPageable(new PageRequest(0,1))
    .build();
String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false);
List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>();
boolean hasRecords = true;
while (hasRecords){
    Page<SampleEntity> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper<SampleEntity>()
    {
        @Override
        public Page<SampleEntity> mapResults(SearchResponse response) {
            List<SampleEntity> chunk = new ArrayList<SampleEntity>();
            for(SearchHit searchHit : response.getHits()){
                if(response.getHits().getHits().length <= 0) {
                    return null;
                }
                SampleEntity user = new SampleEntity();
                user.setId(searchHit.getId());
                user.setMessage((String)searchHit.getSource().get("message"));
                chunk.add(user);
            }
            return new PageImpl<SampleEntity>(chunk);
        }
    });
    if(page != null) {
        sampleEntities.addAll(page.getContent());
        hasRecords = page.hasNextPage();
    }
    else{
        hasRecords = false;
    }
    }
}
View Code

整体 spring 配置参看

 

Dockerized elasticsearch和fscrawler:无法创建Elasticsearch客户端,禁用了搜寻器…连接被拒绝

Dockerized elasticsearch和fscrawler:无法创建Elasticsearch客户端,禁用了搜寻器…连接被拒绝

第一次运行fscrawler(即docker-compose run fscrawler)时,它将使用以下默认设置创建/config/{fscrawer_job}/_settings.yml

elasticsearch:
  nodes:
  - url: "http://127.0.0.1:9200"

这将导致fscrawler尝试连接到localhost(即127.0.0.1)。但是,当fscrawler位于Docker容器中时,这将失败,因为它正在尝试与CONTAINER的本地主机连接。在我的情况下,这尤其令人困惑,因为Elasticsearch WAS可以作为本地主机访问,但可以在我的物理计算机的本地主机(而不是容器的本地主机)上访问。更改网址后,fscrawler可以连接到Elasticsearch实际上所在的网络地址。

elasticsearch:
  nodes:
  - url: "http://elasticsearch:9200"

我使用了以下Docker镜像:https://hub.docker.com/r/toto1310/fscrawler

# FILE: docker-compose.yml

version: '2.2'
services:
  # FSCrawler 
  fscrawler:
    image: toto1310/fscrawler
    container_name: fscrawler
    volumes:
      - ${PWD}/config:/root/.fscrawler
      - ${PWD}/data:/tmp/es
    networks: 
      - esnet
    command: fscrawler job_name

  # Elasticsearch Cluster
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.3.2
    container_name: elasticsearch
    environment:
      - node.name=elasticsearch
      - discovery.seed_hosts=elasticsearch2
      - cluster.initial_master_nodes=elasticsearch,elasticsearch2
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - esnet
  elasticsearch2:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.3.2
    container_name: elasticsearch2
    environment:
      - node.name=elasticsearch2
      - discovery.seed_hosts=elasticsearch
      - cluster.initial_master_nodes=elasticsearch,elasticsearch2
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata02:/usr/share/elasticsearch/data
    networks:
      - esnet

volumes:
  esdata01:
    driver: local
  esdata02:
    driver: local

networks:
  esnet:

docker-compose up elasticsearch elasticsearch2 调出elasticsearch节点。
运行docker-compose run fscrawler创建_settings.yml
_settings.yml编辑为

elasticsearch:
  nodes:
  - url: "http://elasticsearch:9200"

启动了fscrawler docker-compose up fscrawler

elasticsearch java api 使用elasticsearch 6.x.x版本,客户端使用5.6.10版本

elasticsearch java api 使用elasticsearch 6.x.x版本,客户端使用5.6.10版本

es的添加数据方法中 索引index字段不允许为大写字符串,必须全部为小写字符串

public void bulkCreatIndex(){

TransportClient client = es.getClient();

int i = 1;

// bulk单次批操作量
final int BatchSize = 10000;
BulkRequestBuilder bulkRequest = client.prepareBulk();
// 遍历JSONArray,数据量庞大时,for循环比foreach循环效率更高一些
for (i = 1; i <= jsonArray.size(); i++) {
// setSource为上传的文本文档
bulkRequest.add(client.prepareIndex(index.toLowerCase(), type).setSource(jsonArray.getJSONObject(i-1).toString()));
// 每10000条数据执行一次bulk批量操作
if (0 == i % BatchSize) {
bulkRequest.execute().actionGet();
bulkRequest = client.prepareBulk();//此处是bulkRequest执行完成之后会重新创建一个bulkRequest避免下次提交出现重复的数据,如果是一次性全部提交可以不用使用此处
}
}
bulkRequest.execute().actionGet();
bulkRequest = client.prepareBulk();

}

查询方法

public void search(){

Client client = esmanager.getClient();

RangeQueryBuilder rangequerybuilder = QueryBuilders.rangeQuery("startdate").from(startdate).to(enddate);//建立查询是所使用条件startdate 从from  startdate开始至enddate结束,

SearchRequestBuilder responsebuilder = client.prepareSearch(index).setTypes(type);//创建查询使用方法
SearchResponse myresponse = responsebuilder
.setQuery(QueryBuilders.boolQuery().must(rangequerybuilder))//添加查询条件
.setFrom(from).setSize(size).addSort("startdate", SortOrder.ASC) // 分页 并且根据startdate进行排序
.setExplain(true).execute().actionGet();
SearchHits hits = myresponse.getHits();//searchhits 为查询结果相当于jdbc中的ResultSet
for (int i = 0; i < hits.getHits().length; i++) {

hits.getHits()[i].getSourceAsMap().get(key)

}

 根据业务进行方法的修改,本方法制作一个demo参考为主。

elasticsearch 结合 spring springmvc jest 使用做成 web 架构

elasticsearch 结合 spring springmvc jest 使用做成 web 架构

原文地址:http://blog.mkfree.com/posts/40

做成WEB的架构,当然我不用 servlet 了... 直接使用 spring springmvc 去做吧... 也当是一个 ES 跟 spring springmvc 集成的例子,为了简单起见,我这里不用 freemarker 了.. 我直接使用 jsp 做视图... 我也用了 bootstrap 去管理一个 web 页面,这样可以省很多时间...

当然我也是用 maven 了... 如果不有熟悉 maven 的朋友们,可以跟我交流下,大家学习学习...

提示:项目可以用 mvn jetty:run 就可以跑起来了...

代码可能有点长,想学习的童鞋们认真些了...

首先我们看看 web 界面

首页:

点击:创建索引

创建索引成功..

搜索结果:

好了,下面开始真正的代码....

1. 看看项目的目录结构:

我就贴重要的几个文件代码出来,源代码已经有了,大家可以下载

下面 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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mkfree</groupId>
	<artifactId>soso</artifactId>
	<packaging>war</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>java-jest-sample</name>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>3.1.2.RELEASE</spring.version>
		<slf4j.version>1.5.10</slf4j.version>
		<slf4j-log4j12.version>1.6.1</slf4j-log4j12.version>
		<java.version>1.6</java.version>
		<junit.version>4.8.2</junit.version>
		<org.aspectj-version>1.6.9</org.aspectj-version>
	</properties>

	<repositories>
		<repository>
			<id>sonatype</id>
			<name>Sonatype Groups</name>
			<url>https://oss.sonatype.org/content/groups/public/</url>
		</repository>
	</repositories>
	<dependencies>

		<dependency>
			<groupId>io.searchbox</groupId>
			<artifactId>jest</artifactId>
			<version>0.0.2</version>
		</dependency>
		<!-- ES dependency for query builder -->
		<dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>0.19.11</version>
		</dependency>

		<!-- Spring Dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>test</scope>
		</dependency>

		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>

		<!-- View Dependencies -->
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<!-- Test Dependencies -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>1.1.2</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j-log4j12.version}</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2</version>
		</dependency>
	</dependencies>

	<pluginRepositories>
		<pluginRepository>
			<id>cloudbees-public-release</id>
			<url>http://repository-cloudbees.forge.cloudbees.com/public-release</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>

	<build>
		<finalName>java-jest-sample</finalName>
		<plugins>
			<!-- Plugin to run and test through maven -->
			<plugin>
				<groupId>org.mortbay.jetty</groupId>
				<artifactId>maven-jetty-plugin</artifactId>
				<version>6.1.10</version>
				<configuration>
					<stopPort>9966</stopPort>
					<stopKey>foo</stopKey>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<version>2.3</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>copy</goal>
						</goals>
						<configuration>
							<artifactItems>
								<artifactItem>
									<groupId>org.mortbay.jetty</groupId>
									<artifactId>jetty-runner</artifactId>
									<version>7.5.4.v20111024</version>
									<destFileName>jetty-runner.jar</destFileName>
								</artifactItem>
							</artifactItems>
						</configuration>
					</execution>
				</executions>
			</plugin>

			<!-- Ensures we are compiling at 1.6 level -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>

			<plugin>
				<groupId>com.cloudbees</groupId>
				<artifactId>bees-maven-plugin</artifactId>
				<version>1.3.2</version>
			</plugin>
		</plugins>
		<outputDirectory>${basedir}/src/main/webapp/WEB-INF/classes/</outputDirectory>
	</build>
</project>
SearchController 类:

package com.mkfree.soso.action;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.mkfree.soso.model.News;
import com.mkfree.soso.service.SearchService;

/**
 * 搜索控制
 * 
 * @author hk
 * 
 *         2013-1-16 下午8:26:09
 */
@Controller
@RequestMapping("/")
public class SearchController {

	@Autowired
	SearchService searchService;

	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView home() {
		ModelAndView mv = new ModelAndView();
		mv.setViewName("home");
		return mv;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/search")
	public ModelAndView search(@RequestParam("q") String query) {
		Listarticles = searchService.searchsNews(query);
		ModelAndView mv = new ModelAndView();
		mv.setViewName("search");
		mv.addObject("articles", articles);
		return mv;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/search/create")
	public ModelAndView createInitialData() {
		searchService.builderSearchIndex();
		ModelAndView mv = new ModelAndView("forward:/");
		mv.addObject("message", "文章索引已创建成功!");
		return mv;
	}

	@RequestMapping(method = RequestMethod.GET, value = "/about")
	public ModelAndView about() {
		ModelAndView mv = new ModelAndView();
		mv.setViewName("about");
		return mv;
	}
}
配置客户端 SpringConfiguration 类 :

package com.mkfree.soso.configur;

import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.config.ClientConfig;
import io.searchbox.client.config.ClientConstants;

import java.util.LinkedHashSet;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author hk
 * 
 *         2013-1-16 下午8:49:51
 */
@Configuration
public class SpringConfiguration {

	public @Bean
	ClientConfig clientConfig() {

		String connectionUrl = "http://192.168.56.101:9200";

		ClientConfig clientConfig = new ClientConfig();
		LinkedHashSetservers = new LinkedHashSet();
		servers.add(connectionUrl);
		clientConfig.getServerProperties().put(ClientConstants.SERVER_LIST, servers);
		clientConfig.getClientFeatures().put(ClientConstants.IS_MULTI_THREADED, false);
		return clientConfig;
	}

	public @Bean
	JestClient jestClient() {
		JestClientFactory factory = new JestClientFactory();
		factory.setClientConfig(clientConfig());
		return factory.getObject();
	}
}
实体类:

package com.mkfree.soso.model;

import io.searchbox.annotations.JestId;

/**
 * 虚拟news 搜索文章
 * 
 * @author hk
 * 
 *         2013-1-12 下午11:38:29
 */
public class News {

	@JestId
	private int id;
	private String title;
	private String content;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

}
搜索服务类:

package com.mkfree.soso.service;

import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.Bulk;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.indices.CreateIndex;
import io.searchbox.indices.DeleteIndex;

import java.io.IOException;
import java.util.List;

import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mkfree.soso.model.News;

/**
 * es简单服务接口
 * 
 * @author hk
 * 
 *         2013-1-12 下午11:47:16
 */
@Service
public class SearchService {

	@Autowired
	private JestClient jestClient;
	int num = 100000;

	/**
	 * 创建es news索引
	 */
	public void builderSearchIndex() {
		long start = System.currentTimeMillis();
		try {
			// 如果索引存在,删除索引
			DeleteIndex deleteIndex = new DeleteIndex("news");
			jestClient.execute(deleteIndex);

			// 创建索引
			CreateIndex createIndex = new CreateIndex("news");
			jestClient.execute(createIndex);
			// Bulk 两个参数1:索引名称2:类型名称(用文章(article)做类型名称)
			Bulk bulk = new Bulk("news", "article");
			// 添加添加100万条假数据去服务端(ES)
			for (int i = 0; i < num; i++) {
				News news = new News();
				news.setId(i + 1);
				news.setTitle("elasticsearch结合spring springmvc jest 使用做成WEB架构" + (i + 1));
				news.setContent("oyhk 学习笔记 上一篇文章,说到了先利用jest junit构架一个ES的搜索入门例子...现在准备要做一个ES的WEB架构例子,希望大家都学习学习ES分布式搜索引擎,真的非常不错的...欢迎大家一起讨论讨论... 做成WEB的架构,当然我不用servlet了...直接使用spring springmvc去做吧...也当是一个ES跟spring springmvc 集成的例子,为了简单起见,我这里不用freemarker了..我直接使用jsp做视图... 当然我也是用maven了...如果不有熟悉maven的朋友们,可以跟我交流下,大家学习学习..."
						+ (i + 1));
				bulk.addIndex(new Index.Builder(news).build());
			}
			jestClient.execute(bulk);
		} catch (Exception e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("创建索引时间:数据量是  " + num + "记录,共用时间 -->> " + (end - start) + " 毫秒");
	}

	/**
	 * 搜索新闻
	 * 
	 * @param param
	 * @return
	 */
	public ListsearchsNews(String param) {
		try {
			long start = System.currentTimeMillis();
			QueryBuilder queryBuilder = QueryBuilders.queryString(param);
			Search search = new Search(Search.createQueryWithBuilder(queryBuilder.toString()));
			search.addIndex("news");
			search.addType("article");
			JestResult result = jestClient.execute(search);
			long end = System.currentTimeMillis();
			System.out.println("在" + num + "条记录中,搜索新闻,共用时间 -->> " + (end - start) + " 毫秒");
			return result.getSourceAsObjectList(News.class);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
其他的...jsp 文件我就不贴出代码了....





今天关于在Spring WebApp中使用Elasticsearch客户端时发生链接错误spring.data.elasticsearch的分享就到这里,希望大家有所收获,若想了解更多关于006-spring-data-elasticsearch 3.0.0.0 使用【四】-spring-data 之 Elasticsearch Repositories、Dockerized elasticsearch和fscrawler:无法创建Elasticsearch客户端,禁用了搜寻器…连接被拒绝、elasticsearch java api 使用elasticsearch 6.x.x版本,客户端使用5.6.10版本、elasticsearch 结合 spring springmvc jest 使用做成 web 架构等相关知识,可以在本站进行查询。

本文标签: