JavaWeb 入門級專案實戰 -- 文章釋出系統 (第四節)
首先,更正一下上一章中的一個小錯誤,就是在index.jsp中,banner部分沒有新增結束的標籤,加上去就OK了,我也是完善頁面的時候發現的。
另外,index.jsp中引入的jQuery也需要換成本地的。
<script src="${basePath}/static/js/jQuery.js"></script>
今天我把頁面重構了一下,添加了內容區和底欄(footer),我會把目前的程式碼上傳的,有需要的自己去看就行了,我們就不在前臺頁面花費太多的時間了。div + css,佈局等等,這些東西以後有時間的話,我單獨開貼分享吧。
都已經寫了三篇文章了,還沒有寫Java程式碼,實在有些說不過去。
1. 登陸頁面
登陸頁我已經寫好了,現在看看效果,簡單說明一下。
點選登陸按鈕,可以跳轉到登陸頁面。
登陸按鈕就是一個超連結。
JSP頁面就是一個servlet,但是省去了很多寫Servlet的麻煩,login.jsp已經寫好了,就放在WebContent目:
昨天憋了一上午,總算寫好了登陸頁面。我不是專業做前端的,所以只做了一個大概樣子。用了很多css3的屬性,所以IE678上瀏覽的效果是不好的。
關於這個頁面,今天我調整了一下,不想搞得那麼複雜了,我去掉了所有的圖示和飄動白雲,關於css特效,h5的話呢,以後單獨拿出來說明吧,畢竟好多人都反應說太花哨了,因為是入門級的小專案,我也不想弄得那麼複雜了。
雖然頁面單調了些,不過對於初學者來說,相對來說比較好理解。之前的頁面的確有點太花哨了,還弄了幾朵雲飄來飄去的,說不定還影響效能,所以我把這些都去掉了。
2. 新的目錄結構
之前的程式碼有很多冗餘的地方,比如標題欄,每個頁面都需要寫一遍。而且js和css都是寫在本頁面的。實際開發一般都不會這麼做。所以,我把這些東西都分離出來了,放在各自的目錄裡。
以下是新的目錄結構:
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<div class="header">
<div class='logo'>原創文字</div>
<ul>
<li class='first'><a href="index.jsp">首頁</a></li>
<li class='item'><a href="javascript:void(0)">原創故事</a></li>
<li class='item'><a href="javascript:void(0)">熱門專題</li>
<li class='item'><a href="javascript:void(0)">欣賞美文</li>
<li class='item'><a href="javascript:void(0)">贊助</a></li>
</ul>
<div class='login'>
<span><a href="login.jsp">登陸</a></span>
<span>|</span>
<span><a href="javascript:void(0)">註冊</a></span>
</div>
</div>
這就是標題欄,以後新增的jsp頁面,只需要把這個header.jsp引入就可以了。注意,這種引入就相當於把裡面的程式碼原封不動地拷貝進去,所以如果用相對路徑引用資原始檔,就還是以原本的頁面為準。
引入方式:
<!-- 頭部頁面 -->
<%@include file="common/header.jsp" %>
footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<div class='footer'>
免責宣告:本站所有素材均來自網路,僅供學習交流。如果侵犯了您的權益,請聯絡我,我會第一時間刪除侵權內容。
</div>
taglib.jsp (一些公共的配置等)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
int port = request.getServerPort();
String basePath = null;
if(port==80){
basePath = request.getScheme()+"://"+request.getServerName()+path;
}else{
basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
}
request.setAttribute("basePath", basePath);
%>
basePath 就是專案的根路徑。這樣做的好處就是,使得JSP看起來很乾淨,沒有那麼多冗餘的程式碼了。
大概就是這個樣子,接下來,我們開始寫業務。
3. 登陸功能的MVC流程
登陸框中,目前只有使用者名稱和密碼這兩個選項。
我們首先要做的就是將這兩個值傳遞到後臺。所謂的後臺,其實就是Java程式碼。為了看起來比較清晰,我們在WebContent目錄下新建一個controller包。
這是一個MVC分層的示意圖意思就是說,使用者登入之後,我們需要驗證它的使用者名稱和密碼是否正確,那麼就需要將資料拿到資料庫裡面去匹配。總體的流程大概是這樣:我先在前臺獲取使用者名稱和密碼,然後到controller層(控制層),這一層需要接受你傳過來的使用者名稱和密碼,進行一些基本的控制。
然後繼續將資料傳遞到service層,也就是業務層,這一層會根據具體的業務對你的資料進行判斷和分析,最後,才傳遞到dao層,這一層原則上就是和資料庫進行互動的。多半是寫sql語句然後操作資料庫。
就比如說使用者登入這個功能,我需要判斷的就是
- 你這個使用者是否存在?
- 使用者名稱和密碼是否正確?
最終,還需要將登入的標誌返回給前臺。
dao -> servide -> controller -> JSP
這樣就是一個完整的流程。
4. 從JSP到controller層
讓我們開啟login.jsp頁面,引入jQuery
<script src="${basePath}/static/js/jQuery.js"></script>
登入框的HTML程式碼:
<!-- 登陸框 -->
<div class='content'>
<div class='logo'><i style='font-size:90px;' class="iconfont icon-denglu"></i></div>
<div class='inputBox mt50 ml32'>
<input type="text" id="username" autofocus="autofocus" autocomplete="off" maxlength="60" placeholder="請輸入賬號/郵箱/手機號">
<i style='font-size:20px;margin-left:-32px;opacity:0.8;' class='iconfont icon-yonghuming'></i>
</div>
<div class='inputBox mt50 ml32'>
<input type="password" id="password" autofocus="autofocus" autocomplete="off" maxlength="60" placeholder="請輸入密碼">
<i style='font-size:20px;margin-left:-32px;opacity:0.8;' class='iconfont icon-mima'></i>
</div>
<div class='mt50 ml32'>
<button class="login_btn" onclick="#">登陸</button>
</div>
</div>
我們在下面寫一個script塊,js程式碼就全部寫在這裡。
給登陸按鈕繫結一個點選事件:
<div class='mt50 ml32'>
<button class="login_btn" onclick="login()">登陸</button>
</div>
登陸方法
function login(){
var username = $('#username').val();
var password = $('#password').val();
alert(username + "," + password);
}
當成功alert出來資料後,說明到此為止的程式碼是正確的。
接下來,利用jQuery的ajax方法,將資料提交到controller層。
function login(){
var username = $('#username').val();
var password = $('#password').val();
$.ajax({
type:"post",//請求方式
url:"${basePath}/controller/loginController.jsp",//請求地址
data:{"username":username,"password":password},//傳遞給controller的json資料
error:function(){
alert("登陸出錯!");
},
success:function(data){ //返回成功執行回撥函式。
}
});
}
我已經都寫好註釋了,ajax方法在web開發過程中,是被普遍使用的。
新建一個loginController.jsp ,這就是所謂的伺服器端。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
//設定請求的編碼
//request.setCharacterEncoding("UTF-8");
//獲取客戶端傳遞過來引數
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username);
System.out.println(password);
//如果使用者名稱和密碼不為空
%>
從JSP頁面到controller,使用者名稱和密碼是被裝在一個叫做request的變數中,它其實也就相當於一個json,一個map,都是差不多的東西,這裡就不詳細說明了。當然了,他也是JSP九大隱式物件中的一員。
我們來測試一下,點選登陸按鈕。
成功了!可以看到資料已經成功傳遞到controller層了。
因為我們還沒有資料表和JavaBean,所以我們先不急著寫service層,先開始編寫JavaBean吧。
5. 從JavaBean到資料庫表。
我們在src目錄下新建一個存放JavaBean的包
關於JavaBean,如果不是很瞭解的話,可以看看這篇文章:
一個記錄使用者資訊的JavaBean,我想了以下這些屬性:
private String id; //主鍵,採用UUID
private String username; //使用者名稱
private String password; //密碼
private String headerPic; //頭像
private String email; //電子郵箱
private Integer male; //性別 0男 1女 3保密
private String createTime;//建立時間
private String updateTime;//最後更新時間
private Integer isDelete; // 刪除狀態0未刪除1刪除
private String address; //地址
private String telephone; //電話
當你的JavaBean設計好了,差不多對應的資料庫表也就出來了。
之前寫過一篇關於註解的文章:
現在可以用這個知識點做點有趣的事情了,比如將一個JavaBean轉換成建表語句。
新建一個註解包,裡面新增兩個註解
column.java
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD) //註解的目標
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String field() ; //欄位名稱
public boolean primaryKey() default false;//是否為主鍵
public String type() default "VARCHAR(80)";//欄位型別
public boolean defaultNull() default true; //是否允許為空
}
Table.java
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE) //註解的目標是類
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
public String tableName();
}
我們建立了兩個註解。
接下來,在util包(也就是工具包)中新建兩個工具類
StringUtils 字串工具類
package util;
public class StringUtils {
public static boolean isEmpty(String str) {
return null == str || str.equals("")
|| str.matches("\\s*");
}
public static String defaultValue(String content,String defaultValue){
if(isEmpty(content)){
return defaultValue;
}
return content;
}
}
isEmpty的作用是判斷字串是否為空。
defaultValue表示給字串設定預設值,有點類似於oracle資料庫中的nvl語法。
TableUtils 資料表工具類
package util;
import java.lang.reflect.Field;
import annotation.Column;
import annotation.Table;
public class TableUtils {
public static String getCreateTableSQl(Class<?> clazz){
StringBuilder sb = new StringBuilder();
sb.append("create table ");
//獲取表名
Table table = (Table) clazz.getAnnotation(Table.class);
String tableName = table.tableName();
sb.append(tableName).append("(\n");
Field[] fields = clazz.getDeclaredFields();
String primaryKey = "";
//遍歷所有欄位
for (int i = 0; i < fields.length; i++) {
Column column = (Column) fields[i].getAnnotations()[0];
String field = column.field();
String type = column.type();
boolean defaultNull = column.defaultNull();
sb.append("\t" + field).append(" ").append(type);
if(defaultNull){
if(type.toUpperCase().equals("TIMESTAMP")){
sb.append(",\n");
}else{
sb.append(" DEFAULT NULL,\n");
}
}else{
sb.append(" NOT NULL,\n");
if(column.primaryKey()){
primaryKey = "PRIMARY KEY ("+field+")";
}
}
}
if(!StringUtils.isEmpty(primaryKey)){
sb.append("\t").append(primaryKey);
}
sb.append("\n) DEFAULT CHARSET=utf8");
return sb.toString();
}
}
getCreateTableSQl方法是利用反射和註解有關的知識,給一個JavaBean自動生成建表語句,目前只支援MySQL,因為這方面的知識我也是剛開始學,寫得不好的地方還請各位多多包涵。
接下來,給JavaBean添加註解。
@Table(tableName = "t_user")
public class User{
//屬性
}
屬性如下:
@Column(type = "varchar(30)" ,field = "id" ,primaryKey = true ,defaultNull = false)
private String id; //主鍵,採用UUID
@Column(type = "VARCHAR(20)", field = "username")
private String username; //使用者名稱
@Column(type = "VARCHAR(20)", field = "password")
private String password; //密碼
@Column(type = "VARCHAR(60)", field = "headerPic")
private String headerPic; //頭像
@Column(type = "VARCHAR(60)", field = "email")
private String email; //電子郵箱
@Column(type = "VARCHAR(2)", field = "sex")
private Integer sex; //性別 0男 1女 3保密
@Column(type = "datetime", field = "create_time")
private String createTime;//建立時間
@Column(type = "timestamp", field = "update_time")
private String updateTime;//最後更新時間
@Column(type = "int(1)", field = "is_delete")
private Integer isDelete; // 刪除狀態 0未刪除 1刪除
@Column(type = "VARCHAR(200)", field = "address")
private String address; //地址
@Column(type = "VARCHAR(15)", field = "telephone")
private String telephone; //電話
建立一個測試包和測試類:
package test;
import bean.User;
import util.TableUtils;
public class TestMain {
public static void main(String[] args) {
String sql = TableUtils.getCreateTableSQl(User.class);
System.out.println(sql);
}
}
執行
OK,拿到sql語句了。
我已經安裝了mysql,用root使用者登陸後,新建一個database
使用這個database將剛才得到的sql語句複製進去,加分號,回車。
這就表明資料庫表已經建好了,預設編碼是UTF-8。
本文結束。
原碼下載地址 http://download.csdn.NET/download/jg15617651654/9828338