通知
系統的源代碼目錄結構已經上傳到SVN服務器
SVN地址:
https://svn.duapp.com/appid4x2erzscad
用戶名/密碼:
在羣裏
前端界面優化
提示
目前的界面設計暫時不用修改;界面佈局後的HTML頁面即爲整個系統的基礎界面;整理好第二期任務和文檔,按照上次開會討論的要求,各組單獨打包發給團長(郵箱:[email protected]),2014/4/18前。
任務安排
就目前各組情況,請分配大於等於1個人來負責前端界面優化。
1.把HTML佈局全部換成JSP網頁。
2.除了頁面的靜態資源且不會每次訪問都會修改的內容,其餘全部清空。
3.修改界面的靜態圖標(如果有,儘量沒有圖標,用淺一點的顏色塊實現就好),設定背景透明,且沒有立體效果。
4.對於界面的內容擺放位置更換,組內討論修改即可;對於界面功能的刪改必須和各個組交流。
重點
1.對於至今HTML佈局界面還只能在自己電腦的唯一瀏覽器可以完整顯示的界面,全部重新佈局,至少滿足以下要求:
a.對於瀏覽器窗口的比例縮放,界面內容必須完整顯示。
b.在不是太多內容顯示的界面,或者是現在看完整個界面內容只需要稍微滑動一下滾動條的界面,一律去除滾動條,即一屏展示完所有內容(這個要求在佈局時已經要求過,但是有的組在HTML佈局的時候出現無底線的改動)。
c.界面上的一些多功能或者控件至今仍然使用一張靜態圖片糊弄的小組,請儘快修改(如,一個日曆控件竟然是一個div貼個img)。
2.界面的適應性,除了在你們已有的IE系列和360瀏覽器外,還需要在Firefox和Chrome 上測試,不只是測試,還必須都滿足要求。
3.各組的界面目前仍然無法面世,請多瀏覽優秀的網頁和網頁設計站點,然後修改頁面的設計和體驗效果,如果有技術上的問題,隨時郵件或者電話聯繫團長。(注意:不要讓技術的瓶頸限制了各組對界面的設計要求,只要不是太天馬行空的體驗效果且符合整體風格,技術上的問題請不用擔心)
4.全部按照HTML5標準定義界面元素,在HTML5中標記過時且不再使用的標籤或者控件就不許再使用(如,center、font標籤)。
5.界面內容和元素使用jsp的標籤從後臺獲取然後填充到界面。
警告
不是前臺界面優化的人就不需要了解後臺實現問題,頁面內容都是來自服務器後臺整理產生,請時常和後臺開發的人員討論業務流程,防止產生不合理的體驗方式。
具體開發
整個系統的目錄結構(僅頁面目錄):
Coursemap
|……
|--WebContent
| |……
| |--css
| |--js
|--img
|--WEB-INF
| |……
|--pages
|--index.jsp
以上是整個系統源代碼目錄結構,對於紅色標記的部分是前臺界面編碼部分的目錄。
Index.jsp是課程地圖的站點首頁,圖中紅色標記的是文件夾,具體用途可以根據名稱得出。需要注意的是,禁止直接在文件夾根目錄存放各組的數據文件,必須先建好小組文件夾。
現在前臺界面優化的人兒們就只需要訪問這些地方就好了,對於其它目錄裏的內容,可以查看,不能修改。
服務器數據交互(Ajax)
Ajax介紹
Ajax是實現網頁與服務器異步交互的技術理念,此處說是理念,因爲ajax只是一些技術的結合即可實現,沒有新的語言或者開發方式,重點是javascript腳本。
以下是異步交互的實現方式圖:
使用ajax的原因也是想要使用戶體驗不間斷,但是不是強制使用一些ajax框架,因爲這些實現都是javascript,只要實現用戶在操作後等待結果的時候界面不是空白,且可以繼續對其它業務進行處理或操作的體驗方式即可。
開發要求
1.組內討論定義訪問方式(POST/GET),對於特殊的資源需要不同的訪問方式,如,特殊的servlet訪問。
2. 組內討論訪問接口名稱和數據返回類型,即,定義好訪問名稱,返回數據類型json、xml、字符串或者html都可以,根據需要組內討論即可。但是能用json和字符串時就不要選擇其它的數據類型了,以減少傳輸量。
3. 組間討論公共的腳本框架,以便於瀏覽器不用加載重複的資源。
4.
注意
JSP頁面的初始內容不是在用戶瀏覽器訪問到頁面之後獲取,而是在用戶訪問某地址時,服務器把對應的資源全部寫入到頁面之後返回給用戶(不要糾結爲什麼在用戶在獲取到頁面之後還是在加載某些資源,在服務器端頁面已經生成,只是在瀏覽器獲取時不能快速一次性獲取),所以,頁面的初始內容不屬於用戶與服務器交互產生的數據,不需要腳本獲取或者控制。但是在起初頁面內容填充的時候需要JSP的標籤,請配合前臺頁面優化的人一起完成。
後臺結構
Spring容器和struts2攔截器集成後臺架構。
系統後臺框架是spring和struts2集成,在“課程地圖”系統目前使用到這兩個框架,有些高端功能暫時沒有使用到,在系統中,spring負責管理所有後臺功能模塊,struts2負責控制所有的外部請求和轉發。
源代碼目錄結構
Coursemap
|……
|--src
| |--action層
| |--exception層
| |--domain層
| |--util包
| |--servlet包
| |--common包
| |--struts.xml
|
|--WebContent
| |……
| |
|--WEB-INF
| |……
| |--lib
|--spring.xml
|--web.xml
配置說明
從源碼目錄結構說,在src中的所有後臺服務源代碼和struts配置文件。在WebContent/WEB-INF/下,lib是外部程序引用包存放的文件夾,spring.xml是spring配置文件,web.xml是網站的配置文件,用於給web服務器識別和加載使用。
對於web.xml配置文件,需要加載spring和struts2的驅動器,以及配置一些網站的基礎設定。
Spring加載:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Struts2加載:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
其餘的基礎配置
Session:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
站點首頁:
<display-name>courseMap</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
等等……
後臺服務層次
後臺目前分爲兩大塊,struts2控制模塊和spring管理模塊。其中spring管理的是系統的所有功能,分爲三層,action功能定義、exception錯誤信息捕獲和domain基礎操作層。
Struts2控制
配置案例:
UserAction來自spring配置文件中定義。
<action name="gopain"class="UserAction" method="getUsers">
<result>/WEB-INF/pages/test/test.jsp</result>
<resultname="ERROR">/WEB-INF/pages/error.jsp</result>
</action>
Struts2的強大功能在於自動接收外部請求參數。
例如:
當外部使用方法“gopain?ip=1.1.1.1”訪問時,struts2攔截到請求,在配置中找到定義的“gopain”這個action節點,然後訪問該節點定義好的class,並指定訪問getUsers方法。
那麼在UserAction類中,定義:
Peivate String ip;
Public String getIp(){return this.ip;}
Public void setIp(String ip){this.ip = ip;}
那麼,在struts2把請求“gopain?ip=1.1.1.1”給UserAction類的時候,默認參數ip就接收並存儲到成員ip中。
Struts2的控制設置全部在struts.xml文件中。
負責定義外部訪問地址、內部調用方法以及頁面轉發。
在上面的那個配置案例中,
Action是指定外部訪問地址;
Class是指定調用功能類;
Method是指明使用哪個方法;
對於一些簡單且基礎的訪問跳轉,如果無驗證需要也可以不用添加class和method參數。因爲struts2默認有一個缺省類來接收這種訪問方式,默認的method是execute方法,且默認返回參數是“SUCCESS”。
對於action內部的節點result
Name屬性是指定返回參數,所以此處也強調,method返回類型必須是String;
當result沒有填寫name值的時候,默認是表示name=“SUCCESS”。
Struts2根據返回參數來指定跳轉頁面。
此處還有頁面的轉發,在此配置案例中沒有體現。
Spring管理的功能
配置案例:
<beanid="UserAction" class="com.coursemap.a.action.UserAction"scope="prototype">
<propertyname="userException"ref="userException"></property>
</bean>
<bean id="userException"class="com.coursemap.b.exception.impl.UserException"scope="prototype">
<propertyname="userDao" ref="userDao"></property>
</bean>
<bean id="userDao"class="com.coursemap.c.domain.impl.UserDao"></bean>
Spring有兩種配置方式,一種是掃描註解,另一種就是使用配置文件。
由於配置文件的可讀性更好,所以系統選擇配置文件配置方式。
在spring管理的後臺服務代碼中,分爲三層,action、exception和domain。
從以上的三個bean節點配置可以看出來,以上屬於一個完整定義。
bean解釋:
id是指明spring管理好後臺所有的類之後對外暴露的調用名稱;
class顯然就是被重定義的類的全名;
scope默認是單模式,scope="prototype"指定後,會在每一次訪問的時候創建一個實例;
內部的節點prototype是指定class內部成員引用的接口,需要在此指明其名稱和該接口的實現類。
科普:
Action中接口成員的名稱與其property中的name必須一致,且在action的類中定義的該接口的get和set方法。
其它服務或者功能
對於特殊的某些功能要求也許不能使用struts2來處理,以免請求隊列過長等候太久。此處就需要使用servlet來處理需要快速響應的請求。
至於如何讓struts2和servlet共存且不相互影響的原理,在此就不說了,大家可以到我的一篇博客中查看:http://blog.csdn.net/gopain/article/details/16370987。
Servlet的配置方式也是不唯一,但是註解的方式確實不利於管理和查看,所以要求使用在web.xml文件中配置。
配置案例:
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>com.coursemap.d.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/imageServlet.servlet</url-pattern>
</servlet-mapping>
其中,servlet節點是配置servlet的實現和調用類(servlet類),servlet-mapping節點是配置外部訪問接口。
此處可以看到訪問方式是/imageServlet.servlet,要求:
必須添加後綴名,且不能爲do和action。
還有一些其它功能定義就是基礎工具類,在util包裏定義實現即可,如md5碼轉換、發送郵件等等。
開發要求
數據庫
/**
* 連接數據庫
*@author gopain
*
*/
public class DBConnection {
privatestatic String user = "root";
privatestatic String passwd = "gopain";
privatestatic String database = "coursemap";
privatestatic String dbip = "localhost";
privatestatic String dbport = "3306";
privatestatic String dbdriver = "com.mysql.jdbc.Driver";
publicConnection getConnection() throws SQLException {
Stringurl = "jdbc:mysql://" + dbip + ":" + dbport + "/"+ database + "?useUnicode=true&characterEncoding=utf-8";
try{
Class.forName(dbdriver).newInstance();
}catch (Exception e) {
thrownew SQLException(e);
}
returnDriverManager.getConnection(url, user, passwd);
}
/**
* 關閉數據庫資源
* @param connection 需要關閉的連接
* @param statement 預處理語句
* @param result 結果集
* @param position 自定義系統調用的位置,需要指明包名、類名以及方法名
*/
publicvoid close(Connection connection,PreparedStatement statement,ResultSetresult,String position){
try{
if(result!= null){
result.close();
result= null;
}
if(statement!= null){
statement.close();
statement= null;
}
if(connection!= null){
connection.close();
connection= null;
}
}catch(SQLExceptione){
e.printStackTrace();
System.out.println("Exceptionat: " + position);
}
}
}
1. 對於數據庫連接資源,必須“節約”使用。在一次連接完成後必須關閉。
2. 每一個操作數據庫的類繼承以上的DBConnection即可。方便取得連接和關閉連接。
在此,我重要強調的是關閉數據庫的時候的那個position參數,必須指定且說明詳細,
如:
finally{
close(connection, statement, result, "package:com.coursemap.c.domain.impl\n"+
"class:UserDaoImpl \n method:getUsers() \nintent:獲取用戶列表");
}
還有,close方法是在finally中調用,大家應該懂。
3.每一次捕獲錯誤都必須指明和註釋。
如,
catch(Exception e) {
e.printStackTrace();
System.out.println("package:com.coursemap.c.domain.impl\n"+
"class:UserDaoImpl \n method:getUsers() \nintent:獲取用戶列表\n無法獲取前10調用戶的用戶名和email");
}
以便於開發階段調試和生產階段的日誌生成。