415错误在调用Jersey客户端的POST API时发生。

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

415 error while calling post API from jersey client

问题

以下是翻译好的部分:

我有下面的API,它返回访问令牌。

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

在标头中,`content-type` 是 `application/x-www-form-urlencoded`。同时,在请求体中包含以下参数。

[![在此输入图像描述][1]][1]

[1]: https://i.stack.imgur.com/msU8P.png

我发送用户名和密码,并使用基本身份验证进行安全保护。当我从Postman调用时,它会提供访问令牌。同时,当我使用 `HttpUrlConnection` 进行消耗时,它也会提供输出。

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

上述代码正常工作。但是当我使用Jersey时,它会给出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类用于分配请求体参数
Response response = webTarget.request()
           .header("Content-Type", "application/x-www-form-urlencoded")
           .post(Entity.json(post)); 
System.out.println(response);

有人能告诉我在响应行中出了什么错误吗?


<details>
<summary>英文:</summary>

I have below API which returns back the access_token.

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

in header `content-type is application/x-www-form-urlencoded`. also in body it contains below parameter.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/msU8P.png

I send user name and password and it is secured with basic authentication. It provides access_token when I call from postman. also it provides output when I consume using `HttpUrlConnection`

        

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

&lt;b&gt;The above code is working properly. But when I use jersey it gives 415 error. I am using below code.&lt;/b&gt;

    String user=&quot;idcs-oda-zzzxxxxxf93560b94eb8a2e2a4c9aac9a3ff-t0_APPID&quot;;		
        String password=&quot;xxxxxxx-6f71-4af2-b5cc-9110890d1456&quot;;
    	String scope = &quot;https://idcs-oda-xxxxxxxxxxxxxxxxe2a4c9aac9a3ff-t0.data.digitalassistant.oci.oc-test.com/api/v1&quot;;
    	String tokenURL = &quot;https://idcs-xxxxxxxxxxxxxxxx28c3d93a19c.identity.c9dev2.oc9qadev.com/oauth2/v1/token&quot;;
    	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(&quot;client_credentials&quot;,scope);  //Bean class to assign body parameter
    	Response response= webTarget.request()
    			           .header(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;)
    			           .post(Entity.json(post)); 
    	System.out.println(response);

Can somebody tell me what mistake I am doing in Response line.

</details>


# 答案1
**得分**: 2

你需要在 [request][1] 方法中设置你的 Accept:

```java
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&lt;String,String&gt;,然后使用 Entity 上的 form 方法来提交你的内容。

Response response = webTarget.request(MediaType.APPLICATION_JSON)
                       .header("Content-Type", "application/x-www-form-urlencoded")
                       .post(Entity.form(postForm)); // 假设 postForm 被定义为 Form 或 MultiValuedMap&lt;String,String&gt;

关于 post,创建一个 MultiValuedMap&lt;String,String&gt;postForm 可能就像下面这么简单(当然,你需要在你的请求之前放置这个)。

MultiValuedMap&lt;String,String&gt; postForm = new MultiValuedHashMap&lt;&gt;();
postForm.add("client_credentials", scope);
英文:

You need to set your Accept on the request method:

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

You also need to ensure that if your API accepts application/x-www-form-urlencoded content, that is what you are sending.

Currently, you are sending application/json content based on your usage of Entity.json(post).

I don't know what type is assigned to post, but you need to figure out how to convert it either to a Form or a MultiValuedMap&lt;String,String&gt;, and then use the form method on Entity to submit your content.

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

Taking a guess regarding post, creating postForm as a MultiValuedMap&lt;String,String&gt; may be as simple as the following (which you would place prior to your request, of course).

MultiValuedMap&lt;String,String&gt; postForm = new MultiValuedHashMap&lt;&gt;();
postForm.add(&quot;client_credentials&quot;,scope);

答案2

得分: 2

你所需的是:

Response response = webTarget.request()
    .accept("application/json") // 请求头中的 Accept 字段
    .header("Content-Type", "application/x-www-form-urlencoded") // 手动设置内容类型
    .post(Entity.entity(input, MediaType.TEXT_PLAIN)); // 请求体

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

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

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

英文:

What you need is:

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

The best way to see what is Jersey actually is sending is to register logger, and log network. For example:

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

where Slf4jLogger is from org.apache.cxf:cxf-core.

huangapple
  • 本文由 发表于 2020年7月30日 00:23:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/63158146.html
匿名

发表评论

匿名网友

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

确定