通过Java客户端将文件上载到CKAN/datahub.io中的数据集
我正在测试通过API的Java客户端将文件上传到CKAN/datahub.io上的数据集通过Java客户端将文件上载到CKAN/datahub.io中的数据集,java,post,apache-commons-httpclient,ckan,Java,Post,Apache Commons Httpclient,Ckan,我正在测试通过API的Java客户端将文件上传到CKAN/datahub.io上的数据集 public String uploadFile() throws CKANException { String returned_json = this._connection.MultiPartPost("", ""); System.out.println("r: " + returned_json); return returned_json; } 及
public String uploadFile()
throws CKANException {
String returned_json = this._connection.MultiPartPost("", "");
System.out.println("r: " + returned_json);
return returned_json;
}
及
我对我的POST请求的2个回复:
- 当我尝试上载的jpeg为2.83 Mb时,出现413错误(“请求实体太大”)。当我将文件缩小到较小的大小时,这种情况就会消失。上传的文件大小有限制吗
- 500错误(“内部服务器错误”)。这就是我被困的地方。这可能与datahub.io上的数据集不是“已启用数据存储”有关?(我在数据集中看到我的资源文件旁边有一个禁用的“数据API”按钮,工具提示上写着: “由于数据存储已禁用,此资源的数据API不可用”
PS:我用于测试目的的数据集:只有能够访问异常日志的人才能告诉您发生500的原因 但是,我要检查您的请求是否与从数据存储旁编写的python客户端获得的请求相同:
您正在发送“bin”图像缓冲区和“comment”多部分请求中的文件密钥。请注意,每次上传都必须更改文件密钥,因此请添加时间戳或其他内容。也许您需要为二进制文件添加
内容类型:
。我遇到了与此问题海报相同的问题。经过多次尝试和错误,我想出了一个解决方案对问题的解释。在我的例子中,我对我想要上传到的CKAN存储库有一些控制权。如果你没有,你的问题可能无法解决
我假设您使用的是1.8版本的CKAN
首先,检查CKAN存储库是否已设置为允许文件上载,如果未设置,请将其配置为允许文件上载。这可以使用此处发布的步骤在服务器上完成:
您提到的413错误应该在下一步处理。这与服务器的一般配置有关。在我的例子中,CKAN是通过nginx托管的。我在nginx.conf文件中添加了一行“client_max_body_size 100M”。例如,请参阅本文:
然后只剩下500个错误。在撰写本文时,CKAN的api文档仍然有点不成熟…它确实说您必须构建一个请求,就像您对文件上载所做的那样。但是,此请求只是为了请求文件上载权限。如果您的凭据签出文件上载(并不是每个用户都可以上传文件),响应中包含一个对象,告诉您将文件发送到哪里…由于api不清楚,您最终合并了这两个请求
以下场景显示了处理文件上载的两个请求的后续操作。可能是场景中的某些步骤在您的情况下效果不同,因为存储库的设置稍有不同。如果收到错误消息,请确保检查响应的正文以获取线索
以下是我使用的身份验证请求:
String body = "";
String generatedFilename=null;
HttpClient httpclient = new DefaultHttpClient();
try {
// create new identifier for every file, use time
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyyMMMddHHmmss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String date=dateFormatGmt.format(new Date());
generatedFilename=date +"/"+filename;
HttpGet getRequest = new HttpGet(this.CKANrepos+ "/api/storage/auth/form/"+generatedFilename);
getRequest.setHeader(CKANapiHeader, this.CKANapi);
HttpResponse response = httpclient.execute(getRequest);
int statusCode = response.getStatusLine().getStatusCode();
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String line;
while ((line = br.readLine()) != null) {
body += line;
}
if(statusCode!=200){
throw new IllegalStateException("File reservation failed, server responded with code: "+statusCode+
"\n\nThe message was: "+body);
}
}finally {
httpclient.getConnectionManager().shutdown();
}
现在,如果一切顺利,服务器将使用一个json对象进行响应,该对象包含在执行实际文件上载时要使用的参数
{file_key:"some-filename-to-use-when-uploading"}
尽管如此,请务必检查json对象,因为我已经了解到,可能存在需要更多或不同参数的定制ckan存储库
这些响应可用于实际的文件上载:
File file = new File("/tmp/file.rdf");
String body = "";
HttpClient httpclient = new DefaultHttpClient();
try {
FileBody bin = new FileBody(file,"application/rdf+xml");
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("file", bin);
reqEntity.addPart("key", new StringBody(filename));
HttpPost postRequest = new HttpPost(this.CKANrepos+"/storage/upload_handle");
postRequest.setEntity(reqEntity);
postRequest.setHeader(CKANapiHeader, this.CKANapi);
HttpResponse response = httpclient.execute(postRequest);
int statusCode = response.getStatusLine().getStatusCode();
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String line;
while ((line = br.readLine()) != null) {
body += line;
}
if(statusCode!=200){
getWindow().showNotification("Upload Statuscode: "+statusCode,
body,
Window.Notification.TYPE_ERROR_MESSAGE);
}
}finally {
httpclient.getConnectionManager().shutdown();
}
如您所见,file_key属性现在已转换为简单的“key”属性。我不知道为什么
这将上载您的文件。对此上载请求的响应将包含一个json对象,告诉您文件上载到哪里。编辑:实际上,我的ckan似乎用一个简单的html页面响应,告诉我文件已上载……我必须解析页面以确认文件已正确上载:(
就我而言,文件在
this.CKANrepos +"/storage/f/"+location
其中location是在身份验证阶段返回的文件名
在前面的代码片段中:
//the location of your ckan repository, including /api and possibly version, e.g.
this.CKANrepos = "http://datahub.io/api/3/";
this.CKANapiHeader="X-CKAN-API-Key";
this.CKANapi = "your ckan api key here";
“数据API不可用”是一个红鲱鱼-指用于查询数据文件的API,该API与所需的blob存储分开。您是否尝试在本地运行CKAN实例并尝试将文件上载到该实例?这将确认您的问题是否特定于数据中心。它还将使您更好地查看CKAN日志。获取在本地工作,然后在数据库上尝试它只是为了记录,我仍然无法让它工作。如果来自CKAN社区的Java程序员阅读此文章,请联系!
//the location of your ckan repository, including /api and possibly version, e.g.
this.CKANrepos = "http://datahub.io/api/3/";
this.CKANapiHeader="X-CKAN-API-Key";
this.CKANapi = "your ckan api key here";