英文:
Apache camel how to submit body in "body" format
问题
使用Apache Camel,我有一个Rest组件。它看起来像这样:
<post uri="/body" method="POST">
<description>Here is post method</description>
<param name="save" type="body" dataType="string"/>
<route>
<process ref="postRedirectProcessor" />
<to uri="direct:commonRoute" />
</route>
</post>
而且这个端点可以正常处理这样的请求:
curl -i --data "b=hereisbody" http://localhost:8080/body(可以正常工作,但我不需要它)
(我可以看到它进入了**postRedirectProcessor**,这是正常的)。但这不是我想要的。我希望它处理像这样的请求:
```bash
curl -i --data "hereisbody" http://localhost:8080/body(不起作用,导致405错误)
我的意思是,"data"的格式不像"k=v&k2=v2",而是一个字符串,就像示例中的一样(例如**--data "something"**)。
这会导致异常,它不会进入postRedirectProcessor。
2020-04-10 18:43:09,716 ERROR [http-nio-8080-exec-6] - ,,, - 在没有路径的上下文中为servlet [CamelServlet] 提供服务时抛出异常
java.lang.IllegalArgumentException: 无效的参数,预期是一对键值对,但实际是hereisbody
at org.apache.camel.http.common.DefaultHttpBinding.readFormUrlEncodedBody(DefaultHttpBinding.java:272) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.DefaultHttpBinding.readRequest(DefaultHttpBinding.java:116) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.HttpMessage.<init>(HttpMessage.java:56) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.CamelServlet.doService(CamelServlet.java:187) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.CamelServlet.service(CamelServlet.java:79) ~[camel-http-common-2.24.3.jar:2.24.3]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
我以为在xml中发布的**param type="body"**会奏效,但没有成功。
<details>
<summary>英文:</summary>
Using Apache camel, I have Rest component. It looks like:
<post uri="/body" method="POST">
<description>Here is post method</description>
<param name="save" type="body" dataType="string"/>
<route>
<process ref="postRedirectProcessor" />
<to uri="direct:commonRoute" />
</route>
</post>
And this endpoint processes fine requests like this:
curl -i --data "b=hereisbody" http://localhost:8080/body (works fine, but I don't need it)
(I can see it goes into **postRedirectProcessor** and that is fine). But this is not what I want. I want it to process requests like this:
curl -i --data "hereisbody" http://localhost:8080/body (doesn't work, causes 405)
I mean, format of "data" is **not** like **k=v&k2=v2**, but it is just string, like in example (such as **--data "something"**).
It causes an exception, it doesn't go into postRedirectProcessor.
2020-04-10 18:43:09,716 ERROR [http-nio-8080-exec-6] - ,,, - Servlet.service() for servlet [CamelServlet] in context with path [] threw exception
java.lang.IllegalArgumentException: Invalid parameter, expected to be a pair but was hereisbody
at org.apache.camel.http.common.DefaultHttpBinding.readFormUrlEncodedBody(DefaultHttpBinding.java:272) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.DefaultHttpBinding.readRequest(DefaultHttpBinding.java:116) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.HttpMessage.<init>(HttpMessage.java:56) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.CamelServlet.doService(CamelServlet.java:187) ~[camel-http-common-2.24.3.jar:2.24.3]
at org.apache.camel.http.common.CamelServlet.service(CamelServlet.java:79) ~[camel-http-common-2.24.3.jar:2.24.3]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.31.jar:9.0.31]
I thought, **param type="body"** as in xml posted, does the trick, but no luck.
</details>
# 答案1
**得分**: 1
Curl 默认使用 `--data` 将数据以 `Content-Type: application/x-www-form-urlencoded` 头部发送。参见 https://stackoverflow.com/questions/43054195/how-to-post-raw-body-data-with-curl
`x-www-form-urlencoded` 必须采用键值对格式([规范](https://www.w3.org/TR/html401/interact/forms.html))。这是抛出异常的原因。
> 名称与值之间用 `=` 分隔,名称/值对之间用 `&` 分隔。
要发送原始数据,您需要指定另一种 `Content-Type`。
curl -v -i -H "Content-Type: text/plain" --data "hereisbody" http://localhost:8080/body
<details>
<summary>英文:</summary>
Curl sends data in `--data` with `Content-Type: application/x-www-form-urlencoded` header by default. See https://stackoverflow.com/questions/43054195/how-to-post-raw-body-data-with-curl
`x-www-form-urlencoded` must be in key/value format ([specification](https://www.w3.org/TR/html401/interact/forms.html)). This is reason, why exception is thrown.
> The name is separated from the value by `=` and name/value pairs are separated from each other by `&`.
To send raw data you need to specify another `Content-Type`.
curl -v -i -H "Content-Type: text/plain" --data "hereisbody" http://localhost:8080/body
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论