`
阿尔萨斯
  • 浏览: 4175714 次
社区版块
存档分类
最新评论

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相同。


成功。








分享到:
评论

相关推荐

    编译好的CPPCMS库

    CPPCMS是一个C++ WEB库, 这个库在windows下编译的话会遇到很多问题, 而且会有VS版本兼容问题, 编译过程中要依赖很多工具。...上传一份打包好的库文件, 内部有使用说明。省去了配置编译的时间,方便在windows下开发。

    cppcms以及必要的第三方库

    cppcms以及必要的第三方库,可以用vs2005编译。编译方法参考cppcms官网

    cppcms_url_mapping.zip

    其实是cppcms中的example,不过在调试过程中,自己加了若干注释,便于理解使用。其实是cppcms中的example,不过在调试过程中,自己加了若干注释,便于理解使用。其实是cppcms中的example,不过在调试过程中,自己加...

    cppcms编译包x64版

    编译环境:win10 x64+vs2015 x64 运行:x64程序

    cppcms_hello_world.zip

    其实是官方中的example,不过调试过程中,在里面加了些注释。

    cppcms-skeleton:通过cppcms构建的C ++ Web框架

    cppcms的目标是提供工具,以遵循类似MVC的设计模式并严格遵循文件/类/变量的命名约定,自动生成新的projet /新类。 注意:该项目仍处于非常早期的阶段,所以可能还没有准备好(但是底层的 cppcms 框架已经非常稳定...

    cppcms helloworld

    this is ahello world application of cppms. C++ web lib

    CppCMS C++ Web Framework:高性能C ++ Web开发框架-开源

    CppCMS是用C ++编写的Web开发框架,旨在开发高性能Web应用程序。 它使用不同的Web API(最著名的是FastCGI)作为Web层,并使用各种数据库作为存储支持。

    cppcms_forms.zip

    该例子演示的是对服务器的post表单请求,我在里面添加了相关mysql相关函数,想法是,当有post请求到服务器时,将post过来的数据,入库或者返回。

    cppcms_w2p_web.zip

    参考:https://blog.csdn.net/cdnight/article/details/104188339中 web的层次分层【功能模块化】后,整理的项目代码(包含CMakeLists.txt)。

    tatowiki:用 cppcms 制作的维基

    #Tatowiki 简介 Tatowiki 是一个基于 cppcms 和 cppcms-skeleton 的 C++ wiki,它是为通用目的和高性能而设计的。...支持c ++ 11的编译器 铛 #安装说明 git clone https://github.com/allan-simon/tatowiki.gi

    c++多模块web项目实践方案-项目分层骨架

    这是博文 【c++多模块web项目实践方案【cmake+cppcms+boost+fmt】】附带的项目源代码骨架。笔者主要提出了自己对于c++项目如何分层,如何做一个简单的网站的见解。具体文章地址在:...

Global site tag (gtag.js) - Google Analytics