Http 尝试使用多部分发布D2L主题时出现错误302

Http 尝试使用多部分发布D2L主题时出现错误302,http,rest,multipart,desire2learn,valence,Http,Rest,Multipart,Desire2learn,Valence,这个问题是与相关的,但我发现了更多,现在得到了一个不同的错误。我从Android中删除了代码,直接从Java中尝试。我还尝试了两种不同的方法来获取多极信息。userContext具有写入权限,因为我可以轻松创建模块 我试过的一种方法是: String json = "{\"IsHidden\": false, \"IsLocked\": false, \"ShortTitle\": "Test\", \"Type\": 1, \r\n" + "\"DueDate\": null, \"Url

这个问题是与相关的,但我发现了更多,现在得到了一个不同的错误。我从Android中删除了代码,直接从Java中尝试。我还尝试了两种不同的方法来获取多极信息。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());
以下是我尝试的另一种方式:

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>
Statusline:HTTP/1.1 302找到
响应:对象移动对象移动到。

我认为这两种技术都应该按照描述创建结构,所以我真的被卡住了。我还尝试将完整的
/content/exforced/../file.txt
放入Url,结果相同。

302重定向实际上是重定向到404错误页面。我怀疑,因为您将302重定向到系统“404错误”页面,重定向发生在路由处理层:可以从堆栈的更深处获得404,但是您只会得到对请求的直接404响应。因此,最有可能的原因是D2L应用程序堆栈无法将您的URL(加上一些参数)正确绑定到路由处理程序——也就是说,它无法标记您的请求以知道将请求转交给哪一位控制器代码

我想,当你写信的时候

userContext.createAuthenticatedUri("/d2l/api/le/1.0/Orgid/content/modules/moduleid/structure/", "POST")
 ...
 "Content-Type: application/json \r\n" +
 "{\"IsHidden\": false, \"IsLocked\": false, \"ShortTitle\": \"Test\", \"Type\": 1, \r\n" +
 ...
您实际上是在该路径中输入真实的
Orgid
moduleid
值吗?因为所写的字符串肯定会返回404——没有这样的路由——事实上,它可能会完全按照您所描述的重定向到System404错误页面

还请注意,当您编写

userContext.createAuthenticatedUri("/d2l/api/le/1.0/Orgid/content/modules/moduleid/structure/", "POST")
 ...
 "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, ...
当它看起来像这样的时候:

Content-Type: application/json
{"IsHidden": false, "IsLocked": false, ...
Content-Type: application/json

{"IsHidden": false, "IsLocked": false, ...

您可以尝试修复这些问题,看看会发生什么。

我在第一段代码中注意到,我在一个地方使用了
file.txt
,在另一个地方使用了
test.txt
。我固定使用相同的名字,但仍然得到相同的结果。太棒了!那条额外的线带来了所有的不同,现在它完美地工作了!我欠你一个人情!我还必须在
内容类型:text/plain
之后添加额外的行,否则它会创建一个0字节的文件。耶,接收者必须有某种方法来区分零件主体和零件标题。很好的ol'\r\n作为分隔符来拯救:太棒了。8)