Ошибка 500 при попытке загрузить PDF в Mendeley с использованием Java - PullRequest
1 голос
/ 01 апреля 2019

Я пытаюсь написать код Java для загрузки статьи PDF в Mendeley, используя API документа, но получаю сообщение об ошибке 500.Я новичок в Java, так что я могу просто использовать неправильный код или библиотеки.В конечном счете, цель состоит в том, чтобы отправить статью PDF в Mendeley через API документа, чтобы я мог получить метаданные об этой статье.

Для справки, здесь приведен код скручивания, предоставленный в документах API Mendeley, которые я пытаюсьрепликация в Java:

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 Ответ

1 голос
/ 01 апреля 2019

Я инженер-программист, работающий в Mendeley с использованием Java, так что, надеюсь, я в состоянии ответить на этот вопрос.

Кроме того, в вашем первоначальном вопросе говорилось, что вы получаете 501 код ответа, однако после просмотра журналов Mendeley за последние 7 дней и отсутствия каких-либо кодов 501 ответа, а также после опробования введенного вами кода. Я предположил, что вы имели в виду, что вы получили 500 кодов ответов:)

Оказывается, здесь есть две ошибки. Первая ошибка в OpenJDK (см. https://bugs.openjdk.java.net/browse/JDK-8163921 и https://bugs.openjdk.java.net/browse/JDK-8177439) - по какой-то причине, если вы используете HttpUrlConnection, но не устанавливаете заголовок Accept, тогда заголовок Accept по умолчанию вставляется при отправке запроса.

К сожалению, указанный заголовок по умолчанию недействителен! Таким образом, вы должны были вернуть ошибку 400 (Bad Request). Чтобы обойти это, добавьте следующую строку кода, которая добавляет действительный заголовок Accept к вашему запросу, предотвращая тем самым вставку искаженного заголовка по умолчанию:

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

Теперь все должно работать так, как будто вы сделали запрос керли (или, по крайней мере, это заставило его работать у меня)!

Обратите внимание, что я упомянул, что должна быть возвращена ошибка 400 (вместе с полезным сообщением, которое помогло бы вам отладить то, что происходило неправильно). К сожалению, с нашей стороны была ошибка, которая означала, что при разборе искаженного заголовка Accept по умолчанию было создано исключение, которое не было обработано правильно. Поскольку мы не обработали исключение, используемая нами среда вернула 500 по умолчанию. Я собрал билет для этого, так что, надеюсь, это будет исправлено в будущем.

Наконец, способ отправки запросов (т. Е. С классом HttpUrlConnection), хотя он и работает, довольно низкоуровневый - это делает все немного сложнее для вас, чем должно быть. Я бы предложил использовать библиотеку, которая позволяет отправлять запросы, не беспокоясь о некоторых подробностях, например, Jetty HttpClient или Apache HttpComponents Library

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...