Http接口获取数据写入Hdfs
数据源类型:数组列表
[{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的更多相关文章
- flink---实时项目--day02-----1. 解析参数工具类 2. Flink工具类封装 3. 日志采集架构图 4. 测流输出 5. 将kafka中数据写入HDFS 6 KafkaProducer的使用 7 练习
1. 解析参数工具类(ParameterTool) 该类提供了从不同数据源读取和解析程序参数的简单实用方法,其解析args时,只能支持单只参数. 用来解析main方法传入参数的工具类 public c ...
- 豆瓣爬虫——通过json接口获取数据
最近在复习resqusts 爬虫模块,就重新写了一个豆瓣爬虫,这个网页从HTML 源码上来看是没有任何我想要的信息的,如下图所示: 这是网页视图,我在源码中查找影片信息,没有任何信息,如图: 由此我判 ...
- Logstash读取Kafka数据写入HDFS详解
强大的功能,丰富的插件,让logstash在数据处理的行列中出类拔萃 通常日志数据除了要入ES提供实时展示和简单统计外,还需要写入大数据集群来提供更为深入的逻辑处理,前边几篇ELK的文章介绍过利用lo ...
- java接口对接——别人调用我们接口获取数据
java接口对接——别人调用我们接口获取数据,我们需要在我们系统中开发几个接口,给对方接口规范文档,包括访问我们的接口地址,以及入参名称和格式,还有我们的返回的状态的情况, 接口代码: package ...
- 从api接口获取数据-okhttp
首先先介绍下api接口: API:应用程序接口(API:Application Program Interface) 通常用于数据连接,调用函数提供功能等等... 从api接口获取数据有四种方式:Ht ...
- Java之通过接口获取数据并用JDBC存储到数据库中
最近做数据同步功能,从接口获取数据然后存到数据库中以便后续对数据进行相关操作,下面就贴一下相关代码. import com.alibaba.fastjson.JSON; import com.alib ...
- elasticsearch备份与恢复4_使用ES-Hadoop将ES中的索引数据写入HDFS中
背景知识见链接:elasticsearch备份与恢复3_使用ES-Hadoop将HDFS数据写入Elasticsearch中 项目参考<Elasticsearch集成Hadoop最佳实践> ...
- 调用REST接口获取数据
/// <summary> /// 根据机构代码本机构下报警用户列表: /// </summary> /// <param name="org_code&quo ...
- 例子:Vue 配合 vue-resource 从接口获取数据
vue-resource 是 vue 的一个与服务器端通信的 HTTP 插件,用来从服务器端请求数据. 结合例子——图片列表来写一下 Vue获取接口数据. html : <div id=&quo ...
随机推荐
- Linux中在防火墙中开启80端口的例子
最近自己在学习Linux.搭建一个LNMP环境.在测试时一切都好.然后重启Linux后.再次访问网站无法打开.最终原因是在防火墙中没有加入 80 端口的规则.具体方法如下: 在CentOS下配置ipt ...
- debian搭建本地镜像源
1. 安装apt-mirror apt-get install apt-mirror 2. 配置apt-mirror vim /etc/apt/mirror.list 2.1 下载目录什么的基础配置建 ...
- python标准库介绍——37 signal 模块详解
==signal 模块== 你可以使用 ``signal`` 模块配置你自己的信号处理器 (signal handler), 如 [Example 3-11 #eg-3-11] 所示. 当解释器收到某 ...
- Pipeline 与 xargs
Pipeline 与 xargs Pipeline与命令行參数 应用程序接收输入的两种方式: 命令行參数 输入字符串被当成參数,通过int main(int argc, char **argv), 中 ...
- 用bundler安装jeklly
为什么要写这篇文章呢?因为官方的安装文档里,ruby的很多库没有说明怎么安装.所以需要重点说明一下.1.我的安装环境是vultr的16.04版的ubuntu.2.因为ruby的扩展库好多都是Gcc编译 ...
- lame,把ios录音转换为mp3格式
在ios设备中进行录音,录音文件的格式为caf.但这种格式在很多设备中没法播放.为了适应终端的播放功能,特将caf转换为mp3格式文件来使用. 在录制caf文件时,需要使用双通道,否则在转换为MP3格 ...
- burpsuite扩展集成sqlmap插件
通常我们在使用sqlmap测试SQL注入问题的时候会先使用burpsuite来抓包,然后交给sqlmap进行扫描,此操作略显繁琐. 为了避免这种繁琐的重复操作可以将sqlmap以插件的方式集成到bur ...
- 【Android】OAuth验证和新浪微博的oauth实现
关于OAuth验证 OAuth是当下流行的授权方案,twitter,facebook,google等大型网站的开放平台都支持了oauth验证模式,国内的新浪微博.腾讯微博.163微博的开放平台也相继支 ...
- signal.h中的宏定义SIG_DFL及SIG_IGN
SIG_DFL,SIG_IGN 分别表示无返回值的函数指针,指针值分别是0和1,这两个指针值逻辑上讲是实际程序中不可能出现的函数地址值.SIG_DFL:默认信号处理程序SIG_IGN:忽略信号的处理程 ...
- 使用jquery提交FormData数据
https://blog.csdn.net/u011500781/article/details/54931716 http://yunzhu.iteye.com/blog/2177923 ***** ...