如何使用cURL发送JSON数据的POST请求?

3751

我使用Ubuntu并在其上安装了cURL。 我想用cURL测试我的Spring REST应用程序。 我已经在Java端编写了我的POST代码,但是我想用cURL进行测试。 我试图发布JSON数据。 示例数据如下:

{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}

我使用这个命令:

curl -i \
    -H "Accept: application/json" \
    -H "X-HTTP-Method-Override: PUT" \
    -X POST -d "value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true \
    http://localhost:8080/xx/xxx/xxxx

它返回了这个错误:

HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 24 Aug 2011 08:50:17 GMT

错误描述如下:

服务器拒绝此请求,因为该请求实体格式不受所请求方法支持的所请求资源支持。

Tomcat日志: "POST /ui/webapp/conf/clear HTTP/1.1" 415 1051

什么是正确的cURL命令格式?

这是我的Java端 PUT 代码(我已经测试了GET和DELETE并且它们可以工作):

@RequestMapping(method = RequestMethod.PUT)
public Configuration updateConfiguration(HttpServletResponse response, @RequestBody Configuration configuration) { //consider @Valid tag
    configuration.setName("PUT worked");
    //todo If error occurs response.sendError(HttpServletResponse.SC_NOT_FOUND);
    return configuration;
}

7
请查看此链接:https://dev59.com/IOo6XIcBkEYKwwoYNBhQ#16909986,了解Spring 3.2.0中的POST请求。 - AmirHd
14
这里有一篇不错的文章使用Curl进行RESTful微服务的即席测试,其中包含多个示例。 - upitau
顺便提一下,在将 JSON 数据发送到服务器之前最好进行压缩。在2023年,使用smart json是更好的选择。 - cwtuan
33个回答

13

我正在使用以下格式与Web服务器进行测试。

use -F 'json data'

假设这个JSON字典格式如下:

{
    'comment': {
        'who':'some_one',
        'desc' : 'get it'
    }
}

完整示例

curl -XPOST your_address/api -F comment='{"who":"some_one", "desc":"get it"}'

1
我看不出这怎么可能是一个通用的答案。你的服务器可能已经配置好处理这种奇怪的格式,但结果可能因人而异。 - MarkHu

11

这对我在Windows 10上起作用:

curl -d "{"""owner""":"""sasdasdasdasd"""}" -H "Content-Type: application/json" -X  PUT http://localhost:8080/api/changeowner/CAR4

9
我制作了一个名为fetcher的工具,用于发送请求和格式化curl代码片段:
这是一个示例:

enter image description here

示例输出:
curl -XGET -H "Accept: application/json" -d "{\"value\":\"30\",\"type\":\"Tip 3\",\"targetModule\":\"Target 3\",\"configurationGroup\":null,\"name\":\"Configuration Deneme 3\",\"description\":null,\"identity\":\"Configuration Deneme 3\",\"version\":0,\"systemId\":3,\"active\":true}" "http://localhost:8080/xx/xxx/xxxx"

3
请求/提示:URL链接应明确拼写,而不仅仅是神秘的“点击这里”。特别是在自我推广您的自制工具时。 - MarkHu

8

我使用了PowerShell:

curl.exe -H "Content-Type: application/json" --data "@content.json" http://localhost:8080/appname/path

其中content.json是本地请求中包含的JSON文件的名称,使用curl.exe而非仅使用curl以避免使用Invoke-WebRequest的别名。

或者,如果您想直接指定JSON:

curl.exe -H "Content-Type: application/json" --data '{\"username\":\"xyz\",\"password\":\"xyz\"}' http://localhost:8080/appname/path

4

--json <data>将指定的JSON数据作为POST请求发送到HTTP服务器。

curl 7.82.0+

# Send a basic JSON object
curl --json '{"name":"xyz","breed":"xyz","age":100}' http://127.0.0.1:3000/cats

# letter @, read the data from a file
curl --json @cat.txt http://127.0.0.1:3000/cats

# letter -, read the data from stdin
echo '{"name":"xyz","breed":"xyz","age":100}' | curl --json @- http://127.0.0.1:3000/cats

curl 7.82.0-

curl -X POST --header "Content-Type: application/json" --data '{"name":"xyz","breed":"xyz","age":100}' http://127.0.0.1:3000/cats

3
  • -H 用于在请求头中添加类似内容类型或认证令牌之类的信息
  • -d 用于添加您的数据
  • 最后添加一个网站链接

注意: 不要忘记添加认证令牌(如果有)以进行身份验证

curl -X POST -H 'Content-Type: application/json' -H 'Authorization: Token 2de403987713595a7955a9b4655b9e206d4294b3' -d '{"title":"Post test with curl", "body": "test body"}' http://127.0.0.1:8000/api/v1/feeds/

2

简单来说

curl -X POST https://localhost:3000/ 
   -H "Content-Type: application/json"
   -d '{"productId": 123456, "quantity": 100}'

2
要使用cURL POST JSON数据,您应该使用带有数据的单引号的-d标志,并使用-H标志指定内容类型为application/json。以下是更正后的cURL命令:
curl -i \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -X POST -d '{"value":"30","type":"Tip 3","targetModule":"Target 3","configurationGroup":null,"name":"Configuration Deneme 3","description":null,"identity":"Configuration Deneme 3","version":0,"systemId":3,"active":true}' \
    http://localhost:8080/xx/xxx/xxxx

更改说明:

  1. 添加了-H "Content-Type: application/json",以指定您在请求体中发送的是JSON数据。
  2. 用单引号(')括起JSON数据,以确保它被cURL视为单个参数。
  3. {}将JSON数据包装起来,以创建一个有效的JSON对象。

这样应该解决了"415 Unsupported Media Type"错误,您的Spring REST应用程序应该能够正确接受JSON数据。


不,这不起作用。JSON解析错误:意外字符('(代码39)):预期有效值(JSON字符串,数字,数组,对象或令牌'null','true'或'false')] - undefined

2

根据Anand Rockzz的答案,这是我在GitHub Actions上所做的。由于EOF标签,这有点棘手。

我的目标是在Vercel部署完成后发送一次HTTP调用(类似于Webhook)。

这个实例可能会帮助其他人。

send-webhook-callback-once-deployment-ready:
  name: Invoke webhook callback url defined by the customer (Ubuntu 18.04)
  runs-on: ubuntu-18.04
  needs: await-for-vercel-deployment
  steps:
    - uses: actions/checkout@v1 # Get last commit pushed - See https://github.com/actions/checkout
    - name: Expose GitHub slug/short variables # See https://github.com/rlespinasse/github-slug-action#exposed-github-environment-variables
      uses: rlespinasse/github-slug-action@v3.x # See https://github.com/rlespinasse/github-slug-action
    - name: Expose git environment variables and call webhook (if provided)
      # Workflow overview:
      #  - Resolves webhook url from customer config file
      #  - If a webhook url was defined, send a
      run: |
        MANUAL_TRIGGER_CUSTOMER="${{ github.event.inputs.customer}}"
        CUSTOMER_REF_TO_DEPLOY="${MANUAL_TRIGGER_CUSTOMER:-$(cat vercel.json | jq --raw-output '.build.env.NEXT_PUBLIC_CUSTOMER_REF')}"

        VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK=$(cat vercel.$CUSTOMER_REF_TO_DEPLOY.staging.json | jq --raw-output '.build.env.VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK')

        # Checking if a webhook url is defined
        if [ -n "$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK" ]; then
          # Run script that populates git-related variables as ENV variables
          echo "Running script populate-git-env.sh"
          . ./scripts/populate-git-env.sh

          echo "Resolved git variables:"
          echo "'GIT_COMMIT_SHA': $GIT_COMMIT_SHA"
          echo "'GIT_COMMIT_REF': $GIT_COMMIT_REF"
          echo "'GIT_COMMIT_TAGS': $GIT_COMMIT_TAGS"

          # Generates JSON using a bash function - See https://dev59.com/Rmw05IYBdhLWcg3wiyfg#57369772
          # "End Of File" must be at the beginning of the line with no space/tab before or after - See https://dev59.com/12cs5IYBdhLWcg3w433H#12909284
          # But, when executed by GitHub Action, it must be inside the "run" section instead
          generate_post_data() {
            cat <<EOF
          {
            "MANUAL_TRIGGER_CUSTOMER": "${MANUAL_TRIGGER_CUSTOMER}",
            "CUSTOMER_REF": "${CUSTOMER_REF_TO_DEPLOY}",
            "STAGE": "staging",
            "GIT_COMMIT_SHA": "${GIT_COMMIT_SHA}",
            "GIT_COMMIT_REF": "${GIT_COMMIT_REF}",
            "GIT_COMMIT_TAGS": "${GIT_COMMIT_TAGS}",
            "GITHUB_REF_SLUG": "${GITHUB_REF_SLUG}",
            "GITHUB_HEAD_REF_SLUG": "${GITHUB_HEAD_REF_SLUG}",
            "GITHUB_BASE_REF_SLUG": "${GITHUB_BASE_REF_SLUG}",
            "GITHUB_EVENT_REF_SLUG": "${GITHUB_EVENT_REF_SLUG}",
            "GITHUB_REPOSITORY_SLUG": "${GITHUB_REPOSITORY_SLUG}",
            "GITHUB_REF_SLUG_URL": "${GITHUB_REF_SLUG_URL}",
            "GITHUB_HEAD_REF_SLUG_URL": "${GITHUB_HEAD_REF_SLUG_URL}",
            "GITHUB_BASE_REF_SLUG_URL": "${GITHUB_BASE_REF_SLUG_URL}",
            "GITHUB_EVENT_REF_SLUG_URL": "${GITHUB_EVENT_REF_SLUG_URL}",
            "GITHUB_REPOSITORY_SLUG_URL": "${GITHUB_REPOSITORY_SLUG_URL}",
            "GITHUB_SHA_SHORT": "${GITHUB_SHA_SHORT}"
          }
        EOF
          }

          echo "Print generate_post_data():"
          echo "$(generate_post_data)"

          echo "Calling webhook at '$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK'"
          echo "Sending HTTP request (curl):"
          curl POST \
            "$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK" \
            -vs \
            --header "Accept: application/json" \
            --header "Content-type: application/json" \
            --data "$(generate_post_data)" \
            2>&1 | sed '/^* /d; /bytes data]$/d; s/> //; s/< //'

          # XXX See https://dev59.com/UXNA5IYBdhLWcg3wrf83#54225157
          # -vs - add headers (-v) but remove progress bar (-s)
          # 2>&1 - combine stdout and stderr into single stdout
          # sed - edit response produced by curl using the commands below
          #   /^* /d - remove lines starting with '* ' (technical info)
          #   /bytes data]$/d - remove lines ending with 'bytes data]' (technical info)
          #   s/> // - remove '> ' prefix
          #   s/< // - remove '< ' prefix

        else
          echo "No webhook url defined in 'vercel.$CUSTOMER_REF_TO_DEPLOY.staging.json:.build.env.VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK' (found '$VERCEL_DEPLOYMENT_COMPLETED_WEBHOOK')"
        fi

2
您可以通过--data-raw参数将JSON文件的内容传输到curl中。 curl 'https://api.com/route' -H 'Content-Type: application/json' --data-raw "$(cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//')" 注意:使用grep -v '^\s*//'过滤掉JSON文件中的注释。
您也可以使用grepcat通过标准输入将数据传递给curlgrep -v '^\s*//' ~/.json/payload-2022-03-03.json | curl 'https://api.com/route' -H 'Content-Type: application/json' -d @- 将 ~/.json/payload-2022-03-03.json 文件中的内容读取出来,去除以 // 开头的注释行,并将结果通过 POST 请求发送到 https://api.com/route 接口,请求内容的类型为 application/json。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接