尝试使用 Java 将 PDF 上传到 Mendeley 时收到 500 错误
Receiving 500 error when trying to upload PDF to Mendeley using Java
我正在尝试编写 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();
我是一名在 Mendeley 工作的软件工程师,使用 Java,所以希望我 well-placed 能够回答这个问题。
顺便说一句,您最初的问题是您收到了 501 响应代码 - 但是,在查看过去 7 天的 Mendeley 日志后没有看到任何 501 响应代码,并且在尝试该代码之后您已经发布,我假设你的意思是你得到了 500 个响应代码:)
原来这里有两个错误。第一个是 OpenJDK 中的错误(请参阅 https://bugs.openjdk.java.net/browse/JDK-8163921 and https://bugs.openjdk.java.net/browse/JDK-8177439)- 出于某种原因,如果您使用 HttpUrlConnection 但未设置 Accept header,则 "default" Accept header 在您发出请求时插入。
很遗憾,默认提供的header无效!所以你应该已经返回了一个 400 错误(错误请求)。
要解决此问题,请添加以下代码行,它会向您的请求添加有效的 Accept header,从而防止插入格式错误的默认值 header:
con.setRequestProperty("Accept", "*/*");
现在一切都应该像您发出 curl 请求一样工作(或者至少,它对我有用)!
请注意,我提到应该返回 400 错误(以及有助于您调试问题所在的有用信息)。不幸的是,我们这边有一个错误,这意味着当解析格式错误的默认 Accept header 时,会抛出一个未正确处理的异常。由于我们没有处理异常,我们使用的框架默认返回 500。我已经为此在内部提出了一个问题,所以希望将来会得到解决。
最后,您发送请求的方式(即使用 HttpUrlConnection class)虽然有效,但相当 low-level - 这让您的事情比以前更复杂成为。我建议使用一个库,它允许您发送请求而不必担心某些 nitty-gritty 细节,例如 Jetty HttpClient or the Apache HttpComponents library
希望对您有所帮助!
我正在尝试编写 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();
我是一名在 Mendeley 工作的软件工程师,使用 Java,所以希望我 well-placed 能够回答这个问题。
顺便说一句,您最初的问题是您收到了 501 响应代码 - 但是,在查看过去 7 天的 Mendeley 日志后没有看到任何 501 响应代码,并且在尝试该代码之后您已经发布,我假设你的意思是你得到了 500 个响应代码:)
原来这里有两个错误。第一个是 OpenJDK 中的错误(请参阅 https://bugs.openjdk.java.net/browse/JDK-8163921 and https://bugs.openjdk.java.net/browse/JDK-8177439)- 出于某种原因,如果您使用 HttpUrlConnection 但未设置 Accept header,则 "default" Accept header 在您发出请求时插入。
很遗憾,默认提供的header无效!所以你应该已经返回了一个 400 错误(错误请求)。 要解决此问题,请添加以下代码行,它会向您的请求添加有效的 Accept header,从而防止插入格式错误的默认值 header:
con.setRequestProperty("Accept", "*/*");
现在一切都应该像您发出 curl 请求一样工作(或者至少,它对我有用)!
请注意,我提到应该返回 400 错误(以及有助于您调试问题所在的有用信息)。不幸的是,我们这边有一个错误,这意味着当解析格式错误的默认 Accept header 时,会抛出一个未正确处理的异常。由于我们没有处理异常,我们使用的框架默认返回 500。我已经为此在内部提出了一个问题,所以希望将来会得到解决。
最后,您发送请求的方式(即使用 HttpUrlConnection class)虽然有效,但相当 low-level - 这让您的事情比以前更复杂成为。我建议使用一个库,它允许您发送请求而不必担心某些 nitty-gritty 细节,例如 Jetty HttpClient or the Apache HttpComponents library
希望对您有所帮助!