【问题标题】:Microsoft Graph: Requesting an Extension returns http 400 bad requestMicrosoft Graph:请求扩展返回 http 400 错误请求
【发布时间】:2019-09-13 09:45:05
【问题描述】:

我在日历中的事件中添加了一个开放的扩展,并正在尝试将其读回。

这是网址:

https://graph.microsoft.com/v1.0/users/{userid}/calendars/{calendarId}=/events?$expand=Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event')

我无法让它在 Java 程序中工作。以下组合确实有效:

  • 如果我删除 $expand... 参数,它可以运行我的 Java 程序。我也可以询问某些字段,这也可以。
  • 请求在 Postman 中有效(我只需要设置令牌)
  • 当我以日历所有者身份登录时,该请求在 Graph Explorer 中有效

这是我使用 Postman 阅读事件时的扩展名(在其中一个事件中)。这是事件中的最后一项:

        "extensions@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('{userid}')/calendars('{calendarId}')/events('{eventId})/extensions",
        "extensions": [
            {
                "@odata.type": "#microsoft.graph.openTypeExtension",
                "id": "Microsoft.OutlookServices.OpenTypeExtension.c.i.m.p.server.entities.outlook.Event",
                "extensionName": "c.i.m.p.server.entities.outlook.Event",
                "adherentId": "12346",
                "timeSlotID": "346463"
            }
        ]

这里是 Java 代码(Java 8,使用 java.io 和 java.net 库):

    private static void doSomething(String _accessToken) throws IOException {
    String urlString = "https://graph.microsoft.com/v1.0/users/{userId}/calendars/{calendarId}/events?$expand=Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event')";

    URL url = new URL(urlString);

    Proxy webProxy 
  = new Proxy(Proxy.Type.HTTP, new InetSocketAddress({proxy-address}, {port}));
    HttpURLConnection connection = (HttpURLConnection) url.openConnection(webProxy);

    // Set the appropriate header fields in the request header.
    connection.setRequestProperty("Authorization", "Bearer " + _accessToken);
    connection.setRequestProperty("Accept", "application/json");

    connection.setDoOutput(true);
    connection.setReadTimeout(5000);
    connection.setRequestMethod(HttpMethod.GET);

    try {
        connection.connect();
        int responseCode = connection.getResponseCode();
        System.out.println("execute(), response code = " + responseCode);

        String responseMessage = connection.getResponseMessage();
        System.out.println("execute(), response Message = " + responseMessage);

        String responseString = null;
        try {
            InputStream ins = connection.getInputStream();
            BufferedReader br=new BufferedReader(new InputStreamReader(ins));
            StringBuffer sb=new StringBuffer();
            String line;
            while ((line=br.readLine()) != null) {
                sb.append(line);
            }
            responseString = sb.toString();
        } catch (Exception e) {
            System.out.println("Could not get input stream from response, error is " + e.toString());
        }

        System.out.println("execute(), httpResult = " + responseString);
    } catch (IOException e) {
        System.out.println(".execute(), IOException : " + e.toString());
    } finally {
        connection.disconnect();
    }
}

我该如何解决这个问题?谢谢!

【问题讨论】:

  • 您是否尝试过对查询字符串进行编码?类似String urlString = "https://graph.microsoft.com/v1.0/users/{userId}/calendars/{calendarId}/events?"+ URLEncoder.encode("$expand", "UTF-8") + "="+ URLEncoder.encode("Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event')", "UTF-8")?
  • 你能试试这个网址吗? https://graph.microsoft.com/v1.0/users/{userid}/calendars/{calendarId}=/events?$expand=Extensions($filter=Id%20eq%20'c.i.m.p.server.entities.outlook.Event')
  • @user2683814 第一条评论更正了问题。实际上我不必对“$expand”进行编码,只需对最后的部分进行编码。让它成为一个答案,赏金就是你的。

标签: java http microsoft-graph-api webservice-client


【解决方案1】:

400 表示错误请求。这可能是因为 url 编码。 Url 对查询字符串进行编码。

类似

String query = "Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event'";
String url = "https://graph.microsoft.com/v1.0/users/{userId}/calendars/{calendarId}/events?
               $expand=" + URLEncoder.encode(query, StandardCharsets.UTF_8.name());

或者,您可以根据需要使用graph service java api,这将有助于为您抽象所有交互,或者您可以使用任何可用的rest clients

【讨论】:

  • 我查看了图形服务 api,但看不到如何在代理中工作。所以我放弃了,去了本土。我想这应该是另一个问题。
【解决方案2】:

首先,您应该提供有关错误的更多信息 - Stacktrace 和错误消息。但是 400 代码表明这是一个用户错误,这意味着您正在发送一个无效的请求。既然您说邮递员请求有效,那么请比较邮递员发送的所有标头,看看您的代码是否遗漏了一些听众。至于代码,我建议不要编写自己的 Http 客户端功能,而是使用 3d 方 Http 客户端。以下是一些建议:

  1. Apache Http client - 非常流行和知名的 3d 派对 Http 客户端
  2. OK Http client - 开源 Http 客户端。 Here是教程
  3. MgntUtils Http 客户端 - 非常简单的 3d 方 HttpClient:在 MgntUtils 开源库中提供(由我编写)。使用非常简单。看看Javadoc。库本身以Maven artifactsGit 的形式提供(包括源代码和Javadoc)。

【讨论】:

  • 好的,我来看看标题。但是如果我的代码有标题问题,那为什么第一个组合会成功呢?
  • 第一个组合工作是一个有趣的点。但目前我会把它放在一边,专注于比较在邮递员中工作的相同请求,而不是在 java 代码中工作。在我看来,找到差异是主要的关键点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多