Ошибка 302 при попытке опубликовать тему D2L, используя multipart
Эта проблема связана с той, которую я опубликовал вчера, но я обнаружил немного больше и теперь получаю другую ошибку. Я удалил код из Android, чтобы попробовать прямо из Java. Я также попробовал 2 разных способа для получения многопостовой информации. UserContext имеет разрешение на запись, так как я могу легко создавать модули.
Один способ, которым я пытался:
String json = "{\"IsHidden\": false, \"IsLocked\": false, \"ShortTitle\": "Test\", \"Type\": 1, \r\n" + "\"DueDate\": null, \"Url\": \"file.txt\", \r\n" + "\"StartDate\": null, \"TopicType\": 1, \"EndDate\": null, \"Title\": \"Test topic \r\n" + "content\"} \r\n";
URI uri = userContext.createAuthenticatedUri("/d2l/api/le/1.0/Orgid/content/modules/moduleid/structure/", "POST");
MultipartEntity entity = new MultipartEntity();
StringBody part1 = new StringBody(json, "application/json", null);
entity.addPart("json", part1);
File file = new File("test.txt");
FileBody part2 = new FileBody(file, "test.txt", "text/plain", null);
entity.addPart("file", part2);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost(uri);
post.setEntity(entity);
HttpResponse response = httpClient.execute(post);
System.out.println("Statusline: " + response.getStatusLine());
Вот другой способ, которым я пытался:
String body = "--xxBOUNDARYxx \r\n" +
"Content-Type: application/json \r\n" +
"{\"IsHidden\": false, \"IsLocked\": false, \"ShortTitle\": \"Test\", \"Type\": 1, \r\n" +
"\"DueDate\": null, \"Url\": \"file.txt\", \r\n" +
"\"StartDate\": null, \"TopicType\": 1, \"EndDate\": null, \"Title\": \"Test topic \r\n" +
"content\"} \r\n" +
"--xxBOUNDARYxx \r\n" +
"Content-Disposition: form-data; name=\"\"; filename=\"file.txt\" \r\n" +
"Content-Type: text/plain \r\n" +
" This is a sample text file \r\n" +
"with some text content. \r\n" +
"--xxBOUNDARYxx--";
URI uri = userContext.createAuthenticatedUri("/d2l/api/le/1.0/orgid/content/modules/moduleid/structure/", "POST");
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost(uri);
post.addHeader("Content-Type", "multipart/mixed;boundary=xxBOUNDARYxx");
post.setEntity(new StringEntity(body));
HttpResponse response = httpClient.execute(post);
System.out.println("Statusline: " + response.getStatusLine());
Оба эти метода дали один и тот же результат:
Statusline: HTTP/1.1 302 Found
Response: <html><head><title>Object moved</title></head><body><h2>Object moved to <a href="/d2l/error/404">here</a>.</h2></body></html>
ИМХО оба метода должны создавать структуры, как описано здесь, поэтому я действительно застрял. Я также пытался поставить полный /content/enforced/.../file.txt
для URL с тем же результатом.
1 ответ
Перенаправление 302 - это действительно перенаправление на страницу ошибки 404. Я подозреваю, что, поскольку вы получаете перенаправление 302 на системную страницу "Ошибка 404", перенаправление происходит на уровне обработки маршрута: возможно получить 404 из глубины стека, но тогда вы просто получите прямой ответ 404 на ваш запрос. Таким образом, наиболее вероятные причины состоят в том, что стек приложений D2L не может правильно связать ваш URL (плюс несколько параметров) с обработчиком маршрута - то есть он не может токенизировать ваш запрос, чтобы узнать, какой бит кода контроллера нужно передать запрос.
Я полагаю, что когда вы пишете
userContext.createAuthenticatedUri("/d2l/api/le/1.0/Orgid/content/modules/moduleid/structure/", "POST")
вы на самом деле положить в реальный Orgid
а также moduleid
значения в этом маршруте? Поскольку записанная строка определенно вернет 404 - такого маршрута нет - и фактически она, скорее всего, перенаправит на страницу ошибки системы 404 именно так, как вы описали.
Обратите внимание, что когда вы пишете
...
"Content-Type: application/json \r\n" +
"{\"IsHidden\": false, \"IsLocked\": false, \"ShortTitle\": \"Test\", \"Type\": 1, \r\n" +
...
Я не уверен, что это сработает. Я считаю, что соответствующие стандарты для составных частей HTTP указывают, что вы должны пометить отделение заголовка части от полезной нагрузки данных детали пустой строкой, и здесь вы только инертируете один возврат каретки. Ваш пакет будет выглядеть так:
Content-Type: application/json
{"IsHidden": false, "IsLocked": false, ...
Когда это должно выглядеть примерно так:
Content-Type: application/json
{"IsHidden": false, "IsLocked": false, ...
Вы можете попытаться исправить это и посмотреть, что произойдет.