SpringBoot整合ElasticSearch

一、先記錄一下自己傻逼導致的錯誤,耗費了很長時間才解決

java.io.IOException: Request PUT http://47.107.74.116:9200/yao/news/1 HTTP/1.1 yielded text/plain; charset=UTF-8, should be json: HTTP/1.1 400 Bad Request
	at io.searchbox.client.http.JestHttpClient.deserializeResponse(JestHttpClient.java:207)
	at io.searchbox.client.http.JestHttpClient.execute(JestHttpClient.java:68)
	at io.searchbox.client.http.JestHttpClient.execute(JestHttpClient.java:60)
	at com.dxy.es.controller.EsController.insertIndex(EsController.java:27)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)

測試Jest操作ES,報HTTP/1.1 yielded text/plain; charset=UTF-8, should be json: HTTP/1.1 400 Bad Request錯,說是因爲response的content-type是 text/plain; charset=UTF-8而不是需要的application/json; charset=UTF-8,因此拋出異常。

最後發現是如下的配置導致的,爲啥我要配置下面那兩行呢,是因爲第一行配置顯示已過期,我就想着有沒有其他配置替代,源碼裏面就找到了後面兩行,抱着試一試的心態加上了,後來忘了去掉就造成了這麼傻逼的錯誤

spring.elasticsearch.jest.uris=http://47.107.74.116:9200
##下面兩行配置啓用了proxy代理,導致上面的錯誤發生
#spring.elasticsearch.jest.proxy.host=47.107.74.116
#spring.elasticsearch.jest.proxy.port=9200

二、如果在docker中啓動elasticsearch容器過一段時間就會自動關閉,請參考https://blog.csdn.net/qq_41754409/article/details/94134747

三、編寫代碼

 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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dxy</groupId>
    <artifactId>springboot-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!--父級項目的packaging設置爲pom-->
    <packaging>pom</packaging>

    <!--主工程包含子模塊-->
    <modules>
        <module>springboot-elasticsearch</module>
        <module>springboot-rabbitmq</module>
        <module>springboot-cache</module>
    </modules>

    <!--子模塊的Spring Boot配置-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--配置參數(註釋掉的在)-->
    <properties>
        <!-- 下面的三行,其實在前面<parent>的spring-boot-starter-parent中已默認配置有 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.test.skip>true</maven.test.skip>
    </properties>

    <!--子模塊Spring Boot公共依賴-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

2、子模塊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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.dxy</groupId>
        <artifactId>springboot-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>springboot-elasticsearch</artifactId>
    <name>springboot-elasticsearch</name>
    <description>Demo project for Spring Boot</description>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

        <!-- 使用jest操作ES -->
        <dependency>
            <groupId>io.searchbox</groupId>
            <artifactId>jest</artifactId>
            <version>5.3.3</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、application.properties

spring.elasticsearch.jest.uris=http://xx.xx.xx.xx:9200

spring.data.elasticsearch.cluster-name=docker-cluster
spring.data.elasticsearch.cluster-nodes=xx.xx.xx.xx:9300

4、pojo

package com.dxy.es.pojo;

import org.springframework.data.elasticsearch.annotations.Document;

@Document(indexName = "yao",type = "book")
public class Book {

    private Integer id;
    private String bookName;
    private String author;

    public Integer getId() {
        return id;
    }

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

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", bookName='" + bookName + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}
package com.dxy.es.pojo;

import io.searchbox.annotations.JestId;

import java.io.Serializable;

public class News implements Serializable {

    @JestId
    private Integer id;
    private String author;
    private String title;
    private String content;


    public Integer getId() {
        return id;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    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;
    }
}

5、ElasticsearchRepository

package com.dxy.es.repository;

import com.dxy.es.pojo.Book;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.List;

public interface BookRepository extends ElasticsearchRepository<Book,Integer> {

    //該命名方式可參考:https://docs.spring.io/spring-data/elasticsearch/docs/3.2.3.RELEASE/reference/html/#elasticsearch.query-methods
    List<Book> findByBookNameLike(String bookName);
}

6、測試代碼

package com.dxy.es;

import com.dxy.es.pojo.Book;
import com.dxy.es.pojo.News;
import com.dxy.es.repository.BookRepository;
import io.searchbox.client.JestClient;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.test.context.junit4.SpringRunner;

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

@RunWith(SpringRunner.class)
@SpringBootTest
class SpringbootElasticsearchApplicationTests {

    @Autowired
    JestClient jestClient;

    @Autowired
    BookRepository bookRepository;

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;

    @Test
    public void test3(){
        Book book = new Book();
        book.setId(1);
        book.setBookName("Java編程思想");
        book.setAuthor("zhangsan");
        IndexQuery indexQuery = new IndexQuery();
        indexQuery.setId("1");
        indexQuery.setObject(book);
        indexQuery.setIndexName("yao");
        indexQuery.setType("book");
        elasticsearchTemplate.index(indexQuery);
    }

    @Test
    public void test1(){
        Book book = new Book();
        book.setId(100);
        book.setBookName("Java編程思想");
        book.setAuthor("zhangsan");
        bookRepository.index(book);
    }

    @Test
    public void test2(){
        List<Book> books = bookRepository.findByBookNameLike("思想");
        for(Book book:books){
            System.out.println(book);
        }
    }

    @Test
    void exIndexLoads() {
        News news = new News();
        news.setId(1);
        news.setAuthor("ccf");
        news.setTitle("abc");
        news.setContent("Jay Chou play part in Chongqing");
        Index build = new Index.Builder(news).index("yao").type("news").build();
        try {
            jestClient.execute(build);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void search() throws IOException {
        String str = "{\n" +
                "    \"query\" : {\n" +
                "        \"match\" : {\n" +
                "            \"about\" : \"rock climbing\"\n" +
                "        }\n" +
                "    }\n" +
                "}";
        Search search = new Search.Builder(str).addIndex("megacorp").addType("employee").build();
        SearchResult jestResult = jestClient.execute(search);
        System.out.println(jestResult.getJsonString());
    }

}

7、啓動類

package com.dxy.es;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 *SpringBoot默認使用Spring Data ElasticSearch 進行處理,除此之外SpringBoot還實現了Jest的自動配置
 *    1、Jest自動配置(默認不生效,需要導入 io.searchbox.client.JestClient)
 *       JestClient:操作ES的客戶端
 *   2、SpringData ElasticSearch(可能存在版本不一致的情況) 自動配置
 *      Client:客戶端,節點信息clusterNodes;clusterName
 *      ElasticsearchTemplate:操作模板
 *      編寫一個ElasticsearchRepository的子接口來操作ES
 *  兩種用法:https://github.com/spring-projects/spring-data-elasticsearch
 *     1)、編寫ElasticsearchRepository的子接口
 *     2)、ElasticsearchTemplate
 *
 */
@SpringBootApplication
public class SpringbootElasticsearchApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootElasticsearchApplication.class, args);
    }

}

 

發佈了52 篇原創文章 · 獲贊 28 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章