c罩到底多大(C罩有多大?)
2024-05-07
更新時(shí)間:2024-05-08 00:04:33作者:未知
Java Web是指用Java語言來解決相關(guān)Web領(lǐng)域的技術(shù)總和,一個(gè)Web應(yīng)用程序包括Web客戶端和Web服務(wù)器兩個(gè)部分,即基于B/S(瀏覽器/服務(wù)器)架構(gòu)的應(yīng)用程序。
Web客戶端通常是指用戶機(jī)上的瀏覽器,如微軟的IE瀏覽器或火狐瀏覽器等??蛻舳瞬恍枰_發(fā)任何用戶界面,而統(tǒng)一采用瀏覽器即可。
Web服務(wù)器是一臺(tái)或多臺(tái)可運(yùn)行Web應(yīng)用程序的計(jì)算機(jī),通常我們?cè)跒g覽器中輸入的網(wǎng)站地址,即Web服務(wù)器的地址。當(dāng)用戶在瀏覽器的地址欄中輸入網(wǎng)站地址并按回車鍵后,請(qǐng)求即被發(fā)送到 Web服務(wù)器。服務(wù)器接收到請(qǐng)求后,會(huì)返回給用戶帶有請(qǐng)求資源的響應(yīng)消息。Java在服務(wù)器端的應(yīng)用非常豐富,如Servlet、JSP和第三方框架等。
早期的Web應(yīng)用主要是靜態(tài)頁面的瀏覽,即靜態(tài)網(wǎng)站。 這些網(wǎng)站使用HTML語言來編寫,放在Web服務(wù)器上。 用戶使用瀏覽器通過HTTP協(xié)議請(qǐng)求服務(wù)器上的Web頁面,Web服務(wù)器處理接收到的用戶請(qǐng)求后發(fā)送給客戶端瀏覽器顯示給用戶。工作原理如圖:
用戶所訪問的資源已不局限于服務(wù)器中保存的靜態(tài)網(wǎng)頁。更多的內(nèi)容需要根據(jù)用戶的請(qǐng)求動(dòng)態(tài)生成頁面信息,即動(dòng)態(tài)網(wǎng)站。 這些網(wǎng)站通常使用HTML語言和動(dòng)態(tài)腳本語言(如JSP、ASP或PHP等)編寫,并將編寫后的程序部署到Web服務(wù)器中。 由Web服務(wù)器處理動(dòng)態(tài)腳本代碼并將其轉(zhuǎn)換為瀏覽器可以解析的HTML代碼,最后返回客戶端瀏覽器顯示給用戶,其工作流程如圖:
客戶端則需要安裝專用的客戶端軟件。如圖所示:
在B/S結(jié)構(gòu)中客戶端不需要開發(fā)任何用戶界面,而統(tǒng)一采用IE或火狐等瀏覽器。通過Web瀏覽器向Web服務(wù)器發(fā)送請(qǐng)求,由Web服務(wù)器處理并將處理結(jié)果逐級(jí)傳回客戶端,如圖所示。
內(nèi)置對(duì)象
1.Request對(duì)象Request對(duì)象是javax.servlet.http.HttpServletRequest類的實(shí)例。代表請(qǐng)求對(duì)象,主要用于接受客戶端通過HTTP協(xié)議連接傳輸?shù)椒?wù)器端的數(shù)據(jù)。比如表單中的數(shù)據(jù)、網(wǎng)頁地址后帶的參數(shù)等。2.Response對(duì)象Response對(duì)象是javax.servlet.http.HttpServletResponse類的實(shí)例。代表響應(yīng)對(duì)象,主要用于向客戶端發(fā)送數(shù)據(jù)。3.Out對(duì)象Out對(duì)象是javax.servlet.jsp.JspWriter類的實(shí)例。主要用于向客戶端瀏覽器輸出數(shù)據(jù)。4.session對(duì)象Session 對(duì)象是javax.servlet.http.HttpSession類的實(shí)例。主要用來保持在服務(wù)器與一個(gè)客戶端之間需要保留的數(shù)據(jù),比如在會(huì)話期間保持用戶的登錄信息等,會(huì)話狀態(tài)維持是Web應(yīng)用開發(fā)者必須面對(duì)的問題。當(dāng)客戶端關(guān)閉網(wǎng)站的所有網(wǎng)頁或關(guān)閉瀏覽器時(shí),session對(duì)象中保存的數(shù)據(jù)會(huì)自動(dòng)清除。由于Htp協(xié)議是一個(gè)無狀態(tài)協(xié)議,不保留會(huì)話間的數(shù)據(jù),因此通過session對(duì)象擴(kuò)展了htp的功能。比如用戶登錄一個(gè)網(wǎng)站之后,登錄信息會(huì)暫時(shí)保存在session對(duì)象中,打開不同的頁面時(shí),登錄信息是可以共享的,一旦用戶關(guān)閉瀏覽器或退出登錄,就會(huì)清除session對(duì)象中保存的登錄信息。5.Application對(duì)象Application對(duì)象是javax.servlet.ServletContext類的實(shí)例。主要用于保存用戶信息,代碼片段的運(yùn)行環(huán)境;它是一個(gè)共享的內(nèi)置對(duì)象,即一個(gè)容器中的多個(gè)用戶共享一個(gè)application對(duì)象,故其保存的信息被所有用戶所共享。6.PageContext對(duì)象PageContext對(duì)象是javax.servlet.jsp.PageContext類的實(shí)例。用來管理網(wǎng)頁屬性,為JSP頁面包裝頁面的上下文,管理對(duì)屬于JSP中特殊可見部分中已命名對(duì)象的訪問,它的創(chuàng)建和初始化都是由JSP容器來完成的。7.Config對(duì)象Config對(duì)象是javax.servlet.ServletConfig類的實(shí)例。是代碼片段配置對(duì)象,表示Servlet的配置。8.Page(相當(dāng)于this)對(duì)象Page對(duì)象是javax.servlet.jsp.HttpJspPage類的實(shí)例。用來處理JSP網(wǎng)頁,它指的是JSP頁面對(duì)象本身,或者說代表編譯后的servlet對(duì)象,只有在JSP頁面范圍之內(nèi)才是合法的。9.Exception對(duì)象Exception對(duì)象是java.lang.Throwable類的實(shí)例。處理JSP文件執(zhí)行時(shí)發(fā)生的錯(cuò)誤和異常只有在JSP頁面的page指令中指定isErrorPage=“true”后,才可以在本頁面使用exception對(duì)象。復(fù)制代碼
在JSP網(wǎng)頁開發(fā)的初級(jí)階段并沒有框架與邏輯分層概念,需要將Java代碼嵌入到網(wǎng)頁中處理JSP頁面中的一些業(yè)務(wù)邏輯,如字符串處理和數(shù)據(jù)庫操作等,其開發(fā)流程如圖所示。
如果使HTML與Java代碼相分離,將Java代碼單獨(dú)封裝成為一個(gè)處理某種業(yè)務(wù)邏輯的類。然后在JSP頁面中調(diào)用此類,則可以降低HTML與Java代碼之間的耦合度,并且簡化JSP頁面,提高Java程序代碼的重用性及靈活性。這種與HTML代碼相分離,而使用Java代碼封裝的類就是一個(gè)JavaBean組件。 在Java Web開發(fā)可以使用該組件來完成業(yè)務(wù)邏輯的處理,應(yīng)用JavaBean與JSP組合的開發(fā)模式如圖所示。
JavaBean是用Java語言所寫成的可重用組件,其應(yīng)用十分廣泛,可以應(yīng)用于系統(tǒng)的很多層中,如PO、VO、DTO和POJO等。
用戶通過單擊某個(gè)鏈接或者直接在瀏覽器的地址欄中輸入U(xiǎn)RL來訪問Servlet,Web服務(wù)器接收到請(qǐng)求后,并不是將請(qǐng)求直接交給Servlet容器。Servlet容器實(shí)例化Servlet,調(diào)用Servlet的一個(gè)特定方法( service() ),并產(chǎn)生一個(gè)響應(yīng)。這個(gè)響應(yīng)由Servlet容器返回給Web服務(wù)器,Web服務(wù)器包裝這個(gè)響應(yīng),以HTTP響應(yīng)的形式發(fā)送給Web瀏覽器。整個(gè)過程如圖:
Cookie的作用:通俗地說就是當(dāng)一個(gè)用戶通過HTTP協(xié)議訪問一個(gè)服務(wù)器的時(shí)候,這個(gè)服務(wù)器會(huì)將一些Key/Value鍵值對(duì)返回給客戶端瀏覽器,并給這些數(shù)據(jù)加上一些限制條件,在條件符合時(shí)這個(gè)用戶下次訪問這個(gè)服務(wù)器的時(shí)候,數(shù)據(jù)又被完整地帶回給服務(wù)器。 這個(gè)作用就像你去超市購物時(shí),第一次給你辦張購物卡,這個(gè)購物卡里存放了一些你的個(gè)人信息,下次你再來這個(gè)連鎖超市時(shí),超市會(huì)識(shí)別你的購物卡,下次直接購物就好了。當(dāng)初W3C在設(shè)計(jì)Cookie時(shí)實(shí)際上考慮的是為了記錄用戶在一段時(shí)間內(nèi)訪問Web應(yīng)用的行為路徑。由于HTTP協(xié)議是一種無狀態(tài)協(xié)議,當(dāng)用戶的一次訪問請(qǐng)求結(jié)束后,后端服務(wù)器就無法知道下一次來訪問的還是不是上次訪問的用戶,在設(shè)計(jì)應(yīng)用程序時(shí),我們很容易想到兩次訪問是同一人訪問與不同的兩個(gè)人訪問對(duì)程序設(shè)計(jì)和性能來說有網(wǎng)很大的不同。例如,在一個(gè)很短的時(shí)間內(nèi),如果與用戶相關(guān)的數(shù)據(jù)被頻繁訪問,可以針對(duì)這個(gè)數(shù)據(jù)做緩存,這樣可以大大提高數(shù)據(jù)的訪問性能。Cookie的作用正是在此,由于是同一個(gè)客戶端發(fā)出的請(qǐng)求,每次發(fā)出的請(qǐng)求都會(huì)帶有第一次訪問時(shí)服務(wù)端設(shè)置的信息,這樣服務(wù)端就可以根據(jù)Cookie值來劃分訪問的用戶了。
@WebServlet("/CookieTest")public class CookieTest extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");Cookie[] cookies = request.getCookies();PrintWriter out = response.getWriter();if(cookies!=null){out.println("上次訪問的時(shí)間是:");for (Cookie cookie : cookies) {if("lastTime".equals(cookie.getName())){long lastTime = Long.parseLong(cookie.getValue());Date date = new Date(lastTime);out.println(date.toLocaleString());}}}else{out.println("你是第一來");}Cookie cookie = new Cookie("lastTime", String.valueOf(System.currentTimeMillis()));//給cookie設(shè)置一些信息//cookie.setMaxAge(500); //有效期//cookie.setPath(uri);//服務(wù)器端給客戶端一個(gè)Cookieresponse.addCookie(cookie);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}復(fù)制代碼
解碼與編碼(與Cookie無關(guān),只是解決亂碼的一種方式)
//傳中文,避免亂碼??梢赃M(jìn)行編碼Cookie cookie = new Cookie("lastTime",URLEncoder.encode("尚", "utf-8"));//取出Cookie值,需要解碼URLDecoder.decode(cookie.getValue(),"utf-8");復(fù)制代碼
為什么需要Session?前面已經(jīng)介紹了Cookie可以讓服務(wù)端程序跟蹤每個(gè)客戶端的訪問,但是每次客戶端的訪問都必須傳回這些Cookie,如果Cookie很多,這無形地增加了客戶端與服務(wù)端的數(shù)據(jù)傳輸量,而Session的出現(xiàn)正是為了解決這個(gè)問題。 同一個(gè)客戶端每次和服務(wù)端交互時(shí),不需要每次都傳回所有的Cookie值,而是只要傳回一個(gè)ID,這個(gè)ID是客戶端第一次訪問服務(wù)器的時(shí)候生成的,而且每個(gè)客戶端是唯一的。這樣每個(gè)客戶端就有了一個(gè)唯一的ID,客戶端只要傳回這個(gè)ID就行了,這個(gè)ID通常是NANE為JSESIONID的一個(gè)Cookie。
一個(gè)瀏覽器去服務(wù)器租房子,服務(wù)器記錄一下瀏覽器的行為和數(shù)據(jù),然后給了瀏覽器一把房間的鑰匙 然后,每次瀏覽器可以使用自己的鑰匙去打開自己的房間,使用房間的所有東西。(當(dāng)然,你不能去開別人的房間,何況也打不開)
瀏覽器想鍛煉身體,愉悅心情。服務(wù)器心想我不能給你們網(wǎng)每一個(gè)人的房間增加一套體育設(shè)備吧,那我的經(jīng)濟(jì)壓力多大。服務(wù)器想了想,決定建設(shè)一個(gè)公開場所,體育館,所有瀏覽器都可以使用這些共享資源。
@WebServlet("/SessionTest1")public class SessionTest extends HttpServlet {private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");PrintWriter out = response.getWriter();out.write("Session的ID為:");// 獲取 Session HttpSession session = request.getSession();out.write(session.getId());session.setAttribute("name", "shang");//設(shè)置當(dāng)前會(huì)話多久結(jié)束,單位秒。如果設(shè)置的值為零或負(fù)數(shù),則表示會(huì)話將永遠(yuǎn)不會(huì)超時(shí)。常用于設(shè)置當(dāng)前會(huì)話時(shí)間。//session.setMaxInactiveInterval(1);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}復(fù)制代碼
@WebServlet("/SessionTest2")public class SessionTest2 extends HttpServlet {private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");HttpSession session = request.getSession();//移除session的數(shù)據(jù)session.removeAttribute("name");//手動(dòng)注銷當(dāng)前會(huì)話session.invalidate();}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}復(fù)制代碼
運(yùn)行在Java虛擬機(jī)中的每一個(gè)Web應(yīng)用程序都有一個(gè)與之相關(guān)的Servlet上下文。Java Servlet API提供了一個(gè)ServletContext接口用來表示上下文。在這個(gè)接口中定義了一組方法,Servlet可以使用這些方法與它的Servlet容器進(jìn)行通信,例如,得到文件的MIME類型,轉(zhuǎn)發(fā)請(qǐng)求,或者向日志文件中寫入日志消息。 ServletContext對(duì)象是Web服務(wù)器中的一個(gè)已知路徑的根。 比如,Servlet上下文被定位于http://localhost:8080/ch02。以/ch02請(qǐng)求路徑(稱為上下文路徑)開始的所有請(qǐng)求被發(fā)送到與此ServletContext關(guān)聯(lián)的Web應(yīng)用程序。再比如,我們平常使用的http://localhost:8080/。以/請(qǐng)求路徑(稱為上下文路徑)開始的所有請(qǐng)求被發(fā)送到與此ServletContext關(guān)聯(lián)的Web應(yīng)用程序。
ServletContext: 這個(gè)是來自于servlet規(guī)范里的概念,它是servlet用來與容器間進(jìn)行交互的接口的組合,也就是說,這個(gè)接口定義了一系列的方法,servlet通過這些方法可以很方便地與自己所在的容器進(jìn)行一些交互。在一個(gè)應(yīng)用中(一個(gè)JVM),servlet容器可以有多個(gè),而所有的servlet容器共享一個(gè)ServletContext。
最初的JSP開發(fā)模式為Model 1模式:JSP JavaBean
慢慢演變成了Model 2模式:JSP Servlet JavaBean
模型2符合MVC架構(gòu)模式,MVC即模型-視圖-控制器(Model-View-Controller)。
模型代表應(yīng)用程序的數(shù)據(jù)以及用于訪問控制和修改這些數(shù)據(jù)的業(yè)務(wù)規(guī)則。當(dāng)模型發(fā)生改變時(shí),它會(huì)通知視圖,并為視圖提供查詢模型相關(guān)狀態(tài)的能力。同時(shí),它也為控制器提供訪問封裝在模型內(nèi)部的應(yīng)用程序功能的能力。視圖用來組織模型的內(nèi)容。它從模型那里獲得數(shù)據(jù)并指定這些數(shù)據(jù)如何表現(xiàn)。當(dāng)模型變化時(shí),視圖負(fù)責(zé)維護(hù)數(shù)據(jù)表現(xiàn)的一致性。視圖同時(shí)將用戶的請(qǐng)求通知控制器。控制器定義了應(yīng)用程序的行為。它負(fù)責(zé)對(duì)來自視圖的用戶請(qǐng)求進(jìn)行解釋,并把這網(wǎng)些請(qǐng)求映射成相應(yīng)的行為,這些行為由模型負(fù)責(zé)實(shí)現(xiàn)。在獨(dú)立運(yùn)行的GUI客戶端,用戶的請(qǐng)求可能是一些鼠標(biāo)單擊或是菜單選擇操作。在一個(gè)Web應(yīng)用程序中,它們的表現(xiàn)形式可能是一些來自客戶端的GET或POST的HTTP請(qǐng)求。模型所實(shí)現(xiàn)的行為包括處理業(yè)務(wù)和修改模型的狀態(tài)。根據(jù)用戶請(qǐng)求和模型行為的結(jié)果,控制器選擇一個(gè)視圖作為對(duì)用戶請(qǐng)求的響應(yīng)。如圖所示: