CppCMS支援檔案上傳

來源:互聯網
上載者:User

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

成功。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.