討論區(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>
沒有留言:
張貼留言