Springboot 系列 (28) - Springboot+HBase 大数据存储(六)| Springboot 项目通过 RestTemplate 访问 HBase REST 服务
Apache HBase 是 Java 语言编写的一款 Apache 开源的 NoSQL 型数据库,不支持 SQL,不支持事务,不支持 Join 操作,没有表关系。Apache HBase 构建在 Apache Hadoop 和 Apache Zookeeper 之上。
Apache HBase: https://hbase.apache.org/
HBase 的安装配置,请参考 “Springboot 系列 (24) - Springboot+HBase 大数据存储(二)| 安装配置 Apache HBase 和 Apache Zookeeper”。
本文将创建一个 SpringBoot 项目,演示通过 RestTemplate 访问 “Springboot 系列 (27) - Springboot+HBase 大数据存储(五)| HBase REST 服务” 里通过 curl 命令测试过的 HBase REST 服务。
1. 系统环境
操作系统:Ubuntu 20.04
Hadoop 版本:3.2.2
Zookeeper 版本:3.6.3
HBase 版本:2.4.4
HBase 所在路径:~/apps/hbase-2.4.4/
本文使用的 HBase 部署在伪分布式 Hadoop 架构上(主机名:hadoop-master-vm),在 HBase + Zookeeper (独立的) 模式下运行,Zookeeper 使用端口 2182,HBase REST 服务使用端口 8888。
2. 创建 Spring Boot 基础项目
项目实例名称:SpringbootExample22
Spring Boot 版本:2.6.6
创建步骤:
(1) 创建 Maven 项目实例 SpringbootExample22;
(2) Spring Boot Web 配置;
(3) 导入 Thymeleaf 依赖包;
(4) 配置 jQuery;
具体操作请参考 “Springboot 系列 (2) - 在 Spring Boot 项目里使用 Thymeleaf、JQuery+Bootstrap 和国际化” 里的项目实例 SpringbootExample02,文末包含如何使用 spring-boot-maven-plugin 插件运行打包的内容。
SpringbootExample22 和 SpringbootExample02 相比,SpringbootExample22 不配置 Bootstrap、模版文件(templates/*.html)和国际化。
3. 配置 RestTemplate
RestTemplate 默认配置是使用了 JDK 自带的 HttpURLConnection 作为底层 HTTP 客户端实现。可以通过 setRequestFactory 属性来切换使用不同的 HTTP 库,如 Apache HttpComponents、OkHttp、Netty 等。
如何切换 RestTemplate 的底层库,可以参考 “Springboot 系列 (18) - 在 Spring Boot 项目里使用 RestTemplate 访问 REST 服务”。
1) 使用默认配置
创建 src/main/java/com/example/config/RestTemplateConfig.java 文件
package com.example.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @ConditionalOnMissingBean(RestTemplate.class) @Bean public RestTemplate restTemplate(){ RestTemplate restTemplate = new RestTemplate(); return restTemplate; } }
2) 修改 src/main/resources/application.properties 文件,内容如下
spring.main.banner-mode=off # Web server server.display-name=SpringbootExample22 server.address=localhost server.port=9090 # HBase Rest Server hbase.rest.url=http://hadoop-master-vm:8888
注:这里 hbase.rest.url 使用了 REST 服务器所在的主机名 hadoop-master-vm,可以替换成 REST 服务器所在主机的 IP 地址。
3) 运行
Edit Configurations
Click "+" add new configuration -> Select "Maven"
Command line: clean spring-boot:run
Name: SpringbootExample22 [clean,spring-boot:run]
-> Apply / OK
Click Run "SpringbootExample22 [clean,spring-boot:run]"
...
Spring boot example project
访问 http://localhost:9090/test
Test Page
注:打包可以将 Command line 改成 clean package spring-boot:repackage
4. 测试实例 (Web 模式)
创建的一个 demo 表,demo 表包含 cf1,cf2 两个列族 (Column Family) ,我们将向 demo 表添加如下数据:
id | name | age | job |
row1 | Tom | 12 | Student |
row2 | Jerry | 9 | Engineer |
row3 | Jerry | 10 | Engineer |
REST 接口在操作数据时,会对 key、column、value 等值进行 Base64 编解码,可以运行如下命令编解码:
$ echo -ne "Tom" | base64 # 编码
VG9t
$ echo -ne "VG9t" | base64 -d # 解码
Tom
注:echo 的 -n 表示不换行输出,-e 表示处理特殊字符。
以下是操作数据时使用到的 Base64 编码列表:
原值 | 编码后 |
cf1:name | Y2YxOm5hbWU= |
cf1:age | Y2YxOmFnZQ== |
cf2:job | Y2YyOmpvYg== |
row1 | cm93MQ== |
row2 | cm93Mg== |
row3 | cm93Mw== |
Tom | VG9t |
Jerry | SmVycnk= |
12 | MTI= |
9 | OQ== |
10 | MTA= |
Student | U3R1ZGVudA== |
Engineer | RW5naW5lZXI= |
1) 创建 src/main/resources/templates/client.html 文件
<html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title th:text="${var}">Client</title> <script language="javascript" th:src="@{/lib/jquery/jquery-3.6.0.min.js}"></script> </head> <body> <h4>HBase REST API - Client</h4> <p> </p> <p> <label><strong>REST API:</strong></label><br> <select id="otype" style="width: 50%;"> <option value=""></option> <option value="hbase_info">1. HBase 信息</option> <option value="table_operation">2. Table 操作</option> <option value="data_add">3. 添加数据</option> <option value="data_query_get">4. 查询数据 -> GET 操作</option> <option value="data_query_scanner">5. 查询数据 -> 无状态 Scanner</option> <option value="data_delete">6. 删除数据</option> <option value="namespace_operation">7. Namespace 操作</option> </select><br><br> <button type="button" id="btn_exec" class="btn btn-default btn-sm">Execute</button> </p> <p> </p> <div id="result_area" style="padding: 15px; width: 80%; font-size: 12px; min-height: 120px;"> </div> <script type="text/javascript"> $(document).ready(function() { $("#otype").change(function(e) { $('#result_area').html(""); }); $("#btn_exec").click(function(e) { var otype = $("#otype").val(); if (otype == '') { alert("Please select REST API"); $("#otype").focus(); return; } var url = ""; switch(otype) { case "hbase_info": url = "/hbase" break; case "table_operation": url = "/table" break; case "data_add": url = "/data/add" break; case "data_query_get": url = "/data/query/get" break; case "data_query_scanner": url = "/data/query/scanner" break; case "data_delete": url = "/data/delete" break; case "namespace_operation": url = "/namespace" break; default: break; } $('#result_area').append("Executing ...<br><br>"); $('#btn_exec').prop('disabled', true); $.ajax({ type: 'GET', url: url, timeout: 10000, success: function(response) { //console.log(response); $('#result_area').append(response + "<br>"); //$('#result_area').append(JSON.stringify(response + "<br>")); $('#btn_exec').prop('disabled', false); }, error: function(err) { console.log(err); $('#result_area').append('AJAX Error: ' + err.statusText + " " + err.status); $('#btn_exec').prop('disabled', false); } }); }); }); </script> </body> </html>
2) 修改 src/main/java/com/example/controller/IndexController.java 文件
package com.example.controller; import java.util.ArrayList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.stereotype.Controller; //import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; @Controller public class IndexController { @Autowired private RestTemplate restTemplate; @Value("${hbase.rest.url}") private String hbaseRestUrl; @ResponseBody @RequestMapping("/test") public String test() { return "Test Page"; } @RequestMapping("/client") public String client() { return "client"; } @ResponseBody @RequestMapping("/hbase") public String hbase() { // 显示 HBase 版本 String url = hbaseRestUrl + "/version/cluster"; System.out.println("url = " + url); ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class); String str = "显示 HBase 版本 -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 显示 HBase 群集状态 url = hbaseRestUrl + "/status/cluster"; responseEntity = restTemplate.getForEntity(url, String.class); str += "显示 HBase 群集状态 -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br>"; return str; } @ResponseBody @RequestMapping("/table") public String table() { // 头部信息 //MultiValueMap<String, String> headers = new LinkedMultiValueMap<>(); //headers.add("Accept", "application/json"); //headers.add("Content-Type", "application/json"); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); ArrayList<MediaType> acceptList = new ArrayList<>(); acceptList.add(MediaType.APPLICATION_JSON); httpHeaders.setAccept(acceptList); // 参数信息 //MultiValueMap<String, String> mapParams = new LinkedMultiValueMap<>(); //HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(mapParams, headers); // 查看所有表 HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(null, httpHeaders); ResponseEntity<String> responseEntity = restTemplate.exchange(hbaseRestUrl, HttpMethod.GET, httpEntity, String.class); String str = "查看所有表 -> " + hbaseRestUrl + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 创建 demo 表 (1 个列族 cf1) String url = hbaseRestUrl + "/demo/schema"; String jsonParams = "{\"name\":\"demo\",\"ColumnSchema\":[{\"name\":\"cf1\"}]}"; HttpEntity<String> httpEntity2 = new HttpEntity<>(jsonParams, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.PUT, httpEntity2, String.class); str += "创建 demo 表 (1 个列族 cf1) -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 添加 2 个列族 cf2 和 cf3 jsonParams = "{\"name\":\"demo\",\"ColumnSchema\":[{\"name\":\"cf2\"},{\"name\":\"cf3\"}]}"; HttpEntity<String> httpEntity3 = new HttpEntity<>(jsonParams, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity3, String.class); str += "添加 2 个列族 cf2 和 cf3 -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 删除 cf3 列族,不是使用 POST,应该使用 PUT 替换表结构 jsonParams = "{\"name\":\"demo\",\"ColumnSchema\":[{\"name\":\"cf1\"},{\"name\":\"cf2\"}]}"; HttpEntity<String> httpEntity4 = new HttpEntity<>(jsonParams, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.PUT, httpEntity4, String.class); str += "删除 cf3 列族 -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 修改 cf1 列族的 VERSIONS 为 2,默认是 1 (即只保留最后一个版本) jsonParams = "{\"name\":\"demo\",\"ColumnSchema\":[{\"name\":\"cf1\",\"VERSIONS\":\"2\"}]}"; HttpEntity<String> httpEntity5 = new HttpEntity<>(jsonParams, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity5, String.class); str += "修改 cf1 列族的 VERSIONS 为 2,默认是 1 (即只保留最后一个版本) -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 显示 demo 表结构信息 responseEntity = restTemplate.getForEntity(url, String.class); str += "显示 demo 表结构信息 -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 显示 demo 表分区 String url2 = hbaseRestUrl + "/demo/regions"; responseEntity = restTemplate.getForEntity(url2, String.class); str += "显示 demo 表分区 -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; return str; } @ResponseBody @RequestMapping("/data/add") public String dataAdd() { // 查看 demo 表是否存在 String url = hbaseRestUrl + "/demo/exists"; String str = "查看 demo 表是否存在 -> " + url + "<br>"; try { ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class); str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; } catch (Exception e) { str += "Error: " + e.getMessage(); return str; } // 头部信息 HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); ArrayList<MediaType> acceptList = new ArrayList<>(); acceptList.add(MediaType.APPLICATION_JSON); httpHeaders.setAccept(acceptList); // 添加 row1 的 name、age 数据 url = hbaseRestUrl + "/demo/row1"; String jsonParams = "{\"Row\":[{\"key\":\"cm93MQ==\",\"Cell\":[{\"column\":\"Y2YxOm5hbWU=\",\"$\":\"VG9t\"},{\"column\":\"Y2YxOmFnZQ==\",\"$\":\"MTI=\"}]}]}"; HttpEntity<String> httpEntity = new HttpEntity<>(jsonParams, httpHeaders); ResponseEntity<String> responseEntity2 = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, String.class); str += "添加 row1 的 name、age 数据 -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 添加 row1 的 job 数据 jsonParams = "{\"Row\":[{\"key\":\"cm93MQ==\",\"Cell\":[{\"column\":\"Y2YyOmpvYg==\",\"$\":\"U3R1ZGVudA==\"}]}]}"; httpEntity = new HttpEntity<>(jsonParams, httpHeaders); responseEntity2 = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, String.class); str += "添加 row1 的 job 数据 -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 添加 row2 的 name、age 和 job 数据 url = hbaseRestUrl + "/demo/row2"; jsonParams = "{\"Row\":[{\"key\":\"cm93Mg==\",\"Cell\":[{\"column\":\"Y2YxOm5hbWU=\",\"$\":\"SmVycnk=\"},{\"column\":\"Y2YxOmFnZQ==\",\"$\":\"OQ==\"},{\"column\":\"Y2YyOmpvYg==\",\"$\":\"RW5naW5lZXI=\"}]}]}"; httpEntity = new HttpEntity<>(jsonParams, httpHeaders); responseEntity2 = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, String.class); str += "添加 row2 的 name、age 和 job 数据 -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 再次添加 row2 的 age 数据, 值为 10 (Cell 支持 2 个版本,这里不会替换原版本 9,以时间戳为区分,生成一个新版本) jsonParams = "{\"Row\":[{\"key\":\"cm93Mg==\",\"Cell\":[{\"column\":\"Y2YxOmFnZQ==\",\"$\":\"MTA=\"}]}]}"; httpEntity = new HttpEntity<>(jsonParams, httpHeaders); responseEntity2 = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, String.class); str += "再次添加 row2 的 age 数据, 值为 10 -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 添加 row3 的 name、age 和 job 数据 url = hbaseRestUrl + "/demo/row3"; jsonParams = "{\"Row\":[{\"key\":\"cm93Mw==\",\"Cell\":[{\"column\":\"Y2YxOm5hbWU=\",\"$\":\"SmVycnk=\"},{\"column\":\"Y2YxOmFnZQ==\",\"$\":\"MTA=\"},{\"column\":\"Y2YyOmpvYg==\",\"$\":\"RW5naW5lZXI=\"}]}]}"; httpEntity = new HttpEntity<>(jsonParams, httpHeaders); responseEntity2 = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, String.class); str += "添加 row3 的 name、age 和 job 数据 -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 查看 row3 数据 httpEntity = new HttpEntity<>(null, httpHeaders); responseEntity2 = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class); str += "查看 row3 数据 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; return str; } @ResponseBody @RequestMapping("/data/query/get") public String dataQueryGet() { // 查看 demo 表是否存在 String url = hbaseRestUrl + "/demo/exists"; String str = "查看 demo 表是否存在 -> " + url + "<br>"; try { ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class); str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; } catch (Exception e) { str += "Error: " + e.getMessage(); return str; } // 获取 row2 的全部数据 url = hbaseRestUrl + "/demo/row2"; ResponseEntity<String> responseEntity2 = restTemplate.getForEntity(url, String.class); str += "获取 row2 的全部数据 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 获取 row2 的 cf1 列族的全部数据 url = hbaseRestUrl + "/demo/row2/cf1"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "获取 row2 的 cf1 列族的全部数据 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 获取 row2 的 cf1 列族的 age 数据 url = hbaseRestUrl + "/demo/row2/cf1:age"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "获取 row2 的 cf1 列族的 age 数据 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 获取 row2 的 age、job 数据 (多列) url = hbaseRestUrl + "/demo/row2/cf1:age,cf2:job"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "获取 row2 的 age、job 数据 (多列) -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 获取 row2 的 age 数据的最新 2 个版本 url = hbaseRestUrl + "/demo/row2/cf1:age?v=2"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "获取 row2 的 age 数据的最新 2 个版本 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; return str; } @ResponseBody @RequestMapping("/data/query/scanner") public String dataQueryScanner() { // 查看 demo 表是否存在 String url = hbaseRestUrl + "/demo/exists"; String str = "查看 demo 表是否存在 -> " + url + "<br>"; try { ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class); str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; } catch (Exception e) { str += "Error: " + e.getMessage(); return str; } // 扫描整个 demo 表 url = hbaseRestUrl + "/demo/*"; ResponseEntity<String> responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描整个 demo 表 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 扫描 cf2 列簇 url = hbaseRestUrl + "/demo/*/cf2"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描 cf2 列簇 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 扫描 cf1 和 cf2 列簇 url = hbaseRestUrl + "/demo/*/cf1,cf2"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描 cf1 和 cf2 列簇 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 扫描 cf1 列簇的 age,显示最后两个版本 url = hbaseRestUrl + "/demo/*/cf1:age?v=2"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描 cf1 列簇的 age,显示最后两个版本 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 扫描整个 demo 表,限定返回行数 url = hbaseRestUrl + "/demo/*?limit=1"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描整个 demo 表,限定返回行数 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 扫描整个 demo 表,从指定行(包括该行)开始向后扫描 url = hbaseRestUrl + "/demo/*?startrow=row2"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描整个 demo 表,从指定行(包括该行)开始向后扫描 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 扫描整个 demo 表,扫描到指定行(不包括该行) url = hbaseRestUrl + "/demo/*?endrow=row2"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描整个 demo 表,扫描到指定行(不包括该行) -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 扫描整个 demo 表,复合条件 url = hbaseRestUrl + "/demo/*/cf1:age?v=2&limit=1&startrow=row2"; responseEntity2 = restTemplate.getForEntity(url, String.class); str += "扫描整个 demo 表,复合条件 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; return str; } @ResponseBody @RequestMapping("/data/delete") public String dataDelete() { // 查看 demo 表是否存在 String url = hbaseRestUrl + "/demo/exists"; String str = "查看 demo 表是否存在 -> " + url + "<br>"; try { ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class); str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; } catch (Exception e) { str += "Error: " + e.getMessage(); return str; } // 头部信息 HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); ArrayList<MediaType> acceptList = new ArrayList<>(); acceptList.add(MediaType.APPLICATION_JSON); httpHeaders.setAccept(acceptList); // 删除 row3 的 cf2 列族的 job 数据 url = hbaseRestUrl + "/demo/row3/cf2:job/?check=delete"; HttpEntity<String> httpEntity = new HttpEntity<>(null, httpHeaders); ResponseEntity<String> responseEntity2 = restTemplate.exchange(url, HttpMethod.DELETE, httpEntity, String.class); str += "删除 row3 的 cf2 列族的 job 数据 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 删除 row3 整行数据 url = hbaseRestUrl + "/demo/row3/?check=delete"; httpEntity = new HttpEntity<>(null, httpHeaders); responseEntity2 = restTemplate.exchange(url, HttpMethod.DELETE, httpEntity, String.class); str += "删除 row3 整行数据 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; // 删除 demo 表 url = hbaseRestUrl + "/demo/schema"; httpEntity = new HttpEntity<>(null, httpHeaders); responseEntity2 = restTemplate.exchange(url, HttpMethod.DELETE, httpEntity, String.class); str += "删除 demo 表 -> " + url + "<br>"; str += "Status Code: " + responseEntity2.getStatusCode() + "<br>"; str += "Result: " + responseEntity2.getBody() + "<br><br>"; return str; } @ResponseBody @RequestMapping("/namespace") public String namespace() { // 头部信息 HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); ArrayList<MediaType> acceptList = new ArrayList<>(); acceptList.add(MediaType.APPLICATION_JSON); httpHeaders.setAccept(acceptList); // 查看所有 Namespace String url = hbaseRestUrl + "/namespaces"; HttpEntity<String> httpEntity = new HttpEntity<>(null, httpHeaders); ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class); String str = "查看所有 Namespace -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 创建 'ns_test' Namespace url = hbaseRestUrl + "/namespaces/ns_test"; httpEntity = new HttpEntity<>(null, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class); str += "创建 'ns_test' Namespace -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 在 ns_test 下创建 tbl_01 表 (1 个列族 cf1) url = hbaseRestUrl + "/ns_test:tbl_01/schema"; String jsonParams = "{\"name\":\"ns_test:tbl_01\",\"ColumnSchema\":[{\"name\":\"cf1\"}]}"; httpEntity = new HttpEntity<>(jsonParams, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, String.class); str += "在 ns_test 下创建 tbl_01 表 (1 个列族 cf1) -> " + url + "<br>"; str += "Request Entity: " + jsonParams + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 查看 ns_test 下的表 url = hbaseRestUrl + "/namespaces/ns_test/tables"; httpEntity = new HttpEntity<>(null, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class); str += "查看 ns_test 下的表 -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 删除 ns_test 下的 tbl_01 表 url = hbaseRestUrl + "/ns_test:tbl_01/schema"; httpEntity = new HttpEntity<>(null, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.DELETE, httpEntity, String.class); str += "删除 ns_test 下的 tbl_01 表 -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; // 删除 ns_test url = hbaseRestUrl + "/namespaces/ns_test"; httpEntity = new HttpEntity<>(null, httpHeaders); responseEntity = restTemplate.exchange(url, HttpMethod.DELETE, httpEntity, String.class); str += "删除 ns_test -> " + url + "<br>"; str += "Status Code: " + responseEntity.getStatusCode() + "<br>"; str += "Result: " + responseEntity.getBody() + "<br><br>"; return str; } }
3) 测试页面
运行 SpringbootExample22,访问 http://localhost:9090/client。