【问题标题】:Spring WebClient Post method BodySpring WebClient Post 方法正文
【发布时间】:2020-09-16 06:13:20
【问题描述】:

我正在尝试发送带有正文数据的 POST 请求,如下所述:https://scrapyrt.readthedocs.io/en/stable/api.html#post

这是我尝试做的,但它给了我 HTTP 代码 500

String uri = "http://localhost:3000";

WebClient webClient = WebClient.builder()  
            .baseUrl(uri)
            .build();
LinkedMultiValueMap map = new LinkedMultiValueMap();

        String q = "\"url\": \"https://blog.trendmicro.com/trendlabs-security-intelligence\",\"meta\":{\"latestDate\" : \"18-05-2020\"}}";
        map.add("request", q);
        map.add("spider_name", "blog");

        BodyInserter<MultiValueMap<String, Object>, ClientHttpRequest> inserter2
         = BodyInserters.fromMultipartData(map);

        Mono<ItemsList> result = webClient.post()
                                          .uri(uriBuilder -> uriBuilder
                                                           .path("/crawl.json")
                                                           .build())
                                          .body(inserter2)
                                          .retrieve()
                                          .bodyToMono(ItemsList.class);

        ItemsList tempItems = result.block();

【问题讨论】:

  • 您为什么要尝试编写自己的 JSON 的一半? q 应该是什么?它将针对request 序列化为单个字符串值
  • 这是我想用 POST 发送的正文 { "request": { "url": "blog.trendmicro.com/trendlabs-security-intelligence", "meta": { "latestDate" : "14-02-2020" } }, "spider_name": "blog"} q 是结果参数的值

标签: spring rest spring-webflux


【解决方案1】:

对我来说,以下代码有效:

public String wcPost(){

    Map<String, String> bodyMap = new HashMap();
    bodyMap.put("key1","value1");
 

    WebClient client = WebClient.builder()
            .baseUrl("domainURL")
            .build();


    String responseSpec = client.post()
            .uri("URI")
            .headers(h -> h.setBearerAuth("token if any"))
            .body(BodyInserters.fromValue(bodyMap))
            .exchange()
            .flatMap(clientResponse -> {
                if (clientResponse.statusCode().is5xxServerError()) {
                    clientResponse.body((clientHttpResponse, context) -> {
                        return clientHttpResponse.getBody();
                    });
                    return clientResponse.bodyToMono(String.class);
                }
                else
                    return clientResponse.bodyToMono(String.class);
            })
            .block();

    return responseSpec;
}

【讨论】:

    【解决方案2】:

    这是我尝试做的,但它给了我 HTTP 代码 500

    很可能是因为您以错误的格式和错误的类型混合发送了错误的数据:

    • 您使用的是多部分表单数据,而不是 JSON
    • 然后您将 request 参数设置为 JSON 字符串 (q)
    • 您在q 中使用的 JSON 字符串甚至无效(它至少缺少一个左大括号) - 手写 JSON 几乎是一个普遍的坏主意,请利用一个框架来代替您。

    相反,正常的做法是创建一个映射到您的请求的 POJO 结构,因此:

    public class CrawlRequest {
    
        private CrawlInnerRequest request;
        @JsonProperty("spider_name")
        private String spiderName;
    
        //....add the getters / setters
    }
    
    public class CrawlInnerRequest {
    
        private String url;
        private String callback;
        @JsonProperty("dont_filter")
        private String dontFilter;
    
        //....add the getters / setters
    }
    

    ...然后只需创建一个CrawlRequest,根据需要设置值,然后在您的通话后使用:

    .body(BodyInserters.fromValue(crawlRequest))
    

    这是使用WebClient 的一个相当基础的基本部分。我建议您更广泛地阅读,以便更好地了解基础知识,从长远来看,这将大有帮助。

    【讨论】:

    • 谢谢你。我会试试这个,如果它有效,我会把它标记为正确答案。除了文档,你能推荐我可以从哪里学习吗?我不太喜欢文档中的大量文字和大量阅读内容:/
    • 周围有各种教程 (hellokoding.com/spring-webclient-tutorial-with-examples) - 但如果您能接受,这些文档绝对值得一读,它们拥有最完整和最新的信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 2020-08-13
    相关资源
    最近更新 更多