CppCMS支持文件上传

HTTP文件上传

先制作一个简单的html页面,只包含了一个form

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
          "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    test upload
  </head>

  <body>
    <form method="post" name="submit" enctype="multipart/form-data">
      <input type="file" name="fileField"><br /><br />
      <input type="submit" name="submit" value="Submit">
    </form>
  </body>

</html>

form采用post方法提交. enctype的内容应该填写MIME_type,规定from的数据发送给服务器之前如何编码。

这里为了文件上传,必须指定multipart/form-data,也就是要求不要编码。

默认的enctype值是application/x-www-form-urlencoded,会对字符进行编码。

具体参考文档:http://www.w3school.com.cn/tags/att_form_enctype.asp


MIME

因为已经涉及到MIME,这里顺便介绍一下。全称是Multipurpose Internet Mail Extensions.

这个对mail的扩展协议允许mail message能够支持非ASCII字符,二进制格式附件等多种格式。

它的写法格式是:

Content-Type: [type]/[subtype]; parameter
比如multipart是 type, form-data是 subtype。

具体请参考:http://zh.wikipedia.org/wiki/MIME

HTTP协议有时候也会使用MIME,但并不完全遵循MIME。


CppCMS示例

这个程序很简单,upload 一个pdf文件,然后保存到文件系统。我没有使用CppCMS的Form类,因为那是用C++类渲染HTML Form以及里面的html tags。就像JSF一样,会把事情搞复杂。我并不欣赏这种设计。因此我用的是CppCMS的最基本的方法,从request里获取上传的文件对象,然后保存到磁盘上。因此我的例子比CppCMS的example更好理解。

首先创建CMake工程,目录结构如下:

chenshu@chenshu-beijing:~/work/research/upload$ tree
.
├── CMakeLists.txt
├── config.js
├── include
│ ├── controller
│ │ └── upload_site.h
│ └── model
│     └── content.h
├── src
│ ├── CMakeLists.txt
│ ├── controller
│ │ └── upload_site.cpp
│ ├── main.cpp
│ └── view
│     └── upload.cpp
└── template
    └── upload.tmpl

7 directories, 9 files

因为CppCMS也是一个MVC架构,controller目录中的upload_site.cpp负责:

1.负责调用渲染引擎,生成并返回网页

2.将不同的HTTP URL映射到不同的函数


template目录存放了要渲染的网页模板文件。

view目录存放了CppCMS解析模板文件生成的C++类

model存放了渲染网页时需要的数据


现在看一下config.js,配置很简单:

{
    "service" : {
	"ip":"0.0.0.0",
        "api" : "http",
        "port" : 8081
    },
    "http" : {
        "script_names" : ["/cppcms"]
    }
}

好,将一开始的html页面转成upload.tmpl文件。

<% c++ #include "model/content.h" %>
<% skin upload %>
<% view upload_view uses content::upload_content %>
<% template render() %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    test upload
  </head>

  <body>
    <form method="post" action="./process_uploaded_file" name="submit" enctype="multipart/form-data">
      <input type="file" name="fileField"><br /><br />
      <input type="submit" name="submit" value="Submit">
    </form>
  </body>

</html>
<% end template %>
<% end view %>
<% end skin %>

model/content.h就是一个目前什么都没有的C++类,以便日后使用:

#ifndef CONTENT_H
#define CONTENT_H

#include <cppcms/view.h>

namespace content  {

    struct upload_content : public cppcms::base_content {

    };
}

#endif

现在重点看一下controller,

upload_site.h

#include <cppcms/application.h>
#include <cppcms/applications_pool.h>
#include <cppcms/service.h>

class upload_site : public cppcms::application {
public:
    upload_site(cppcms::service &srv);
    void upload_page();
    void process_uploaded_file();
};

upload_site.cpp

#include "controller/upload_site.h"
#include <cppcms/url_dispatcher.h>
#include "model/content.h"
#include <cppcms/http_file.h>

using namespace std;


upload_site::upload_site(cppcms::service &srv):cppcms::application(srv) {
    //web page
    dispatcher().assign("/upload" , &upload_site::upload_page, this);

    dispatcher().assign("/process_uploaded_file" , &upload_site::process_uploaded_file, this);
}

void upload_site::upload_page() { 
  content::upload_content content;
  render("upload","upload_view", content);
}

void upload_site::process_uploaded_file() {
  if(request().request_method()=="POST") {
    cppcms::http::request::files_type files = request().files();
    int size = files.size();
    booster::shared_ptr<cppcms::http::file> file = files.at(0);
    string file_name = file->filename();
    file->save_to("/home/chenshu/"+file_name);
  }
}

我的src/CMakeLIsts.txt

cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Debug)
set(TEMPLATE_DIR ${CMAKE_SOURCE_DIR}/template)
set(VIEW_DIR ${CMAKE_SOURCE_DIR}/src/view)

find_package (Threads)
find_package(Boost COMPONENTS system filesystem REQUIRED)

include_directories(${CMAKE_SOURCE_DIR}/include)
add_definitions(-Wall)

add_custom_command(
  OUTPUT ${VIEW_DIR}/upload.cpp
  COMMAND cppcms_tmpl_cc ${TEMPLATE_DIR}/upload.tmpl -o ${VIEW_DIR}/upload.cpp
  DEPENDS ${TEMPLATE_DIR}/upload.tmpl
)

AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src CPP_LIST1)
set(CPP_LIST2 ${VIEW_DIR}/upload.cpp )
AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/controller CPP_LIST3)
add_executable(upload ${CPP_LIST1} ${CPP_LIST2} ${CPP_LIST3})

target_link_libraries(upload ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} cppcms booster)

编译运行后,通过浏览器访问 http://localhost:8081/cppcms/upload

然后upload一个pdf文件。到/home/chenshu/下寻找这个pdf文件。

我用md5sum对比了源文件和网站保存的文件,md5相同。


成功。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容发布系统NetCMS与Discuz论坛整合源码 本代码将NetCMS与Discuz!NT3.1进行注册、登录、退出等功能的整合,整合过程如下: 整合环境: 1、NetCMS和Disicuz的架设请参考相关的文档说明,但要注意不要用XP的IIS5.0进行测试,直接用服务器的IIS测试; 2、在VS下直接调试运行NetCMS的登录(user/Logout.aspx)时会出错,最好直接在架设好的环境下测试。 论坛设置: 1、架设好Discuz论坛,打开Discuz论坛系统后台->扩展->通行证设置,通行证的返回地址设置为NetCMS的回调页面地址(此回调页面用于处理CMS的登录退出等功能),如:http://http://netcms.com/api/discuz/apicallback.aspx,此回调页面在源代码的api/discuz/apicallback.aspx下,开发人员可根据需求在这个页面里进行其他的功能处理; 2、打开Discuz论坛系统后台->常规选项->基本设置,找到"身份验证Cookie域"选项,在此填入NetCMS系统的域,如: .netcms.com,注意这项一定要和NetCMS设置里第1条web.config里设置的DNTCookieDomain值一样。 NetCMS设置: 1、在web.config里将<appSettings>配置节里的DNTCookieDomain设置为论坛域,DNTAPIKey,DNTSecert,DNTWebServer修改为在论坛后台扩展设置里获取到的相应值。 2、架设NetCMS,整合就完成了。 整合代码修改说明: 1、引用了DiscuzToolkit插件,用于discuz论坛api接口调用; 2、在API/Discuz目录下添加apicallback.aspx程序页,用于处理论坛回调请求处理; 3、在API/Discuz目录下添加DiscuzSessionHelper.cs,用于实例化论坛API接口; 4、在user/Login.aspx.cs、user/Logout.aspx.cs、user/Register.aspx.cs、user/UserLoginajax.aspx.cs里添加了相应的整合代码; 5、修改了NetCMS源码版本安装初始化数据,首页不能登录和退出等几个bug。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值