Apache Camel如何以”body”格式提交请求体

huangapple go评论72阅读模式
英文:

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:

        &lt;post uri=&quot;/body&quot; method=&quot;POST&quot;&gt;
            &lt;description&gt;Here is post method&lt;/description&gt;
            &lt;param name=&quot;save&quot; type=&quot;body&quot; dataType=&quot;string&quot;/&gt;
            &lt;route&gt;
                &lt;process ref=&quot;postRedirectProcessor&quot; /&gt;
                &lt;to uri=&quot;direct:commonRoute&quot; /&gt;
            &lt;/route&gt;
        &lt;/post&gt;

And this endpoint processes fine requests like this:

    curl -i --data &quot;b=hereisbody&quot; http://localhost:8080/body (works fine, but I don&#39;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 &quot;hereisbody&quot; http://localhost:8080/body (doesn&#39;t work, causes 405)
I mean, format of &quot;data&quot; is **not** like **k=v&amp;k2=v2**, but it is just string, like in example (such as **--data &quot;something&quot;**). 

It causes an exception, it doesn&#39;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.&lt;init&gt;(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=&quot;body&quot;** 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))。这是抛出异常的原因。

&gt; 名称与值之间用 `=` 分隔,名称/值对之间用 `&amp;` 分隔。

要发送原始数据,您需要指定另一种 `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.

&gt; The name is separated from the value by `=` and name/value pairs are separated from each other by `&amp;`.

To send raw data you need to specify another `Content-Type`.

    curl -v -i -H &quot;Content-Type: text/plain&quot; --data &quot;hereisbody&quot; http://localhost:8080/body

</details>



huangapple
  • 本文由 发表于 2020年4月10日 19:50:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/61139668.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定