数据源类型:数组列表

[{field:value}, {field:value}, {field:value}, {field:value}]

1. 定义http数据源链接

package com.etl.datalink;

import java.util.Map;

public class LinkHttp {

        private String url;
private Map<String,Object> params; public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, Object> getParams() {
return params;
}
public void setParams(Map<String, Object> params) {
this.params = params;
} }

2. 定义hdfs链接配置

package com.etl.datalink;

import org.apache.hadoop.conf.Configuration;

public class LinkHdfs {

        private Configuration conf = new Configuration();
private String fsName="fs.defaultFS";
private String fsURI; public LinkHdfs(String fsName, String fsURI) {
this.fsName = fsName;
this.fsURI = fsURI;
conf.set(this.fsName, this.fsURI);
} public LinkHdfs(String fsURI) {
this.fsURI = fsURI;
conf.set(this.fsName, this.fsURI);
} public String getFsName() {
return fsName;
} public void setFsName(String fsName) {
this.fsName = fsName;
} public String getFsURI() {
return fsURI;
} public void setFsURI(String fsURI) {
this.fsURI = fsURI;
} public Configuration getConf() {
return conf;
} public void setConf(Configuration conf) {
this.conf = conf;
} }

3. 定义泛型类用于传送http的内容到hdfs

这里存在一点小问题:由于json是数组列表,所以需要获取每条记录,然后加入换行符号\n写入hdfs。这样在hive中查询才能获取到多个记录。否则会全部当作一条记录。

/**
* 通用的http抽取数据到hdfs文件中
* @author KingWang
* @date 2018-10-15
* @description
*/
public class Api2Hdfs{ private static Logger log = Logger.getLogger(Api2Hdfs.class); public static <T> void run(String[] args, Class<T> clazz) { //http
String url = args[0];
String method = args[1];
String startTime = args[2];
String endTime = args[3]; //hdfs
String fsName = args[4];
String fsURI = args[5];
String targetFilePath = args[6];
//http config
Map<String,Object> params = new HashMap<String,Object>(); //....省略部分参数
params.put("timestamp", System.currentTimeMillis()/1000L);
params.put("start_time", startTime);
params.put("end_time", endTime); LinkHttp http = new LinkHttp();
http.setUrl(url);
http.setParams(params); //hdfs config
LinkHdfs hdfs = new LinkHdfs(fsName, fsURI);
try {
Api2Hdfs.process(http, hdfs, targetFilePath, clazz);
} catch(Exception e) {
e.printStackTrace();
}
} private static <T> void process(LinkHttp http,LinkHdfs hdfs, String hdfsFile, Class<T> clazz) throws Exception{ if(null==http) {
log.error("请求参数http未设置");
throw new Exception("请求参数http未设置");
}
if(null==hdfs) {
log.error("请求参数hdfs未设置");
throw new Exception("请求参数hdfs未设置");
} //创建http请求
String url = http.getUrl();
Map<String,Object> params = http.getParams();
OkHttpClient client = new OkHttpClient(); //添加参数
FormBody.Builder bodyParams=new FormBody.Builder();
if(params!=null && params.size() > 0) {
Iterator<Map.Entry<String,Object>> it = params.entrySet().iterator();
while(it.hasNext()) {
Map.Entry<String, Object> entry = it.next();
bodyParams.add(entry.getKey(), entry.getValue().toString());
}
} final Request request = new Request.Builder().url(url).post(bodyParams.build()).build();
Call call = client.newCall(request);
call.enqueue(new Callback() { //网络错误延迟处理
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
log.error(e.getMessage());
} @Override
public void onResponse(Call call, Response response) throws IOException {
FileSystem fs = null;
try { Path dstPath = new Path(hdfsFile);
fs = FileSystem.get(hdfs.getConf());
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
if(response.isSuccessful()) { //对后台返回的数据进行处理
System.out.println(df.format(LocalDateTime.now()) +" response.code:" +response.code());
if (200 == response.code()) { //注意:response.body().string()只能有效调用一次
ResponseInfo info = JSONObject.parseObject(response.body().string(), ResponseInfo.class); //error不为空,则错误
if(StringUtils.isNotBlank(info.getError())) {
log.error(info.getError());
} else { String rspcode = info.getResult().getRsp();
//写入hdfs
if(rspcode.equalsIgnoreCase(ResultCode.SUCCESS.getCode())) {
System.out.println(info.getResult().getData());
if(info.getResult().getData().equals("[]")) {
System.out.println(df.format(LocalDateTime.now()) + " " + info.getResult().getMsg());
} else {
List<T> objList = JSON.parseArray(info.getResult().getData(),clazz);
// byte[] bt = info.getResult().getData().getBytes();
FSDataOutputStream outputStream = fs.create(dstPath);
int size = objList.size();
for(int i=0;i<size; i++) {
String orderstr = JSON.toJSONString(objList.get(i)) + '\n';
System.out.println(orderstr);
outputStream.write(orderstr.getBytes());
if(i % 1000==0) {
outputStream.flush();
}
}
outputStream.flush();
outputStream.close();
log.info("create file " + hdfsFile + " success!");
}
} else {
log.error(info.getResult().getMsg());
}
}
}
//对后台返回200~300之间的错误进行处理
else {
log.error(response.message());
} //fs.close();
}
}catch (Exception e){
e.printStackTrace();
log.error(e.getMessage());
}finally {
fs.close();
//关闭
if(response.body()!=null) {
response.body().close();
}
}
log.info("write hdfs file end: " + hdfsFile);
}
}); } }

4. 定义bean用于解析, 由于定义了泛型,可以针对不同到接口定义不同的bean。

类似如下

5. 定义执行的每个接口主类:

public class MemberApi extends Api2Hdfs{

        public static void main(String[] args) {
Api2Hdfs.run(args, Member.class);
}
}
public class OrderApi extends Api2Hdfs{

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

6. 定义每个接口的shell脚本,执行即可。

java -Djava.ext.dirs=lib com.etl.MemberApi \
${url} ${method} ${startDate} ${endDate} ${fsName} ${fsURI} ${targetFilePath} ${salt} >> ./logs/${table}.log >& &
java -Djava.ext.dirs=lib com.etl.OrderApi \
${url} ${method} ${startDate} ${endDate} ${fsName} ${fsURI} ${targetFilePath} ${salt} >> ./logs/${table}.log >& &

Http接口获取数据写入Hdfs的更多相关文章

  1. flink---实时项目--day02-----1. 解析参数工具类 2. Flink工具类封装 3. 日志采集架构图 4. 测流输出 5. 将kafka中数据写入HDFS 6 KafkaProducer的使用 7 练习

    1. 解析参数工具类(ParameterTool) 该类提供了从不同数据源读取和解析程序参数的简单实用方法,其解析args时,只能支持单只参数. 用来解析main方法传入参数的工具类 public c ...

  2. 豆瓣爬虫——通过json接口获取数据

    最近在复习resqusts 爬虫模块,就重新写了一个豆瓣爬虫,这个网页从HTML 源码上来看是没有任何我想要的信息的,如下图所示: 这是网页视图,我在源码中查找影片信息,没有任何信息,如图: 由此我判 ...

  3. Logstash读取Kafka数据写入HDFS详解

    强大的功能,丰富的插件,让logstash在数据处理的行列中出类拔萃 通常日志数据除了要入ES提供实时展示和简单统计外,还需要写入大数据集群来提供更为深入的逻辑处理,前边几篇ELK的文章介绍过利用lo ...

  4. java接口对接——别人调用我们接口获取数据

    java接口对接——别人调用我们接口获取数据,我们需要在我们系统中开发几个接口,给对方接口规范文档,包括访问我们的接口地址,以及入参名称和格式,还有我们的返回的状态的情况, 接口代码: package ...

  5. 从api接口获取数据-okhttp

    首先先介绍下api接口: API:应用程序接口(API:Application Program Interface) 通常用于数据连接,调用函数提供功能等等... 从api接口获取数据有四种方式:Ht ...

  6. Java之通过接口获取数据并用JDBC存储到数据库中

    最近做数据同步功能,从接口获取数据然后存到数据库中以便后续对数据进行相关操作,下面就贴一下相关代码. import com.alibaba.fastjson.JSON; import com.alib ...

  7. elasticsearch备份与恢复4_使用ES-Hadoop将ES中的索引数据写入HDFS中

    背景知识见链接:elasticsearch备份与恢复3_使用ES-Hadoop将HDFS数据写入Elasticsearch中 项目参考<Elasticsearch集成Hadoop最佳实践> ...

  8. 调用REST接口获取数据

    /// <summary> /// 根据机构代码本机构下报警用户列表: /// </summary> /// <param name="org_code&quo ...

  9. 例子:Vue 配合 vue-resource 从接口获取数据

    vue-resource 是 vue 的一个与服务器端通信的 HTTP 插件,用来从服务器端请求数据. 结合例子——图片列表来写一下 Vue获取接口数据. html : <div id=&quo ...

随机推荐

  1. ADO.NET事务

    在发布System.Transaction命名空间之前,可以直接用ADO.NET创建事务,也可以通过组件.特性和COM+运行库(位于System.EnterpriseServices命名空间中)进行事 ...

  2. databus编译:Could not resolve all dependencies for configuration ':databus2-relay:databus2-event-producer-mock:compile

    FAILURE: Build failed with an exception. * What went wrong: Could not resolve all dependencies for c ...

  3. 用Entityframework 调用Mysql时,datetime格式插入不进去数据库的解决办法。

    1. 打开Model.edmx, 2. 选择userinfo中的createtime字段的属性 3. storegeneratedpattern设置值为None

  4. JavaScript权威指南第02章 词法结构

    词法结构 2.1字符集 JavaScript 是Unicode字符集编写,差点儿支持地球上全部的语言. 2.1.1区分大写和小写 javascript是区分大写和小写的语言. 2.1.2 空格.换行符 ...

  5. Atitit opencv3.0  3.1 3.2 新特性attilax总结

    Atitit opencv3.0  3.1 3.2 新特性attilax总结 1. 3.0OpenCV 3 的改动在哪?1 1.1. 模块构成该看哪些模块?2 2. 3.1新特性 2015-12-21 ...

  6. iPhone-获取网络数据或者路径的文件名

    Phone中,在网络中的数据流中提取链接中的文件名称时,有很多方法,这里总结一些. 方法一:最直接. 1     NSString * urlString = @"http://www.ba ...

  7. sql索引唯一

    alter table et_tb_1111 add constraint tbunique unique (itemid) alter table 表名 add constraint 约束名 uni ...

  8. 【Unity】第5章 3D坐标系和天空盒

    分类:Unity.C#.VS2015 创建日期:2016-04-20 一.简介 这一张主要介绍3D坐标系的基础知识以及各种形状的天空盒. 二.示例 本章的示例都在ch05Demos工程下.

  9. 【iOS XMPP】使用XMPPFramewok(二):用户登录

    转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/10/3069397.html 用户登录 准备工作 比较知名的开源XMPP服务器:一个是Ope ...

  10. lua -- 商店控制器部分

    -- 创建商店类,继承了Behavior local UIShopController = class("UIShopController", Behavior); -- 包含并引 ...