Apache HttpClient 进行 Post 请求 异常问题( Java 对接 walmart mp)

2023-10-24 17:47:46 +08:00
 RedBeanIce
(由于请求 walmart 有账号密码,属于公司保密信息,所以无法提供实际代码)

问题:请求异常只体现在日志中,如下面的第三行日志就是日志,有体现 carrier 字段是错误的。
如果在 response 里面获取,只能获取到 bad request ,没有具体的某个字段的错误。

请问,我如何获取到日志里面的报错,然后在自己写的代码里面获取到这个报错,自己打印出来。

1 ,
```
请求框架是,Apache HttpClient

org.apache.httpcomponents
4.5.6
HttpClient
```

```
17:33:50.629 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "Connection: close[\r][\n]"
17:33:50.629 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "[\r][\n]"
17:33:50.629 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "{"errors":{"error":[{"code":"INVALID_REQUEST_CONTENT.GMP_ORDER_API","field":"carrier","description":"Unsupported carrier 'Fedex' was specified in line number 1. Only pre-defined names are allowed for 'carrier.' For a list of acceptable carriers, see https://developer.walmart.com/api/us/mp/orders#operation/shippingUpdates . If you select 'otherCarrier' you must also provide the tracking URL.","info":"Request content is invalid.","severity":"ERROR","category":"DATA","errorIdentifiers":{"entry":[]}}]}}"
17:33:50.629 [main] DEBUG org.apache.http.headers - http-outgoing-0 << HTTP/1.1 400 Bad Request
17:33:50.629 [main] DEBUG org.apache.http.headers - http-outgoing-0 << Accept-Ranges: bytes

```

2 ,如果换成 resttemplate ,那么直接连日志也没有了。。response 和上述一样
我将日志等级修改 debug ,也是没有日志,只有 response 。


问题:如开头
1046 次点击
所在节点    Java
14 条回复
lsk569937453
2023-10-24 18:09:20 +08:00
http 状态码 400 很明显了,你的请求入参不对。
RedBeanIce
2023-10-24 18:11:09 +08:00
@lsk569937453

请再看一下我的问题。我们问题不是 400 。

而是具体的详细的报错,仅仅体现在日志中,无法让 ta 体现在返参中。
hmmm000
2023-10-24 18:18:12 +08:00
resttemplate 可以通过 catch HttpStatusCodeException ,用 getResponseBodyAsString 方法获取非 200 返回的响应体。httpclient 不清楚。
xiaokongwu
2023-10-24 18:25:00 +08:00
“如果在 response 里面获取,只能获取到 bad request ,没有具体的某个字段的错误。”

贴一下获取代码吧
RedBeanIce
2023-10-24 19:08:44 +08:00
@hmmm000

```
请求方式

HttpEntity<String> request = new HttpEntity<>(parse.toJSONString(), headersV2);
String personResultAsJsonStr = null;
try {
personResultAsJsonStr = restTemplate.postForObject(url, request, String.class);
} catch (RestClientException e) {
e.printStackTrace();
}
System.out.println(personResultAsJsonStr);

```

```
打印

19:05:22.927 [main] DEBUG org.springframework.web.client.RestTemplate - Created POST request for "https://marketplace.walmartapis.com/v3/orders/108829823812146/shipping"
19:05:22.928 [main] DEBUG org.springframework.web.client.RestTemplate - Setting request Accept header to [text/plain, application/json, application/cbor, application/*+json, */*]
19:05:22.929 [main] DEBUG org.springframework.web.client.RestTemplate - Writing [{"orderShipment":{"orderLines":{"orderLine":[{"lineNumber":"1","orderLineStatuses":{"orderLineStatus":[{"status":"Shipped","statusQuantity":{"amount":"1","unitOfMeasurement":"EACH"},"trackingInfo":{"carrierName":{"carrier":"Fedex"},"methodCode":"Standard","shipDateTime":1698132951000,"trackingNumber":"785444130107"}}]},"sellerOrderId":"FO231024144001001"}]}}}] using [org.springframework.http.converter.StringHttpMessageConverter@7a362b6b]
19:05:23.423 [main] DEBUG org.springframework.web.client.RestTemplate - POST request for "https://marketplace.walmartapis.com/v3/orders/108829823812146/shipping" resulted in 400 (Bad Request); invoking error handler
null
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:118)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:103)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:730)

```

但是我想要的是,,

"{"errors":{"error":[{"code":"INVALID_REQUEST_CONTENT.GMP_ORDER_API","field":"carrier","description":"Unsupported carrier 'Fedex' was specified in line number 1. Only pre-defined names are allowed for 'carrier.' For a list of acceptable carriers, see https://developer.walmart.com/api/us/mp/orders#operation/shippingUpdates . If you select 'otherCarrier' you must also provide the tracking URL.","info":"Request content is invalid.","severity":"ERROR","category":"DATA","errorIdentifiers":{"entry":[]}}]}}

它提示我,,,carrier 字段有问题。。(相关描述,请看开头)
RedBeanIce
2023-10-24 19:16:23 +08:00
@xiaokongwu

apache http ,,,伪代码
```
// 执行请求
CloseableHttpResponse response = httpClient.execute(post, new BasicHttpContext());
// 返回的状态 200 404 等等
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
logger.info("request url failed, http code={}, url={}", response.getStatusLine().getStatusCode(), url);
return null;
}
```
如果像是上述代码获取,,则只能获取到 bad request


报错都在日志打印里面,org.apache.http.wire ,carrier 字段有问题
hmmm000
2023-10-24 20:00:40 +08:00
@RedBeanIce
String personResultAsJsonStr = null;
try {
personResultAsJsonStr = restTemplate.postForObject(url, request, String.class);

catch (HttpStatusCodeException e) {
//你要的响应体
System.out.println(e.getResponseBodyAsString());
}
ZZ74
2023-10-24 20:14:10 +08:00
OP 写代码时首先要明白自己要什么。
你现在要的是那段报错 json OK
那么 httpclient 你请求时就要返回一个 response ,然后判断 http code ,400 就取 response 的内容,那就是你要的东西。至于是哪个 api 可以自行查找

resttemplate 没用过 楼上的应该就行。
0xsui
2023-10-25 08:36:01 +08:00
最简单方法就是用 postman ,在浏览器里调试获取到登录的连接和所有请求参数,复制粘贴到 postman ,发起请求调试没问题了,直接在 postman 里面生成 java 代码,复制代码到开发工具,运行就行了,这些网络请求代码完全不用自己写。
RedBeanIce
2023-10-25 09:11:36 +08:00
@RedBeanIce

apache http ,,,伪代码
```
// 执行请求
CloseableHttpResponse response = httpClient.execute(post, new BasicHttpContext());
// 返回的状态 200 404 等等
int statusCode = response.getStatusLine().getStatusCode();
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = IOUtils.toString(instream, StandardCharsets.UTF_8);
}
if (statusCode != CONNCET_SUCCESS) {
logger.info("request url failed, http code={}, url={}, result={}", response.getStatusLine().getStatusCode(), url, result);
return null;
}
if (statusCode != 200) {
logger.info("request url failed, http code={}, url={}", response.getStatusLine().getStatusCode(), url);
return null;
}



```
RedBeanIce
2023-10-25 09:12:52 +08:00
@RedBeanIce

apache http ,,,伪代码
```
// 执行请求
CloseableHttpResponse response = httpClient.execute(post, new BasicHttpContext());
// 返回的状态 200 404 等等
int statusCode = response.getStatusLine().getStatusCode();

HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = IOUtils.toString(instream, StandardCharsets.UTF_8);
}
if (statusCode != 200) {
logger.info("request url failed, http code={}, url={}, result={}", response.getStatusLine().getStatusCode(), url, result);
return null;
}


result 里面就是,成功信息,或者是异常信息

```
xiaokongwu
2023-10-25 11:23:51 +08:00
OP 的意思应该是,status 400 时,`result = IOUtils.toString(instream, StandardCharsets.UTF_8);`获取不到内容
RedBeanIce
2023-10-25 12:51:52 +08:00
@xiaokongwu

hhhh ,是我让你产生误解了。很抱歉。

最开始的时候,result 的处理在下面,,现在挪到上面去就好了,
xiaokongwu
2023-10-25 13:48:48 +08:00
@RedBeanIce 嗯,那就是 stream 读取的事,可能之前的代码在前面有 read 操作,导致 IOUtils 读不到

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/985000

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX