2016-01-21 113 views
-2

我試圖將用戶提交的HTTP數據保存到Redis中。這是我的代碼中使用鎳:如何將從HTML表單提交的數據插入到Redis數據庫中?

#[macro_use] 
extern crate nickel; 
extern crate redis; 
extern crate hyper; 

use redis::{Client,Parser, Commands, Connection, RedisResult}; 
use nickel::{Nickel, Request, Response, HttpRouter, MiddlewareResult,Middleware, MediaType,JsonBody}; 
use std::collections::HashMap; 
use nickel::status::StatusCode; 
use nickel_redis::{RedisMiddleware, RedisRequestExtensions}; 
use hyper::Url; 
use url::form_urlencoded; 
use std::sync::{Arc, Mutex}; 
use std::io; 
use std::io::prelude::*; 
use std::fs::File; 

fn save_db<'a>(req: &mut Request, res: Response<'a>) -> MiddlewareResult<'a> { 
    let mut server = Nickel::new(); 
    /* FIXME: connect redis*/ 
    let client = Client::open("redis://127.0.0.1/").unwrap(); 
    let conn = client.get_connection().unwrap(); 

    server.post("/confirmation", middleware!{|req, res| 
     let mut form_data = String::new(); 
     req.origin.read_to_string(&mut form_data).unwrap(); 
     let _:() = conn.set("contents", form_data).unwrap(); 
     println!("{}", form_data); 

     let mut data = HashMap::<&str, String>::new(); 
     data.insert("content", form_data); 
     data.insert("page_title", "Save blog data".to_string()); 
     return res.render("app/views/blog/save.tpl", &data); 
    }); 
} 

fn main() { 
    let mut server = Nickel::new(); 

    // start using router 
    let mut router = Nickel::router(); 
    let client = Client::open("redis://127.0.0.1/").unwrap(); 
    let conn = client.get_connection().unwrap(); 

    router.get("/test-save-db", save_db); 

    server.utilize(router); 
    server.listen("127.0.0.12:8080"); 
} 

Save.tpl

<!DOCTYPE html> 
    <html> 
    <head lang="en"> 
     <meta charset="UTF-8"> 
     <title>{{ page_title }}</title> 
    </head> 
    <body> 
    <h1>Saved new blog.</h1> 
    <h2>Author {{form_data}}</h2> 
    <h2>Content {{content}}</h2> 
    <form> 
    First name:<br> 
    <input type="text" name="firstname" > 
    <br> 
    <button type="submit" formenctype="application/x-www-form-urlencoded" formaction="/test-save-db" formmethod="post">SEND</button> 
    </form> 
</body> 
</html> 

但我得到這個錯誤

error: cannot infer an appropriate lifetime for lifetime parameter 'b due to conflicting requirements [E0495](req.origin.read_to_string(&mut form_data).unwrap();)

+2

爲什麼要在看起來像鎳請求處理程序的內部創建一個新的鎳服務器?我只希望一次只能有一臺服務器。 – Shepmaster

+0

如果我不創建一個新的鎳服務器,我不會調用函數server.post()。你如何解決問題? – kenzi

+0

您還沒有提供[MCVE](/ help/mcve)(首先強調** C **,然後是** M **),所以我無法編譯您的代碼以提供任何有用的反饋。我很確定這段代碼沒有正確使用Nick,但我無法猜測爲什麼你已經突出顯示的行('req.origin.read_to_string(&mut form_data).unwrap()')會導致你所說的錯誤。 – Shepmaster

回答

0

我在你的代碼中看到的問題是,你試圖在匹配/test-save-db路由時調用的處理程序中註冊路由處理程序(POST /confirmation)。這看起來不正確。

爲了使您的代碼和意圖更清晰,我建議您使用宏,我發現這是用鎳描述路線最簡單的方法。至少這是我的經驗,因爲在開始使用框架昨日:-)

那麼如下的例子可能被改寫:

fn main() { 
    let client = Client::open("redis://127.0.0.1/").unwrap(); 
    let mut server = Nickel::new(); 

    server.get("/test-save-db", middleware! { |req, res| 
     // do something with the request and send a response 
    }); 

    server.listen("127.0.0.12:8080"); 
} 

如果需要多個處理程序共享相同的客戶端,您將需要使用std::sync::Arc具有線程安全共享狀態,併爲每個處理程序克隆它(它只會克隆Arc,而不是客戶端)。

相關問題