今天意外發現好久以前寫過的一篇網站開發學習筆記,感受還不錯,拿出來記錄一下。html
網站開發學習筆記:前端
與服務器交互的方法:java
在瀏覽器裏輸入URLjquery
原理:由瀏覽器發起一個HTTP GET請求web
在網頁裏提交表單ajax
由瀏覽器發起一個HTTP GET/POST請求apache
在JavaScript裏使用AJAX方法json
原理:使用jQuery.ajax()函數,令瀏覽器發起一個HTTP GET/POST請求api
用Java代碼完成完成HTTP請求瀏覽器
使用java的API,完成HTTP請求(可以使用apache http-component)
AJAX方法
Asynchronous JavaScript And XML
一種異步更新的方法:指的是在不刷新整個網頁的狀況,與服務器交互數據,對網頁的某個部分作局部更新。
(能夠實現交互式網頁界面)
實現方法:
使用jQuery提供的函數來實現AJAX交互
引入jQuery腳本
使用jQuert.ajax()函數
jQuery.ajax()
jQuery.ajax(settings)參數說明
參數settings對象是一個Object(能夠認爲是一個結構體),有如下屬性:
- method:」GET」或」post」
- url: 字符串
- success: 回調函數,AJAX交互成功
- error: 回調函數,AJAX交互失敗
AJAX:總體不變,局部更新
實例——與定時器相結合
目標效果:
上面實時顯示在線人數(jQuery Timer+AJAX)
限免播放視頻(HTML5<video>)
DOM元素的屬性:
五類功能:
class: 給元素添加/刪除class
<div class=」selected highlight」>ssss</div>
attr:元素的其餘屬性
Prop:目標對象的成員變量
Html:元素的innerHTML
元素的value(針對表單元素)
上傳數據:
例如,用戶在文本框裏輸入ISBN,Keyword,點檢索,查詢相關圖書
怎麼把用戶輸入的值經過AJAX傳到後臺呢?
jQuery.ajax({
method: "GET",
url:"servlet/HelloServlet1",
//要上傳的數據
data:{
"isbn":isbn,
"keyword":keyword,
},
success:function(data,textStatus,jqXHR)
{
$("#result").html(data);
},
error:function(jqXHR,textStatus,errorThrown){
$("$result").html("error:"+errorThrown);
}
});
AJAX-JSON數據格式
應用場景:
在頁面輸入一個ISBN點,點「檢索」 後臺檢所獲得一本書的詳細信息:
Title author isbn publisher
數據格式:
服務器以何種格式返回數據,是核心問題
例如,服務器能夠按以下格式返回
Title=xxxx&author=yyyy&isbn=zzzz&publisher=zzzz
這對服務器並不困難,直接用java代碼就能夠拼湊出來。可是,對於客戶端來講,解析這段文本卻很困難。
JSON數據格式:
JSON:JavaScript Object Notation
一種文本化表示的JavaScript Object
其格式爲:
{
「title」:」xxx」,
「author」:」yyy」,
「isbn」:」zzz」,
「publisher」:」www」
}
其實就是定義一個Object的JavaScript代碼樣式
JSON數據格式
replyText=
「{「
+」\」title\」:」+」\」」+title+」\」」+」,」
+」\」author\」:」+」\」」+author+」\」」+」,」
+」\」isbn\」:」+」\」」+isbn+」\」」+」,」
+」\」publisher\」:」+」\」」+publisher+」\」」
+」}」;
(注:之後將使用API來完成)
以JSON格式返回數據時,前端的解析將十分便捷
JSON格式:就是用JavaScript定義對象的代碼格式
JSON API:
顯然,手工拼寫一個JSON字符串比較麻煩,容易出錯,須要一個API來完成
JSON官網:http://www.json.org/
下載JAVA版本的解析器
下載獲得的是源代碼形式
咱們能夠直接使用源代碼,或者本身打包成jar包json-org.jar
注:能操做JSON的API不止一個,還有其餘庫也支持JSON
注:在Myeclipse界面下粘貼,會自動把jar配置到Build-Path下
使用JSON API
下面,使用org.json.*提供的API來改編上街可得代碼
JSONObject jsReply=new JSONObject();
jsReply.put(「title」,title);
jsReply.put(「author」,author);
jsReply.put(「isbn」,isbn);
jsReply.put(「publisher」,publisher);
String replyText=jsReply.toString();
在涉及頁面id有重名時,必定要很是注意!由於在寫JavaScript時獲取id時可能會蒙圈。
JSON構造:
JSON中,除了字符串值須要雙引號,其餘的Integer,Boolean,Double型都不須要雙引號
{
「id」:123,
「male」:true,
「name」:曾鴻發,
「avg」:98.5
}
注意:Object內部也能夠是Object
{
」title」:」學習指南」,
「audio」:
{
」sampleRate」:44100,
「channel」:2
}
「vedio」:
{
「height」:720,
「width」:1080
}
}
注意:JSONObject的屬性不分先後順序
JSON能夠把一個Map轉成JSONObject
Map values=new HashMap();
Values.put(「id」,123);
Values.put(「name」,」shaofa」);
JSONObject result=new JSONObject(values);
VM.C
已經有一個JSON格式的字符串,能夠轉成JSONObject或JSONArray
注意:
在解析的時候有可能拋異常
//若是str格式不規範,會拋出異常
//若相應字段不存在,會拋出異常
//若字段類型不匹配,會拋異常
上行數據的格式
假設如今下行數據已經肯定使用JSON格式
那麼,上行數據數據是否有其餘選擇呢?
默認的上行數據格式:
在使用GET/POST時,默認地,jQuery.ajax()會把數據轉成
K1=v1&k2=v2&……的格式
JSON格式的上行數據:
能夠令jQuery上傳一段JSON格式的數據,方法爲:
設processData屬性爲false
processData:false,
Data:」本身的字符串」,
設data爲一段JSON格式的字符串
怎麼把一個JavaScript對象轉成JSON字符串呢?
使用jquery.json.js.API
<script src=」jquery/jquery.js></script>
<script src=」jquery/jquery.json-2.3.js></script>
而後就能夠轉換了:
Var jsonText=jQuery.toJSON(jsReq);
服務器端代碼:因爲客戶端上傳的代碼是JSON格式因此不能再用getParameter()來獲取參數了,改爲:
InputStream streamIn=request.getInputStream();
String userText=readAsText(streamIn,」UTF-8」);
JSONObject jreq=new JSONObject(userText);
String reqId=jreq.getString(「id」);
String reqName=jreq.getString(「name」);
String reqPhone=jreq.getString(「phone」);
InputStream.read() 返回類型:int
Int read():
從輸入流中讀取數據的下一個字節。返回 0 到 255 範圍內的 int 字節值。若是由於已經到達流末尾而沒有可用的字節,則返回值 -1。在輸入數據可用、檢測到流末尾或者拋出異常前,此方法一直阻塞。
因此,能夠把數據以JSON格式上傳
注:當數據較爲複雜時,應使用這種方式
當要上傳的數據比較複雜時,先構造一個JavaScript對象,而後以JSON格式上傳
指定格式:dataType
告訴jQuery:服務器發來的是JSON文本,請自動轉成一個對象,
dataType:」json」,
Success:function(data,textStatus,jqXHR)
{
//var result=jQuery.parseJSON(data);
//data:已經轉成了Object
}
若是不指定dataType,則jQuery會根據Content-Type,自動判斷
若是是text/plain,data就是String
若是是text/json,data就自動地轉成了Object
Shorthand Methods:
jQuery.get()
jQuery.post()
jQuery.getJSON()
在app裏訪問服務器
Servlet所提供的服務,不只在瀏覽器裏能夠訪問,也能夠在其餘任意app裏經過HTTP訪問。
服務URL:
http://127.0.0.1/myweb/servlet/HelloServlet
在任意App裏,均可以經過HTTP來訪問這個服務。
APP:>>>HTTP請求>>>Tomcat
APP:<<<HTTP應答<<<Tomcat
Apache HttpComponents
Java的App項目裏,可使用apache.org下的一個庫來完成HTTP交互。
Apache HttpComponentsClient:
Apache下提供了不少開源庫/框架,稱爲Apache Project,在下面找到HttpComponents,其提供了Http的支持。
Apache HttpComponents:
它提供了兩個模塊,
HttpCore:HTTP服務器應用
HttpClient:HTTP客戶端應用
在java項目中添加HttpClient庫:
注意:
Java中異常Default constructor cannot handle exception type UnsupportedEncodingException thrown by impli:
默認的構造函數不能處理由父類構造函數拋出的異常類型:UnsupportedEncodingException。必須定義一個明確的構造函數。
這時候,你立刻要想到的是,你寫的代碼是否是有異常要處理或者要拋出,你是否是放在一個類中或者方法中忘記處理異常了。
這樣你的異常就好解決了。
注意:
在服務器端,建議使用Content-Length方式來發送應答(目的是方便客戶端的解析)
在客戶端,HttpEntity表示發送的數據內容,含Content-Type,Content-Length,charset和正文信息
EntityUtils不能接收chunked方式的數據
RESTful-RESTful API(基於JSON)
應用示例:
假設有一個網站,提供電影票訂單的功能
普通方式:
List_movie.jsp:瀏覽正在上映的電影列表
Book.jsp:預約電影票
也就是說,該網站以WEB形式提供服務,用戶必須用瀏覽器登陸該網站才能使用相關服務。
RESTful API:representational state transfer (REST)
能夠用另一種形式提供服務,用戶以API調用的方式來訪問這些服務。
實現方式:HTTP+JSON(或XML)
例如,安卓app通常都是使用這種接口與後臺交互
RESTful API示例:
以上述院線定義服務爲例,
提供至少兩個服務:
/api/ListMovie用於查詢電影的列表
(電影名稱、主演、票價、區域)
/api/Book 用於預約電影票
(用戶上傳客戶信息,用於快遞送票上門)
請求:GET
應答:
{
error:
Reason:
Data:[...電影信息]
請求:POST
{
Movieid:
Time:
Client:{用戶姓名、快遞地址、聯繫電話}
}
應答:
{
Error:
Reason:
Data:{...訂單信息...}
}
一個網站能夠用RESTful API的形式來提供服務,客戶端經過HTTP+JSON來調用這些服務
爲何須要日誌?
服務器通常都是終年累月運行的,須要把重要的時間記錄下來(時間、操做者、事件、其餘參數)
日誌能夠用於分析。
好比,某天發生了一個錯誤,則須要根據日誌來判斷是什麼事情致使了這個錯誤。
日誌級別:
Trace,
Debug,
Info,
Warn,
Error,
Fatal,
其中,fatal最嚴重,trace最輕微
(設置級別是爲了過濾和分類)
日誌的過濾:閥值Threshold
在log4j.properties裏能夠按級別過濾,讓低級別的不顯示
在調試的時候,通常設爲DBG,這樣全部>=DBG的日誌都會被記錄。
在正式上線被運行的時候,通常設爲INFO,通常只有>=INFO級別的日誌纔會被記錄。
記錄器Appender
Appender指定輸出目標,log4已經內置了幾個類,
Org.apache.log4.ConsoleAppender 控制檯
Org.apache.log4.FileAppender 文件
Org.apache.log4.DailyRollingFileAppender 天天一個日誌文件
Org.apache.log4.RollingFileAppender 文件過大時,產生一個備份文件(能夠指定備份的數量)
指定多個Appender:
Log4j.logger.my=DEBUG,C,R
其中,
DEBUG是總的日誌級別
C,第一個Appender的名字,是本身起的名字
R,第二個Appender的名字,隨便起
目標:客戶端選擇一個文件,點上傳,將文件傳給服務器上。
普通表單域:<input>數據較小(短的文本)
文件域:<file>文件數據較大,處理起來相對複雜
前端網頁:
<form enctype=」multipart/form-data」 action=」servlet/HelloServlet」>
選擇文件:<input type=」file」 name=」upfile」>
說明:<input type=」file」 name=descr」>
<input type=」submit」 value=」上傳」>
</form>
後臺處理:使用apache commons fileupload
下載庫,放到WEB-INF\libs
在doPost()中,調用ServletFileUpload
java.io.FileNotFoundException: .\xx\xx (拒絕訪問。) at java.io.FileOutputStream.open(Native Method) at java.io.FileOutputStream.<init>(Unknown Source) at java.io.FileOutputStream.<init>(Unknown Source) at com.yaohong.test.InputStreamTest.fileInputStream(InputStreamTest.java:13) at com.yaohong.test.InputStreamTest.main(InputStreamTest.java:27)
當遇到這種錯誤時,先要分析緣由,遇到這種情況,是由於你訪問的是一個文件目錄,若是這個目錄沒有權限或者目錄不存在,就會拋出問題。
好比,我在作項目的時候,先新創文件到c盤目錄下,結果有問題,改爲f盤後就沒問題了。因此在此以前應當看一下該目錄的訪問權限。
對C盤讀寫訪問權限進行修改後,發現仍是行不通,具體緣由也不知道爲何,之後再來弄懂吧
文件上傳進度的顯示(HTML5)
在上節課中,點上傳以後,由瀏覽器負責上傳文件,直到完成。完成後顯示副武器的應答
缺點:
要打開一個新界面
不能實時顯示進度
文件顯示進度一直是一個頭疼的問題,不能很好地解決。。。除非瀏覽器給咱們提供API,獲取文件的顯示進度
HTML對文件上傳的支持
支持獲取文件對象的屬性(Name,Size...)
支持事件回調
Progress:上傳進度
Load:上傳完成
Error:出錯
Abort:取消
實現:
服務器端處理不變,使用apache commons fileupload
客戶端使用XMLHttpRequest
前端:獲取文件的屬性
當選中文件後,能夠獲知文件的屬性
Var file=document.getElementById(「fileToUpload」).file[0];
$(「#fileName」).html(「Name:」+file.name);
$(「#fileSize」).html(「Size:」+file.size);
應用背景:在網站有一個admin目錄,下面的網頁和資源只容許「admin」帳戶訪問(超級管理員)。
這意味着,若是當前沒有用戶登陸,或者用戶名不是「admin」,都不容許訪問admin/下的任何資源。
例如,當用戶在瀏覽器裏輸入
http://127.0.0.1:8080/myweb/admin/aaa.jpg時,應提示其無權訪問!
Filter過濾器:
過濾器:當Tomcat收到WEB請求時,首先調用過濾器來處理,過濾器能夠攔截請求。
例如,
設置了三個過濾器
[filter 1]
[filter 2]
[filter 3]
一個請求到來時,首先交給filter1過濾,若是filter1沒有攔截該請求,則交給下一個filter2過濾。。。
添加一個Filter
建立一個類,
Public class AsSampleFilter implements filter
在web.xml中配置
<filter>
<filter-name>AsSampleFilter</filter-name>
<filter-class>my.AsSampleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AsSampleFilter</filter-name>
<url-mapping>/admin/*</url-mapping>
</filter-mapping>
即:當請求的URL爲/admin/*格式時,將交給AsSampleFilter處理
Filter攔截請求
在Filter裏,能夠決定是否攔截請求:
代碼框架爲:
Void doFilter(request,response,chain)
{
If(須要攔截)
{
...處理該請求..
}
Else
{
chain.doFilter(request,response); //不感興趣
}
}
應用1:
檢查用戶是否爲「admin」,
若是不是,則跳轉到登陸頁
Response.sendRidirect(...);
應用2:只有某固定網段的IP才容許訪問/admin/*
Filter的更多細節:
Filter的生命期
Filter在APP啓動時一併建立,直到APP被卸載時才被刪除
也就是說,在app運行期間,filter的實例是一直存在的。
Init():初始化
Destroy():退出時執行
filter的配置參數:
Filter能夠設置一些配置參數:
<filter>
<filter-name>AfSampleFilter<filter-name>
<filter-class>my.AfSampleFilter<filter-class>
` <!-- filter的配置參數 -->
<init-param>
<param-name>id</param-name>
<param-value>201501</param-value>
</init-param>
<init-param>
<param-name>loaction</param-name>
<param-value>aaa</param-value>
</init-param>
</filter>
多項url-pattern:
同一個filter能夠設置多個url-pattern
<filter-mapping>
<filter-name>AfSampleFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AfSampleFilter</filter-name>
<url-pattern>*.jsp</url-pattern</url-pattern>
</filter-mapping>
則凡是*.html和*.jsp都會被交給AfSampleFilter過濾
FilterChain多個Filter串連
在web.xml中,能夠添加多個Filter,它們組成的一串叫作FilterChain
[filter 1]
[filter 2]
[filter 3]
[filter ...]
web請求時會依次交給它們過濾
注:多個filter會按web.xml的出現的順序排列
自定義應用框架:
其實,Servlet機制就是一個應用框架。它是Tomcat自帶的應用框架。
使用Filter+Reflection技術,能夠添加一套自定義的應用框架。(如:比較著名的struts框架)
應用實例:
在服務器添加RESTful API的通常流程爲:
添加xxxServlet類
在web.xml裏添加該servlet的配置
在doPost()
讀取URL裏的參數
讀取上傳上來的HTTP請求正文reqText
---------------處理請求---------------
返回reqText給客戶端
能夠把這個標準改形成一個應用框架,以提升開發效率
Dom4j是用來解析xml文件的。
添加 setters 框架直接把 URL 中附帶的參數經過 setters 設置到成員變量中。例如,請求爲: /hello.api?id=201601&name=shaofa 則框架會經過 setId 和 setName 來設置成員變量的值。
使用框架的好處:
精簡代碼
把業務處理與框架流程獨立開來,寫api的人能夠沒必要懂servlet
總結:該框架設計過程當中,所應用到的最主要的反射機制在於當輸入網頁地址時附加的參數可以上傳到對應的服務器進行解析,主要是設置了對應的setter,我想主要是由於對解析參數值的過程利用了Class函數
文件的下載和上傳:
WEB-INF 和 META-INF 下的文件不支持下載
Web Application 目錄以外的文件不支持下載
前端權限檢查:
前端權限檢查:藉助於瀏覽器緩存,在前端自行完成檢查。
在登陸返回時,將當前用戶的信息存在緩存裏。
sessionStorage.setItem("key",value)
在點發帖時,從緩存裏檢查當前用戶的信息。
value=sessionStorage.getItem("key")
sessionStorage是瀏覽器對象,能夠用JavaScript來訪問它,前端頁面能夠把數據存儲到這裏。
注意:
當瀏覽器關閉時,sessionStorage的內容被清空。
只能存儲字符串,若是想存儲一個對象,須要轉成字符串。
sessionStorage.setItem("key",JSON.stringify(obj));
var obj=JSON.parse(sessionStorage.getItem("key");
用戶以手機號進行註冊:
手機短信驗證:
用戶在以手機號進行用戶註冊時,須要填寫驗證碼
綁定手機號
點「發送驗證碼」...後臺系統將發送一個驗證碼到這個手機號,同時把驗證碼放到session中。
用戶在手機上查看短信驗證碼,填寫到頁面
用戶點擊「註冊」,後臺檢查驗證碼是否正確
多重過濾:
FilterChain,過濾器
指一個請求可能被多個過濾器屢次過濾
chain.doFilter(request,response)
告訴Tomcat讓後面的Filter繼續處理這個請求。
Filter Chain裏的順序:
當有多個Filter時,按出現的前後順序依次執行:
web.xml方式:按出現的順序排列
註解方式:按類名的順序排序