You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot连接Hadoop HBase失败 求可运行示例项目

Spring Boot集成HBase可运行示例及问题解决

问题描述

报错信息:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'feedService': Unsatisfied dependency expressed through field 'hbaseTemplate': Error creating bean with name 'hbaseTemplate' defined in class path resource [com/example/demo/HbaseConfig.class]: Failed to instantiate [org.springframework.data.hadoop.hbase.HbaseTemplate]: Factory method 'hbaseTemplate' threw exception with message: org/apache/hadoop/hbase/client/HTableInterface

核心原因:spring-data-hadoop:2.5.0.RELEASE适配的是HBase 1.x版本,而你使用的HBase 2.5.2已移除HTableInterface类(替换为Table接口),版本不兼容导致该错误。

你的现有依赖配置

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-hadoop</artifactId>
    <version>2.5.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase</artifactId>
    <version>2.5.2</version>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>2.5.2</version>
    <scope>compile</scope>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

你的现有HBase连接类代码

public class HConnection {

private String hbasezookeeperquorum = "PRODDMSDN04";// ,proddmsdn02,proddmsdn01
private String hbasezookeeperpropertyclientPort = "2181";
private String hbasemaster = "proddmsdn01:16010";
private String zookeeperznodeparent = "/hbase-unsecure";

private String dmshbasetable="DMSMASTER";
private String dmshbasetableimgfamily="img";
private String  dmshbasetabledatafamily="data";
private String  dmshbasetablemetafamily="meta";
 static Configuration conf;
 
 static Connection connection;
 private String dmsid="1a2c3e0e-8363-4e94-87c9-701029933b37";
private Connection newConnection() {
    

     Connection conn = null;
        try {
            conf = HBaseConfiguration.create();
            conf.set("hbase.zookeeper.quorum", hbasezookeeperquorum);
            conf.set("hbase.zookeeper.property.clientPort", hbasezookeeperpropertyclientPort);
            conf.set("hbase.master", hbasemaster);
            conf.set("zookeeper.znode.parent", zookeeperznodeparent);
            conn = ConnectionFactory.createConnection(conf);
            System.out.println("conn" + conn.getConfiguration());

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    return conn;

}

public static void main(String[] args) throws IOException, URISyntaxException, Exception {
    System.out.println("Connecting to Hadoop-------&gt;");

     connection=new HConnection().newConnection();
    
     FileSystem fileSystem = FileSystem.get(conf);

    if (fileSystem instanceof DistributedFileSystem) {
        System.out.println("HDFS is the underlying filesystem");
        HashMap<String, String> map = new HashMap<>();

    } else {
        System.out.println("Other type of file system " + fileSystem.getClass());
        
        System.out.println("Filesystem connected-------&gt;");
    }
}

ArrayList<Map<String, String>> list = new ArrayList<>();

public Optional<List<Map<String, String>>> searchMetaData(Map<String, String> searchParams)
        throws IOException {
    
    System.out.println("searchParams--------------&gt;"+searchParams);
    

    TableName tablename = TableName.valueOf(dmshbasetable);
    Table table = connection.getTable(tablename);
    System.out.println("Connecting table--------------&gt;"+table);
    Scan scan = new Scan();
    scan.addFamily(Bytes.toBytes(dmshbasetabledatafamily));
    scan.addFamily(Bytes.toBytes(dmshbasetablemetafamily));
    FilterList allFilters = new FilterList(new Filter[0]);
    for (Map.Entry<String, String> entry : searchParams.entrySet()) {
        SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes(dmshbasetablemetafamily),
                Bytes.toBytes(entry.getKey()), CompareFilter.CompareOp.EQUAL, Bytes.toBytes(entry.getValue()));
        allFilters.addFilter((Filter) filter);
    }
    SingleColumnValueFilter filter2 = new SingleColumnValueFilter(Bytes.toBytes(dmshbasetabledatafamily),
            Bytes.toBytes("status"), CompareFilter.CompareOp.EQUAL, Bytes.toBytes("1"));
    allFilters.addFilter((Filter) filter2);
    scan.setFilter((Filter) allFilters);
    ResultScanner resultScanner = table.getScanner(scan);
    Iterator<Result> arr = resultScanner.iterator();
    list = new ArrayList<>();
    while (arr.hasNext()) {
        Get g = new Get(((Result) arr.next()).getRow());
        Result result = table.get(g);
        Map<String, String> map = new HashMap<>();
        NavigableMap<byte[], byte[]> data = result.getFamilyMap(Bytes.toBytes(dmshbasetabledatafamily));
        NavigableMap<byte[], byte[]> metadata = result.getFamilyMap(Bytes.toBytes(dmshbasetablemetafamily));
        data.putAll(metadata);
        for (Map.Entry<byte[], byte[]> entry : data.entrySet())
            map.put(new String(entry.getKey()), new String(entry.getValue()));
        list.add(map);
        
    }
    if (list.isEmpty())
        return Optional.empty();
    
    List<JSONObject> jsonObj = new ArrayList<JSONObject>();

    for(Map<String, String> data : list) {
        JSONObject obj = new JSONObject(data);
        jsonObj.add(obj);
    }

    JSONArray test = new JSONArray(jsonObj);

    System.out.println(test.toString());
    
    writeCSV(test.toString());
    
    return Optional.of(list);
}

private void writeCSV(String list) {
    
     try (PrintWriter writer = new PrintWriter(new File("hadoopconnection_test.csv"))) {

          StringBuilder stringbuilder = new StringBuilder();

          stringbuilder.append("DMSid");
          stringbuilder.append(',');
          stringbuilder.append("Payload");
          stringbuilder.append('\n');
          stringbuilder.append(dmsid);
          stringbuilder.append(',');
          stringbuilder.append(list);
          stringbuilder.append('\n');

          writer.write(stringbuilder.toString());
        System.out.println("Data Imported to CSV successfully Done-------&gt;");

        } catch (FileNotFoundException exception) {
            
          System.out.println(exception.getMessage());

        }
    
}
}

可运行的Spring Boot集成HBase示例

1. 调整依赖(移除spring-data-hadoop,使用原生HBase客户端)

<!-- Spring Boot基础依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- HBase客户端 -->
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>2.5.2</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
        <!-- 排除冲突的Hadoop依赖 -->
        <exclusion>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 适配HBase版本的Hadoop common -->
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>3.3.4</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2. HBase配置类(Spring统一管理连接)

import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
public class HBaseConfig {

    @Value("${hbase.zookeeper.quorum}")
    private String zookeeperQuorum;

    @Value("${hbase.zookeeper.property.clientPort}")
    private String zookeeperPort;

    @Value("${zookeeper.znode.parent}")
    private String znodeParent;

    @Bean
    public org.apache.hadoop.conf.Configuration hbaseConfig() {
        org.apache.hadoop.conf.Configuration config = HBaseConfiguration.create();
        config.set("hbase.zookeeper.quorum", zookeeperQuorum);
        config.set("hbase.zookeeper.property.clientPort", zookeeperPort);
        config.set("zookeeper.znode.parent", znodeParent);
        return config;
    }

    @Bean(destroyMethod = "close")
    public Connection hbaseConnection() throws IOException {
        return ConnectionFactory.createConnection(hbaseConfig());
    }
}

3. 配置文件(application.yml)

hbase:
  zookeeper:
    quorum: PRODDMSDN04,proddmsdn02,proddmsdn01
    property:
      clientPort: 2181
znode:
  parent: /hbase-unsecure

4. HBase操作Service

import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class HBaseService {

    private final Connection hbaseConnection;
    private static final String TABLE_NAME = "DMSMASTER";
    private static final String FAMILY_DATA = "data";
    private static final String FAMILY_META = "meta";

    @Autowired
    public HBaseService(Connection hbaseConnection) {
        this.hbaseConnection = hbaseConnection;
    }

    public Optional<List<Map<String, String>>> searchMetaData(Map<String, String> searchParams) throws IOException {
        List<Map<String, String>> resultList = new ArrayList<>();

        try (Table table = hbaseConnection.getTable(TableName.valueOf(TABLE_NAME))) {
            Scan scan = new Scan();
            scan.addFamily(Bytes.toBytes(FAMILY_DATA));
            scan.addFamily(Bytes.toBytes(FAMILY_META));

            FilterList filterList = new FilterList();
            // 添加搜索参数过滤
            for (Map.Entry<String, String> entry : searchParams.entrySet()) {
                SingleColumnValueFilter filter = new SingleColumnValueFilter(
                        Bytes.toBytes(FAMILY_META),
                        Bytes.toBytes(entry.getKey()),
                        CompareFilter.CompareOp.EQUAL,
                        Bytes.toBytes(entry.getValue())
                );
                filterList.addFilter(filter);
            }
            // 添加状态过滤
            SingleColumnValueFilter statusFilter = new SingleColumnValueFilter(
                    Bytes.toBytes(FAMILY_DATA),
                    Bytes.toBytes("status"),
                    CompareFilter.CompareOp.EQUAL,
                    Bytes.toBytes("1")
            );
            filterList.addFilter(statusFilter);

            scan.setFilter(filterList);

            try (ResultScanner scanner = table.getScanner(scan)) {
                for (Result result : scanner) {
                    Map<String, String> rowMap = new HashMap<>();
                    // 读取data列族数据
                    result.getFamilyMap(Bytes.toBytes(FAMILY_DATA)).forEach((k, v) ->
                            rowMap.put(Bytes.toString(k), Bytes.toString(v))
                    );
                    // 读取meta列族数据
                    result.getFamilyMap(Bytes.toBytes(FAMILY_META)).forEach((k, v) ->
                            rowMap.put(Bytes.toString(k), Bytes.toString(v))
                    );
                    resultList.add(rowMap);
                }
            }
        }

        return resultList.isEmpty() ? Optional.empty() : Optional.of(resultList);
    }
}

5. 测试Controller

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
public class HBaseController {

    @Autowired
    private HBaseService hBaseService;

    @GetMapping("/search")
    public String searchMetaData(@RequestParam Map<String, String> searchParams) throws IOException {
        Optional<List<Map<String, String>>> result = hBaseService.searchMetaData(searchParams);
        return result.map(Object::toString).orElse("无匹配数据");
    }
}

关键优化说明

  1. 版本兼容:移除spring-data-hadoop,直接使用HBase 2.x原生客户端,彻底解决API不兼容问题。
  2. 连接管理:将HBase Connection配置为Spring Bean,由Spring负责生命周期管理,避免手动管理连接的线程安全问题。
  3. 资源安全:使用try-with-resources语法自动关闭Table、ResultScanner等资源,防止资源泄漏。
  4. 配置解耦:将HBase配置移至application.yml,便于不同环境切换配置。

内容的提问来源于stack exchange,提问作者Kalyani Mvn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:10:25