Apache HttpClient 进行 Post 请求 异常问题( Java 对接 walmart mp) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
RedBeanIce
V2EX    Java

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

  •  
  •   RedBeanIce 2023-10-24 17:47:46 +08:00 1449 次点击
    这是一个创建于 791 天前的主题,其中的信息可能已经有所发展或是发生改变。
    (由于请求 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 。


    问题:如开头
    14 条回复    2023-10-25 13:48:48 +08:00
    lsk569937453
        1
    lsk569937453  
       2023-10-24 18:09:20 +08:00
    http 状态码 400 很明显了,你的请求入参不对。
    RedBeanIce
        2
    RedBeanIce  
    OP
       2023-10-24 18:11:09 +08:00
    @lsk569937453

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

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

    贴一下获取代码吧
    RedBeanIce
        5
    RedBeanIce  
    OP
       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
        6
    RedBeanIce  
    OP
       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
        7
    hmmm000  
       2023-10-24 20:00:40 +08:00 via Android   1
    @RedBeanIce
    String persOnResultAsJsonStr= null;
    try {
    persOnResultAsJsonStr= restTemplate.postForObject(url, request, String.class);
    }
    catch (HttpStatusCodeException e) {
    //你要的响应体
    System.out.println(e.getResponseBodyAsString());
    }
    ZZ74
        8
    ZZ74  
       2023-10-24 20:14:10 +08:00   1
    OP 写代码时首先要明白自己要什么。
    你现在要的是那段报错 json OK
    那么 httpclient 你请求时就要返回一个 response ,然后判断 http code ,400 就取 response 的内容,那就是你要的东西。至于是哪个 api 可以自行查找

    resttemplate 没用过 楼上的应该就行。
    0xsui
        9
    0xsui  
       2023-10-25 08:36:01 +08:00   1
    最简单方法就是用 postman ,在浏览器里调试获取到登录的连接和所有请求参数,复制粘贴到 pstman ,发起请求调试没问题了,直接在 postman 里面生成 java 代码,复制代码到开发工具,运行就行了,这些网络请求代码完全不用自己写。
    RedBeanIce
        10
    RedBeanIce  
    OP
       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
        11
    RedBeanIce  
    OP
       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
        12
    xiaokongwu  
       2023-10-25 11:23:51 +08:00
    OP 的意思应该是,status 400 时,`result = IOUtils.toString(instream, StandardCharsets.UTF_8);`获取不到内容
    RedBeanIce
        13
    RedBeanIce  
    OP
       2023-10-25 12:51:52 +08:00
    @xiaokongwu

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

    最开始的时候,result 的处理在下面,,现在挪到上面去就好了,
    xiaokongwu
        14
    xiaokongwu  
       2023-10-25 13:48:48 +08:00   1
    @RedBeanIce 嗯,那就是 stream 读取的事,可能之前的代码在前面有 read 操作,导致 IOUtils 读不到
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3054 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 13:25 PVG 21:25 LAX 05:25 JFK 08:25
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86