3

I am modifying software to export client data to Microsoft OneNote instead of to local html files. I'm also not an experienced programmer, so I've been trying to teach myself this API and these protocols as I go along.

I am able to sucessfully use both the Apigee interface and hurl.it to send multipart POST requests and upload pages to a OneNote Notebook.

On hurl.it, I include two headers:

"Authorization", "myAuthCode"

"Content-Type", "multipart/form-data; boundary=NewPart"

While these interfaces work fine, I am unable to replicate the process in my Java project.

Here is my test code:

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));

    }
}

When I execute this code, I receive the following response:

"code":"20110","message":"Page create requests require the content to be multipart, with a presentation part."

From this, I know that I'm successfully contacting OneNote, and successfully authenticating.

I believe that my error is in the way I set up the headers in Java. I'm unsure if you're allowed to chain .header methods. The only other way that I'm aware of is to pass a MultiValuedMap to the .headers method, though I'm unfamiliar with the interface and how to implement it.

The OneNote Dev Center is a bit unhelpful, telling me only what I already know and seem to have included in my code.

Edit:

I've updated my code with CRLF's in place of single \n characters, though the problem persists:

Updated Java Code OneNote Error Code

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720

2 Answers2

1

Look at Entity.text()

Create a "text/plain" entity.

I haven't tested, but I'm guessing that this overwrites the Content-Type you set in the header() method. You can use

Entity.entity(entity, MediaType)

to create a generic entity, where you can specify the media type.

Another thing, I don't know what JAX-RS implementation you are using, but any implementation should have multipart support, so you don't to manually handle the building of the body. Here is an example using Jersey.

Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • 1
    Thank you! I changed payload to an Entity.xhtml, and the page posts successfully to my notebook. What's interesting is that it completely disregards the part boundaries, and uploads the entire payload to a notebook page, including the part headers "Content-Disposition" and "Content-Type", in plain text. I'm not very worried, because my html is still being pushed successfully to a page! – Dillon Strichman Jun 24 '15 at 15:31
0

You should use CRLF \r\n instead of \n [especially when dealing with ms/windows].

It looks like you are missing a \n character at the beginning of payload and a 2nd \n after the \n on the line "Content-Type: application/xhtml+xml\n"

sources:

http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html

https://www.ietf.org/rfc/rfc2046.txt

PS the rest of your code looks good

  • I've replaced all of my \n characters with CRLF's. I've also read through the documentation you've provided; thank you! Unfortunately, even after including another CRLF before each boundary, my problem persists. I will continue to play with the escape characters throughout my code in the meantime. [Screenshot](http://puu.sh/izLbY/fcd2620ee2.png) of my code. (Apologies, I'm unsure if screenshots are against stackoverflow question/comment etiquette.) – Dillon Strichman Jun 23 '15 at 14:57
  • Hi again, there is a stray decimal point at the end of `payload`. You should also add the `charset=[utf8|iso-8859-1]` to both your Content-Type headers. The XML is declared as utf-8 but coming from windows it may in fact be iso-8859-1, make sure it's the right one. You should update your code above to reflect the changes so that others can help – codemonk113 Jun 23 '15 at 16:45
  • Maybe a last resort: if you could capture both a successful api call and a failed one with wireshark/tcpdump/etc. the problem would probably present itself more clearly. – codemonk113 Jun 23 '15 at 17:20
  • Thank you, I appreciate your help very much! I've been able to resolve the problem thanks to @peeskillet 's suggestion to change the entity type. There are still some strange things going on, but I will edit my original post. Thank you again! – Dillon Strichman Jun 24 '15 at 15:24