尝试使用Java将PDF上载到Mendeley时收到500错误

时间:2019-03-31 21:38:06

标签: java api pdf httpurlconnection mendeley

我正在尝试编写Java代码,以使用其文档API将文章PDF上传到Mendeley,但是我一直收到500错误。我是Java的新手,所以我可能只是使用了错误的代码或库。最终,目标是通过其文档API将文章PDF发送给Mendeley,以便我可以检索有关该文章的元数据。

作为参考,这是我试图在Java中复制的Mendeley API文档中提供的curl代码:

curl 'https://api.mendeley.com/documents' \
    -X POST \
    -H 'Authorization: Bearer ACCESS_TOKEN' \
    -H 'Content-Type: application/pdf' \
    -H 'Content-Disposition: attachment; filename="example.pdf"' \
    --data-binary @example.pdf   

我能够使用Python和请求库使其工作。当我使用错误的访问令牌时,我收到401错误,因此我知道API正在接收我的查询。返回的500错误不包含其他错误文本。

// setup connection
String url = "https://api.mendeley.com/documents";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);

// set headers
String ACCESS_TOKEN = getApiValue("api_token");        
con.setRequestProperty("Authorization", "Bearer " + ACCESS_TOKEN);
con.setRequestProperty("Content-Type", "application/pdf");
con.setRequestProperty("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

// send PDF
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
File pdfFile = new File(fileName);
byte[] buf = new byte[8192];
InputStream pdfIS = new FileInputStream(pdfFile);
int c = 0;

while ((c = pdfIS.read(buf, 0, buf.length)) > 0) {
    wr.write(buf, 0, c);
    wr.flush();
}

wr.close();
pdfIS.close();

// get results
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();

1 个答案:

答案 0 :(得分:1)

我是在Mendeley使用Java的软件工程师,所以希望我有能力回答这个问题。

顺便说一句,您最初的问题是您得到了501个响应代码-但是,在查看过去7天的Mendeley日志并没有看到任何501个响应代码之后,并尝试了已发布的代码,我认为您的意思是您有500个响应代码:)

事实证明这里有两个错误。第一个是OpenJDK中的错误(请参阅https://bugs.openjdk.java.net/browse/JDK-8163921https://bugs.openjdk.java.net/browse/JDK-8177439)–由于某种原因,如果您使用HttpUrlConnection但未设置Accept标头,则将插入“默认” Accept标头当您提出请求时。

很遗憾,提供的默认标题无效!因此,您应该已经返回了400错误(错误请求)。 要解决此问题,请添加以下代码行,该代码将有效的Accept标头添加到您的请求中,从而防止插入格式错误的默认标头:

con.setRequestProperty("Accept", "*/*");

现在一切都应该像您发出卷曲请求一样工作(或者至少使它对我有用)!

注意,我提到应该返回400错误(以及类似的有用信息,可以帮助您调试出了什么问题)。不幸的是,我们这边有一个错误,这意味着当解析格式错误的默认Accept标头时,会引发异常,无法正确处理。由于我们没有处理异常,因此默认情况下,我们使用的框架返回500。我为此在内部提出了罚单,因此希望将来能够解决。

最后,您发送请求的方式(即使用HttpUrlConnection类)虽然很有效,但它是底层的-这使您的工作比必须的复杂。我建议使用一个库,该库可以让您发送请求而不必担心一些细节问题,例如Jetty HttpClientApache HttpComponents library

希望对您有帮助!