在線協(xié)作編輯器之周報(bào)收集

在線協(xié)作編輯器之周報(bào)收集

一、實(shí)驗(yàn)說(shuō)明

下述介紹為實(shí)驗(yàn)樓默認(rèn)環(huán)境,如果您使用的是定制環(huán)境痒留,請(qǐng)修改成您自己的環(huán)境介紹。

1. 環(huán)境登錄

無(wú)需密碼自動(dòng)登錄杖挣,系統(tǒng)用戶名shiyanlou

2. 環(huán)境介紹

本實(shí)驗(yàn)環(huán)境采用帶桌面的Ubuntu Linux環(huán)境,實(shí)驗(yàn)中會(huì)用到桌面上的程序:

  1. LX終端(LXTerminal): Linux命令行終端刚陡,打開后會(huì)進(jìn)入Bash環(huán)境惩妇,可以使用Linux命令
  2. Firefox:瀏覽器株汉,可以用在需要前端界面的課程里,只需要打開環(huán)境里寫的HTML/JS頁(yè)面即可
  3. Eclipse:Eclipse 是著名的跨平臺(tái)的自由集成開發(fā)環(huán)境(IDE)歌殃。主要用來(lái) Java 語(yǔ)言開發(fā)乔妈,但是目前亦有人通過(guò)插件使其作為 C++ 和 Python 等語(yǔ)言的開發(fā)工具

3. 環(huán)境使用

使用GVim編輯器輸入實(shí)驗(yàn)所需的代碼及文件,使用LX終端(LXTerminal)運(yùn)行所需命令進(jìn)行操作氓皱。

實(shí)驗(yàn)報(bào)告頁(yè)面可以在“我的主頁(yè)”中查看路召,其中含有每次實(shí)驗(yàn)的截圖及筆記,以及實(shí)驗(yàn)的有效學(xué)習(xí)時(shí)間(指的是在實(shí)驗(yàn)桌面內(nèi)操作的時(shí)間波材,如果沒(méi)有操作股淡,系統(tǒng)會(huì)記錄為發(fā)呆時(shí)間),這些都是您學(xué)習(xí)的真實(shí)性證明廷区。

二唯灵、課程介紹

1. 實(shí)驗(yàn)內(nèi)容

大家在工作和學(xué)習(xí)中時(shí)常會(huì)遇到多人編輯一個(gè)文件的情況;那么多人在線協(xié)作文檔編輯器將是一個(gè)很實(shí)用的工具隙轻,適合小組內(nèi)的文檔編輯埠帕,例如可用于小團(tuán)隊(duì)內(nèi)部進(jìn)行實(shí)時(shí)編寫和收集周報(bào)等。

課程通過(guò)分析項(xiàng)目要實(shí)現(xiàn)的功能大脉,調(diào)研目前的技術(shù)現(xiàn)狀搞监,設(shè)計(jì)了該課程來(lái)實(shí)現(xiàn)該功能水孩,課程使用java語(yǔ)言開發(fā)镰矿,應(yīng)用非常流行的springmvc框架,引入ckeditor插件俘种,并加入localStorage緩存技術(shù)秤标,最終使用Eclipse開發(fā)工具完成。

項(xiàng)目不太難宙刘,非常適合JAVA或其他愛(ài)好者進(jìn)行共同學(xué)習(xí)苍姜,只要有一些 Java Web開發(fā)基礎(chǔ)的同學(xué)都會(huì)看懂的!

2. 實(shí)驗(yàn)知識(shí)點(diǎn)

  • ckeditor (在線的編輯器) 【重點(diǎn)掌握】
  • localStorage (HTML 5 Web 存儲(chǔ))【重點(diǎn)掌握】
  • springmvc (輕量級(jí)Web框架) 【需提前了解java web的springmvc框架】
  • spring jdbcTemplate 【需提前了解java web的spring框架】
  • mysql 數(shù)據(jù)庫(kù) 【需了解mysql的創(chuàng)建數(shù)據(jù)悬包、創(chuàng)建表】

3. 源碼下載

本課程提供源碼下載地址衙猪,建議大家根據(jù)實(shí)驗(yàn)步驟一步一步完成,將收獲更大布近;

項(xiàng)目源碼

4.項(xiàng)目效果截圖

代碼開發(fā)完成后垫释,在eclipse中啟動(dòng)項(xiàng)目后,打開火狐瀏覽器撑瞧,輸入 localhost:9090/index ,將出現(xiàn)本節(jié)實(shí)驗(yàn)的效果圖棵譬,如下:

實(shí)驗(yàn)效果圖
實(shí)驗(yàn)效果圖

三、實(shí)驗(yàn)原理

1预伺、待實(shí)現(xiàn)的功能需求

序號(hào) 需求名稱 需求詳述
1 在線協(xié)作編輯 嵌入瀏覽器網(wǎng)頁(yè)的在線編輯器订咸,支持多人協(xié)作編輯曼尊,刷新后讀取后臺(tái)最新編輯保存的內(nèi)容
2 實(shí)時(shí)自動(dòng)保存 通過(guò)在線編輯器,輸入的內(nèi)容脏嚷,能夠?qū)崟r(shí)自動(dòng)保存到客戶端骆撇;刷新后數(shù)據(jù)不丟失;點(diǎn)擊提交能夠保存到數(shù)據(jù)庫(kù)中

2然眼、技術(shù)調(diào)研

1 在線協(xié)作編輯

實(shí)現(xiàn)多人在線編輯的功能艾船,可自行開發(fā)web編輯器插件,但是實(shí)現(xiàn)成本較高高每,經(jīng)調(diào)研目前已經(jīng)有很多在線編輯器插件可以調(diào)用屿岂,請(qǐng)參靠:
HTML編輯器-HTML網(wǎng)頁(yè)表單可視化在線編輯器插件大全

其中,CKEditor(原FCKEditor)是一個(gè)現(xiàn)成的使用旨在簡(jiǎn)化Web內(nèi)容創(chuàng)建HTML文本編輯器鲸匿。是國(guó)外比較流行的網(wǎng)頁(yè)文本在線編輯器爷怀,早期DEDECMS管理后臺(tái)發(fā)布內(nèi)容地方使用此編輯器,這是一個(gè)所見(jiàn)即所得的編輯器带欢,帶來(lái)了共同的文字處理器的功能运授,直接到您的網(wǎng)頁(yè)。

最后乔煞,因?yàn)镃KEditor免費(fèi)開源吁朦、完全可定制、高標(biāo)準(zhǔn)的質(zhì)量等優(yōu)點(diǎn)渡贾,該課程選擇該插件作為前端的輸入逗宜。

2 實(shí)時(shí)自動(dòng)保存

web緩存技術(shù),涉及內(nèi)容很多空骚;可參看

最終熬甚,為了兼顧數(shù)據(jù)保存的簡(jiǎn)單高效和安全,我們選用 sessionStorage作為前端存儲(chǔ)肋坚,因?yàn)閟essionStorage的優(yōu)點(diǎn)就是方便高效乡括;同時(shí)為了保證數(shù)據(jù)的安全不丟失,我們?cè)谟脩舸_認(rèn)編寫信息無(wú)誤后智厌,通過(guò)觸發(fā)按鈕的方式將數(shù)據(jù)提交后臺(tái)诲泌,交由服務(wù)器進(jìn)行存儲(chǔ),因?yàn)榉?wù)器存儲(chǔ)數(shù)據(jù)安全性高峦剔。

3档礁、系統(tǒng)設(shè)計(jì)

系統(tǒng)框架圖
系統(tǒng)框架圖

四、開發(fā)準(zhǔn)備工作

1 新建項(xiàng)目

雙擊桌面的eclipse圖標(biāo)吝沫,打開eclipse軟件呻澜,點(diǎn)擊工具欄FILE-New-Dynamic Web Project递礼,進(jìn)入新建java web項(xiàng)目頁(yè)面;新建 Dynamic Web Project羹幸,命名為 WeekReport脊髓,然后點(diǎn)擊 Next,


new-project
new-project

第二次點(diǎn)擊 Next 按鈕會(huì)進(jìn)入如下所示的步驟栅受,注意勾選生成 web.xml 選項(xiàng)将硝。


勾選web.xml
勾選web.xml

2 導(dǎo)入jar包

先下載依賴的jar包,下載地址url為http://labfile.oss.aliyuncs.com/courses/742/lib.zip屏镊。

$ wget url
$ unzip lib.zip
$ cp lib/* /home/shiyanlou/workspace/WeekReprot/WebContent/WEB-INF/lib 
解壓復(fù)制jar包
解壓復(fù)制jar包

將jar包解壓之后依疼,將所有的jar包文件,全部都復(fù)制到WeekReport項(xiàng)目工程下的 WebContent/WEB-INF/lib 目錄下面即可(jar文件目錄截圖如下)而芥。

jar文件目錄截圖
jar文件目錄截圖

3 搭建springmvc框架

包含三步律罢,

  • 增加必要文件及其目錄;【增加service、controller棍丐、dao误辑、model目錄等】
  • 修改web.xml配置;【配置了listener和servlet】
  • 增加spring歌逢、spring-mvc和數(shù)據(jù)庫(kù)jdbc配置文件巾钉。
    該部分內(nèi)容不是本文的重點(diǎn),如有疑問(wèn)可以參考如下文章秘案,
    http://www.cnblogs.com/xing901022/p/5240044.html 砰苍;或者在課程問(wèn)答里進(jìn)行提問(wèn)解答。

a) 在src下新建一個(gè)包踏烙,包名自定義师骗,該實(shí)驗(yàn)此處我命令為:com.zn.wr历等。
然后在該包下讨惩,分別新建4個(gè)文件夾,service寒屯、controller荐捻、dao、model寡夹;供后續(xù)服務(wù)器端保存數(shù)據(jù)時(shí)使用处面。


新建包
新建包

b) 修改web.xml,配置了spring監(jiān)聽和servlet菩掏。為了是增加spring和spring-mvc配置文件魂角,使項(xiàng)目完成spring-mvc的框架。

<!-- 增加spring監(jiān)聽-->  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext.xml</param-value>
  </context-param> 
  <!-- springmvc文件配置在這里 -->  
  <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
     <param-value>classpath*:spring-mvc.xml</param-value> 
      <!-- 上面是放在 resources下智绸, 也可以配置在 /WEB-INF/spring-mvc.xml -->
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>   
</web-app>

c) 增加配置文件
在 WebContent\WEB-INF新建3個(gè)配置文件applicationContext.xml野揪,spring-mvc.xml访忿,jdbc.properties。
applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
       
    <!-- 配置jdbc文件 -->
    <context:property-placeholder location="/WEB-INF/jdbc.properties" />

    <!-- 掃描類包斯稳,將標(biāo)注Spring注解的類自動(dòng)轉(zhuǎn)化Bean海铆,同時(shí)完成Bean的注入 -->
    <context:component-scan base-package="com.zn.wr.controller" />
    <context:component-scan base-package="com.zn.wr.dao" />

    <!-- 配置Jdbc模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 配置數(shù)據(jù)源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass">
            <value>${jdbc.driverClassName}</value>
        </property>
        <property name="jdbcUrl">
            <value>${jdbc.url}</value>
        </property>
        <property name="user">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
        <!--連接池中保留的最小連接數(shù)。 -->
        <property name="minPoolSize">
            <value>5</value>
        </property>
        <!--連接池中保留的最大連接數(shù)挣惰。Default: 15 -->
        <property name="maxPoolSize">
            <value>30</value>
        </property>
        <!--初始化時(shí)獲取的連接數(shù)卧斟,取值應(yīng)在minPoolSize與maxPoolSize之間。Default: 3 -->
        <property name="initialPoolSize">
            <value>10</value>
        </property>
        <!--最大空閑時(shí)間,60秒內(nèi)未使用則連接被丟棄憎茂。若為0則永不丟棄珍语。Default: 0 -->
        <property name="maxIdleTime">
            <value>60</value>
        </property>
        <!--當(dāng)連接池中的連接耗盡的時(shí)候c3p0一次同時(shí)獲取的連接數(shù)。Default: 3 -->
        <property name="acquireIncrement">
            <value>5</value>
        </property>
        <!--JDBC的標(biāo)準(zhǔn)參數(shù)竖幔,用以控制數(shù)據(jù)源內(nèi)加載的PreparedStatements數(shù)量廊酣。但由于預(yù)緩存的statements 屬于單個(gè)connection而不是整個(gè)連接池。所以設(shè)置這個(gè)參數(shù)需要考慮到多方面的因素赏枚。 
            如果maxStatements與maxStatementsPerConnection均為0亡驰,則緩存被關(guān)閉。Default: 0 -->
        <property name="maxStatements">
            <value>0</value>
        </property>
        <!--每60秒檢查所有連接池中的空閑連接饿幅。Default: 0 -->
        <property name="idleConnectionTestPeriod">
            <value>60</value>
        </property>
        <!--定義在從數(shù)據(jù)庫(kù)獲取新連接失敗后重復(fù)嘗試的次數(shù)凡辱。Default: 30 -->
        <property name="acquireRetryAttempts">
            <value>30</value>
        </property>
        <!--獲取連接失敗將會(huì)引起所有等待連接池來(lái)獲取連接的線程拋出異常。但是數(shù)據(jù)源仍有效 保留栗恩,并在下次調(diào)用getConnection()的時(shí)候繼續(xù)嘗試獲取連接透乾。如果設(shè)為true,那么在嘗試 
            獲取連接失敗后該數(shù)據(jù)源將申明已斷開并永久關(guān)閉磕秤。Default: false -->
        <property name="breakAfterAcquireFailure">
            <value>true</value>
        </property>
        <!--因性能消耗大請(qǐng)只在需要的時(shí)候使用它乳乌。如果設(shè)為true那么在每個(gè)connection提交的 時(shí)候都將校驗(yàn)其有效性。建議使用idleConnectionTestPeriod或automaticTestTable 
            等方法來(lái)提升連接測(cè)試的性能市咆。Default: false -->
        <property name="testConnectionOnCheckout">
            <value>false</value>
        </property>
    </bean>
</beans>

spring-mvc.xml 下載地址:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!-- 定義 SpringMVC的掃描路徑 base-package的值與上述 a) 中在src下新建一個(gè)包汉操,包名自定義 的值保持一致即可 --> 
    <context:component-scan base-package="com.zn.wr" />
    <!-- 定義view 【jsp】映射關(guān)系  -->
     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="viewClass"  value="org.springframework.web.servlet.view.JstlView" />
       <property name="prefix" value="/WEB-INF/jsp/" />
       <property name="suffix" value=".jsp" />
    </bean>
</beans>

jdbc.properties下載地址:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/weekreport
jdbc.username=root
jdbc.password=admin

其中,本實(shí)驗(yàn)涉及到的如下文件需修改下蒙兰。
jdbc.properties中的mysql的數(shù)據(jù)庫(kù)的用戶名和密碼磷瘤,請(qǐng)修改為你安裝時(shí)設(shè)定的用戶名和密碼,即可搜变。

修改jdbc配置文件
修改jdbc配置文件

3 項(xiàng)目文件結(jié)構(gòu)

最終采缚,項(xiàng)目的文件結(jié)構(gòu)如下截圖:


項(xiàng)目文件結(jié)構(gòu)截圖
項(xiàng)目文件結(jié)構(gòu)截圖

五、實(shí)驗(yàn)步驟

1. 前臺(tái) 在線協(xié)作編輯 新建jsp

在\WebContent\WEB-INF下新建jsp文件目錄挠他,在jsp目錄下新建index.jsp文件作為前臺(tái)輸入頁(yè)面扳抽。index.jsp 頁(yè)面代碼如下:

<html>
<head>
    <title>CKEditor Classic Editing Sample</title> 
 
    <script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js" type="text/javascript"></script> 
    
    <script src="https://cdn.ckeditor.com/4.6.0-441b33b/full-all/ckeditor/ckeditor.js"></script>     
 
    <style type="text/css">
    /* Minimal styling to center the editor in this sample */
    body {
        padding: 30px;
        display: flex;
        align-items: center;
        text-align: center;
    }
    p{
    text-align:right; 
    }
    
    .container {
        margin: 0 auto;
    }
    </style>
</head>
<body>
    <%-- 1 添加編輯頁(yè)面 --%>
    <div class="container">   
          <form method="post">
            <h2><label for="editor1">周報(bào)編輯器</label></h2>  
            <p><a href="javascript:void(0);" onclick="ManualSave();" >保存</a></p>             
<!--         <a href="javascript:void(0);" onclick="Export();" >導(dǎo)出</a></p> -->
            <textarea name="editor1" id="editor1"> </textarea>      
          </form> 
    </div>
</body>
</html>

在該jsp頁(yè)面添加div,包含一個(gè)label、一個(gè)保存按鈕和一個(gè)輸入框贸呢。
另外通過(guò)引入js插件(jquery.min.js和ckeditor.js)赂苗,來(lái)實(shí)現(xiàn)“在線協(xié)作編輯”功能。

2. 前臺(tái) 在線協(xié)作編輯 編寫js

通過(guò)初始化一個(gè)編輯器函數(shù)贮尉,并設(shè)置了編輯器的主題樣式以及模式等拌滋,從而可以看到一個(gè)web端的編輯器,并且可以輸入內(nèi)容猜谚,就像在本地電腦的word中進(jìn)行編輯败砂。其中初始化函數(shù)中的相關(guān)參數(shù)設(shè)置可以去參考官網(wǎng)資料Ckeditor

  1. 增加實(shí)時(shí)緩存功能魏铅,采用sessionStorage的方式昌犹,將在線編輯器中輸入內(nèi)容進(jìn)行本地緩存,保證數(shù)據(jù)刷新后不丟失览芳;
  2. 添加手動(dòng)保存功能斜姥,點(diǎn)擊保存后,將編輯好的數(shù)據(jù)異步傳到后臺(tái)沧竟,保存到mysql數(shù)據(jù)庫(kù)中铸敏;
  3. 刷新加載最新數(shù)據(jù),手動(dòng)保存后會(huì)自動(dòng)刷新前臺(tái)一次悟泵,將最新的數(shù)據(jù)加載到前臺(tái)頁(yè)面中杈笔;
<script>    
/*
* 1. 每次進(jìn)入頁(yè)面前    都從后臺(tái)取最新的數(shù)據(jù)到前臺(tái)   【在index方法里】
* 2. 緩存數(shù)據(jù)判斷   緩存為空 則將后臺(tái)最新數(shù)據(jù)賦值    2 本地緩存  localStorage 自動(dòng)保存
* 3. 緩存數(shù)據(jù)賦值給 texture值
* 4. 遇到 texture值變化,則自動(dòng)保存
*/

$(document).ready(function () {  
    var editor=initeditor();
    var  initcontent= window.sessionStorage.getItem("comment_top");     
    // 初始化頁(yè)面賦值
    initdata(editor,initcontent);
    // 觸發(fā)自動(dòng)保存  自動(dòng)保存功能
    editor.on('change', function(evt) {  
        window.sessionStorage.setItem("comment_top", evt.editor.getData()); 
    });
});
 
function initeditor(){
      var editor=  CKEDITOR.replace( 'editor1' , {
        toolbar: [
                    { name: 'clipboard', items: [ 'Undo', 'Redo' ] },
                    { name: 'styles', items: [ 'Format', 'Font', 'FontSize' ] },
                    { name: 'basicstyles', items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'RemoveFormat', 'CopyFormatting' ] },
                    { name: 'colors', items: [ 'TextColor', 'BGColor' ] },
                    { name: 'align', items: [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
                    { name: 'links', items: [ 'Link', 'Unlink' ] },
                    { name: 'paragraph', items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote' ] },
                    { name: 'insert', items: [ 'Image', 'Table' ] },
                    { name: 'tools', items: [ 'Maximize' ] },
                    { name: 'editing', items: [ 'Scayt' ] }
                ],
                
        height: 800 ,  //外面長(zhǎng)方形 高多少
        contentsCss: [ 'https://cdn.ckeditor.com/4.6.0-441b33b/full-all/ckeditor/contents.css', 'mystyles.css' ] ,   //有無(wú)里面的方格          
        allowedContent : true ,
        disallowedContent: 'img{width,height,float}'   ,                
        extraAllowedContent: 'img[width,height,align]' ,                
        extraPlugins: 'tableresize,uploadimage,uploadfile' , 
        bodyClass: 'document-editor' ,               
        format_tags: 'p;h1;h2;h3;pre' ,               
        removeDialogTabs: 'image:advanced;link:advanced'  
      });
      return editor;
};
      
function initdata(editor,initcontent){  
        //顯示進(jìn)度條代碼結(jié)束
    var aj =$.ajax({
            type : "POST",
            url : "initdata",
            async: false,
            dataType : "json",       
            success : function(data) {
                if (data == null) {
                    alert("沒(méi)查到最新的信息");
                } else if (!initcontent && typeof initcontent != "undefined" && initcontent != 0) {
                    editor.setData(data.scontent); 
                }else{
                    editor.setData(initcontent); 
                }
            }
    });
};
//手動(dòng)保存頁(yè)面 
 function ManualSave(){    
            var aj = $.ajax( {    
                url:'save',   // 跳轉(zhuǎn)到 action               
                type:'POST',       
                dataType:'json',    
               contentType: 'application/json;chartset=UTF-8',           
               data:JSON.stringify(window.sessionStorage.getItem("comment_top")), //  傳批量的參數(shù) list           
                success:function(data) {    
                    if(data.state){       
                        alert("保存成功糕非!");    
                        window.sessionStorage.removeItem("comment_top");
                        window.location.reload();   
                    }else{    
                        alert("保存失斆删摺!");    
                    }    
                 },    
                 error : function() {      
                      alert("網(wǎng)絡(luò)異常朽肥!");    
                 }    
    });  
};    
        
</script> 
     

3. 后臺(tái)實(shí)時(shí)自動(dòng)保存功能解析

在src\com\zn\wr\model下新建一個(gè)實(shí)體類Content.java用于對(duì)應(yīng)前臺(tái)的輸入框禁筏,其中包含的字段scontent用來(lái)存儲(chǔ)編輯的內(nèi)容。Model層衡招,用持久化類描述實(shí)例對(duì)象篱昔。

 public class Content{
    String scontent; // 編輯內(nèi)容
    public String getScontent() {
        return scontent;
    }
    public void setScontent(String scontent) {
        this.scontent = scontent;
    }   

在src\com\zn\wr\controller下新建一個(gè)實(shí)體類SaveController.java,用來(lái)處理在前臺(tái)輸入編輯內(nèi)容完成后蚁吝,點(diǎn)擊保存按鈕動(dòng)作旱爆,觸發(fā)的后臺(tái)操作舀射。Controller層窘茁,連接前臺(tái)頁(yè)面和后臺(tái)業(yè)務(wù),接收數(shù)據(jù)并調(diào)用Dao層操作脆烟。

 
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; 
 import com.zn.wr.dao.contentDAO;
import com.zn.wr.model.Content;

@Controller
public class SaveController {
    private Content content;
    
    @Resource 
    private contentDAO contentdao;
 
    @RequestMapping("/index") // 通過(guò)spring mvc 的requestingmapping 跳轉(zhuǎn)到前臺(tái)index.jsp
    public String toLoginPage()throws Exception {
        return "index";
    }
       /*
        * 初始化最新數(shù)據(jù)
        */
    @ResponseBody
    @RequestMapping(value = "initdata", method = RequestMethod.POST)
    public Content toInitData(){
        this.content = new Content();
        this.content.setScontent(contentdao.search());
        System.out.println("content:"+contentdao.search());
        return content;
    }
    
   /*
    * 手工保存
    */
    @RequestMapping(value="save", method = {RequestMethod.POST} ,produces = "text/html;charset=UTF-8") 
    @ResponseBody  
     public  Map<String, Object> doSave(@RequestBody String initcontent) {   
        boolean state = contentdao.insert(initcontent); 
        Map<String, Object> modelMap = new HashMap<String, Object>();  
        modelMap.put("state", state);  
        return modelMap;  
     } 

}

在src\com\zn\wr\dao下新建一個(gè)實(shí)體類contentDAO.java,用于響應(yīng)Controller層的操作山林, DAO層,數(shù)據(jù)持久化,把對(duì)象的各種操作進(jìn)行封裝驼抹;并將前臺(tái)的數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中桑孩。

 import java.util.HashMap; 
import java.util.Map; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.stereotype.Repository;

@Repository
public class contentDAO {
    @Autowired // 注入 spring jdbctemplate
    private JdbcTemplate jdbcTemplate;
    
    // 手動(dòng)保存功能
    public boolean insert(String content)
    {
        try {
            String sql = " INSERT INTO w_content(content,createtime,updatetime )VALUES (?,now(),now())";
            Object[] params = new Object[] { content };
            jdbcTemplate.update(sql, params);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    //刷新最新數(shù)據(jù)    
    public String search()
    {    
        String content = null;
        try {
            String sql = "SELECT content from w_content  ORDER BY updatetime DESC LIMIT 1";
            content = (String) jdbcTemplate.queryForObject(sql, java.lang.String.class);             
        } catch (Exception e) {
            e.printStackTrace();         
        }
        return content;
    }   
}

Service層,業(yè)務(wù)邏輯層框冀,調(diào)用DAO層操作流椒,此處業(yè)務(wù)邏輯簡(jiǎn)單,省略該層明也。

六宣虾、數(shù)據(jù)庫(kù)

1 查看數(shù)據(jù)庫(kù)狀態(tài)

$ sudo service mysql status  // 查看mysql狀態(tài)
$ sudo service mysql start   //如果沒(méi)啟動(dòng)就可以啟動(dòng)
$ sudo service mysql stop    //使用完畢之后就可以關(guān)閉

2 啟動(dòng)mysql數(shù)據(jù)庫(kù)

啟動(dòng)數(shù)據(jù)庫(kù)
啟動(dòng)數(shù)據(jù)庫(kù)

啟動(dòng)mysql數(shù)據(jù)庫(kù),如不熟悉這部分內(nèi)容温数,可先學(xué)習(xí)實(shí)驗(yàn)樓中的【SQL的介紹及MySQL的安裝】這個(gè)課程绣硝。

默認(rèn)實(shí)驗(yàn)樓環(huán)境中的mysql的root用戶的密碼為null,為了安全起見(jiàn)撑刺,需要進(jìn)行修改密碼鹉胖。修改root密碼的方法。

通過(guò)使用SET PASSWORD命令

$ mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');

3 創(chuàng)建項(xiàng)目數(shù)據(jù)庫(kù)和表

創(chuàng)建數(shù)據(jù)庫(kù)

$ mysql -u root -p
$  mysql> create database weekreport default character set utf8 collate utf8_general_ci;
$  mysql> show databases;
$  mysql> use weekreport;
創(chuàng)建使用數(shù)據(jù)庫(kù)
創(chuàng)建使用數(shù)據(jù)庫(kù)

創(chuàng)建表的SQL

Navicat MySQL Data Transfer

Source Server         : localhost_3306
Source Server Version : 50715
Source Host           : localhost:3306
Source Database       : weekreport

Target Server Type    : MYSQL
Target Server Version : 50715
File Encoding         : 65001

Date: 2016-12-21 10:47:58
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for w_content
-- ----------------------------
DROP TABLE IF EXISTS `w_content`;
CREATE TABLE `w_content` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `content` text,
  `createtime` datetime DEFAULT NULL,
  `updatetime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS=1;

七够傍、實(shí)驗(yàn)效果圖

1 eclipse項(xiàng)目啟動(dòng)

選中server中的Tomcat V7.0 Server甫菠,然后右鍵點(diǎn)擊 add and remove,


tomcat添加工程
tomcat添加工程

選擇weeklyreport 項(xiàng)目冕屯,然后雙擊server中TomcatV7.0Server淑蔚,出現(xiàn)如下圖示,進(jìn)行修改訪問(wèn)的port=9090(可隨意定義愕撰,保證沒(méi)有其他的服務(wù)使用該端口即可)


tomcat配置
tomcat配置

啟動(dòng)成功的console提示頁(yè)面


tomcat console成功
tomcat console成功

2 火狐瀏覽器訪問(wèn)測(cè)試

打開火狐瀏覽器刹衫,輸入 localhost:9090/index ,出現(xiàn)課程的初始效果圖:


初始化實(shí)驗(yàn)效果圖
初始化實(shí)驗(yàn)效果圖

輸入 “2017 first course shiyanlou 2017.2.12”等字樣后,數(shù)據(jù)自動(dòng)保存到緩存中搞挣,直接刷新頁(yè)面带迟,數(shù)據(jù)不丟失


輸入漢字
輸入漢字

3 保存之后顯示最新數(shù)據(jù)

點(diǎn)擊保存按鈕,彈出保存成功字樣囱桨。


保存成功
保存成功

點(diǎn)擊仓犬,確定后自動(dòng)刷新最新數(shù)據(jù):


確定后刷新
確定后刷新

八、課后習(xí)題

  • 本次項(xiàng)目課的內(nèi)容比較多舍肠,建議多動(dòng)手操作幾遍搀继,并且仔細(xì)回顧和思考,才能真正理解翠语。
  • 目前還不支持導(dǎo)出功能叽躯;可以考慮添加另存為word、pdf等格式的文件肌括;還可以添加工作流点骑、添加郵件、短信通知功能。
  • 課后作業(yè):本項(xiàng)目的前臺(tái)代碼中黑滴,js調(diào)用的是外部鏈接憨募,請(qǐng)動(dòng)手修改為本地的鏈接調(diào)用試試?看下效果是不是一樣袁辈。

感興趣的可以直接到實(shí)驗(yàn)樓去操作完成這個(gè)課程菜谣。

友情提示

我是和奇谷樸,一個(gè)在帝都周末自己選擇加班的有志好青年晚缩,讀完我的文章如果有收獲葛菇,記得打賞、關(guān)注和點(diǎn)贊哦橡羞!么么噠C型!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卿泽,一起剝皮案震驚了整個(gè)濱河市莺债,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌签夭,老刑警劉巖齐邦,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異第租,居然都是意外死亡措拇,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門慎宾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)丐吓,“玉大人,你說(shuō)我怎么就攤上這事趟据∪纾” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵汹碱,是天一觀的道長(zhǎng)粘衬。 經(jīng)常有香客問(wèn)我,道長(zhǎng)咳促,這世上最難降的妖魔是什么稚新? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮跪腹,結(jié)果婚禮上褂删,老公的妹妹穿的比我還像新娘。我一直安慰自己尺迂,他們只是感情好笤妙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布冒掌。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哆致。 梳的紋絲不亂的頭發(fā)上菠齿,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音骑疆,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛苍凛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兵志,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼醇蝴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了想罕?” 一聲冷哼從身側(cè)響起悠栓,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎按价,沒(méi)想到半個(gè)月后惭适,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡楼镐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年癞志,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片框产。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凄杯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秉宿,到底是詐尸還是另有隱情盾舌,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布蘸鲸,位于F島的核電站妖谴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏酌摇。R本人自食惡果不足惜膝舅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窑多。 院中可真熱鬧仍稀,春花似錦、人聲如沸埂息。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至享幽,卻和暖如春铲掐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背值桩。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工摆霉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奔坟。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓携栋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親咳秉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子婉支,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)澜建,斷路器向挖,智...
    卡卡羅2017閱讀 134,672評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,190評(píng)論 25 707
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,827評(píng)論 6 342
  • 馬上就到畢業(yè)季了,很多同學(xué)想進(jìn)入IT行業(yè)霎奢,應(yīng)聘軟件工程師户誓,如何準(zhǔn)備一份高質(zhì)量的簡(jiǎn)歷。還有的同學(xué)培訓(xùn)剛剛結(jié)束幕侠,自己也...
    嵌入式學(xué)習(xí)閱讀 1,057評(píng)論 0 1
  • 滿世界都是成功學(xué)理論帝美,滿世界都是成功人士的勵(lì)志言論,然而他們的成功之路我們真的可以復(fù)制嗎晤硕?他們的言論真的可以拯救普...
    南星云閱讀 448評(píng)論 0 1