一、先記錄一下自己傻逼導致的錯誤,耗費了很長時間才解決
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);
}
}