如何使用 Apache Camel HTTP 组件进行多部分文件上传?
4 回答
我不知道是否可以使用 HTTP 组件发送多部分表单。
如果您需要解决方法,您可以创建使用 Apache Http Client(及其MultipartPostMethod
)的 POJO Spring Bean。然后您可以将您的消息路由到该 bean:
from("activemq:uploadQueue").to("bean:myApacheHttpClientBean?method=sendMultiPart")
只要您的消息正文是 multipart/form-data 格式,您就可以使用 Camel http 组件将其 POST 到另一台服务器。诀窍是正确设置您的 Content-Type 并将请求方法设置为 POST:
<route>
<from uri="direct:start"/>
<setBody>
<![CDATA[
--__MyCoolBoundary__
Content-Disposition: form-data; name="name"
Paul Mietz Egli
--__MyCoolBoundary__
Content-Disposition: form-data; name="email"
paul@example.com
--__MyCoolBoundary__--
]]>
</setBody>
<setHeader headerName="Content-Type">
<constant>multipart/form-data; boundary="__MyCoolBoundary__"</constant>
</setHeader>
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<to uri="http://www.example.com/mywebservice.php"/>
</route>
显然,上面的示例正文并没有那么有用,因为它都是静态数据。有多种方法可以构建主体——我使用了文本模式下的 XSLT 输出、脚本表达式(例如 <groovy>...</groovy>)和 Spring bean。当传入的消息正文已经是 XML 文档时,XSLT 可以很好地工作:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
--__MyCoolBoundary__
Content-Disposition: form-data; name="name"
<xsl:value-of select="//name"/>
--__MyCoolBoundary__--
</xsl:stylesheet>
但是,您确实需要小心额外的空格。希望这可以帮助!
我曾通过以下功能从事网络项目:
登录表格:人登录并可以上传文件;(骆驼:码头、Http、JDBC)
上传表格;上传 servlet:如果人们可以登录;可以上传xml文件到ftp或者web服务器;(骆驼:文件)
3.文件由我的 .xsd 文件验证;(骆驼:验证者)
- 文件由我的 .xsl 模式文件检查;(骆驼:XSLT)
我是由我最喜欢的 IDE(Jetbrains的 IntelliJ IDEA )创建的 Web 项目;我用源代码描述了我的部分场景,希望这很有用☺</p>
1) index.html
<form action="http://0.0.0.0:8080/hello" method="post">
<fieldset title="Login" >
username:<input type="text" id="user" name="user"/>
password:<input type="password" id="pass" name="pass" />
<input type="submit" id="submit" value="submit"/>
</fieldset>
首先你必须创建数据库和登录表;然后添加一些样本数据;例如添加这些文件:
2)schema.sql
DROP TABLE IF EXISTS CONTACT;
CREATE TABLE CONTACT (
ID INT NOT NULL AUTO_INCREMENT
, NAME VARCHAR(40) NOT NULL
, USERNAME VARCHAR(40) NOT NULL
, PASSWORD VARCHAR(60) NOT NULL
, VERSION INT NOT NULL DEFAULT 0
, UNIQUE UQ_CONTACT_1 (USERNAME)
, PRIMARY KEY (ID));
3) 测试数据.sql
insert into contact (name, username, password) values ('ali', 'aliti', '123');
insert into contact (name, username, password) values ('shahab', 'shahab', '147');
insert into contact (name, username, password) values ('farhad', 'farhad', '159');
4) 配置 spring-context.xml
然后,您可以使用嵌入式数据库,如 derby、H2、mysql 或其他。将以下配置添加到您的 spring 配置文件中:
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
5)骆驼上下文.xml
现在,您可以运行您的项目了;在此之前,您必须将此路线添加到您的骆驼上下文中:
<route>
<from uri="jetty:http://0.0.0.0:8080/hello"/>
<setBody>
<simple>
select * from contact where USERNAME = '${in.header.user}' and PASSWORD = '${in.header.pass}'
</simple>
</setBody>
<to uri="jdbc:dataSource"/>
<process ref="loginProcessor"/>
<log message=">>>header: ${in.header.name}"/>
<choice>
<when>
<simple>${in.header.name} == null</simple>
<to uri="jetty://http://localhost:9090/fail.html?bridgeEndpoint=true"/>
</when>
<otherwise>
<to uri="jetty://http://localhost:9090/file.html?bridgeEndpoint=true"/>
</otherwise>
</choice>
当您运行我们的项目时;index.html 页面已显示,您可以输入用户名和密码文本框并发送您的表单。
实际上,骆驼正在监听这个码头端口并获得了您的帖子信息。您可以通过 Camel 的标头(例如 '${in.header.user}')获取这些信息。
如您所见,我在 Camel's Body 中设置了我的选择查询,因此选择结果也存储在 Camel's Body 中。我想阅读我的结果并做出一些决定,因此我添加了 Camel 处理器,如下所示:
6) 登录处理器.java
public class LoginProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
int size = ((ArrayList) exchange.getIn().getBody()).size();
if (size > 0) {
Object name = ((LinkedHashMap) (((ArrayList) exchange.getIn().getBody()).get(0))).get("NAME");
System.out.println("welcome user: " + name);
exchange.getOut().setHeader("name",name);
} else {
System.out.println("user or pass are invalid. ");
exchange.getOut().setHeader("name",null);
}
}
}
在 LoginProcessor 我检查了正文,输入的用户名和密码是否有效;添加 Camel 的 header 属性,并按表的字段名称以 'name' 命名。否则在 Camel 的 header 属性中设置 null 值。
返回 Camel 上下文 xml 文件并继续路由。如果 Camel 的 header 为 null;将用户重定向到 fail.html 页面;否则重定向到从用户(file.html)获取文件的页面。
注意:bridgeEndpoint 属性您将 http 端点设置为 bridgeEndpoint,这意味着请求 url 将使用请求 URI 进行更新。
您能否提供更多详细信息,您希望多部分表单如何到达 apache camel?
它应该是直接发送到骆驼路线的网页上的某种形式吗?还是 AMQ 队列?我建议您检查Apache HTTP和Apache Jetty组件。