英文:
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("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);
<b>The above code is working properly. But when I use jersey it gives 415 error. I am using below code.</b>
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);
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
被分配了什么类型,但你需要弄清楚如何将其转换为 Form
或 MultiValuedMap<String,String>
,然后使用 Entity
上的 form
方法来提交你的内容。
Response response = webTarget.request(MediaType.APPLICATION_JSON)
.header("Content-Type", "application/x-www-form-urlencoded")
.post(Entity.form(postForm)); // 假设 postForm 被定义为 Form 或 MultiValuedMap<String,String>
关于 post
,创建一个 MultiValuedMap<String,String>
的 postForm
可能就像下面这么简单(当然,你需要在你的请求之前放置这个)。
MultiValuedMap<String,String> postForm = new MultiValuedHashMap<>();
postForm.add("client_credentials", scope);
英文:
You need to set your Accept on the request method:
Response response= webTarget.request(MediaType.APPLICATION_JSON)
.header("Content-Type", "application/x-www-form-urlencoded")
.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<String,String>
, and then use the form
method on Entity
to submit your content.
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>
Taking a guess regarding post
, creating postForm
as a MultiValuedMap<String,String>
may be as simple as the following (which you would place prior to your request, of course).
MultiValuedMap<String,String> postForm = new MultiValuedHashMap<>();
postForm.add("client_credentials",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("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
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论