Ошибка 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, ...

Вы можете попытаться исправить это и посмотреть, что произойдет.

Другие вопросы по тегам