HttpUrlConnection获取SharePoint Online表单摘要值遇411错误求助
Hey there, I’ve run into similar SharePoint auth quirks before, so let’s break down why you’re hitting that 411 Length Required error even after setting Content-Length: 0.
Key Issues in Your Current Code
Let’s go through the main problems that are probably causing this:
Overwriting Cookie Headers
You’re callingsetRequestProperty("Cookie", ...)twice, which replaces the first cookie with the second one instead of combining them. SharePoint needs all the auth cookies sent in a singleCookieheader, separated by semicolons.Incorrect Accept Header
TheAcceptheader is set toapplication/x-www-form-urlencoded, but SharePoint’s/_api/contextinfoendpoint returns either XML or JSON. This mismatch can throw off the server’s response handling.Unwritten Output Stream
When you setsetDoOutput(true),HttpURLConnectionexpects you to write something to the output stream—even if it’s empty. Just settingContent-Length: 0isn’t always enough; you need to explicitly open and close the stream to signal the request is complete.
Revised Code with Fixes
Here’s your code updated with these fixes applied, with comments highlighting changes:
public String getFormDigestValue(List<String> cookies) throws IOException { URL u = new URL("https://xxx.sharepoint.com/_api/contextinfo"); HttpURLConnection connection = (HttpURLConnection) u.openConnection(); connection.setRequestMethod("POST"); connection.setDoInput(true); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); // Fix 1: Use an appropriate Accept header for SharePoint's API connection.addRequestProperty("Accept", "application/xml;odata=verbose"); connection.addRequestProperty("Content-Type", "text/xml; charset=utf-8"); // Fix 2: Combine cookies into a single header instead of overwriting String combinedCookies = cookies.get(1) + "; " + cookies.get(2); connection.setRequestProperty("Cookie", combinedCookies); connection.setRequestProperty("Origin", "https://xxx.sharepoint.com"); // Added https:// for validity // Fix 3: Explicitly handle the empty output stream connection.setFixedLengthStreamingMode(0); // Ensures Content-Length is properly set try (OutputStream out = connection.getOutputStream()) { // Write nothing, just close the stream to complete the request out.flush(); } // Read the response try (InputStream in = connection.getInputStream()) { StringBuilder sb = new StringBuilder(); int c; while ((c = in.read()) != -1) { sb.append((char) c); } String result = sb.toString(); String startTag = "<d:FormDigestValue>"; String endTag = "</d:FormDigestValue>"; if (!(result.contains(startTag)) || !(result.contains(endTag))) { throw new IOException("Error during getting form digest value: Value missing in response."); } else { int startIndex = result.indexOf(startTag); int endIndex = result.indexOf(endTag, startIndex + startTag.length()); return result.substring(startIndex + startTag.length(), endIndex); } } }
Why This Works
- Combined Cookies: SharePoint receives all necessary auth cookies in one header, so it recognizes your authenticated session.
- Correct Accept Header: The server returns a response format your code can parse, avoiding unexpected handling.
- Explicit Output Stream Handling: By opening and flushing the empty output stream, you signal to
HttpURLConnectionthat the request body is complete, which resolves the 411 error.
Why Postman Works
Postman automatically handles small details like combining cookies from your session, setting appropriate headers, and properly sending empty request bodies—things that HttpURLConnection requires you to handle manually.
内容的提问来源于stack exchange,提问作者Петър Петров

