【问题标题】:Apache Camel multipart HTTP post (file upload)Apache Camel 多部分 HTTP 帖子(文件上传)
【发布时间】:2011-01-25 19:41:59
【问题描述】:

如何使用 Apache Camel HTTP 组件进行分段文件上传?

【问题讨论】:

    标签: java apache-camel


    【解决方案1】:

    我曾通过以下功能从事网络项目:

    1. 登录表单:人登录并可以上传文件; (骆驼:Jetty、Http、JDBC)

    2. 上传表格;上传 servlet:如果人们可以登录;可以上传xml文件到ftp或者web服务器; (骆驼:文件)

    3.文件由我的 .xsd 文件验证; (骆驼:验证者)

    1. 文件由我的 .xsl 架构文件检查; (骆驼:XSLT)

    我是通过我最喜欢的 IDE(Jetbrains 的 IntelliJ IDEA)创建 Web 项目; 我用源代码描述了我的部分场景,希望这很有用☺

    1) 索引.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 正在监听这个码头端口并获得了您的帖子信息。 您可以通过 Camel 的 header 获取这些信息,例如 '${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 属性,并通过 table 的字段名称以“name”命名。否则在 Camel 的 header 属性中设置 null 值。

    返回 Camel 上下文 xml 文件并继续路线。 如果 Camel 的 header 为 null;将用户重定向到 fail.html 页面;否则重定向到从用户(file.html)获取文件的页面。

    注意:bridgeEndpoint 属性 您将 http 端点设置为 bridgeEndpoint,这意味着请求 url 将使用请求 URI 进行更新。

    【讨论】:

      【解决方案2】:

      只要您的消息正文是 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 输出、脚本表达式(例如 ...)和 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>
      

      但是,您确实需要小心额外的空格。希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        您能否提供更多详细信息,您希望多部分表单如何到达 apache camel?

        应该是直接发送到骆驼路线的网页上的某种形式吗?还是 AMQ 队列? 我建议您检查Apache HTTP 和Apache Jetty 组件。

        【讨论】:

          【解决方案4】:

          我不知道是否可以使用 HTTP 组件发送多部分表单。

          如果您需要解决方法,您可以创建使用 Apache Http 客户端(及其MultipartPostMethod)的 POJO Spring Bean。然后您可以将您的消息路由到该 bean:

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

          【讨论】:

          • @KaiSternad:你能详细解释一下你是怎么做到的吗?
          • @AbhishekRanjan 很抱歉,我不记得细节了。已经有一段时间了。
          猜你喜欢
          • 1970-01-01
          • 2014-09-05
          • 1970-01-01
          • 2019-06-08
          • 1970-01-01
          • 2012-03-01
          • 1970-01-01
          • 2013-01-23
          • 1970-01-01
          相关资源
          最近更新 更多