从泽西客户端调用 post API 时出现 415 错误

Posted

技术标签:

【中文标题】从泽西客户端调用 post API 时出现 415 错误【英文标题】:415 error while calling post API from jersey client 【发布时间】:2020-11-19 07:29:12 【问题描述】:

我有以下返回 access_token 的 API。

发布https://idcs-xxxxxxxxxbf08128c3d93a19c.identity.c9dev2.oc9qadev.com/oauth2/v1/token

在标题 content-type is application/x-www-form-urlencoded 中。在正文中也包含以下参数。

我发送用户名和密码,并通过基本身份验证进行保护。当我从邮递员那里打电话时,它会提供 access_token。当我使用 HttpUrlConnection 消费时它也提供输出

          url = new URL(tokenURL);
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Authorization", auth);
        connection.setRequestProperty("Accept", "application/json");
        OutputStream os = connection.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
        osw.write("grant_type=client_credentials&scope=" + scope);

以上代码运行正常。但是当我使用球衣时,它会出现 415 错误。我正在使用下面的代码。

String user="idcs-oda-zzzxxxxxf93560b94eb8a2e2a4c9aac9a3ff-t0_APPID";       
    String password="xxxxxxx-6f71-4af2-b5cc-9110890d1456";
    String scope = "https://idcs-oda-xxxxxxxxxxxxxxxxe2a4c9aac9a3ff-t0.data.digitalassistant.oci.oc-test.com/api/v1";
    String tokenURL = "https://idcs-xxxxxxxxxxxxxxxx28c3d93a19c.identity.c9dev2.oc9qadev.com/oauth2/v1/token";
    HttpAuthenticationFeature feature= HttpAuthenticationFeature
                                .basicBuilder()
                                .nonPreemptive()
                                .credentials(user,password)
                                .build();
    ClientConfig clientConfig = new ClientConfig();
    clientConfig.register(feature);
    
    Client client = ClientBuilder.newClient(clientConfig);
    WebTarget webTarget= client.target(tokenURL);
    PostDetails post= new PostDetails("client_credentials",scope);  //Bean class to assign body parameter
    Response response= webTarget.request()
                       .header("Content-Type", "application/x-www-form-urlencoded")
                       .post(Entity.json(post)); 
    System.out.println(response);

谁能告诉我我在响应行中犯了什么错误。

【问题讨论】:

请编辑您的existing question 而不是创建重复项 其实我这里已经给出了更多的细节。我会删除旧的。你能帮忙吗?我真的很挣扎 webTarget.request("application/x-www-form-urlencoded") 这是干什么用的? 你没有设置这个connection.setRequestProperty("Accept", "application/json");为什么? webTarget.request() .header("Content-Type", "application/x-www-form-urlencoded") .header('Accept','application/x-www-form- urlencoded') .post(Entity.json(post)); 【参考方案1】:

你需要在request方法上设置你的Accept:

Response response= webTarget.request(MediaType.APPLICATION_JSON)
                       .header("Content-Type", "application/x-www-form-urlencoded")
                       .post(Entity.json(post));

您还需要确保如果您的 API 接受 application/x-www-form-urlencoded 内容,那就是您发送的内容。

目前,您正在根据您对Entity.json(post) 的使用情况发送application/json 内容。

我不知道post分配了什么类型,但是你需要弄清楚如何将它转换为FormMultiValuedMap<String,String>,然后在form上使用form方法@提交您的内容。

Response response= webTarget.request(MediaType.APPLICATION_JSON)
                       .header("Content-Type", "application/x-www-form-urlencoded")
                       .post(Entity.form(postForm)); //assuming postForm typed as Form or MultiValuedMap<String,String>

猜测post,将postForm 创建为MultiValuedMap&lt;String,String&gt; 可能就像以下一样简单(当然,您可以在请求之前放置)。

MultiValuedMap<String,String> postForm = new MultiValuedHashMap<>();
postForm.add("client_credentials",scope);

【讨论】:

菲利普,还有其他问题吗?【参考方案2】:

你需要的是:

Response response= webTarget.request()
    .accept("application/json") // Accept field from header of request
    .header("Content-Type", "application/x-www-form-urlencoded") //manually set content-tyoe
    .post(Entity.entity(input, MediaType.TEXT_PLAIN)); // request body

查看 Jersey 实际发送的内容的最佳方法是注册记录器并记录网络。例如:

clientConfig.register(
    new LoggingFeature(
            new Slf4jLogger(this.getClass().getName(), null)));

Slf4jLogger 来自org.apache.cxf:cxf-core

【讨论】:

我收到此错误。 MessageBodyWriter 未找到媒体 type=application/x-www-form-urlencoded、type=class org.studyeasy.showroom.resources.PostDetails、genericType=class org.studyeasy.showroom.resources.PostDetails。 尝试使用.header("Content-Type", "application/x-www-form-urlencoded") 设置内容类型。并使用MediaType.TEXT_PLAIN 让球衣选择文本编写器进行实体反序列化。

以上是关于从泽西客户端调用 post API 时出现 415 错误的主要内容,如果未能解决你的问题,请参考以下文章

Python Post 请求 - 通过 Outlook API 发送文件时出现 415 错误

api rest 调用更新 django 模型时出现错误 415

调用 Web API 2 端点时出现 HTTP 415 不支持的媒体类型错误

在 rest api 中发布请求时出现 415 错误,尝试运行 cms 查询

“标题”:“不支持的媒体类型”,“状态”:从 python 请求 API 时出现 415 错误

使用多部分 FormData 获取 POST 时出现 415