目錄
第一章 概述
1.1 目的與意義
當今社會人們對信息的需求日益增大,及時獲得有用信息需要有信息源,更需要有高效集成的信息管理方式。各行各業的發展都需要有良好的信息數據處理方式,計算機憑藉其卓越強大的性能,被廣泛用於信息管理。
家教在線管理平臺力求解決大學生有知識無處施展、中小學生想學知識卻不易尋找家教老師的尷尬狀況,讓高校學生學以致用,讓需要知識的人得償所願,達到施教方和受教方的雙贏。家教在線管理平臺整合處理家教信息,着重收集學員、教員信息,分類處理及時更新、及時反饋信息,幫助廣大學生找到合適的家教老師,幫助大學生獲得歷練機會。因此,家教在線管理平臺聯繫了教學雙方,起到了紐帶作用。
第二章 需求分析
2.1 市場需求分析
就消費需要方面來看,本市教育需求較大,同時需求也呈現出分散的不集中的特點。
在市場供給主體方面,幾乎所有中介和經營機構都呈現出一種"散、 小、亂”的特點。現在的家教市場上涉足家教服務的機構非常多,但真正合法經營家教,持有工商行政部門註冊頒發的含有家教經營範圍的營業執照和教育部門]批准的家教機構,數量極少。絕大部分的家教服務機構既未經過教育行政部門批准,也沒有經過工商行政部門註冊,根本就是不具備經營家教資格。
2.2 客戶需求分析
1.從學員方面來說:
第一,由於孩子受到智力發展水平、記憶力強弱、上課注意力集中程度、學習方法、個人刻苦程度、知識鏈等衆多因素的影響,在接受同樣教學活動的一羣孩子會產生不同的學習效果;
第二,近年來中小學的課餘時間愈加豐富,寒暑假也各有所延長,就形成了許多比較集中的輔導時間,這樣更有利於學生輔導的連貫性和各種培訓機構的課程安排;
第三,受教育人口逐年增加,升學壓力逐漸增大,單依靠學校學習很難使成績有巨大的提升,而且教師在年齡上與學生存在一定的代溝,講解時會存在一些隔閡,而大學生在年齡上會比較接近中小學生的年齡特點,溝通上會較教師更加輕鬆,而且在交談時會更加像“朋友”一樣;
2.從教員方面來說:
第一,由於我們師說家教網的教員來自大學生,多以在教員的數量上很容易追趕上其他家教企業;
第二,大學生對於金錢的消費觀已經不同與父輩,消費也變得更加高,但是大部分大學生的生活消費都是自己校外兼職獲取的,可是此類兼職大都是一些依靠力氣賺取錢財的,他們更加渴望能夠找到一份腦力勞動;
第三,不同學校不同專業對大學生的要求不一樣,這對於我們師說家教網在招聘學員方面可供篩選,對平臺科目的設置提供了現實依據;
第三章 總體設計
本章節主要講述網站的總體佈局以及數據庫中表的基本關係。
本網站主要使用了我們組員熟悉的JSP和Servlet,網站開發採用了增量模型與原型模型相結合的開發方式。首先確定網站主要需求,之後根據已有的網上的網站開發案例進行二次開發。在二次開發基礎上又增加了社區模塊,以及基本的數據操作等。
3.1網站開發模型及總體創新
使用增量開發模型,首先確認首頁,然後構思管理員,教員,學員,社區新聞模塊,之後進行逐一實現。
使用原型模型,首先熟悉模板網站所有的基本構架,在原有的基本構架上加有了如下幾點新意:
①增加了在線留言功能。考慮到某些師生存在着一點行爲不規範的因素,造成某一方或者雙方不滿意的情況,可以使用此在線留言進行申訴。
②增加了社區新聞功能。用來分享一些家教新聞以及網站收費標準等。
③增加了信息檢索功能。之前的網站並不存在信息檢索功能,經過提議,決定在他們的模塊進行基本的實現。
④提議更改了底部頁數信息跳轉頁面。之前的原型只能一頁一頁的跳轉,現在可以進行指定頁的頁面跳轉。
備註:(1)總體規劃的任務是心中有了構思,再往下進行分發。
(2)公共頁面和用戶控制屬於輔助,在第二層模塊需要一些公共操作時,會有他們進行實現。
3.2網站總體結構圖
3.3 數據庫關係
展現數據庫中各個表:
備註:
①cProblem表,experience表,hostCure表,tutorNews表這四個表是依賴於news表,news表中存的都是社區新聞ID,以及標題和屬於哪類新聞。在上述四個表中存的都是問題的答案。爲了區別news中吧標題是上述四類哪一類新聞,我們另建設了一個字段,用0~3標記屬於哪個類型。
②我們使用student表teacher表存儲用戶的個人信息,用user表存儲用戶的賬戶與密碼。這student表teacher表依賴於user表,他們的相關聯的字段是ID。
③我們使用orders表存儲訂單信息,其中使用SID來關聯student表中學員發佈的訂單信息,tID來關聯teacher表中教員接收的訂單信息。當一個訂單中即存在tIDy也存在SID時,就說明此ID訂單已被接收。
④數據庫的E-R圖只在各個模塊展現,再次總結中不做展示。
在數據庫中,存在一個數據庫連接的代碼,以便其他用戶更方便的對數據庫進行查找。使用context.xml進行數據庫信息保存:
<Resource
name="mydb"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://DESKTOP-FC6QLTM:1433;databaseName=db_tutor"
username="sa"
password="1234"
maxActive="200"
maxIdle="10"
maxWait="5000"/>
使用java代碼來實現數據庫的連接與操作,存於一個類中,主要有以下功能:
1)、獲取連接的方法:
InitialContext initCtx = new InitialContext();
DataSource ds = (DataSource)initCtx.lookup("java:comp/env/"+dbSourceName);
this.con = ds.getConnection();
return con;//返回數據庫連接
2)、執行數據庫的操作語句:
pstm=con.prepareStatement(sql);
利用sql語句返回一個ResultSet結果集:
return pstm.executeQuery();
3)、利用sql語句返回結果集的第一行第一列單元格數據:
String value;
ResultSet rs=pstm.executeQuery();
rs.next();
value=rs.getString(1);
rs.close();
return value;//返回第一個單元格數據
4)、利用sql返回結果集的第一行所有數據:
excute(sql);
ArrayList aList=new ArrayList();//新建一個arrayList對象。
ResultSet rs=pstm.executeQuery();
rs.next();//將指針指向結果集的第一行。
int columns=rs.getMetaData().getColumnCount();//獲取該結果集的列數。
for(int i=1;i<columns+1;i++){//因爲用索引取值是從1開始的。
aList.add(rs.getString(i));//將第一行的所有列都以String形式封裝到Arraylist。
}
return aList;//返回封裝好的arraylist.
5)、返回受影響的行數:
excute(sql);
return pstm.executeUpdate();
6)、關閉連接方法。
第四章 詳細設計與實現
4.1 管理員模塊
管理員是一個網站運作的核心部分,他們操控着網站的基本運作,主要實現了新聞的增刪改查以及用戶權限的更改,此部分主要講述管理員的功能以及具體實現。
4.1.1數據庫設計
字段名稱 |
數據類型 |
主 鍵 |
是否可空 |
說 明 |
uId |
int |
是 |
否 |
用戶編號 |
uName |
varchar(20) |
否 |
否 |
用戶姓名 |
uPwd |
varchar(20) |
否 |
否 |
用戶密碼 |
popedom |
int |
否 |
否 |
用戶權限 |
loginCount |
int |
否 |
否 |
登錄次數 |
question |
varchar(80) |
否 |
否 |
用於找回密碼的問題 |
answer |
varchar(80) |
否 |
否 |
用於找回密碼的答案 |
管理員不存在任何信息,所以沒有其他表與之關聯。
4.1.2功能分析
師說家教網管理員功能的詳細分解如下圖所示:
4.1.3頁面設計
管理員不存在註冊界面,賬號和密碼隱藏技術學的不是多好,所以有兩種添加管理員的方法:
1.需要註冊的管理員要註冊賬號密碼,然後修改註冊者的權限。
2.直接在數據庫中添加管理員。
3.解決了網站能夠不登錄就直接訪問的問題。
以上就是我的創新部分。
在網站的實現中,我們使用可taglib指令,編寫了一個自定義標籤,主要檢測是否具有那個權限達到這個網址:
<tag>
<name>adminPop</name>
<tag-class>admin.adminPop</tag-class>
<body-content>JSP</body-content>
</tag>
其中的java代碼:
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return this.EVAL_BODY_INCLUDE;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
beans.User user = (beans.User) pageContext.getSession().getAttribute(
"user");
if (user == null || user.getPopedom() != 0) {
try {
pageContext.getResponse().getWriter().write("<script>alert('您不是管理員,無法訪問此頁面!');history.go(-1);</script>");
} catch (IOException e) {
e.printStackTrace();
}
}
return this.EVAL_PAGE;
}
1)登錄管理員之後的首頁如下:
在管理員首頁的左側是一個管理員功能列表,在他的右側是統計網站中社區新聞各部分的總條數。
主要代碼實現:
DbAccess dao = new DbAccess("mydb");
sql = "select count(*) from news";
count = dao.getFirstUnit(sql);
//獲取留言總數
String sqlmsg = "select count(*) from msgBoard";
int msgCount = Integer.parseInt(dao.getFirstUnit(sqlmsg));
//學員總數
String stuSql = "select count(*) from student";
int stuCount = Integer.parseInt(dao.getFirstUnit(stuSql));
//教員總數
String tchSql = "select count(*) from teacher";
int tchCount = Integer.parseInt(dao.getFirstUnit(tchSql));
2)用戶管理功能
主要用於修改用戶的權限,這個權限的修改可以以此來添加管理員:
其中更改權限的主要代碼實現:
JSP中JavaScript控制:
<SCRIPT>
function getPopValue(popId){
//alert("ssssssssss");
var pop=document.getElementById(popId).value;
alert(pop);
var url="http://localhost:8080/zhaoTutor/changePop?uId="+popId+"&popedom="+pop;
alert(url);
location.replace(url);
}
</SCRIPT>
Servlet控制代碼:
db.DbAccess dao=new db.DbAccess("mydb");
String popedom=request.getParameter("popedom");
if(dao.getInt("update users set popedom="+popedom+" where uId="+request.getParameter("uId"))>0){
System.out.println("權限修改成功");
}else{
response.getWriter().write("<SCRIPT>alert('權限修改失敗!');</SCRIPT>");
}
response.sendRedirect("admin/userManage.jsp");
3)新聞管理功能
該功能主要用於實現社區新聞模塊的添加與刪除,其界面是:
其主要處理代碼:
刪除新聞Servlet:
db.DbAccess dao=new db.DbAccess("mydb");
if(dao.getInt("delete from news where Id="+request.getParameter("Id"))>0){
response.getWriter().write("<SCRIPT>alert('留言刪除成功!');</SCRIPT>");
}else{
response.getWriter().write("<SCRIPT>alert('留言刪除失敗!');</SCRIPT>");
}
response.sendRedirect("admin/newsManage.jsp");
添加新聞Servlet:
String popedom=request.getParameter("popedom");
String title=request.getParameter("title");
String content=request.getParameter("content");
title = new String(title.getBytes("ISO8859-1"), "UTF-8");
db.DbAccess dao=new db.DbAccess("mydb");
String sql="insert into news(popedom,title) values ("+popedom+",'"+title+"')";
if(dao.getInt(sql)>0){
System.out.println("數據插入成功");
}else{
System.out.println("數據插入失敗....");
}
response.sendRedirect("admin/newsManage.jsp");
4)留言管理
主要展現用戶的留言,給用戶提供申訴的平臺。
主要處理Servlet:
db.DbAccess dao=new db.DbAccess("mydb");
if(dao.getInt("delete from msgBoard where mId="+request.getParameter("mId"))>0){
System.out.println("留言刪除成功");
}else{
response.getWriter().write("<SCRIPT>alert('留言刪除失敗!');</SCRIPT>");
}
response.sendRedirect("admin/msgManage.jsp");
5)退出系統
退出系統之後會顯示網站首頁,主要代碼:
<%
session.invalidate();
out.println("<script>alert('您已成功退出登錄!');this.location.href='index.jsp';</script>");
%>
4.2 教員模塊
教員管理頁面:管理頁面+簡歷頁面+照片頁面+密碼管理+最新訂單+家教記錄
4.2.1 數據庫設計
教員信息頁面數據庫設計;
tId |
int |
Sex |
nchar(4) |
tPhone |
varchar(11) |
|
varchar(50) |
School |
varchar(50) |
Subject |
varchar |
[level] |
int |
Description |
nchar(100) |
Age |
int |
Education |
varchar(20) |
idCard |
varchar(18) |
pubtTime |
datetime |
Address |
nchar(100) |
realName |
nchar(15) |
tPhoto |
varchar(50) |
Appraise |
varchar(500) |
訂單頁面數據庫設計:
OId |
int |
TId |
int |
SId |
int |
State |
varchar(4) |
WorkTime |
varchar(50) |
Subject |
nchar(70) |
Require |
varchar(200) |
SDesc |
varchar(150) |
TSex |
nchar(4) |
TEducation |
varchar(50) |
Address |
varchar(50) |
Money |
varchar(50) |
Area |
varchar(50) |
PubTime |
datetime |
4.2.2 邏輯結構設計
teacher(tId,Sex,tPhone,Email,School,Subject,[level],Description,Age,Education,idCard,pubtTime,Address,realName,tPhoto,appraise)
教員(編號,性別手機,電子郵件,學校,科目,年齡,學歷,訂單號,時間,地址,)
orders(oId,tId,sId,State,workTime,Subject,Require,sDesc,tSex,tEducation,Address,Money,Area,pubTime)
4.2.3 功能分析
4.2.4 E-R關係圖
4.2.5 頁面設計
管理頁面:教員可以看見自己的登陸次數
簡歷管理頁面:現有身份+自我描述+手機號碼+電子郵件+通訊方式+教授科目
教員可以修改一些自己的個人信息。
照片管理:教員可以上傳自己的個照片
密碼管理:新密碼+確實密碼+提示問題+答案
教員可以修改自己的密碼。
最新訂單:訂單編號+所屬區縣+教員性別+相關科目+學院性別
教員可以在該頁面查詢管理員發佈的家教訂單相關信息。
家教記錄:訂單號+時間+年級科目+狀態+薪資
教員可以在該頁面查詢自己接的家教的相關信息。什麼時間接的,目前是否還在授課,工資多少都可以查詢到。
4.3 學員模塊
學員模塊是師說家教網的核心模塊,用戶以學生身份登陸師說家教網之後,會首先進入學生模塊界面。學生模塊是師說家教網的核心模塊之一,對於學生模塊的設計需要做到以下幾點:界面簡潔、功能一目瞭然、條理清晰、層次分明並且有一定的安全性。
4.3.1數據庫設計
users.table
列名 |
數據類型 |
是否爲空 |
主鍵 |
說明 |
uId |
int |
否 |
是 |
用戶id |
uName |
varchar(20) |
否 |
否 |
登錄用戶名 |
uPwd |
varchar(60) |
否 |
否 |
用戶密碼 |
popedom |
int |
是 |
否 |
用戶權限,0表示管理員,1表示教員,2表示學員 |
loginCount |
int |
否 |
否 |
登錄次數 |
question |
varchar(80) |
否 |
否 |
密保提示問題 |
answer |
varchar(80) |
否 |
否 |
密保問題答案 |
Student.table
列名 |
數據類型 |
是否允許爲空 |
主鍵 |
說明 |
sId |
int |
否 |
是 |
學員id |
sex |
nchar(4) |
是 |
否 |
學員性別 |
age |
Int |
是 |
否 |
學員年齡 |
education |
nchar(20) |
是 |
否 |
學員學歷 |
sPhone |
varchar(50) |
是 |
否 |
學生電話 |
subject |
varchar(150) |
是 |
否 |
科目 |
address |
nchar(100) |
是 |
否 |
地址 |
pubTime |
datetime |
是 |
否 |
註冊時間 |
realName |
nchar(15) |
是 |
否 |
真實姓名 |
|
varchar(50) |
是 |
否 |
電子郵箱 |
Orders.table
列名 |
數據類型 |
是否允許爲空 |
主鍵 |
說明 |
oId |
int |
否 |
是 |
訂單編號 |
tId |
int |
是 |
否 |
教員id |
sId |
int |
否 |
否 |
學員id |
state |
varchar(4) |
是 |
否 |
訂單狀態 |
workTime |
varchar(50) |
是 |
否 |
進行家教的時間 |
subject |
nchar(70) |
是 |
否 |
家教科目 |
require |
varchar(200) |
是 |
否 |
家教要救 |
sDesc |
varchar(150) |
是 |
否 |
對學員的基本描述 |
tSex |
nchar(4) |
是 |
否 |
要求家教的性別 |
tEducation |
varchar(50) |
是 |
否 |
要求家教的學歷 |
address |
varchar(50) |
是 |
否 |
要求進行家教的地址 |
money |
varchar(50) |
是 |
否 |
工資待遇 |
area |
varchar(50) |
是 |
否 |
學員所在區 |
pubTime |
datetime |
是 |
否 |
訂單發佈時間 |
4.3.2 E-R關係圖
學生用戶關係圖:
訂單信息關係圖
4.3.3功能分析
家教網學生模塊功能的詳細分解如下圖所示:
4.3.4功能界面
圖4.3.6-1 管理首頁
圖4.3.6-2 簡歷管理
圖4.3.6-3 發佈家教
圖4.3.6-4 家教記錄
圖4.3.6-5 教員信息
4.3.5功能實現
添加訂單評價:
db.DbAccess dbAccess=new db.DbAccess("mydb");
if(dbAccess.getInt("update orders set state='over' where oId="+request.getParameter("oId"))>0){
String tid=dbAccess.getFirstUnit("select tId from orders where oId="+request.getParameter("oId"));
String oldAppraise=dbAccess.getFirstUnit("select appraise from teacher where tId="+tid);
if(dbAccess.getInt("update teacher set [level]=[level]+"+Integer.parseInt(request.getParameter("appraise"))
+",appraise='"+oldAppraise+"<br/>"+request.getParameter("appraiseDetail")+"' where tId="+tid)>0){
response.sendRedirect("../student/tutorLog.jsp");
刪除家教訂單信息:
db.DbAccess dbAccess=new db.DbAccess("mydb");
if(!request.getParameter("state").trim().equals("s")){
response.getWriter().write("<script>alert('只能取消已發佈的訂單');history.go(-1);</script>");
return;
}
if(dbAccess.getInt("delete from orders where oId="+request.getParameter("oId"))>0){
response.sendRedirect("../student/tutorLog.jsp");
}else{
response.getWriter().write("<script>alert('取消訂單失敗!');history.go(-1);</script>");
}
取消家教訂單:
db.DbAccess dba=new db.DbAccess("mydb");
if(dba.getInt("update orders set state='s' where oId="+request.getParameter("oId"))>0){
response.sendRedirect("../student/tutorLog.jsp");
}else{
response.getWriter().write("<script>alert('操作失敗!');history.go(-1);</script>");
}
修改密碼:
beans.User uu=(beans.User)request.getSession().getAttribute("user");
uu.setUserPwd(request.getParameter("txtPassword"));
uu.setUserAnswer(request.getParameter("txtAnswer"));
System.out.println(uu.getUserAnswer());
db.DbAccess dbAccess=new db.DbAccess("mydb");
if(dbAccess.getFirstUnit("select answer from users where uId="+uu.getUserId()).equals(uu.getUserAnswer())){
if(dbAccess.getInt("update users set uPwd='"+uu.getUserPwd()+"' where uId="+uu.getUserId())>0){
response.getWriter().write("<script>alert('更新成功!');history.go(-1)</script>");
}else{
response.getWriter().write("<script>alert('更新失敗!');history.go(-1)</script>");
}
}else{
response.getWriter().write("<script>alert('問題回答錯誤!');history.go(-1)</script>");
}
學生頁面權限控制:
beans.User u=(beans.User)pageContext.getSession().getAttribute("user");
if(u==null||u.getPopedom()!=2){
try {
pageContext.getResponse().getWriter().write("<script>alert('您沒有權限訪問此頁面!');history.go(-1);</script>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return this.EVAL_PAGE;
確認訂單信息:
db.DbAccess dba=new db.DbAccess("mydb");
if(dba.getInt("update orders set state='ok' where oId="+request.getParameter("oId"))>0){
response.sendRedirect("../student/tutorLog.jsp");
}else{
response.getWriter().write("<script>alert('確認失敗!');history.go(-1);</script>");
}
在教員信息界面,實現了按照篩選條件檢索教員信息:
String condition="";//用於存儲執行的sql語句
//中間逐步得到condition執行語句。
if(condition.length()>3){
condition=condition.substring(0,condition.length()-3); request.getSession().setAttribute("condition",condition);
} response.sendRedirect("../student/teacherList.jsp?index=1");
根據輸入的頁數跳轉到相應頁數的教員信息:
if (request.getParameter("pageCount") != null) {//獲取每頁顯示的記錄數。
pageCount = Integer.parseInt(request.getParameter("pageCount"));
}
if(request.getParameter("condition")!=null){//獲取查詢條件 session.setAttribute("condition",request.getParameter("condition"));}
Boolean flag=true;
current = Integer.parseInt(request.getParameter("index"));//獲取請求的頁編號。
db.DbAccess dba = new db.DbAccess("mydb"); totalPage=Integer.parseInt(dba.getFirstUnit("select count(tid) from teacher where "+session.getAttribute("condition"))); totalPage=(totalPage/pageCount*pageCount==totalPage?totalPage/pageCount:totalPage/pageCount+1);//總頁數
ResultSet rs = dba.getResultSet("select top " + pageCount
+ " * from teacher where "+session.getAttribute("condition")+" and tId not in ("+ "select top " + (current-1) * pageCount + " tId from teacher where "+session.getAttribute("condition")+")");
驗證用戶輸入的各項信息格式是否正確:
1)、驗證姓名是否爲空?
if(name.value.length == 0){
alert("姓名不能爲空!");
return ;}
2)、驗證郵箱不能爲空,格式是否正確?
if(mmail.value.length==0){
alert("郵箱不能爲空!");
return ;
}
if(mmail.value.length!=0){ //如果填寫了郵箱
if(!reg1.exec(mmail.value)){
alert("郵箱格式錯誤!");
return;
}
}
3)、驗證電話不能爲空,格式是否正確?
if(phone.value.length==0){
alert("電話不能爲空!");
return ;
}
if(phone.value.length!=0){
if(!phone.value.match(reg2)){
alert("手機號碼輸入錯誤!");
return;
}
}
4.4 社區模塊
師說家教網的整個前臺部分是供用戶使用的部分,一個好的網站前臺部分設計的一定非常合乎市場需求,而且對於一個經營教育行業的網站對客戶還要有引導部分,以便及時解決用戶的問題,因此,社區部分的設計主要把握以下幾點:簡明扼要、條理清晰、層次分明。社區模塊是構成網站主體的一個重要組成部分,網站設置社區的目的之一在於方便網站信息的管理。下面將針對師說家教網站的社區部分進行詳細的介紹。
4.4.1數據庫設計
cProblem.table/ experience.table/hostCure.table
字段名稱 |
數據類型 |
主 鍵 |
是否可空 |
說 明 |
Id |
int |
是 |
否 |
XX編號 |
datails |
ntext |
否 |
否 |
詳細信息 |
readTime |
int |
否 |
否 |
閱讀次數 |
表4.4.1-1
msgBoard.table
字段名稱 |
數據類型 |
主 鍵 |
是否可空 |
說 明 |
mId |
int |
是 |
否 |
留言編號 |
mname |
nvarchar(50) |
否 |
否 |
留言者姓名 |
mEmaile |
nvarchar(50) |
否 |
否 |
留言郵箱 |
details |
nvarchar(100) |
否 |
否 |
留 言 |
表4.4.1-2
news.table
字段名稱 |
數據類型 |
主 鍵 |
是否可空 |
說 明 |
Id |
int |
是 |
否 |
消息編號 |
title |
nvarchar(100) |
否 |
否 |
標 題 |
readTime |
int |
否 |
是 |
閱讀次數 |
popedom |
int |
否 |
否 |
身份編號 |
表4.4.1-3
tutorNews.table
字段名稱 |
數據類型 |
主 鍵 |
是否可空 |
說 明 |
Id |
int |
是 |
否 |
訪客編號 |
details |
ntext |
否 |
否 |
詳細信息 |
readTime |
int |
否 |
否 |
閱讀次數 |
|
|
|
|
|
表4.4.1-4
4.4.2E-R關係圖
圖4.4.2-1
4.4.3邏輯結構設計
cProblem(cproblem _Id, cproblem _ details, cproblem _ readTime)
問題(問題編號,問題詳情, 問題閱讀次數)
experience(experience_Id, experience_details, experience_readTime)
經驗(經驗編號, 經驗詳情, 經驗閱讀次數)
hostCure(hostCure_Id, hostCure_details, hostCure_readTime)
熱點(熱點編號, 熱點詳情, 熱點閱讀次數)
msgBoard(mId, mName, mEmail, details)
留言板(留言編號, 留言者姓名, 留言郵箱, 留言詳情)
news(Id, title, readTime, popedom)
新聞(新聞編號, 新聞標題, 新聞閱讀次數, 身份 )
tutorNews(tutorNews_Id, tutorNews_details, tutorNews_readTime)
訪客新聞(訪客編號, 訪客詳情, 訪客閱讀次數)
4.4.4功能分析
師說家教網社區模塊功能的詳細分解如下圖所示:
圖4.4.4-1
4.4.5功能界面
圖4.4.6-1 常見問題
圖4.4.6-2 家教新聞
圖4.4.6-3 留言板
4.4.6功能實現
留言板:
String sql="insert into msgBoard values('"+name+"','"+email+"','"+details+"')";
int rs=dao.getInt(sql);
if(rs>0){
System.out.println("數據插入成功!");
}else{
System.out.println("數據插入失敗:"+sql);
}
閱讀次數:
readTime=Integer.parseInt(request.getParameter("readTime"))+1;
String Id=request.getParameter("Id");
String sql="update news set readTime="+readTime+"where Id="+Id;
DbAccess dao=new DbAccess("mydb");
if(dao.getInt(sql)>0){
System.out.println("update readTime right");
}else{
System.out.println("update readTime error!!!");
}
對顯示的信息頁面所在區間進行判斷與定位:
if (currentPage < 1) currentPage = 1;
if (currentPage > count) currentPage = count;
for (int i = 0; i < (currentPage - 1) * pageSize; i++)
{
if (rs.next() == false)
break;
}
根據不同的用戶身份顯示不同信息:
dao=new DbAccess("mydb");//數據庫連接
String lineCount = dao.getFirstUnit("select count(*) from news where popedom="+popedom);
留言板信息格式驗證:
function checkEmail(email){
if(!/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test(email)){
alert("郵箱格式不正確,請重新填寫!");
frmMsg.txtEmail.focus();
}
}
4.5 public模塊
公共部分是師說家教網的重要組成部分,它的是所有的用戶都可以看到的公公界面,它包含了用戶註冊的整個過程,登陸界面,和師說家教網底部的的一些超鏈接,它是師說家教網最開始需要操作的地方,包括註冊、登錄、找回密碼等功能,下面將介紹公共模塊的詳細內容。
4.5.1 邏輯結構設計
student(student_sId, student_sex, student_age, student_education, student_sPhone, student_subject, student_address, student_pubTime, student_realName, student_email)
學員(學員id,性別,年齡,學歷,電話,學科,地址,登錄次數,真實姓名,電子郵箱)
teacher(teacher_tId, teacher_sex, teacher_tPhone, teacher_email, teacher_school, teacher_subject, teacher_level, teacher_description, teacher_age, teacher_education, teacher_idCard, teacher_pubTime, teacher_address, teacher_realName, teacher_tPhone, teacher_appraise)
教員(教員id,性別,教員電話,電子郵箱,學校,學科,接家教次數,描述,,年齡,學歷,身份證號,登錄次數,地址,真實姓名,電話,評價)
users(users_uId, users_uName, users_uPwd, users_popedom, users_loginCount, users_question, users_answer)
用戶(用戶id,用戶姓名,用戶密碼,權限,登錄次數,問題,回答)
功能分析
4.5.2 頁面設計
頁面主要包含上、下、左、右四部分,公共部分主要負責右邊頁面的編寫,剩下的均由include標籤加入jsp頁面
登陸界面login.jsp
註冊界面reg.jsp
教員註冊協議第一步message.jsp
教員註冊協議第二步info.jsp
上傳照片uploadPic.jsp
學員申請賬號messageStu.jsp
學員家教信息infoStu.jsp
找回密碼界面findPwd.jsp
找回密碼信息驗證界面findPwd2.jsp
4.5.3 功能實現
找回密碼:
String userName=request.getParameter("userName");
beans.User uu=new beans.User();
uu.setUserName(userName);
String sql="select count(uName) from users where uName='"+userName+"'";
db.DbAccess dbAccess=new db.DbAccess("mydb");
if(Integer.parseInt(dbAccess.getFirstUnit(sql))>0){
request.getSession().setAttribute("user3", uu);
response.sendRedirect("http://localhost:8080/zhaoTutor/pub/findPwd2.jsp");
}
else{
response.getWriter().write("<script>alert('用戶名錯誤!');history.go(-1)</script>");
}
驗證問題:
String answer=request.getParameter("answer");
String password=request.getParameter("password");
User uu=(User)request.getSession().getAttribute("user3");
String userName=uu.getUserName();
String sql="select answer from users where uName='"+userName+"'";
String sql1="update users set uPwd='"+password+"' where uName='"+userName+"'";
db.DbAccess dbAccess=new db.DbAccess("mydb");
if(dbAccess.getFirstUnit(sql).equals(answer)){
if(dbAccess.getInt(sql1)>0){
response.getWriter().write("<script>alert('更新成功!');location.href('../pub/login.jsp')</script>");
}else{
response.getWriter().write("<script>alert('更新失敗!');history.go(-1)</script>");
}
}else{
response.getWriter().write("<script>alert('問題答案錯誤!');history.go(-1)</script>");
}
教師信息:
Teacher tt=(Teacher)req.getSession().getAttribute("user1");
String userName=tt.getUserName();
String email=tt.getEmail();
String pwd=tt.getUserPwd();
String question=tt.getUserQuestion();
String answer=tt.getUserAnswer();
String sql0="insert into [users](uName,uPwd,loginCount,popedom,question,answer) values('"+userName+"','"+pwd+"',1,1,'"+question+"','"+answer+"')";
String sql1="select uId from users where uName='"+userName+"'";
String sql3="update [users] set popedom=1 where uName="+"'"+userName+"'";
db.DbAccess dbAccess=new db.DbAccess("mydb");
dbAccess.getInt(sql0);
int uid=Integer.parseInt(dbAccess.getFirstUnit(sql1));
String sql2="insert into teacher(tId,sex,tPhone,email,school,subject,description,age,education,idCard,address,realName,pubtTime) " +
"values("+uid+",'"+sex+"',"+tPhone+",'"+email+"','"+school+"','"+subject+"','"+description+"',"+age+",'"+education+"','"+idCard+"','"+address+"','"+realName+"','"+date+"')";
if(dbAccess.getInt(sql2)>0){
tt.setPopedom(1);
beans.User uuUser=new beans.User();
uuUser.setLoginCount(1);
uuUser.setPopedom(1);
uuUser.setUserId(uid);
uuUser.setUserName(tt.getUserName());
req.getSession().setAttribute("user", tt);
dbAccess.getInt(sql3);
resp.sendRedirect("../pub/uploadPic.jsp");
}
學員信息:
- 先使用類型轉換來將存在的中文替換成編譯器能夠正確識別的類型。如:
grade=new String(req.getParameter("education").getBytes("iso-8859-1"),"utf-8");
2.使用會話得到原先存在的數據庫信息,之後一個個的賦值給每個變量,之後進行存儲信息:
beans.User uu=new beans.User();
Student ss=(Student)req.getSession().getAttribute("user2");
String userName=ss.getUserName();
String password=ss.getUserPwd();
String realName=ss.getRealName();
String sex=ss.getSex();
String mobile=ss.getSphone();
String question=ss.getUserQuestion();
String answer=ss.getUserAnswer();
String date=getDate();
ss.setPopedom(2);
String sql="insert into users (uName,uPwd,loginCount,question,answer) values('"+userName+"','"+password+"',1,'"+question+"','"+answer+"')";
String sql1="select uId from [users] where uName="+"'"+userName+"'";
String sql3="update [users] set popedom=2 where uName="+"'"+userName+"'";
db.DbAccess dbAccess=new db.DbAccess("mydb");
dbAccess.getInt(sql);
int id=Integer.parseInt(dbAccess.getFirstUnit(sql1));
String sql2="insert into student(sId,sex,age,education,sPhone,address,realName,email,pubTime) values("+id+",'"+sex+"',"+age+",'"+grade+"','"+mobile+"','"+address+"','"+realName+"','"+email+"','"+date+"')";
if(dbAccess.getInt(sql2)>0){
uu.setUserId(id);
uu.setLoginCount(1);
uu.setPopedom(ss.getPopedom());
uu.setUserName(ss.getUserName());
req.getSession().setAttribute("user",uu);
dbAccess.getInt(sql3);
resp.sendRedirect("../student/student.jsp");
}
}
登錄功能:
1.先使用前面的類進行驗證碼的生成,之後先驗證驗證碼是否正確。
2.之後使用sql語句查詢數據庫中是否存在此名稱,只用得到查詢的第一條數據,之後使用第一列數據進行對比看用戶名是否存在。
3.之後再驗證數據庫中的密碼是否正確,使用上一步得到的第一條數據的第二列數據進行驗證密碼是否正確。
代碼太過於繁雜,沒有寫上,這些驗證錯開了多次查詢數據庫的弊端,少查了用戶名比對的過程。
教員會員註冊:
beans.Teacher tt=new beans.Teacher();
tt.setUserName(userName);
tt.setUserPwd(password);
tt.setEmail(email);
tt.setUserQuestion(question);
tt.setUserAnswer(answer);
req.getSession().setAttribute("user1", tt);
resp.sendRedirect("../pub/info.jsp");
學員會員註冊:
String mobile=req.getParameter("mobile");
beans.Student ss=new beans.Student();
ss.setUserName(userName);
ss.setUserPwd(password);
ss.setUserQuestion(question);
ss.setUserAnswer(answer);
ss.setRealName(realName);
ss.setSphone(mobile);
ss.setSex(sex);
req.getSession().setAttribute("user2", ss);
resp.sendRedirect("../pub/infoStu.jsp");
檢測註冊的時候是否有重複名:
String userName=new String(request.getParameter("userName").getBytes("iso-8859-1"),"utf-8");
String sql="select count(uName) from [users] where uName='"+userName+"'";
db.DbAccess dbAccess=new db.DbAccess("mydb");
PrintWriter out = response.getWriter();
if(Integer.parseInt(dbAccess.getFirstUnit(sql))==0){
out.print(0);
}
if(Integer.parseInt(dbAccess.getFirstUnit(sql))==1){
out.print(1);
}
function checkName(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
//獲取服務器傳輸的數據,在此例中爲0、1。
var returnValue = xmlHttp.responseText;
if(returnValue==0){
document.getElementById("view_name").innerHTML="恭喜,該用戶名可用!!!!";
}
if(returnValue==1){
document.getElementById("view_name").innerHTML="該用戶名已被註冊";
}
}
}
照片檢測只允許jpg,jpeg,png格式的照片上傳:
<script>
function checkFile(){
var file = document.uploadForm.image.value ;
if(file==null||file==""){
alert("你還沒有選擇任何文件,不能上傳!") ;
return ;
}
if(file.lastIndexOf(".")==-1){
alert("路徑不正確!") ;
return ;
}
var allImgExt = ".jpg|.jpeg|.png|" ;
var extName = file.substring(file.lastIndexOf(".")) ;
if(allImgExt.indexOf(extName+"|")==-1){
errMsg="該文件類型不允許上傳。請上傳 "+allImgExt+" 類型的文件,當前文件類型爲"+extName;
alert(errMsg);
return;
}
document.uploadForm.submit() ;
}
</script>
控制手機號的格式:
使用正則表達式來驗證手機號:reg=/^((13\d{9}$)|(16\d{9}$)|(17\d{9}$)|(14\d{9}$)|(15\d{9}$)|(18\d{9})$)/;
5.6 用戶控制模塊
查看新聞、常見問題、經驗等
頁面跳轉,即上一頁、下一頁等
5.6.1 功能界面
新聞 圖5.6.1-2
熱點關注 圖5.6.1-3
頁面跳轉 圖5.6.1-4
經驗雜談 圖5.6.1-5
驗證碼 圖5.6.1-6
側向導航欄 圖5.6.1-7
5.6.2 功能實現
news.jsp:新聞
<TBODY> <%!DbAccess dao = null; String sql = null;
ResultSet rs = null;
int popedom=3;
String tableName="tutorNews";
%>
<% dao = new DbAccess("mydb");//數據庫連接
sql = "select top 5 Id,title from news where popedom=" + popedom;
rs = dao.getResultSet(sql);
for (int i = 1; i <= 5; i++) {
try {
if (rs.next()){
out.println("<TR><TD style='WIDTH:100%; HEIGHT:'30px' align='left'><IMG src='image/doc_more.gif' width='9' height='9'>");
out.println("<a href='community/activePage.jsp?Id="+rs.getString("Id")+"&title="+rs.getString("title")+"&tableName="+tableName+"'>" + rs.getString("title") + "</a>");
out.println("</TD></TR>");
}
}
%>
</TBODY>
webtop.jsp:網站頂部界面
<a href="http://localhost:8080/zhaoTutor/index.jsp">
<% if(session.getAttribute("user")==null) { %>
<A href="pub/login.jsp" style="COLOR: white">登錄</A>
<% } else {
%>
<%
if(((beans.User)session.getAttribute("user")).getPopedom()==1){ %>
<a href="teacher/teacher.jsp" style="COLOR: white">我的師說家教</a>
<A href="logout.jsp" style="COLOR: white">退出</A> <%}else if(((beans.User)session.getAttribute("user")).getPopedom()==2){ %>
<a href="student/student.jsp" style="COLOR: white">我的師說家教</a>
<A href="logout.jsp" style="COLOR: white">退出</A>
<%}
else{
%>
<a href="admin/homeManage.jsp" style="COLOR: white">我的師說家教</a>
<A href="logout.jsp" style="COLOR: white">退出</A>
<% }
} %>
<A href="pub/reg.jsp" style="COLOR: white">註冊</A>
<A style="color:white"href="javascript:window.external.addFavorite('http://localhost:8080/zhaoTutor','師說家教網')">收藏網站</A>
</TD></TR></TBODY></TABLE></TD></TR>
teacherLeft.jsp
<TBODY>
<TR>
<TD width="25%" align="center"><IMG
src="image/left-dot.gif" width=22 height=25></TD>
<TD height=10 vAlign=bottom align=right><A
href="teacher/teacher.jsp">管 理 首 頁</A></TD></TR>
<TR>
<TD height=10 colSpan=2 align="center"><IMG
src="image/leftbtn_bottom.gif" width=149
height=11></TD></TR></TBODY></TABLE>
<TABLE border=0 cellSpacing=0 cellPadding=0 width="80%" height=40>
- 在只能上一頁、下一頁跳轉的基礎上加了按頁碼跳轉
<%@page import="db.DbAccess"%>
<%@page import="java.sql.ResultSet"%>
<%!
int current=1;//設置當前頁。
int pageCount=10;//設置每頁顯示的記錄數。
%>
<%
String table=request.getParameter("table");//獲取select語句。
String columnName=request.getParameter("columnName");//獲取比較字段名。
if(request.getParameter("pageCount")!=null){//獲取每頁顯示的記錄數。
pageCount=Integer.parseInt(request.getParameter("pageCount"));
}
current=Integer.parseInt(request.getParameter("index"));//獲取請求的頁編號。
db.DbAccess dba=new db.DbAccess("mydb");
ResultSet rs=dba.getResultSet("select top "+current*pageCount+" * from "+table+" where "+columnName+" not in ("
+"select top "+(current-1)*pageCount+" "+columnName+" from "+table+")");
while(rs.next()){
%>
<tr>
<td><%=rs.getString("tId") %></td>
<td><%=rs.getString("realName").substring(0,1)+"教員<br/>("+rs.getString("sex")+")" %></td>
<td><%=rs.getString("education") %></td>
<td><%=rs.getString("school") %></td>
<td><%=rs.getString("subject") %></td>
<td><%=rs.getString("description") %></td>
<td><%=rs.getString("level") %></td></tr> <% } %>
- 給普通註冊界面增添了驗證碼
<%!Color getRandColor(int fc, int bc) {
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}%>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
int width = 60, height = 20;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 155; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}
String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = String.valueOf(random.nextInt(10));
sRand += rand;
g.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
g.drawString(rand, 13 * i + 6, 16);
}
session.setAttribute("rand", sRand);
g.dispose();
ImageIO.write(image, "JPEG", response.getOutputStream());
out.clear();
out =pageContext.pushBody();
%>
第五章 總結
通過開發《師說家教網》,我們較爲熟練的掌握了JSP與SERVLET的編程技巧,並且開發能力得到了進一步的提高。在開發過程中我們學到了一些經驗:系統設計的好壞將決定着的系統開發成功與否,一份好的分析設計將是成功開發主要因素。我們在着手開發之前不要急於編程,先應有較長的時間去把分析做好,做好數據庫設計工作,寫出相關的開發文檔等。然後再開始編寫程序代碼。同時在開發該網站的過程中我們也認識到自己知識的有限性,其中在網絡上查找了諸多的資料,修改了很多的不足