Java 为什么可以';我是否向Microsoft OneNote发送多部分/表单数据请求?

Java 为什么可以';我是否向Microsoft OneNote发送多部分/表单数据请求?,java,rest,jax-rs,multipartform-data,onenote,Java,Rest,Jax Rs,Multipartform Data,Onenote,我正在修改软件以将客户端数据导出到Microsoft OneNote,而不是本地html文件。我也不是一个有经验的程序员,所以我一直在努力自学这个API和这些协议 我能够成功地使用和发送多部分POST请求,并将页面上载到OneNote笔记本 在hull.it中,我包括两个标题: “授权”、“myAuthCode” “内容类型”,“多部分/表单数据;边界=新部分” 虽然这些接口工作正常,但我无法在Java项目中复制该过程 以下是我的测试代码: import javax.ws.rs.client.C

我正在修改软件以将客户端数据导出到Microsoft OneNote,而不是本地html文件。我也不是一个有经验的程序员,所以我一直在努力自学这个API和这些协议

我能够成功地使用和发送多部分POST请求,并将页面上载到OneNote笔记本

在hull.it中,我包括两个标题:

“授权”、“myAuthCode”

“内容类型”,“多部分/表单数据;边界=新部分”

虽然这些接口工作正常,但我无法在Java项目中复制该过程

以下是我的测试代码:

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;

public class Main {


public static void main(String[] args) {

    String tokenString = "LONG_TOKEN_STRING"

    Client client = ClientBuilder.newClient();
    Entity<String> payload = Entity.text("--NewPart\n" +
            "Content-Disposition: form-data; name=\"Presentation\"\n" +
            "Content-Type: application/xhtml+xml\n" +
            "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
            "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en-us\">\n" +
            "  <head>\n" +
            ... //the rest of the POST request body is in here
            ...
            "</body></html>\n" +
            "--NewPart--\n" +
            ".\n");

    Response response = client.target("https://www.onenote.com/api/v1.0/pages")
            .request(MediaType.TEXT_PLAIN_TYPE)
            .header("Authorization", "Bearer " + tokenString)
            .header("Content-Type", "multipart/form-data; boundary=NewPart")
            .post(payload);

    System.out.println("status: " + response.getStatus());
    System.out.println("headers: " + response.getHeaders());
    System.out.println("body: \n" + response.readEntity(String.class));

    }
}
导入javax.ws.rs.client.client;
导入javax.ws.rs.client.ClientBuilder;
导入javax.ws.rs.client.Entity;
导入javax.ws.rs.core.Response;
导入javax.ws.rs.core.MediaType;
公共班机{
公共静态void main(字符串[]args){
String tokenString=“LONG\u TOKEN\u String”
Client Client=ClientBuilder.newClient();
实体负载=Entity.text(“--NewPart\n”+
“内容处置:表单数据;名称=\”演示文稿\“\n”+
“内容类型:应用程序/xhtml+xml\n”+
“\n”+
“\n”+
“\n”+
…//POST请求正文的其余部分在这里
...
“\n”+
“--新部件--\n”+
“\n”);
响应=客户端。目标(“https://www.onenote.com/api/v1.0/pages")
.request(MediaType.TEXT\u PLAIN\u类型)
.header(“授权”、“承载人”+令牌字符串)
.header(“内容类型”、“多部分/表单数据;边界=新部分”)
.员额(有效载荷);
System.out.println(“状态:+response.getStatus());
System.out.println(“headers:+response.getHeaders());
System.out.println(“body:\n”+response.readEntity(String.class));
}
}
当我执行此代码时,我收到以下响应:

“代码”:“20110”,“消息”:“页面创建请求要求内容是多部分的,带有演示部分。”

由此,我知道我正在成功联系OneNote并成功进行身份验证

我相信我的错误在于我在Java中设置头的方式。我不确定是否允许您链接.header方法。我知道的唯一其他方法是将多值映射传递给.headers方法,尽管我不熟悉该接口以及如何实现它

OneNote开发中心没有什么帮助,它只告诉我已经知道并且似乎已经包含在代码中的内容

编辑:

我已用CRLF代替单个字符\n更新了代码,但问题仍然存在:


您应该使用CRLF
\r\n
而不是
\n
[尤其是在处理ms/windows时]

看起来您在“内容类型:应用程序/xhtml+xml”一行的
\n
开头缺少一个
\n
字符,在
\n
之后缺少第二个
\n

资料来源:

PS代码的其余部分看起来不错

看看

创建一个“文本/普通”实体

我还没有测试,但我猜这会覆盖您在
header()方法中设置的
内容类型。你可以用

Entity.entity(entity, MediaType)
要创建通用实体,可以在其中指定媒体类型


另一件事,我不知道您使用的是什么JAX-RS实现,但是任何实现都应该具有多部分支持,因此您不需要手动处理主体的构建

我已用CRLF替换了所有\n字符。我还通读了您提供的文档;非常感谢。不幸的是,即使在每个边界之前包含另一个CRLF,我的问题仍然存在。在此期间,我将继续在代码中使用转义字符。我的代码。(抱歉,我不确定截图是否违反stackoverflow问题/评论礼仪。)您好,在
有效负载
的末尾有一个零散的小数点。您还应该将
charset=[utf8 | iso-8859-1]
添加到两个内容类型标题中。XML声明为utf-8,但来自windows,它实际上可能是iso-8859-1,请确保它是正确的。您应该更新上面的代码以反映这些更改,以便其他人能够提供帮助可能是最后的手段:如果您可以使用wireshark/tcpdump/etc捕获成功的api调用和失败的api调用。问题可能会更清楚地显示出来。谢谢您,我非常感谢您的帮助!由于@peeskillet建议更改实体类型,我已经能够解决这个问题。仍然有一些奇怪的事情发生,但我会编辑我原来的帖子。再次感谢你!非常感谢。我将有效负载更改为Entity.xhtml,页面成功地发布到我的笔记本上。有趣的是,它完全忽略了部件边界,并以纯文本形式将整个有效负载上载到笔记本页面,包括部件标题“Content Disposition”和“Content Type”。我不是很担心,因为我的html仍然被成功地推到一个页面上!