Java请求Microsoft Graph API表现正常,但返回500错误。

huangapple go评论79阅读模式
英文:

Java requests to Microsoft Graph API perform ok but return 500

问题

public static String createUser(String token) {
    String user = "{\n"
            + "  \"accountEnabled\": true,\n"
            + "  \"displayName\": \"displayName-value\",\n"
            + "  \"mailNickname\": \"mailNickname-value\",\n"
            + "  \"userPrincipalName\": \"upn@microsoft.ro\",\n"
            + "  \"passwordProfile\" : {\n"
            + "    \"forceChangePasswordNextSignIn\": false,\n"
            + "    \"password\": \"Complexity2021\"\n"
            + "  },\n"
            + "  \"usageLocation\" : \"RO\""
            + "}";
    HttpURLConnection conn = null;
    URL url = null;
    try {
        url = new URL("https://graph.microsoft.com/beta/users");
        conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Authorization", "Bearer " + token);
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.connect();
        OutputStream os = conn.getOutputStream();
        os.write(user.getBytes());
        os.flush();
        int status = conn.getResponseCode();
        System.out.println(status); // 500!!!!! AND THE USER is ok in AzureAD
        switch (status) {
            case 200:
            case 201:
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                br.close();
                return sb.toString();
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        if (conn != null) {
            try {
                conn.disconnect();
            } catch (Exception ex1) {
                ex1.printStackTrace();
            }
        }
    }
    return null;
}
英文:

I have a small Java program with 3 methods:

  • one for getting the token from graph api for authentication bearer token. This is ok, token is ok and returns 200 http
  • the other two are for creating a user in Azure AD and assigning an licences.
    Taking the first, creating the user. The token is ok, the user is created, and authentication on platform works fine(password is set ok). BUT on response I get 500 http even task is done correctly in AzureAD. If I place same request in PowerShell there is no problem, no error. Please help me with an advice. My method for creating user is:
public static String createUser(String token) {
String user = "{\n"
+ "  \"accountEnabled\": true,\n"
+ "  \"displayName\": \"displayName-value\",\n"
+ "  \"mailNickname\": \"mailNickname-value\",\n"
+ "  \"userPrincipalName\": \"upn@microsoft.ro\",\n"
+ "  \"passwordProfile\" : {\n"
+ "    \"forceChangePasswordNextSignIn\": false,\n"
+ "    \"password\": \"Complexity2021\"\n"
+ "  },\n"
+ " \"usageLocation\" : \"RO\""
+ "}";
HttpURLConnection conn = null;
URL url = null;
try {
url = new URL("https://graph.microsoft.com/beta/users");
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Bearer " + token);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
OutputStream os = conn.getOutputStream();
os.write(user.getBytes());
os.flush();
int status = conn.getResponseCode();
System.out.println(status); // 500!!!!! AND THE USER is ok in AzureAD
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (conn != null) {
try {
conn.disconnect();
} catch (Exception ex1) {
ex1.printStackTrace();
}
}
}
return null;
}

答案1

得分: 1

感谢您的回复,我已经检查了errorStream并且包含以下内容:

{
  "error": {
    "code": "InternalServerError",
    "message": "MIME类型'text/html、image/gif、image/jpeg、*; q=.2、*/*; q=.2'在类型和子类型之间需要一个'/'字符,就像'text/plain'一样。",
    "innerError": {

    }
  }
}

解决方案是:

conn.setRequestProperty("Accept", "application/json");

谢谢!

英文:

Thanks for reply, I was checked the errorStream and was containing:

{
"error": {
"code": "InternalServerError",
"message": "The MIME type 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2' requires a '/' character between type and subtype, such as 'text/plain'.",
"innerError": {
" 
}
}
}

The solution was:

conn.setRequestProperty("Accept", "application/json");

Thank you!

答案2

得分: 0

你正忽略了服务器返回的错误数据,然而根据文档,它应该解释这个500状态的原因。建议的代码:

// ...
System.out.println(status); // 500!!!!! 而用户在AzureAD中是正常的

// 总是读取服务器响应
StringBuilder sb = new StringBuilder();
try (BufferedReader br = 
        new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
    String line;
    while ((line = br.readLine()) != null) {
          sb.append(line + "\n");
    }
} // <-- br会在这里自动关闭!

String output = sb.toString();
if (status == 200 || status == 201) {
    return output;
} else {
    // 选择合适的异常,或返回null但记录错误
    throw new FooException("在执行Foo时收到错误 " + status + 
            ",详细信息如下:" + output);
}
// ...

我还建议将所有使用`try { } finally { }`释放资源的地方都替换为[try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)版本,它们更安全(总是关闭已获取的资源)且更易读。
英文:

You are ignoring the error data returned by the server - but, according to the documentation, it should explain the cause of the 500 status. Suggested code:

        // ...
System.out.println(status); // 500!!!!! AND THE USER is ok in AzureAD
// always reads server response
StringBuilder sb = new StringBuilder();
try (BufferedReader br = 
new BufferedReader(new InputStreamReader(conn.getInputStream())) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line + &quot;\n&quot;);
}
} // &lt;-- br is automatically closed here!
String output = sb.toString();
if (status == 200 || status == 201) {
return output;
} else {
// choose a suitable exception, or return null but log error
throw new FooException(&quot;Received error &quot; + status + 
&quot; while doing Foo; details follow: &quot; + output);
}
// ... 

I also suggest replacing all your try { } finally { } that free resources with try-with-resources versions -- they are safer (always closing acquired resources) and more readable.

huangapple
  • 本文由 发表于 2020年10月21日 15:14:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/64458434.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定