在 Clojure 中使用 clj-http 发布请求 - 正文不被接受?

问题描述 投票:0回答:3

通过我的发布请求,我希望发布的 CRM API 文档也要求我发布 JSON 文件。

JSON 文件是一个多级文件,在 clojure 中被视为持久数组映射。

我要发布的代码是:

(def contacts (http/post "https://api.close.com/api/v1/data/search" 
           {:basic-auth [api ""]
            :body closeFilter 
            })) 

CloseFilter 代表我希望发布的多级 JSON。

但是,我收到以下错误:

class clojure.lang.PersistentArrayMap cannot be cast to class [B (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; [B is in module java.base of loader 'bootstrap')

我在这里犯了什么错误?

更新

我正在用 Javascript 重新创建一个程序。发布相同的文件效果非常好。

更新 2 - MRE

我仍在努力解决这个问题,所以这是我的代码示例。

我的代码首先需要我需要的包:

(ns schedule-emails.core
  (:require [clj-http.client :as http]
            [clojure.data.json :as json]
            [cheshire.core :refer :all]))

然后,我将文件系统中的本地 JSON 文件解析到应用程序中。 JSON。这将返回带有嵌入向量的地图。

(def closeFilter
  (json/read-str
   (slurp "URL TO LOCAL FILE")))

最后,我想将本地文件中的这些信息发布到软件中:

def contacts (http/post "API URL HERE"
           {:accept :json
            :as :json
            :content-type :json
            :basic-auth [api ""]
            :body closeFilter}))

但是,我收到以下错误:

class clojure.lang.PersistentArrayMap cannot be cast to class [B (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; [B is in module java.base of loader 'bootstrap')

我也尝试了下面建议的解决方案,但我遇到了同样的问题。

post clojure clj-http
3个回答
1
投票

clj-http
本身不会与某些后端协商它的内容 期望并强制“自动”传输数据。你可以 但是配置,在 JSON 的情况下,所以一些数据带有 正确的内容类型将从正文转换为 请求,并使用 JSON 从响应返回数据。

  1. 所以你通常想要以下东西 在请求中:

    {:as :auto
     :coerce :always
     :content-type :application/json
     :body ...
     ; your own additional stuff...
     }
    

    所以添加一个mime-type,这样clj-http就知道要做什么,后端也知道 它得到什么。

    参见 输入强制输出强制

  2. 你必须确保让它真正发挥作用的方法 在那儿。这意味着您已添加

    cheshire
    作为依赖项。 请参阅可选依赖项

当然,另一种选择是自己处理这个问题。所以你会 添加了一个库,可以从字符串或流创建 JSON,或者从字符串或流创建 JSON,

content-type
并改变身体/反应。


1
投票

要对请求正文使用内置 JSON 强制,您需要设置

:form-params
而不是
:body
,以及
:content-type :json
:

;; Send form params as a json encoded body (POST or PUT)
(client/post "http://example.com" {:form-params {:foo "bar"} :content-type :json})

详情:https://github.com/dakrone/clj-http#post


0
投票

此错误来自 clj-http/post ,可能是因为

closeFilter
的类型既不是
HttpEntity
实例,也不是 Java 字节数组 (
[B
) 或 java.lang.String。来自
3.12.3
https://github.com/dakrone/clj-http/blob/d92be158230e8094436f415324d96f2bd7cf95f7/src/clj_http/core.clj#L605C1-L611C54

接受的答案假设您想要自动强制。使用 clj-http 时,我倾向于手动将 JSON 序列化为

body
值:

(client/post
 "http://example.com"
 {:content-type :json
  :body (-> form ch/generate-string})
© www.soinside.com 2019 - 2024. All rights reserved.