在線協(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ì)用到桌面上的程序:
- LX終端(LXTerminal): Linux命令行終端刚陡,打開后會(huì)進(jìn)入Bash環(huán)境惩妇,可以使用Linux命令
- Firefox:瀏覽器株汉,可以用在需要前端界面的課程里,只需要打開環(huán)境里寫的HTML/JS頁(yè)面即可
- 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)步驟一步一步完成,將收獲更大布近;
4.項(xiàng)目效果截圖
代碼開發(fā)完成后垫释,在eclipse中啟動(dòng)項(xiàng)目后,打開火狐瀏覽器撑瞧,輸入 localhost:9090/index ,將出現(xiàn)本節(jié)實(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)容很多空骚;可參看
- Web前后端緩存技術(shù)
- 簡(jiǎn)談常用緩存技術(shù)
- HTML5本地存儲(chǔ) localStorage 纺讲、sessionStorage、WebSQL囤屹、indexedDB
最終熬甚,為了兼顧數(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ì)

四、開發(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,

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

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

將jar包解壓之后依疼,將所有的jar包文件,全部都復(fù)制到WeekReport項(xiàng)目工程下的 WebContent/WEB-INF/lib 目錄下面即可(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è)定的用戶名和密碼,即可搜变。

3 項(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 。
- 增加實(shí)時(shí)緩存功能魏铅,采用sessionStorage的方式昌犹,將在線編輯器中輸入內(nèi)容進(jìn)行本地緩存,保證數(shù)據(jù)刷新后不丟失览芳;
- 添加手動(dòng)保存功能斜姥,點(diǎn)擊保存后,將編輯好的數(shù)據(jù)異步傳到后臺(tái)沧竟,保存到mysql數(shù)據(jù)庫(kù)中铸敏;
- 刷新加載最新數(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)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)建表的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,

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

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

2 火狐瀏覽器訪問(wèn)測(cè)試
打開火狐瀏覽器刹衫,輸入 localhost:9090/index ,出現(xià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型!!