通过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; } 及

我正在测试通过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;
}

我对我的POST请求的2个回复:

  • 当我尝试上载的jpeg为2.83 Mb时,出现413错误(“请求实体太大”)。当我将文件缩小到较小的大小时,这种情况就会消失。上传的文件大小有限制吗

  • 500错误(“内部服务器错误”)。这就是我被困的地方。这可能与datahub.io上的数据集不是“已启用数据存储”有关?(我在数据集中看到我的资源文件旁边有一个禁用的“数据API”按钮,工具提示上写着: “由于数据存储已禁用,此资源的数据API不可用”

=>这可能是500错误的原因吗?如果是,我如何从客户端启用它?(指向Python代码的指针会很有用!)

Thx!

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";