我使用 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;
}
您需要将内容类型设置为 application/json。但是 -d
(或 --data
)发送 Content-Type application/x-www-form-urlencoded
,这在 Spring 方面是不被接受的。
查看 curl man page,我认为您可以使用 -H
(或 --header
):
-H "Content-Type: application/json"
完整示例:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"username":"xyz","password":"xyz"}' \
http://localhost:3000/api/login
(-H
是 --header
的缩写,-d
是 --data
的缩写)
请注意,如果您使用 -d
,则 -request POST
是可选,因为 -d
标志意味着一个 POST 请求。
在 Windows 上,情况略有不同。请参阅评论线程。
尝试将您的数据放入文件中,例如 body.json
,然后使用
curl -H "Content-Type: application/json" --data @body.json http://localhost:8080/ui/webapp/conf
--data-binary
选项而不是 --data
。人们会期望客户端按原样发送数据,但 --data
从输入中去除 CR 和 LF。
@
字符,否则将不起作用。我只花了 20 分钟在这个垃圾上敲我的头......
对于 Windows,对 -d
值使用单引号对我不起作用,但在更改为双引号后它确实起作用。我还需要在大括号内转义双引号。
也就是说,以下内容不起作用:
curl -i -X POST -H "Content-Type: application/json" -d '{"key":"val"}' http://localhost:8080/appname/path
但以下工作:
curl -i -X POST -H "Content-Type: application/json" -d "{\"key\":\"val\"}" http://localhost:8080/appname/path
您可能会发现 resty 很有用:https://github.com/micha/resty
它是一个 CURL 的包装器,它简化了命令行 REST 请求。您将它指向您的 API 端点,它会为您提供 PUT 和 POST 命令。 (示例改编自主页)
$ resty http://127.0.0.1:8080/data #Sets up resty to point at your endpoing
$ GET /blogs.json #Gets http://127.0.0.1:8080/data/blogs.json
#Put JSON
$ PUT /blogs/2.json '{"id" : 2, "title" : "updated post", "body" : "This is the new."}'
# POST JSON from a file
$ POST /blogs/5.json < /tmp/blog.json
此外,通常仍然需要添加 Content Type 标头。不过,您可以这样做一次,以设置默认值,即为每个站点的每个方法添加配置文件:Setting default RESTY options
它对我有用:
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":100}' http://localhost/api/postJsonReader.do
它很高兴地映射到 Spring 控制器:
@RequestMapping(value = "/postJsonReader", method = RequestMethod.POST)
public @ResponseBody String processPostJsonData(@RequestBody IdOnly idOnly) throws Exception {
logger.debug("JsonReaderController hit! Reading JSON data!"+idOnly.getId());
return "JSON Received";
}
IdOnly
是具有 id 属性的简单 POJO。
https://i.stack.imgur.com/g8F0j.png
https://i.stack.imgur.com/fD0dp.png
笔记:
最新的 Postman 版本进行了一些 UI 升级,现在侧栏中提供了代码链接。
https://i.stack.imgur.com/7vOBG.png
例如,创建一个 JSON 文件 params.json,并将以下内容添加到其中:
[
{
"environment": "Devel",
"description": "Machine for test, please do not delete!"
}
]
然后你运行这个命令:
curl -v -H "Content-Type: application/json" -X POST --data @params.json -u your_username:your_password http://localhost:8000/env/add_server
~/.curlrc
文件:--header Content-Type:Application/JSON
我只是遇到了同样的问题。我可以通过指定来解决它
-H "Content-Type: application/json; charset=UTF-8"
这对我来说效果很好。
curl -X POST --data @json_out.txt http://localhost:8080/
在哪里,
-X
表示 http 动词。
--data
表示您要发送的数据。
-X POST
在此示例中是多余的
--data
而不是 -d
。这取决于团队对 Bash 的整体使用情况,但对于 Bash 初学者和不每天使用它的人来说绝对更容易。
您可以使用 Postman 及其直观的 GUI 来组装您的 cURL
命令。
安装并启动 Postman 输入您的 URL、帖子正文、请求标头等。 pp. 单击代码 从下拉列表中选择 cURL 复制并粘贴您的 cURL 命令
注意:下拉列表中有几个用于自动生成请求的选项,这就是为什么我认为我的帖子首先是必要的。
HTTPie 是 curl
的推荐替代品,因为您可以这样做
$ http POST http://example.com/some/endpoint name=value name1=value1
它默认使用 JSON,并且会为您设置必要的标头以及将数据编码为有效的 JSON。还有:
Some-Header:value
对于标题,和
name==value
用于查询字符串参数。如果你有大量数据,你也可以从一个文件中读取它,并对其进行 JSON 编码:
field=@file.txt
httpie
支持溢出 curl
格式的命令,那将是很好的,以应对 httpie
在特定主机上不可用的情况。
使用 CURL Windows,试试这个:
curl -X POST -H "Content-Type:application/json" -d "{\"firstName\": \"blablabla\",\"lastName\": \"dummy\",\"id\": \"123456\"}" http-host/_ah/api/employeeendpoint/v1/employee
这对我来说效果很好,另外还使用了 BASIC 身份验证:
curl -v --proxy '' --basic -u Administrator:password -X POST -H "Content-Type: application/json"
--data-binary '{"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://httpbin.org/post
当然,您永远不应该在没有 SSL 和经过检查的证书的情况下使用 BASIC 身份验证。
我今天又遇到了这个问题,使用 Cygwin 的 cURL 7.49.1 for Windows...当使用带有 JSON 参数的 --data
或 --data-binary
时,cURL 会感到困惑,并将 JSON 中的 {}
解释为 URL 模板.添加一个 -g
参数来关闭 cURL globbing 解决了这个问题。
另请参阅Passing a URL with brackets to curl。
您还可以将 JSON 内容放在一个文件中,并使用 --upload-file
选项通过标准输入将其传递给 curl,如下所示:
echo 'my.awesome.json.function({"do" : "whatever"})' | curl -X POST "http://url" -T -
使用 -d 选项添加有效负载
curl -X POST \
http://<host>:<port>/<path> \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"foo": "bar",
"lorem": "ipsum"
}'
此外:
使用 -X POST 使用 POST 方法
使用 -H 'Accept: application/json' 添加接受类型标头
使用 -H 'Content-Type: application/json' 添加内容类型标头
curl
的 -v
开关以获取更多详细信息。您点击的服务可能只处理某些内容类型值。
TL;博士:
使用神圣的三位一体,jo
+ curl
+ jq
(或 fx
):
jo value=30 type="Tip 3" targetModule="Target 3" configurationGroup=null name="Configuration Deneme 3" description=null identity="Configuration Deneme 3" | \
curl --json @- \
-X POST \
http://localhost:8080/xx/xxx/xxxx | \
jq
这将涵盖缺少的必要标头:无需显式定义 Content-Type
和 Accept
标头。
使用 --json 的新卷曲方式
2022 年 3 月上旬,curl
发布了 a new command line parameter --json
版本 7.82.0。这允许通过 JSON 发送快捷方式,并且无需定义 Content-Type
您丢失的 和 Accept
标头,因为这些是自动假定的,从而降低了出错的风险:
curl --json '{"tool": "curl"}' https://example.com/
但是等等……还有更多。不要将 json 参数定义为 curl
命令行的字符串,而是使用 nifty jo
CLI tool 将 JSON 定义为一系列键值对并通过 curl 管道输出。仅使用 jo
来定义您的 JSON,它的工作方式如下:
> jo -p 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
{
"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
命令展示这一点,但没有额外的标题,并使用 jo
+ jq
来获得漂亮的输出:
jo value=30 type="Tip 3" targetModule="Target 3" configurationGroup=null name="Configuration Deneme 3" description=null identity="Configuration Deneme 3" | \
curl --json @- \
-X POST \
http://localhost:8080/xx/xxx/xxxx | \
jq
带有免费 API 的示例
Using a free (but limited) API 用于演示:
> jo name=Grogu gender=male email=frog.menace@jedi.edu status=active | \
curl --json @- \
-H $env:GOREST_TOKEN \
-XPATCH "https://gorest.co.in/public/v2/users/1138" | \
jq
由于 jq
,输出具有漂亮的格式:
{
"email": "frog.menace@jedi.edu",
"name": "Grogu",
"gender": "male",
"status": "active",
"id": 1138
}
brew
安装了 curl
,您还可以通过 brew upgrade curl
获取 7.82.0
这对我有用:
curl -H "Content-Type: application/json" -X POST -d @./my_json_body.txt http://192.168.1.1/json
我知道,这个问题已经回答了很多,但想分享一下我遇到的问题:
curl -X POST http://your-server-end-point -H "Content-Type: application/json" -d @path-of-your-json-file.json
看,我做的一切都是正确的,只有一件事 - 我在 JSON 文件路径之前错过了“@”。
我在互联网上找到了一份相关的首选文档 - https://gist.github.com/subfuzion/08c5d85437d5d4f00e58
希望对少数人有所帮助。谢谢
如果您要包含动态数据,这是另一种方法。
#!/bin/bash
version=$1
text=$2
branch=$(git rev-parse --abbrev-ref HEAD)
repo_full_name=$(git config --get remote.origin.url | sed 's/.*:\/\/github.com\///;s/.git$//')
token=$(git config --global github.token)
generate_post_data()
{
cat <<EOF
{
"tag_name": "$version",
"target_commitish": "$branch",
"name": "$version",
"body": "$text",
"draft": false,
"prerelease": false
}
EOF
}
echo "Create release $version for repo: $repo_full_name branch: $branch"
curl --data "$(generate_post_data)" "https://api.github.com/repos/$repo_full_name/releases?access_token=$token"
我正在使用以下格式使用 Web 服务器进行测试。
use -F 'json data'
让我们假设这个 JSON dict 格式:
{
'comment': {
'who':'some_one',
'desc' : 'get it'
}
}
完整示例
curl -XPOST your_address/api -F comment='{"who":"some_one", "desc":"get it"}'
这在 Windows10 上对我有用
curl -d "{"""owner""":"""sasdasdasdasd"""}" -H "Content-Type: application/json" -X PUT http://localhost:8080/api/changeowner/CAR4
为此,我制作了一个名为 fetcher 的工具。它可以发送请求并格式化 curl 片段:
这是一个例子:
https://i.stack.imgur.com/pYTNO.png
示例输出:
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"
对于 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
-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/
问题在这里
HTTP/1.1 415 Unsupported Media Type
服务器登录无法解释此请求的媒体类型,因此将其解析为 text/html
任何资源的媒体类型都在请求头的 Content-Type 属性中声明
"accept" ... 标头将失败此请求,因此发送任何 JSON 请求都需要以下内容,即内容类型
-H 'content-type: application/json'
假设数据和 URL 是这样的
{“电子邮件”:“admin@admin.com”,“密码”:“123456”}
http://localhost:5000/api/login
然后在 LINUX
curl http://localhost:5000/api/login -H 'content-type: application/json' -d '{"email": "user@admin.com", "password": "123456"}'
在 WINDOWS 中(参数周围的单引号不起作用)
curl http://localhost:5000/api/login -H "content-type: application/json" -d "{\"email\": \"user@admin.com\", \"password\": \"123456\"}"
当 -d {.....} 出现在命令中时,不需要 -X POST 键
对于 Put 请求
-X PUT
根据 https://stackoverflow.com/a/57369772/2391795 的回答,这是我在 GitHub Actions 上对此所做的。由于 EOF
标记,这有点棘手。
我的目标是在 Vercel 部署完成后发送 HTTP 调用(类似于 webhook)。
希望这个 real-world example 可以帮助其他人。
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://stackoverflow.com/a/57369772/2391795
# "End Of File" must be at the beginning of the line with no space/tab before or after - See https://stackoverflow.com/a/12909284/2391795
# 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://stackoverflow.com/a/54225157/2391795
# -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
您可以通过 --data-raw
参数将 json
文件的内容 cat
到 curl
curl 'https://api.com/route' -H 'Content-Type: application/json' --data-raw "$(cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//')"
注意:json 文件中的注释通过 grep -v '^\s*//'
过滤掉
您还可以使用 grep
或 cat
通过 stdin
将数据传递给 curl
grep -v '^\s*//' ~/.json/payload-2022-03-03.json | curl 'https://api.com/route' -H 'Content-Type: application/json' -d @-
cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//' | curl 'https://api.com/route' -H 'Content-Type: application/json' -d @-
curl -X POST -H "Content-Type: application/json" -d "{ \"key1\": \"value1\" }" http://localhost:3000/api/method
"{ """key1""": """value1""" }"
的引号来转义引号。还有这个答案:stackoverflow.com/questions/18314796/…"Content-Type: application/json"
,而不仅仅是"application/json"
。这浪费了我很多时间...