Apache Camel多部分HTTP post(文件上载)

xriantvc  于 2022-11-07  发布在  Apache
关注(0)|答案(5)|浏览(277)

如何使用Apache Camel HTTP组件进行多部分文件上载?

rfbsl7qr

rfbsl7qr1#

我不知道是否可以使用HTTP组件发送多部分表单。
如果需要解决方法,可以创建使用Apache Http客户端(及其MultipartPostMethod)的POJO Spring Bean。然后,可以将消息路由到该Bean:

from("activemq:uploadQueue").to("bean:myApacheHttpClientBean?method=sendMultiPart")
wsxa1bj1

wsxa1bj12#

只要您的消息正文是multipart/form-data格式,您就可以使用Camel http组件将其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以文本模式输出、脚本表达式(例如...)和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>

不过,你确实需要小心多余的空格。希望这对你有帮助!

i2byvkas

i2byvkas3#

我曾在一个网络项目的工作,通过以下功能:
1.登录表单:用户登录后即可上传文件;(Camel:码头、Http、JDBC)
1.上传表单;上载servlet:是否可以登录;可以将xml文件上传到ftp或web服务器;( Camel :文件)
3.文件由我的.xsd文件验证;(Camel:验证器)
1.文件由我的.xsl架构文件检查;( Camel :XSLT)
我正在用我最喜欢IDE(Jetbrains的IntelliJ IDEA)创建Web项目;我用源代码描述了我的场景的一部分,希望这对我有用

  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));
  1. test-data.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上下文. 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>
  1. camel-context.xml
    现在,您可以运行您的项目;在此之前,您必须将此路由添加到您camel上下文中:
<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正在监听这个码头端口,并获得了您的帖子信息。您可以通过Camel的头(如“${in.header.user}”)获得这些信息。
如您所见,我将选择查询设置在Camel 's Body中,因此选择结果也存储在Camel' s Body中。我希望读取我的结果并获得一些决策,因此我添加了Camel处理器,如下所示:
6) LoginProcessor.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属性中设置空值。
返回Camel上下文xml文件并继续路由。如果Camel的标头为空;将用户重定向到fail.html页面;否则重定向到从用户处获取文件的页面(file.html)。
注意:bridgeEndpoint属性您正在将http端点设置为bridgeEndpoint,这意味着将使用请求URI更新请求URL。

pxiryf3j

pxiryf3j4#

你能提供更多的细节,你想如何多部分形式达到Apache Camel ?
它应该是网页上直接发送到Camel路由的表单吗?还是AMQ队列?我建议你检查Apache HTTPApache Jetty组件。

nr9pn0ug

nr9pn0ug5#

您可以通过编程方式来完成
路由:

from("jetty:{{camel.address}}/" + method)
    .process(ex -> SomeClassProcessing.ProcessMultipart(ex));

加工过程:

public class SomeClassProcessing {
public static void ProcessMultipart(Exchange exchange) {
    AttachmentMessage attIn = exchange.getIn(AttachmentMessage.class);
    Map<String, DataHandler> atts = attIn.getAttachments();

    for (var pair: atts.entrySet()) {
        var fileName = pair.getKey();
        var att = pair.getValue();

        var is = att.getInputStream();
        var fileContent = new byte[is.available()];
        is.read(fileContent);

        // Now file content is in array of byte
    }
}

相关问题