討論區

討論區(Forum)通常簡稱論壇,提供相關訊息串連的相關程式。經過複雜的進化後又經過了簡化,演變至今成為社群網站。事實上不管是具備基礎功能的討論區或社群網站,都只是BBS的進階版本。討論區動態伺服器產生動態的網頁內容多半有固定格式,需要美觀的裝飾。本篇重點在介紹JSP中重複使用裝飾的方式,將頁首、頁尾、選單等使用 JSP include 加入到網頁中。使得不同的程式能夠使用風格相同的裝飾,甚至是一些看不到的程式也能重複使用。

JSP include 在處理靜態組件時如頁首、頁尾...等這些文件不會改變內容的文件時,能自動重讀取並顯示。能減少開發者的程式維護工作,也能讓伺服器節省不斷地重新建立這些文字的記憶體。凡是可以重複使用的地方,都應該用 JSP include 。這個方法無論在開發階段或是在程式執行階段,都能提高運作的效率。

建立 JSP include

通常會需要共用資料庫的連線字串,因此先建立 conn.jsp 內容如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<%@ page import="org.sqlite.*"%>
<%
        request.setCharacterEncoding("UTF-8");			//將輸入編碼設定為UTF-8
        response.setCharacterEncoding("UTF-8");			//將輸出編碼設定為UTF-8
        SQLiteConfig cfg = new SQLiteConfig();
        SQLiteDataSource ds = new SQLiteDataSource(cfg);
        ds.setUrl("jdbc:sqlite:E:\\joop\\my.db");		//請選擇資料庫連線位置
        ResultSet rs;
        String sql;
        Statement stat;
        stat = ds.getConnection().createStatement();
%>

選單是每個網頁都要呈現的靜態文字,因此也建立 menu.jsp 內容如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<div class="navbar navbar-static-top">
	<div class="navbar-inner">
		<div class="container">
			<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
			<span class="icon-bar"></span>
			<span class="icon-bar"></span>
			<span class="icon-bar"></span>
			</a>
			<a class="brand" href="index.jsp">我的學習歷程</a>
			<div class="nav-collapse collapse">
				<ul class="nav">
					<li class="active"><a href="index.jsp">首頁</a></li>
					<li class="dropdown"><a href="#" class="dropdown-toggle"
						data-toggle="dropdown">課程選單 <b class="caret"></b></a>
						<ul class="dropdown-menu">
							<li><a href="temp.jsp">裝飾器</a></li>
							<li><a href="ch02.jsp">計數器</a></li>
							<li class="divider"></li>
							<li class="nav-header">期中</li>
							<li><a href="ch03.jsp">BBS</a></li>
							<li><a href="ch04.jsp">討論區</a></li>
							<li><a href="#">大樂透開獎</a></li>
							<li class="divider"></li>
							<li class="nav-header">期末</li>
							<li><a href="#">問卷/投票</a></li>
							<li><a href="#">購物車</a></li>
						</ul></li>
					<li><a href="#">筆記1</a></li>
					<li><a href="#">筆記2</a></li>
				</ul>
			</div>
		</div>
	</div>
</div>

頁首頁尾也大都是重複文字,因此建立 foot.jsp 並複製以下內容
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<div class="page-footer">
內容是由 <a href="#" style="color:#ffffff"><b>中華科技大學</b></a> 資管系 <a href="#" style="color:#ffffff"><b>10X14D0XX同學</b></a> 建立
</div>

除了導入套裝的裝式器之外,有時也會需要自定義的裝飾器。因此建立 style.css並複製以下內容:
body {
        padding-top: 0px;
        padding-bottom: 40px;
}
 
.sidebar-nav {
        padding: 9px 0;
}
 
@media ( max-width : 980px) {
        .navbar-text.pull-right {
                float: none;
                padding-left: 5px;
                padding-right: 5px;
        }
}

.page-footer {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  background-color: #3b5998;
  color: white;
  text-align: center;
  padding:10px;
  
}

.page-footer.a {
  color: white;  
}

組裝 JSP include (建立樣版)

建立了上面這些重複使用的頁面後,要開始組裝JSP。首先建立新 JSP 檔案,可以先命名為: temp.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%@include file="conn.jsp"%><!-- 資料庫連線 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title><!-- 瀏覽器標題 -->
<link href="style.css" rel="stylesheet">
<!-- 自定義裝飾 -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap-responsive.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</head>
<body>
	<%@include file="menu.jsp"%><!-- 選單 -->
	<div class="container">		
		<div class="page-header">
			<h1>網頁標題</h1><!-- 網頁標題 -->
		</div>

		+++置換內容區塊+++

	</div>
	<%@include file="foot.jsp"%><!-- 頁尾 -->
</body>
</html>

討論區

討論其實只是留言版的進階版本,主要是讓每條訊息都可以追加額外的訊息而不影響原文。簡單來說,就是將原本的資料表增加一個欄位,並將此欄位對應到另一個資料表讓網頁能顯示相關連的資料。因為變更了BBS資料表的結構,請打開「DB Browser for SQLite」將原有的BBS資料表刪除。將資料表刪除後請應用現有的temp.jsp複製成新網頁ch04.jsp,在「內容區塊」取代成以下內容

<%//建立資料表以try,catch的方式,因CREATE TABLE IF NOT EXISTS在不同資料庫中有錯誤的風險
try {
	 stat.executeUpdate("DROP TABLE bbs;");
    stat.executeUpdate("CREATE TABLE'bbs'('Oid'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'title'TEXT,'content'TEXT,'user'TEXT);");
} catch (Exception e) {}
try {
    stat.executeUpdate("CREATE TABLE'bbs_feedback'('Oid'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'bbs'INTEGER,'content'TEXT,'user'TEXT);");
} catch (Exception e) {}
//判斷有接收到表單中含有title則做資料庫新增資料
if (request.getParameter("title") != null) {
    if (!request.getParameter("title").equals("")) {
        stat.executeUpdate("INSERT INTO bbs(title, content, user)VALUES('"+ request.getParameter("title")+ "', '"+ request.getParameter("content") + "', '"+request.getParameter("user")+"')");
    }
}
sql = "SELECT * FROM bbs ORDER BY Oid DESC";//建立查詢字串
rs = stat.executeQuery(sql);//將查詢結果放入容器%>
<form action="ch04.jsp" method="POST">
  標題: <input type="text" name="title" style="width:80%;"><br>
  作者: <input type="text" name="user" style="width:80%;"><br>
  內容: <textarea name="content" style="width:80%;"></textarea>
  <input type="submit" class="btn btn-large btn-danger" value="發佈">
</form>
<%while (rs.next()) {%>
  標題:<%=rs.getString("title")%><br>
  作者:<%=rs.getString("user")%><br>
  內容:<%=rs.getString("content")%>
  <a href="ch04-1.jsp?Oid=<%=rs.getString("Oid")%>" class="btn btn-primary btn-mini">回覆</a><hr>
<%}%>

討論區的列表頁ch04.jsp完整代碼如下
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%@include file="conn.jsp"%><!-- 資料庫連線 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title><!-- 瀏覽器標題 -->
<link href="style.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap-responsive.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</head>
<body>
	<div id="wrap">
		<div class="container">
			<%@include file="menu.jsp"%><!-- 選單 -->
			<div class="page-header">
				<h1>網頁標題</h1><!-- 網頁標題 -->
			</div>			
			<%//建立資料表以try,catch的方式,因CREATE TABLE IF NOT EXISTS在不同資料庫中有錯誤的風險
			try {
            	stat.executeUpdate("DROP TABLE bbs;");
					stat.executeUpdate("CREATE TABLE'bbs'('Oid'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'title'TEXT,'content'TEXT,'user'TEXT);");
            } catch (Exception e) {}
			try {
                 stat.executeUpdate("CREATE TABLE'bbs_feedback'('Oid'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'bbs'INTEGER,'content'TEXT,'user'TEXT);");
            } catch (Exception e) {}			
            //判斷有接收到表單中含有title則做資料庫新增資料                     
            if (request.getParameter("title") != null) {
	             if (!request.getParameter("title").equals("")) {
	                     stat.executeUpdate("INSERT INTO bbs(title, content, user)VALUES('"+ request.getParameter("title")+ "', '"+ request.getParameter("content") + "', '"+request.getParameter("user")+"')");
	             }
            }                       
            sql = "SELECT * FROM bbs ORDER BY Oid DESC";//建立查詢字串
            rs = stat.executeQuery(sql);//將查詢結果放入容器%>
			<form action="ch04.jsp" method="POST">
				標題: <input type="text" name="title" style="width:80%;"><br> 
				作者: <input type="text" name="user" style="width:80%;"><br>                 
				內容: <textarea name="content" style="width:80%;"></textarea> 
                <input type="submit" class="btn btn-large btn-danger" value="發佈">
            </form>
            <%while (rs.next()) {%>
                                標題:<%=rs.getString("title")%><br>  
                                作者:<%=rs.getString("user")%><br>  
                                內容:<%=rs.getString("content")%>
             <a href="ch04-1.jsp?Oid=<%=rs.getString("Oid")%>" class="btn btn-primary btn-mini">回覆</a><hr>
             <%}%>
		</div>
	</div>
	<%@include file="foot.jsp"%><!-- 頁尾 -->
</body>
</html>

因為變更了BBS資料表的結構,打開「DB Browser for SQLite」請一定要執行刪除BBS資料表的動作。

討論區的內容頁整體架構與留言版相同,差別在於每則留言都可以獨立成為新的留言版。請建立ch04-1.jsp,內容可參考下列程式碼
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%@include file="conn.jsp"%><!-- 資料庫連線 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<!-- 瀏覽器標題 -->
<link href="style.css" rel="stylesheet">
<!-- 自定義裝飾 -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap-responsive.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</head>
<body>
	<div class="container">
		<%@include file="menu.jsp"%><!-- 選單 -->
		<div class="page-header">
			<h1>網頁標題</h1>
			<!-- 網頁標題 -->
		</div>
		<%	sql = "SELECT b.* FROM bbs b WHERE b.Oid="+ request.getParameter("Oid")+" ORDER BY Oid DESC";//建立查詢字串
			rs = stat.executeQuery(sql);//將查詢結果放入容器%>
		<h2>
			<a href="ch04-1.jsp?Oid=<%=rs.getString("Oid")%>"><%=rs.getString("title")%></a>
			<small><%=rs.getString("user")%></small>
		</h2>
		<%=rs.getString("content")%>
		<%
			if (request.getParameter("content") != null) {
				stat.executeUpdate("INSERT INTO bbs_feedback(bbs, content, user)VALUES('"+ request.getParameter("Oid")+ "','"+ request.getParameter("content")+ "', '"+ request.getParameter("user") + "')");
			}
			sql = "SELECT b.* FROM bbs_feedback b WHERE b.bbs="+ request.getParameter("Oid")+" ORDER BY Oid DESC";//建立查詢字串
			rs = stat.executeQuery(sql);//將查詢結果放入容器
		%>
		<hr />
		<%while (rs.next()) {%>
		<%=rs.getString("user")%>:
		<%=rs.getString("content")%>
		<hr />
		<%}%>
		<form action="ch04-1.jsp?" method="POST">
			<input type="hidden" name="Oid" value="<%=request.getParameter("Oid")%>" /> 
				作者: <input type="text" name="user" style="width:80%;"> <br>
				內容:<textarea name="content" style="width:80%;"></textarea><br>
			<input type="submit" class="btn btn-danger" value="確定發佈">
			<a href="ch04.jsp" class="btn">返回列表</a>
		</form>
	</div>
	<%@include file="foot.jsp"%><!-- 頁尾 -->
</body>
</html>

沒有留言:

張貼留言