1. 程式人生 > >一 Javaweb 專案中常見的思想、思路從哪去、原則 反思回顧:

一 Javaweb 專案中常見的思想、思路從哪去、原則 反思回顧:

1 分層;

2 封裝;

3 發現問題本質,方法解決轉化

4 字串的拼接

5 一張表一個dao類一個servlet

6 根據隱含引數判斷資料來源

7 資料放在哪,從哪取

8 命名統一 規範問題

 針對上述介紹中,部分一般性規律:

1 分層;常見為src

com.example.dao        //資料訪問層

com.example.daoimpl

com.example.entity(或者com.example.bean)  //實體層 域模型層

com.example.service        //業務邏輯層

com.example.service.impl

com.example.util     //工具類層

com.example.web.cotroller   //表現層

com.example.web.filter

com.example.web.formbean

com.example.web.listener

com.example.web.ui

com.example.util.test    //工具測試類層

webRoot

   js  css  jsp  html  imgs  等等,要注意分門別類存放

2 封裝  面向物件的思維方式,共同的部分要抽取出來

建立一個新的Javaweb 專案

利用eclipse  hbuilder  等建立一個Java web 專案,其中需要注意的地方

1、專案中,在建立src裡的包層時,需要注意包層的名稱需要用小寫字母

2、包層的命名是 com為二級域名 example為三級域名,這個一般是公司域名倒寫+名稱

3、導包 導庫 將用到的的第三方包 、庫匯入相應的資料夾  

比如需要將資料庫驅動程式jar包匯入 web-inf 下的lib資料夾中

4、注意各處的字元編碼是否統一,建議為utf-8

5、需要在清單檔案中配置的專案要記得配置

四  常見的問題及分析:

1 資料庫的連線(此處以MyEclipse 連線本地Oracle資料庫 為例):

1)如何在MyEclipse 中連線Oracle資料庫?

準備階段:首先要在本地計算機上正確安裝

Oracle 資料庫軟體,資料庫管理客戶端管理軟體

擴充套件:具體的安裝過程中可能出現一些問題比如:

  1 為何資料庫提示無法安裝?

如果你的電腦之前安裝過Oracle 資料庫,在清理過程中未徹底清理乾淨會出現此問題,這裡需要特別注意的是,Oracle 資料庫特別霸道 變態,只要電腦中目前無論任何的資料夾、登錄檔等各種地方有一個與Oracle資料庫相關的檔案,都意味著未清理乾淨,具體我百度到了一個地址,介紹還算不錯可以根據上面提示保證完全清理乾淨

https://wenku.baidu.com/view/df5196f3ba0d4a7302763ac7.html

http://blog.csdn.net/oceanaut/article/details/3863222

2 開啟資料庫需要的服務

連線資料庫之前,一定要確保Oracle資料庫的相關服務開啟,否則無法使用,因為Oracle資料庫沒有介面顯示,來證明是否開啟,所以要檢查oracle資料庫最基本的服務是否開啟

2 在使用Oracle資料庫管理軟體時,要Oracle資料庫的賬號 密碼,怎麼填?是多少?

這個在你安裝Oracle資料庫時需要填寫的,所以在安裝Oracle資料庫時,要特別注意讓你填寫的東西  賬號和密碼一定要記住,這裡要填的賬號 密碼就是當時填寫的

軟體連線部分: 開啟eclipse———>點選上方的window選項——>open perspective-->MyEclipse Database Explore在左側單擊右鍵,出現一個連線資料庫的資訊列表單,driverManager templates: 資料庫驅動程式的型別,這個會有MySQL sqlserver oracle 等各版本選項

driver name:這個隨便填寫,作為資料庫的名稱

Connection URl: 連線資料庫的地址  jdbc:axiondb:<database-name>[:<database-directory>] 大致都類似於這個,尖括號為必填項,方括號可不寫

user name;使用者名稱  這個就是你使用資料庫的賬號

password:密碼 也好理解

driver jars: 這個就是你使用的資料庫驅動程式的jar包的路徑,可以通過檔案選擇功能找到,(並且這個jar包是需要複製貼上到web專案中——>web Root ——>WEB-INF——>lib資料夾內)driver className:這個在你完成上一步之後會自動生成

到此就填寫可以了,直接下一步或者完成就可。左邊會產生一個伺服器樣式的資料夾,雙擊,正常會在該圖示下產生檔案,不報錯,應該就是連線成功了

3 當然每個專案中需要有一個dao方法,連線資料庫,具體的Java程式碼寫法,後面介紹

(2)在專案的dao層中,要寫一個與資料庫進行連線的具體方法BaseDao的單獨的類或者一個方法具體程式碼參考如下。(為了在本文件書寫自動有提示,讓類的內容顯示有層次感,於是寫在script中,因為script中接

 Java程式碼)

<script type="text/javascript">

public class BaseDao{  //定義基本的BaseDao

//定義連線資料庫用到的基本引數 包括驅動程式名,驅動程式的url 資料庫使用者名稱、密碼

String driver="";

String url="";

String username="";

String password="";

//建立連線資料用到的基本類物件 包括連線物件Connection  conn sql語句預編譯物件PreparedStatement pst  呼叫資料庫返回結果集 ResultSet sql語句

Connection conn=null;

PreparedStatement pst=null;

Resultset res=null;

String sql=null;

try{

//Java虛擬機器中載入資料庫連線驅動程式  簡稱 載入驅動

Class.forName(driver);

//呼叫驅動程式管理器連線資料庫的方法連線資料庫   亦稱 獲取連線

conn=DriverManager.getConnection(url,username,password);

}catch(Exception e){

e.printStactrace();

}

//關閉資料庫連線資源的方法

public int closeAll(Connection conn,PreparedStatement pst,ResultSet res){

//如果不為空,表示處於連線狀態,所以關閉資源

if (res!=null) {

try {

res.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if (pst!=null) {

try {

pst.close();

} catch (SQLException e) {

e.printStackTrace();

return 0;

}

}

if (conn!=null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

return 0;

}

}

return 1; //告訴呼叫者是否關閉資源成功

}

public int executeUpdate(String sql,Object...params){

//預編譯語句的通用方法,

int result=0;

conn=getConnection();  //獲取資料庫連線

try {

pst=conn.prepareStatement(sql);  // sql語句進行預編譯操作

for (int i = 0; i < params.length; i++) {  

//動態將sql語句的片段集合化為一句

pst.setObject(i+1, params[i]);

}

pst.executeUpdate();  //執行sql語句

} catch (SQLException e) {

e.printStackTrace();

}finally{

this.closeAll(conn, pst, res);

}

return result;

}

}

</script>

2 對於專案的分析

1

3 資料庫中表的設計

資料庫一般的三正規化是要遵循的。

欄位的取值範圍的考慮

4 在資料庫中建立表的方法

因為不同的資料庫,一些細節方面略有不同,但是都有一些共通的地方

1)利用資料庫管理軟體工具直接按照分析好的表結構,進行建表

對於主鍵等的設定,一般命名格式為

主鍵名為  pk_表名_欄位名,

外來鍵名為  fk_參考的表名_欄位名

2)利用sql語句在Java程式碼中進行建立

5 如何在Oracle 資料庫中設定欄位自增(比如主鍵id int 型別 自增為例)

oracle 資料庫中,沒有直接設定欄位自增的控制元件,如果涉及,需要利用序列的形式進行

設定,具體方法以pl/sql 軟體為例,假如需要設定以student 表中主鍵idint)自增為例

在左側sequences ——>右鍵單擊——>new 建立一張序列表,序列表表名的命名格式為

seq_原表表名_自增欄位名    seq_student_id  

而在dao層新增資料的方法中,id列則不需要從外界獲取值,新增方法的sql語句格式為

sql="insert into 表名(主鍵id,欄位名2..,欄位名n) value(序列表表名.nextval,?,?,...?)";

例如:

sql="insert into student(id,name,age,..,address) value(seq_student_id.nextVal,?,?,...,?)"

在建立序列表時,注意內容的填寫,以原表中新建,還未新增資料,且以int型別自增為例,序列表的填寫

owner system  (表示資料庫使用者名稱)        next number 1 (因為原表中沒有資料,從1開始)

Name  seq_student_id  (此處為序列表表名) increatment by  1  (表示每次自動增加1)

min value  1  (表示id1 開始)           Cache size   20  (表示數字的位數)

max  value    (此處不填預設為某個最大數值)    

該處填寫完,即表示序列表已經建立完成,不需要其他操作

6 當軟體連線完資料庫後,一般會開始新建一個web專案,然後在其中開始寫實體類 資料庫基本的增刪改查的方法

實體類對應於資料庫中的實體 包括常見的set get方法。

完成訪問資料庫的方法,為了更顯層次,會建立介面dao  dao對應的實現類

實現類中有基本的增刪改查方法,如果可能,還可能需要建立根據條件進行查詢、模糊查詢等方法,這些應該在專案分析中考慮到。

7 建立使用者介面 html 或者jsp 檔案

webRoot 下面建立 資料夾 js  css  imgs 方便對各種資原始檔進行管理

新建立html 或者jsp 檔案時,注意更改字符集,

8 建立html(靜態網頁) jsp(動態網頁)中需要注意的問題:

(1) 注意網頁佈局和樣式、 程式碼的分層獨立

(2) 注意網頁中應該記得匯入與該網頁相關的css  js  jQuery 等相關的檔案

9 建立好網頁之後,即可開始書寫業務邏輯層,完成前後臺的邏輯對接

10 網頁佈局中 div css 浮動 定位 清除浮動之間有哪些規律?

11 書寫服務層的一般邏輯:

(1) 從網頁獲取暗含的請求引數、判斷邏輯需求,根據需求確定服務類別,因為一張表可能對應一個服務類,裡面有多個服務

(2) 獲取請求頁面的請求引數(這裡的請求引數和業務相關)reques.getParameter("");

(3) 呼叫相應的dao層的方法

(4) 根據dao方法返回的結果,進行業務處理

12 書寫服務層是最常見的字元編碼問題如何解決?

 (1) 利用過濾器,直接將所有相關的配置進行字元過濾處理

 (2) 將涉及到的所有可能出現亂碼等問題的地方進行字元設定處理

 常見的情景有:

a 服務類裡,第一件事,加入  request.setCharsetEncording("utf-8");

b 每項服務中,如果涉及將資料庫中的資料取出來,傳到網頁,則設定響應物件 response.setCharsetEncording("utf-8");

13 專案中,日期類的格式轉換問題,怎麼解決?

(一)如果bean 中實體類匯入的包是Java.util 包,則以學生類 student 為例:

1、實體類中的日期set get方法各自的書寫

2dao 中,新增add 方法中,關於日期的項 語句書寫

3servlet中,

1)完成新增含有日期的資料的功能時, 從網頁html 或者jsp 時,獲取請求引數

String time=request.getParameter("birthday_day");

//假設網頁上生日是通過input標籤 name="birthday_day"傳入

//因為網頁傳過來的都是字串,所以此句是一定的。

Student  student=new Student();

student.setBirthday(?);

StudentDao dao=new StudentDao();

dao.add(student);

  2)完成根據條件查詢資料,從資料庫中查詢到資料後的處理;

 StudentDao dao=new StudentDao();

 List<Student> list=dao.find();

//如果此處是將查詢到的list 作為結果返回到jsp介面

request.setAttribute("result",list);

request.getRequestDispatcher("index.jsp").forward(request,response);

4、網頁中

(二)如果bean 中實體類匯入的包是Java.sql 包,則以學生類 student 為例:

1、實體類中的日期set get 方法各自的書寫

2dao 中,新增add 方法中,關於日期的項 語句書寫

3servlet中,

1)完成新增含有日期的資料的功能時, 從網頁html 或者jsp 時,獲取請求引數

String time=request.getParameter("birthday_day");

//假設網頁上生日是通過input標籤 name="birthday_day"傳入

//因為網頁傳過來的都是字串,所以此句是一定的。

Student  student=new Student();

student.setBirthday(?);

StudentDao dao=new StudentDao();

dao.add(student);

2)完成根據條件查詢資料,從資料庫中查詢到資料後的處理;

 StudentDao dao=new StudentDao();

 List<Student> list=dao.find();

//如果此處是將查詢到的list 作為結果返回到jsp介面

request.setAttribute("result",list);

request.getRequestDispatcher("index.jsp").forward(request,response);

4、 網頁中

14 請求轉發與重定向有何區別?

請求轉發:伺服器行為,request.getRequsetDispatcher().forward(requset,response);是一次請求,轉發後請求物件會儲存,位址列的URL地址不會改變。(伺服器內部轉發,所有客戶端看不到位址列的改變)

重定向:客戶端行為,response.sendRedirect(),從本質上講等同於兩次請求,前一次的請求物件不會保持,位址列的URL地址會改變。

(1) 位址列中是否發生變化?

請求轉發地址不改變

(2) 哪個可以攜帶請求引數?

請求轉發可以攜帶

深入細解:

  HTTP中的重定向和請求轉發的區別

一、呼叫方式

我們知道,在servlet中呼叫轉發、重定向的語句如下:

request.getRequestDispatcher("new.jsp").forward(request, response);  

 //轉發到new.jsp

response.sendRedirect("new.jsp");   //重定向到new.jsp

jsp頁面中你也會看到通過下面的方式實現轉發:

<jsp:forward page="apage.jsp" />

當然也可以在jsp頁面中實現重定向:

<%response.sendRedirect("new.jsp"); %> //重定向到new.jsp

二、本質區別

解釋一   一句話,轉發是伺服器行為,重定向是客戶端行為。為什麼這樣說呢,這就要看兩個動作的工作流程:

轉發過程:客戶瀏覽器傳送http請求——》web伺服器接受此請求——》呼叫內部的一個方法在容器內部完成請求處理和轉發動作——》將目標資源傳送給客戶;在這裡,轉發的路徑必須是同一個web容器下的url,其不能轉向到其他的web路徑上去,中間傳遞的是自己的容器內的request。在客戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感覺不到伺服器做了轉發的。轉發行為是瀏覽器只做了一次訪問請求。

重定向過程:客戶瀏覽器傳送http請求——》web伺服器接受後傳送302狀態碼響應及對應新的location給客戶瀏覽器——》客戶瀏覽器發現是302響應,則自動再發送一個新的http請求,請求url是新的location地址——》伺服器根據此請求尋找資源併發送給客戶。在這裡location可以重定向到任意URL,既然是瀏覽器重新發出了請求,則就沒有什麼request傳遞的概念了。在客戶瀏覽器路徑欄顯示的是其重定向的路徑,客戶可以觀察到地址的變化的。重定向行為是瀏覽器做了至少兩次的訪問請求的。

解釋二

重定向,其實是兩次request 第一次,客戶端request   A,伺服器響應,並response回來,告訴瀏覽器,你應該去B。這個時候IE可以看到地址變了,而且歷史的回退按鈕也亮了。重定向可以訪問自己web應用以外的資源。在重定向的過程中,傳輸的資訊會被丟失。

例子:

response.sendRedirect("loginsuccess.jsp");

請求轉發是伺服器內部把對一個request/response的處理權,移交給另外一個對於客戶端而言,它只知道自己最早請求的那個A,而不知道中間的B,甚至CD。傳輸的資訊不會丟失。

例子:

   RequestDispatcher dis=request.getRequestDispatcher(loginsuccess.jsp);

 Dis.forward(request,response);

解釋三

假設你去辦理某個執照

重定向:你先去了A局,A局的人說:“這個事情不歸我們管,去B局”,然後,你就從A退了出來,自己乘車去了B局。

轉發:你先去了A局,A局看了以後,知道這個事情其實應該B局來管,但是他沒有把你退回來,而是讓你坐一會兒,自己到後面辦公室聯絡了B的人,讓他們辦好後,送了過來。

15 如何確定用請求轉發還是重定向?

瞭解上述詳細內容後,對於簡單的問題,一般可遵循這個原則:

(1)在服務中,對於一般的查詢性質的,用請求轉發,其他的多數時候用重定向(到本服務,執行本servlet中的某個服務)

(2)如果需要傳遞引數,除了使用者登入賬號、密碼等可以用cookie response.sendRedirect();request.getSession())進行設定,其他一般的用請求轉發;

(3) 不需要傳遞引數的,一般為重定向;

16 頁面轉換,如何準確使用絕對路徑和相對路徑?

"/" 表示根目錄,也就是專案中

"../" 表示到上一級目錄

jsp頁面中,為了防止因為絕對路徑因檔案移動等產生問題,一般都會使用相對路徑,而不是絕對路徑,基本上在所有的jsp的介面中都加入類似這種相對路徑的引用語句,當然如下,還可以進行適當的修改

第一句利用請求物件request 獲取當前路徑的getContextPath();

第二句 request.getScheme() 返回當前連結使用的協議;比如,一般應用返回http;SSL返回https;

複習一下request 的常用方法:

request.getSchema()可以返回當前頁面使用的協議,http 或是 https;

request.getServerName()可以返回當前頁面所在的伺服器的名字;

request.getServerPort()可以返回當前頁面所在的伺服器使用的埠,就是80;

request.getContextPath()可以返回當前頁面所在的應用的名字;

<%  

String path = request.getContextPath();

String basePath=request.getScheme()+"://"+request.getServerName()+":"+

                   request.getServerPort()+path+"/";

%>

而在<head></head>標籤內部通過以下方式引用

<base href="<%=basePath%>">

17 如何修改tomcat配置,解決中文亂碼問題?

在開發過程中,遇到中文亂碼的問題。以前的解決辦法是:用JAVA程式碼進行轉換,今天請教了一下公司的高手,給出的解決方案是:修改Tomcat的配置檔案也可以解決這個問題。

具體的解決方案是:

1.Tomcat目錄下找到server.xml檔案,找到程式碼:

<Connector port="80" protocol="HTTP/1.1"  connectionTimeout="20000"  redirectPort="8443" />

2. 把上面的程式碼註釋掉,用下面的程式碼代替:

<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>

3. 注意Tomcat的埠號,我的Tomcat的埠品號是 80,所以 port="80"。請你修改成你自己的Tomcat的埠號。

18 如何修改eclipse 或者myeclipse 中的字符集問題?

開啟windows——> preferences——>general——>workSpace

19 如何設定eclipse 或者myeclipse 中自動提示資訊功能?

開啟windows——> preferences——>Java——>editors

開啟windows——> preferences——>xml——>editors

20 單元測試:

  注意:測試用例是用來達到測試想要的預期結果,而不能測試出程式的邏輯錯誤。

   ①測試方法上必須使用@Test進行修飾

   ②測試方法必須使用public void 進行修飾,不能帶任何的引數

   ③新建一個原始碼目錄來存放我們的測試程式碼,即將測試程式碼和專案業務程式碼分開

   ④測試類所在的包名應該和被測試類所在的包名保持一致

   ⑤測試單元中的每個方法必須可以獨立測試,測試方法間不能有任何的依賴

   ⑥測試類使用Test作為類名的字尾(不是必須)

   ⑦測試方法使用test作為方法名的字首(不是必須)

        2.JUnit常用註解

        * @Test:將一個普通的方法修飾成為一個測試方法

              @Test(expected=XX.class)

              @Test(timeout=毫秒)

        * @BeforeClass:它會在所有的方法執行前被執行,static修飾

        * @AfterClass:它會在所有的方法執行結束後被執行,static修飾

        * @Before:會在每一個測試方法被執行前執行一次

        * @After:會在每一個測試方法執行後被執行一次

        * @Ignore:所修飾的測試方法會被測試執行器忽略

        * @RunWith:可以更改測試執行器 org.junit.runner.Runner

1.1 測試程式碼和專案程式碼分開

   結構應如下:包名要一致;最好以Test作為測試類字尾;最好以test作為測試方法字首。

    Java中,一般是建立一個與src同層次的資原始檔夾,命名為test 在其中建立和src中一樣的包名,並且建立和src中相應包下相同的類,只是鑑於習慣,會將這裡的類名命名為在原類名基礎上加個Test而已

     在測試類裡,假設測試src資料夾下,com.examlple.dao 包下 StudentDao 類中的public int addStudent student),方法,則需要寫的就是

      在專案中與src同層,建立一個test 資原始檔夾,其中建立一個com.example.dao 包,在包中建立一個StudentDaoTest類, 類中寫入

  @Test   //註解,必須寫

   public void testadd(){    //方法必須以public void 修飾,加方法名其中,不得帶任何引數

       Student stu=new Student();    //因為被測試的方法需要一個引數

       stu.setid="小明";

       StudentDao dao=new StudentDao();      

       int abc=dao.add(stu);     

       Assert.assertEquals(3,abc);     //呼叫該方法 斷言 第一個引數是預期值,第二個引數是實際測驗值

  }

21 sql語句防注入如何做?

22 sql 基本語句:

原則:

---先在主表新增資料,再在子表新增資料

---先刪除子表資料,再刪除主表資料

查詢語句:

-select<*|列名,...列名> from 表名 where 條件1 and 條件2......

例:

select t.*, t.rowid from student t

select *from student

select name,id from student

select name "姓名",id as 編號 from student

select * from student where id ='U003'--等值條件查詢

select * from student where name like '%'--模糊查詢,查詢孫開頭的

select * from student where name like '%%'

select * from student where name like '__'

select * from student where name like '__'and site like '222%'

select * from student where name like '__'or phone like '%888%'

select * from student where id='U002'or ID='u005'or id='U004'

select * from student where id in('U002','u005','U004')

新增語句:

nsert into 表名(欄位名1,欄位名2...,欄位名n) values(引數值1,引數值2,...引數值n);

insert into student (id,name,age,phone,gender,email,site,address) values ('U010','李四',22,'44444','','[email protected]','555.com','四海');

修改語句:

update 表名 set 欄位名1=引數值,欄位名2=引數值,..where 條件

update 表名 set 欄位名1=引數值,欄位名2=引數值,..where 欄位名i=引數值i

update  student set name='111',phone='110' where name like '__'

刪除語句:

delete from 表名 where 條件;

delete from score where student_id='U001';

23