JavaWeb

Web應用程序

WEB,在英語中web即表示網(wǎng)頁的意思,它用于表示Internet主機上供外界訪問的資源。Internet上供外界訪問的Web資源分為:

1.靜態(tài)web資源(如html 頁面):指web頁面中供人們?yōu)g覽的數(shù)據(jù)始終是不變。
靜態(tài)web資源開發(fā)技術(shù):HTML+CSS+Javascript

2.動態(tài)web資源:指web頁面中供人們?yōu)g覽的數(shù)據(jù)是由程序產(chǎn)生的,不同時間點 訪問web頁面看到的內(nèi)容各不相同
動態(tài)web資源開發(fā)技術(shù):JSP/Servlet

在Java中,動態(tài)web資源開發(fā)技術(shù)統(tǒng)稱為Javaweb。
學習web開發(fā),需要先安裝一臺web服務器,然后再在web服務器中開發(fā)相應的web資源,供用戶使用瀏覽器訪問。

WEB應用程序指供瀏覽器訪問的程序,通常也簡稱為web應用。一個web應用由多個靜態(tài)web資源和動態(tài)web資源組成。Web應用開發(fā)好后,若想供外界訪問,需要把web應用所在目錄交給web服務器管理。

Web服務器是指駐留于因特網(wǎng)上某種類型計算機的程序,是可以向發(fā)出請求的瀏覽器提供文檔的程序。


圖片1.png

BC/CS
CS:客戶機/服務器 結(jié)構(gòu) 網(wǎng)絡(luò)游戲客戶端,QQ等
BS:瀏覽器/服務器 結(jié)構(gòu) 百度,淘寶,新浪

Web應用:基于HTTP協(xié)議的應用程序
屬于 B/S架構(gòu)
瀏覽器客戶端:通過HTTP協(xié)議向服務器發(fā)出請求
服務器:通過HTTP協(xié)議向客戶端響應結(jié)果

HTTP協(xié)議:
是由W3C制定的一種網(wǎng)絡(luò)應用層協(xié)議,規(guī)定了瀏覽器和web服務器之間如何通信
以及通信的數(shù)據(jù)格式
特點:一次請求,一次連接
優(yōu)點:利用有限的連接,為近可能多的請求服務


http.png
Tomcat:開源的Java Web服務器

tomcat目錄結(jié)構(gòu)
bin:主要存放一些可執(zhí)行文件(比如啟動startup.bat以及關(guān)閉的shutdown.bat)
conf:配置文件;
lib:第三方依賴jar包;
logs:日志目錄;
temp:臨時文件目錄;
work:jsp經(jīng)過翻譯成Servlet再翻譯成.class的文件等;
webapps:真正的web應用可以部署的位置;

測試Tomcat服務器是否可以正常運行

配置環(huán)境變量
1.名稱:JAVA_HOME
變量值: jdk 的路徑(例:C:\Program Files (x86)\Java\jdk1.8.0_111)

2.名稱:CLASS_PATH
變量值:%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

3.系統(tǒng)環(huán)境變量中有一個path選中后選擇編輯
;%JAVA_HOME%\bin;

進入 tomcat 的 bin 目錄,然后雙擊 startup.bat 。

Web項目的創(chuàng)建以及配置Tomcat
c1.gif

填寫項目名稱 - version 2.5 -Next


c2.gif

目錄結(jié)構(gòu)


c3.gif
配置Tomcat

Window - Preferences - Server - Runtime - Add
選擇需要配置Tomcat的版本 Tomcat 8.0
點擊 Next - Browser
選擇相應版本的Tomcat所在本地路徑

測試是否配置成果

在WebContent下 創(chuàng)建index.html
將項目部署到Tomcat內(nèi)
啟動Tomcat服務器
通過瀏覽器訪問 localhost:8080/項目名/index.html

Web server只能訪問靜態(tài)資源,為了提高是服務的擴張性,使用Servlet

什么是Servlet:

Java Servlet是和平臺無關(guān)的服務器端組件,它運行在Servlet容器中。Servlet容器負責Servlet和客戶的通信以及調(diào)用Servlet的方法,Servlet和客戶的通信采用“請求/響應”的模式。

Servlet本質(zhì)就是一個運行在Servlet容器中的Java類,Servlet容器就是Tomcat

Servlet的作用
創(chuàng)建并返回基于客戶請求的動態(tài)HTML頁面。
與其它服務器資源(如數(shù)據(jù)庫或基于Java的應用程序)進行通信

創(chuàng)建Servlet : 繼承HttpServlet,實現(xiàn)doGet( ),doPost( )方法

通過提交表單 訪問Servlet

設(shè)計表單:文本框,按鈕
<form>屬性method 表示提交表單的方法
Get: - -doGet( )
采用路徑傳參,參數(shù)在傳遞過程中可見(地址欄)
隱私性差
傳參能力有限,只能傳少量參數(shù)
所有的請求默認都是GET請求

Post:- - doPost( )
采用實體內(nèi)容傳參,參數(shù)在傳遞過程中不可見
隱私性好
實體內(nèi)容專門用來傳參,大小不受限制
在form上加method="post"

瀏覽器發(fā)送請求后,如何找到Servlet

配置web.xml

2.0 web項目會自動創(chuàng)建該文件
<servlet>
<servlet-name>Servlet1</servlet-name>//指定servlet類的唯一標識
<servlet-class>test.Servlet1</servlet-class>//servlet的全類名(包名.類名)
</servlet>

<servlet-mapping>//設(shè)定servlet與客戶端的映射路徑
<servlet-name>Servlet1</servlet-name>//與<servlet>中保持一致
<url-pattern>/Servlet1</url-pattern>//用于設(shè)定請求路徑
</servlet-mapping>
3>關(guān)于Servlet路徑配置問題詳解
<url-pattern>
路徑匹配:
/AServlet --http://localhost:8080/項目名/AServlet
/ABC/AServlet --http://localhost:8080/項目名/ABC/AServlet
/ABC/ABC/AServlet http://localhost:8080/項目名/ABC/ABC/AServlet
/ABC/ABC/* --http://localhost:8080/項目名/ABC/ABC/任意
/* -- http://localhost:8080/項目名/任意
/ 相當于 /*

        后綴名匹配:
            *.do ==> struts
            *.action ==> struts2
            *.html ==> 

Servlet的生命周期

①服務器加載Servlet

②創(chuàng)建Servlet實例
--只有第一次請求Servlet時,創(chuàng)建Servlet實例,調(diào)用構(gòu)造器

③初始化init()
--只被調(diào)用一次,在創(chuàng)建好實例后立即被調(diào)用,用于初始化當前Servlet

④service()處理用戶請求
--可以被多次調(diào)用,每次請求都會調(diào)用service方法,實際用于響應請求的,根據(jù)用戶請求的類型(get或者post),調(diào)用doGet或者doPost方法。

⑤destory()銷毀
--只被調(diào)用一次,在當前Servlet所在的WEB應用被卸載前調(diào)用,用于釋放當前Servlet所占用的資源

//設(shè)置加載時機,默認訪問servlet時加載
//值為1時,啟動過程中便開始加載
//多個servlet之間值越小,越優(yōu)先
<load-on-startup></load-on-startup>

Servlet運行原理
s1.png

request對象

1.提取客戶端提交表單的信息
2.提取HTTP請求報頭的信息
3.在服務器段保存數(shù)據(jù),進行數(shù)據(jù)傳遞
4.處理Web資源跳轉(zhuǎn)

HttpServletRequest常用的方法:
String getParameter(String name)
--根據(jù)請求參數(shù)的名字,返回參數(shù)值,特別常用

產(chǎn)生亂碼的原因:瀏覽器的編碼格式和服務器的解碼格式不同
解決亂碼:只要確保編碼和解碼一致,就絕對沒有問題

Get
修改Tomcat配置文件,Server.xml第65行加 URIEncoding="UTF-8"
<Connector port="8080" protocol="HTTP/1.1"  URIEncoding="UTF-8"
        connectionTimeout="20000"   redirectPort="8443" />
    
POST
因為Post解碼是在第一次調(diào)用getParameter之前,那么解決亂碼只需要在調(diào)用該方法之前設(shè)置編碼:
            request.setCharacterEncoding("UTF-8");      

獲取HTTP請求頭信息

1.請求行
2.請求頭
3.請求空行
4.請求數(shù)據(jù)

    request.getMethod(): 請求方式
    request.getRequestURI(): /項目名/Servlet映射名
    request.getServletPath(): /Servlet映射名
    request.getContextPath(): /項目名
    request.getScheme(): http
封裝好的方法.
        request.getContentType(): null
        request.getLocale(): zh_CN
        request.getQueryString(): name=tom&age=18
        request.getRequestURL(): http://localhost:8080/Day08-request/AServlet
        request.getRemotePort(): 52074
        request.getServerName(): localhost
        request.getServerPort(): 8080
        request.getRemoteAddr() :客戶端IP

設(shè)計用戶注冊功能
1.獲取表單注冊信息
2.添加到數(shù)據(jù)庫

設(shè)置響應信息 response對象

1.設(shè)置響應信息的字符集
2.向客戶端響應信息
3.Web資源跳轉(zhuǎn)

response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");//設(shè)置響應內(nèi)容的類型
        PrintWriter pw=response.getWriter();//獲取輸出流 ,向瀏覽器響應信息
        String html="<!DOCTYPE html>"
                +"<html>"
                +"<meta charset='UTF-8'>"
                +"<title>Insert title here</title>"
                +"</head>"
                +"<body>"
                +"abc"
                +"</body>"
                +"</html>";
        pw.write(html);//寫內(nèi)容
        pw.close();//關(guān)閉流

設(shè)計程序
注冊成功后,在網(wǎng)頁上顯示 - - 注冊成功

完善用戶注冊
用戶信息符合規(guī)定條件 才允許注冊
如何注冊成功 顯示登陸頁面

12306項目驅(qū)動

軟件開發(fā)基本流程

需求分析
成果物:頁面原型 需求分析文檔
相關(guān)系統(tǒng)分析員向用戶初步了解需求,然后用相關(guān)的工具軟件列出要開發(fā)的系統(tǒng)的大功能模塊,每個大功能模塊有哪些小功能模塊,對于有些需求比較明確相關(guān)的界面時,在這一步里面可以初步定義好少量的界面。系統(tǒng)分析員深入了解和分析需求,根據(jù)自己的經(jīng)驗和需求用WORD或相關(guān)的工具再做出一份文檔系統(tǒng)的功能需求文檔。這次的文檔會清楚列出系統(tǒng)大致的大功能模塊,大功能模塊有哪些小功能模塊,并且還列出相關(guān)的界面和界面功能。系統(tǒng)分析員向用戶再次確認需求。

數(shù)據(jù)庫設(shè)計
基于需求分析的成果進行數(shù)據(jù)庫的設(shè)計,包含表,列以及關(guān)聯(lián)關(guān)系,初始數(shù)據(jù)。

概要設(shè)計(開發(fā)框架的搭建,核心技術(shù)的選擇)
首先,開發(fā)者需要對軟件系統(tǒng)進行概要設(shè)計,即系統(tǒng)設(shè)計。概要設(shè)計需要對軟件系統(tǒng)的設(shè)計進行考慮,包括系統(tǒng)的基本處理流程、系統(tǒng)的組織結(jié)構(gòu)、模塊劃分、功能分配、接口設(shè)計、運行設(shè)計、數(shù)據(jù)結(jié)構(gòu)設(shè)計和出錯處理設(shè)計等,為軟件的詳細設(shè)計提供基礎(chǔ)。

詳細設(shè)計
(通過UML建模實現(xiàn) 類圖 時序圖)
在概要設(shè)計的基礎(chǔ)上,開發(fā)者需要進行軟件系統(tǒng)的詳細設(shè)計。在詳細設(shè)計中,描述實現(xiàn)具體模塊所
涉及到的主要算法、數(shù)據(jù)結(jié)構(gòu)、類的層次結(jié)構(gòu)及調(diào)用關(guān)系,需要說明軟件系統(tǒng)各個層次中的每一個
程序(每個模塊或子程序)的設(shè)計考慮,以便進行編碼和測試。應當保證軟件的需求完全分配給整個
軟件。詳細設(shè)計應當足夠詳細,能夠根據(jù)詳細設(shè)計報告進行編碼。

編碼
在軟件編碼階段,開發(fā)者根據(jù)《軟件系統(tǒng)詳細設(shè)計報告》中對數(shù)據(jù)結(jié)構(gòu)、算法分析和模塊實現(xiàn)等方面的設(shè)計要求,開始具體的編寫程序工作,分別實現(xiàn)各模塊的功能,從而實現(xiàn)對目標系統(tǒng)的功能、
性能、接口、界面等方面的要求。在規(guī)范化的研發(fā)流程中,編碼工作在整個項目流程里最多不會
超過1/2,通常在1/3的時間,所謂磨刀不誤砍柴功,設(shè)計過程完成的好,編碼效率就會極大提高
,編碼時不同模塊之間的進度協(xié)調(diào)和協(xié)作是最需要小心的,也許一個小模塊的問題就可能影響了
整體進度,讓很多程序員因此被迫停下工作等待,這種問題在很多研發(fā)過程中都出現(xiàn)過。

測試
測試編寫好的系統(tǒng)。交給用戶使用,用戶使用后一個一個的確認每個功能。軟件測試有很多種:
按照測試執(zhí)行方,可以分為內(nèi)部測試和外部測試;按照測試范圍,可以分為模塊測試和整體聯(lián)調(diào);
按照測試條件,可以分為正常操作情況測試和異常情況測試;按照測試的輸入范圍,可以分為全
覆蓋測試和抽樣測試。以上都很好理解,不再解釋??傊?,測試同樣是項目研發(fā)中一個相當重要
的步驟,對于一個大型軟件,3個月到1年的外部測試都是正常的,因為永遠都會有不可預料的問
題存在。完成測試后,完成驗收并完成最后的一些幫助文檔,整體項目才算告一段落,當然日后
少不了升級,修補等等工作,只要不是想通過一錘子買賣騙錢,就要不停的跟蹤軟件的運營狀況
并持續(xù)修補升級,直到這個軟件被徹底淘汰為止。

數(shù)據(jù)庫的范式
消除重復數(shù)據(jù),減少冗余數(shù)據(jù),進行數(shù)據(jù)庫設(shè)計的方式
第一范式:數(shù)據(jù)表中每一個屬性都是不可分的基本數(shù)據(jù)項,同一個列中不能有多個值
第二范式 :要求數(shù)據(jù)表中的每個實例或行必須是唯一的,依賴于主鍵

所有列必須依賴主鍵(支持聯(lián)合主鍵)
第三范式;一個數(shù)據(jù)表不能包含其他表中非主鍵的列

MD5字符串加密處理

MD5是一種不可逆的加密算法
網(wǎng)站一般會保存用戶密碼:
為了不讓數(shù)據(jù)庫管理員看到用戶的密碼。
比如你輸入的密碼明明是這樣的:123456
網(wǎng)站加密后的密碼可能是這樣的:E10ADC3949BA59ABBE56E057F20F883E

public final static String md5(String s) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f' };

        try {
            byte[] btInput = s.getBytes();
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    

常見錯誤:
404:服務器依據(jù)請求地址找不到相應的資源
1.沒有將項目部署到服務器 2.<servlet-name>不一致 3.瀏覽器中請求地址有誤
500:系統(tǒng)出錯,程序在運行過程中出現(xiàn)問題
405:方法聲明錯誤

2.request的請求轉(zhuǎn)發(fā)和包含功能.
轉(zhuǎn)發(fā):
服務器接到客戶端的請求后,將請求轉(zhuǎn)發(fā)給WEB應用內(nèi)的其他資源處理

轉(zhuǎn)發(fā):request.getRequestDispatcher(“url”).forward(req,res);
url中的/可以寫,也可以不寫,建議寫。默認相對于項目名進行跳轉(zhuǎn)

3.request域的應用.
原理:
在request對象中含有一個map.這個map就是request域.
作用:
在將來開發(fā)中. 使用請求轉(zhuǎn)發(fā)時,servlet處理完數(shù)據(jù), 處理結(jié)果要交給jsp顯示. 可以使用request域?qū)⑻幚斫Y(jié)果由servlet帶給jsp顯示.

操作:
    1.setAttribute  存入一個鍵值對
    2.getAttribute  通過鍵取出值
    3.getAttributeNames 獲得域中所有鍵
    4.removeAttribute 跟據(jù)鍵移除一個鍵值對        
    
request的范圍:
    一個request對象對應一個request域(map).
    系統(tǒng)當前有多少個request就有多少request域.

重定向
服務器接收到客戶端的請求之后,返回給客戶端一個URL,客戶端根據(jù)URL
重新發(fā)出HTTP請求
重定向:response.sendRedirect(“url”);
url:如果不以/開頭,表示相對于當前路徑進行跳轉(zhuǎn)(localhost:port/項目名/)
response.sendRedirect(“index.html”)
url:如果以/開頭,表示相對于服務器域名進行跳轉(zhuǎn)(localhost:port/)
response.sendRedirect(request.getContextPath+“/index.html”)

圖片3.png

共同點:都是用來解決web組件(Servlet/JSP) 之間的跳轉(zhuǎn)問題

兩種方式的區(qū)別:
1.重定向支持項目資源外的跳轉(zhuǎn)(站外跳轉(zhuǎn)),轉(zhuǎn)發(fā)只能站內(nèi)跳轉(zhuǎn)。
2.請求對象個數(shù):重定向2個 ,轉(zhuǎn)發(fā)1個。
3.重定向后瀏覽器地址欄發(fā)生改變,轉(zhuǎn)發(fā)不變。
4.請求轉(zhuǎn)發(fā)性能好于重定向

至于選用哪種方式取決于數(shù)據(jù)共享的方式。如果采
用請求對象做數(shù)據(jù)的共享,則必須選用請求轉(zhuǎn)發(fā)的方式進行資源的跳轉(zhuǎn)。如果不選用請求對象做數(shù)據(jù)的共享,都可以。

解決項目中不同的組件(Servlet)之間地跳轉(zhuǎn)(降低耦合度):
一個Servlet只去處理一個功能
使用規(guī)律:一般在增加,修改,刪除之后轉(zhuǎn)到查詢


661d.png

設(shè)計程序
注冊成功- - 跳轉(zhuǎn)到登陸頁面
登陸成功- - 跳轉(zhuǎn)到系統(tǒng)主頁
登陸失敗- - 重新回到 登陸頁面

完善12306項目的注冊功能以及登陸功能

JSP
用戶輸入錯誤的信息時,做出相應的提示。登錄到主頁時,顯示當前用戶的信息
對于這些信息需要在什么時候設(shè)置,就是在對一次請求做出響應時,將相應的信息
傳遞到頁面當中

想要共享數(shù)據(jù),就需要在后臺進行數(shù)據(jù)的處理。需要將數(shù)據(jù)封裝起來,在網(wǎng)頁中來接受后臺封裝好的數(shù)據(jù)。對HTML來說,它是一種靜態(tài)頁面,用來制作網(wǎng)頁,顯示網(wǎng)頁內(nèi)容沒有問題,但是想要處理動態(tài)的數(shù)據(jù)時,用來訪問后臺傳遞的數(shù)據(jù)時,是沒有這個功能的,需要用JSP來解決這個問題

什么是JSP: JSP:動態(tài)網(wǎng)頁技術(shù)。
如何編寫JSP:在WebContent下創(chuàng)建JSP文件 修改字符集,
Eclipse-window - preferences - 搜索 file -JSP files - utf-8 - apply -OK

JSP本質(zhì)是Servlet,瀏覽器與服務器連接后,服務器的通信組件會先找到JSP,tomcat將它翻譯成servlet(jsp->.java->.class),初始化調(diào)用_jspInit(),_jspService(),_jspDestory()之后與servlet原理相同。

JSP的頁面元素


JSP腳本元素.png

1.網(wǎng)頁內(nèi)容,HTML編寫

2.指令<%@ %> 用來設(shè)置JSP的數(shù)據(jù)項
Page:用于定義和頁面相關(guān)的屬性信息
Language=”java” JSP支持的腳本語言,目前僅支持Java
ContentType:告訴瀏覽器輸出文本的格式及編碼
PageEncoding:設(shè)置文件的編碼,定義輸出流的字符集編碼,默認iso-8859-1
Charset:設(shè)置文本內(nèi)容的字符集
Import=”java.util.*” 將指定的類引入到JSP上
JSP中page屬性可以寫多個,但建議每個page中的屬性只寫一次,import除外。

include指令:引入其他jsp

修改為了使項目默認部署到tomcat安裝目錄下的webapps中,show view—>servers—>找到需要修改的tomcat—>右擊
①停止eclipse內(nèi)的Tomcat服務器(stop)
②刪除該容器中部署的項目(add and remove)
③清除該容器相關(guān)數(shù)據(jù)(clean)
④打開tomcat的修改界面(open)
⑤找到servers location,選擇第二個(User tomcat Installation)
⑥修改deploy path為webapps
⑦保存關(guān)閉需要說明的是①②③必須操作,否則下面的步驟會被置灰無法操作。

3.嵌套java代碼,處理動態(tài)數(shù)據(jù)(腳本元素)
JSP表達式:<%= %>
內(nèi)容編譯后成為變量, 表達式 ,有返回值的方法,會顯示結(jié)果

需要導入對應的java包 import="java.util.Date" 
<%= new Date() %>

JSP腳本: <% %>
內(nèi)容編譯后成為寫在方法里的java代碼片段

<%
    for(int i=0;i<=5;i++){

     }
%>

JSP聲明:<%! %>
內(nèi)容編譯后成為的成員變量(屬性)或成員方法

<%!
        int a;
        public void show(){
            
        }
        
%>

腳本元素之間可以相互嵌套

    <%!
        public void show(){
    %>      
        <%
            for(int i=0;i<=5;i++){
        %>
                <%=i %>
        <%
            }
        %>
    <%!     
        }
    %>
jsp和servlet的區(qū)別和聯(lián)系:

1.jsp經(jīng)編譯后就變成了Servlet.
(JSP的本質(zhì)就是Servlet,JVM只能識別java的類,不能識別JSP的代碼,Web容器將JSP的代碼編譯成JVM能夠識別的java類)

2.jsp更擅長表現(xiàn)于頁面顯示,servlet更擅長于邏輯控制.

3.Servlet中沒有內(nèi)置對象,Jsp中的內(nèi)置對象都是必須通過HttpServletRequest對象,HttpServletResponse對象以及HttpServlet對象得到.Jsp是Servlet的一種簡化,使用Jsp只需要完成程序員需要輸出到客戶端的內(nèi)容,Jsp中的Java腳本如何鑲嵌到一個類中,由Jsp容器完成。而Servlet則是個完整的Java類,這個類的Service方法用于生成對客戶端的響應。

JSP的9大內(nèi)置對象
JSP內(nèi)置對象.png

JSP如何處理后臺封裝的參數(shù)
Web層共享數(shù)據(jù)的范圍:
應用對象:ServletContext 整個Web項目都可以使用
會話對象:HttpSession 瀏覽器從打開到關(guān)閉,就是一個會話。
請求對象:HttpServletRequest 在一次請求中公用一個對象
頁面對象:PageContext 在當前頁面中有效
原則:盡量使用范圍小的共享數(shù)據(jù)對象

利用request作數(shù)據(jù)共享:
request.setAttribute(數(shù)據(jù)名,數(shù)據(jù)值) / request.getAttribute(數(shù)據(jù)名)
session. setAttribute(數(shù)據(jù)名,數(shù)據(jù)值) / session. getAttribute(數(shù)據(jù)名)
在JSP頁面中獲取后臺傳遞的數(shù)據(jù),默認是Object,需要類型轉(zhuǎn)換

<%
 String error=(String)request.getAttribute("error");
%>

<form action="Servlet1">
    用戶名<input type="text" name="username"> 
    <span>
      <%
        if(error!=null){
      %>
        <%=error %>
      <%
        }
      %>
    </span><br>
    用戶名<input type="password" name="pwd"> 
    <input type="submit"> 
</form>

設(shè)計程序
登陸失敗 重新回到登陸頁面 在登陸頁中顯示錯誤提示

完成12306項目 登陸頁錯誤提示

會話對象HttpSession

指的是一段時間內(nèi),單個客戶端與服務器之間多次的交互過程

作用范圍:瀏覽器從打開到關(guān)閉,都可以使用

會話對象的作用

保證同一個客戶端,多次請求之間的聯(lián)系

創(chuàng)建HttpSession

HttpSession session=request.getSession();

session.setAttribute(key, value);
JSP中獲取Session
HttpSession sessions=request.getSession();

sessions.getAttribute("")

設(shè)計程序
登陸成功后,在主要顯示當前用戶名

銷毀Session對象
session.invalidate();

設(shè)計程序
主頁中設(shè)計退出按鈕,完成退出功能
正常情況 退出之后 跳轉(zhuǎn)到登陸頁
這里為了驗證是否退出成功,可以重新跳轉(zhuǎn)到主頁 查看用戶名是否存在
如果不存在 表示session對象已經(jīng)被銷毀 退出成功

完成12306項目 主頁退出功能
可以設(shè)計退出后重定向到主頁,看是否存在用戶名
12306項目網(wǎng)頁用frame進行嵌套的,則無法使用轉(zhuǎn)發(fā)進行頁面跳轉(zhuǎn)

驗證碼
編寫驗證碼工具類
public final class ImageUtil {
    
    // 驗證碼字符集
    private static final char[] chars = { 
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 
        'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    // 字符數(shù)量
    private static final int SIZE = 4;
    // 干擾線數(shù)量
    private static final int LINES = 5;
    // 寬度
    private static final int WIDTH = 80;
    // 高度
    private static final int HEIGHT = 40;
    // 字體大小
    private static final int FONT_SIZE = 30;

    /**
     * 生成隨機驗證碼及圖片
     */
    public static Object[] createImage() {
        StringBuffer sb = new StringBuffer();
        // 1.創(chuàng)建空白圖片
        BufferedImage image = new BufferedImage(
            WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 2.獲取圖片畫筆
        Graphics graphic = image.getGraphics();
        // 3.設(shè)置畫筆顏色
        graphic.setColor(Color.LIGHT_GRAY);
        // 4.繪制矩形背景
        graphic.fillRect(0, 0, WIDTH, HEIGHT);
        // 5.畫隨機字符
        Random ran = new Random();
        for (int i = 0; i <SIZE; i++) {
            // 取隨機字符索引
            int n = ran.nextInt(chars.length);
            // 設(shè)置隨機顏色
            graphic.setColor(getRandomColor());
            // 設(shè)置字體大小
            graphic.setFont(new Font(
                null, Font.BOLD + Font.ITALIC, FONT_SIZE));
            // 畫字符
            graphic.drawString(
                chars[n] + "", i * WIDTH / SIZE, HEIGHT / 2);
            // 記錄字符
            sb.append(chars[n]);
        }
        // 6.畫干擾線
        for (int i = 0; i < LINES; i++) {
            // 設(shè)置隨機顏色
            graphic.setColor(getRandomColor());
            // 隨機畫線
            graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
                    ran.nextInt(WIDTH), ran.nextInt(HEIGHT));
        }
        // 7.返回驗證碼和圖片
        return new Object[]{sb.toString(), image};
    }

    /**
     * 隨機取色
     */
    public static Color getRandomColor() {
        Random ran = new Random();
        Color color = new Color(ran.nextInt(256), 
                ran.nextInt(256), ran.nextInt(256));
        return color;
    }
    
}

Servlet中獲取驗證碼
                // 生成驗證碼圖片
                Object[] objs = ImageUtil.createImage();
                // 將驗證碼存入session
                String imgcode = (String) objs[0];
                request.getSession().setAttribute("imgcode", imgcode);
                // 將圖片輸出給瀏覽器
                BufferedImage img = (BufferedImage) objs[1];
                response.setContentType("image/png");
                // tomcat自動創(chuàng)建輸出流
                // 目標就是本次訪問的瀏覽器
                OutputStream os = response.getOutputStream();
                ImageIO.write(img, "png", os);
                os.close();
客戶端調(diào)用驗證碼
<img src=Servlet映射路徑" alt="驗證碼"
  onclick="this.setAttribute('src','Servlet映射路徑?x='+Math.random())"/>
會話對象Cookie

HTTP是無狀態(tài)協(xié)議,服務器無法記住瀏覽器,cookie和session能夠?qū)顟B(tài)進行管理,讓服務器記住瀏覽器。
狀態(tài):用來證明瀏覽器來過服務器的表示數(shù)據(jù)
Cookie是在客戶端保存信息的技術(shù)
Cookie 是一小段文本信息,伴隨著用戶請求和頁面在 Web 服務器和瀏覽器之間傳遞。用戶每次訪問站點時,Web 應用程序都可以讀取 Cookie 包含的信息。
cookie原理.
讓瀏覽器記住鍵值對.是向響應頭中添加一下頭即可:
set-Cookie:name=tom;
瀏覽器記住之后,向服務器發(fā)送鍵值對,是在請求頭中添加下面的信息:
Cookie: name=tom;

創(chuàng)建 Cookie
創(chuàng)建Cookie對象 設(shè)置存儲的內(nèi)容
Cookie cookie=new Cookie("username","chen");
設(shè)定cookie的保存時長,單位 秒
cookie.setMaxAge(60*60*5);
將cookie添加到response對象中
response.addCookie(cookie);

cookie細節(jié)問題:
1.瀏覽器記多久?
默認是在會話期間有效.(關(guān)閉瀏覽器,cookie就被刪除).(有效時間-1)
2.有效時間如何設(shè)置?
//設(shè)置cookie的最大有效時間
1>設(shè)置一個正數(shù),標示最大有效時間.單位是秒
//cookie.setMaxAge(60*60);
2>設(shè)置為-1 , 就是相當于默認有效時間, 瀏覽器關(guān)閉就消失.
//cookie.setMaxAge(-1);
3> 標示cookie的有效時間為0.發(fā)送到瀏覽器就消失了.

JSP中獲取Cookie
<%
    String name="";
    Cookie[] cookies=request.getCookies();
    /* 通過cookie中的key 獲取需要的cookie元素    */
    for(Cookie cookie:cookies){
        if(cookie.getValue().equals("chen")){
            name=cookie.getValue();
        }
    }
%>
Cookie的原理
圖片6.png

Cookie的特點:
存儲在瀏覽器端,隱私性差,安全性較低。
保存在本地磁盤中,臨時存儲。
用于數(shù)據(jù)的傳遞

設(shè)計程序
登陸成功的用戶,關(guān)閉瀏覽器后。下一次打開瀏覽器時
登陸頁自動顯示用戶名和密碼

解決自動登錄問題:Cookie

圖片5.png

當用戶訪問到一在創(chuàng)建這個SESSION的時候,服務器首先檢查這個用戶發(fā)來的請求里是否包含了一個SESSION ID,如果包含了一個SESSION ID則說明之前該用戶已經(jīng)登陸過并為此用戶創(chuàng)建過SESSION,那服務器就按照這個SESSION ID把這個SESSION在服務器的內(nèi)存中查找出來(如果查找不到,就有可個服務器,如果服務器啟用Session,服務器就要為該用戶創(chuàng)建一個SESSION,能為他新創(chuàng)建一個),如果客戶端請求里不包含有SESSION ID,則為該客戶端創(chuàng)建一個SESSION并生成一個與此SESSION相關(guān)的SESSION ID。這個SESSION ID是唯一的、不重復的、不容易找到規(guī)律的字符串,這個SESSION ID將被在本次響應中返回到客戶端保存,而保存這個SESSION ID的正是COOKIE,這樣在交互過程中瀏覽器可以自動的按照規(guī)則把這個標識發(fā)送給服務器。

3.原理
瀏覽器第一次訪問服務器,服務器會在內(nèi)存中開辟一個空間(session),并把session對應的ID發(fā)送給瀏覽器.
那么下次瀏覽器再去訪問服務器,會把sessionID 交給服務器,服務器通過sessionID 找到剛才開辟的空間.
以上就是session的原理.
4.session細節(jié)問題
1> 服務器讓瀏覽器記住sessionID的cookie 默認過期時間是 (-1)==> 關(guān)閉瀏覽器 cookie就丟失 ==> cookie丟失 sessionID就丟失 ==> 找不到服務器的session
2> session中除了 4個操作 map的方法之外,還有哪些方法.
long getCreationTime() 獲得創(chuàng)建時間
String getId() 獲得sessionID
long getLastAccessedTime() 獲得最后一次訪問時間
int getMaxInactiveInterval() 獲得session的壽命
void setMaxInactiveInterval(int interval) 設(shè)置session的過期時間
void invalidate() 讓session立即失效
boolean isNew()
3> 關(guān)于設(shè)置session的最大有效時間
默認是30分鐘. ==> 在tomcat的web.xml中 <session-config> 配置的.
如何修改session的過期時間?
1.修改在tomcat的web.xml中 <session-config> ==> 影響服務器中的所有項目
2.在項目的web.xml中 加入<session-config> 配置.==> 影響的是當前項目
3.通過setMaxInactiveInterval(int interval)方法設(shè)置.==> 當前操作的session

4>(了解內(nèi)容)URL重寫
    如果瀏覽器 禁用cookie功能不能保存任何cookie.那么session技術(shù)要是用 cookie來保存sessionID. 沒有cookie怎么保存?
        使用url重寫解決該問題.
        將頁面中所有的連接 末尾全都加上 cookieid的參數(shù). 這樣用戶點擊連接訪問網(wǎng)站,通過url把SeesionID帶到了服務器.這樣就解決了.
        但是 互聯(lián)網(wǎng)行業(yè)沒有這么干的.

當用戶長時間沒有做出任何指令和動作時,自動退出。
解決方式:修改session的超時時間,默認30分鐘。當服務器(tomcat)檢查到用戶超過這個時間沒有任何動作時,將session銷毀。從session不活動的時候開始計算,如果session一直活動,session就總不會過期。從該Session未被訪問,開始計時; 一旦Session被訪問,計時清0;在web.xml配置<session-config> <session-timeout></~></session-config>

EL表達式:代替JSP中的JAVA代碼,作為動態(tài)數(shù)據(jù)的輸出。
JSP表達式如果為空值時,會報空指針異常,在代碼上需要做判斷處理
而EL表達式則不會有這樣的問題
語法:${表達式}
可以訪問req和res中的數(shù)據(jù),可以訪問cookie和其他請求報文中的信息

EL表達式默認從4個內(nèi)置對象中取值,并且是依次取值。(page,request ,session,appliction)
從小的作用域開始查找對應的數(shù)據(jù)對象,找到為止。
在實際開發(fā)中,不同的作用域不建議起相同的數(shù)據(jù)名

Cookie不是EL的內(nèi)置對象,取值 ${cookie.參數(shù)名.value}

練習:用EL表達式獲取bean(實體類)中的屬性和方法 ${user.username}

數(shù)據(jù)庫連接池

數(shù)據(jù)庫連接的建立和資源的關(guān)閉都是消耗巨大的
每次操作數(shù)據(jù)庫都要打開,關(guān)閉物理連接,系統(tǒng)的性能嚴重受損

解決方案:
系統(tǒng)初始運行的時候,主動建立足夠的連接,組成一個連接池。
每次程序請求數(shù)據(jù)庫連接時,無需重新打開數(shù)據(jù)庫連接,而是從連接池
中獲取已有的連接。使用完后,不再關(guān)閉,而是歸還給連接池。

private static BasicDataSource ds;// 數(shù)據(jù)庫連接池

    static {

            ds = new BasicDataSource();
            ds.setDriverClassName("com.mysql.jdbc.Driver");// Class.forName(...)
            ds.setUrl("jdbc:mysql://localhost:3306/mysql");
            ds.setUsername("root");
            ds.setPassword("root");
            ds.setInitialSize(5);
            System.out.println(ds.getInitialSize());
    }

    /**
     * 獲取數(shù)據(jù)庫連接
     */
    public static Connection getConnection() throws Exception {

        return ds.getConnection();
    }

    public static void closeConnection(Connection conn) {

        try {
            conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

功能顯示查詢數(shù)據(jù) (組合查詢)
由于查詢的條件不同,所有顯示的數(shù)據(jù)也會有所不同(內(nèi)容和數(shù)量)
HTML本身的標簽無法實現(xiàn),需要使用自定義標簽JSTL

jstl.jar在jsp中通過taglib指令引入,才可以使用.<%@ taglib uri=”” prefix=”” %>
uri:是自定義標簽庫的地址 prefix:標簽庫的別名


jstl.png

<c:foreach items=”” var =””> </> 循環(huán)遍歷


foreach.png

分頁查詢


復合查詢.png

刪除功能

ServletConfig對象是什么?
封裝了servlet在web.xml中的配置.
方法:
1>getServletName ==> 獲得配置文件中 <servlet-name> 元素的內(nèi)容
2>getInitParameter ==> 根據(jù) <init-param>中的 <param-name> 獲得 </param-value>
<init-param>
<param-name>name</param-name>
<param-value>tom</param-value>
</init-param>
3>getInitParameterNames 返回所有<param-name> .

HTTPServlet:
1.因為我們web項目基于HTTP協(xié)議,所以Service方法中傳過來的request,response對象都是 基于HTTP協(xié)議的.
也就是HttpServletReueqst,也就是HttpServletResponse. 它幫我們進行了強轉(zhuǎn).
2.我們有可能在不同的請求方式時做不同的事情. 根據(jù)請求方式不同,調(diào)用不同的方法
例如 GET --> doGet()
POST ==> doPost();

相關(guān)對象之 ---- ServletContext
1.獲得: servletConfig ==> getServletContext
2.servletContext 的作用
1> servletContext 封裝了web.xml 中的配置
<context-param>
<param-name>name</param-name>
<param-value>jerry</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>1234</param-value>
</context-param>

                getInitParameterNames();  ==> 獲得所有鍵
                getInitParameter(key);  ==> 根據(jù)鍵獲得對應的值
    2> servlet技術(shù)中3大域?qū)ο笾? 
        ServletContext對應著Application(應用)域.利用了一個項目中只有一個ServletContext實例的特點.
在servletContext中放置了一個map用作數(shù)據(jù)通信.
        這個Map就是所謂域.
            關(guān)于域的操作,有4個.
                放入鍵值對 setAttribute(key,value)
                通過鍵取值 getAttribute(key)
                通過鍵刪除 removeAttribute(key)
                遍歷所有鍵 getAttributeNames()
            application ==> servletContext
            session ==> 
            request ==> 
    3>獲得項目中資源.  
        所有servletContext中關(guān)于路徑的獲得,相對路徑都是相對的 WebRoot(項目根)下
            getRealPath  ==> 通過相對路徑獲得絕對路徑
            getResourceAsStream ==> 根據(jù)相對路徑獲得指定資源流
    
3.servlet技術(shù)中對象的范圍
    servlet ==> 項目啟動期間一個servlet只有一個servlet實例
    request ==> 項目啟動期間,request對象的數(shù)量,要看當前有多少個請求正在處理.
    response ==> 同上.
    servletConfig ==> 一個servlet實例對應一個servletConfig對象
    servletContext ==> 整個項目中,永遠只有一個servletContext實例存在

在web.xml中配置錯誤頁面攔截(報錯后跳轉(zhuǎn)到錯誤頁面)

正常情況系統(tǒng)不應該將報錯的頁面顯示給用戶,或者說不應該讓用戶看到。對于一些懂技術(shù)的人來說,看到報錯信息,可能會找到系統(tǒng)的漏洞,造成不必要的麻煩。
解決:系統(tǒng)報錯時,根據(jù)錯誤類型,跳轉(zhuǎn)到相應的頁面
通過配置web.xml文件,讓tomcat統(tǒng)一處理異常,即告訴tomcat在發(fā)生異常時,轉(zhuǎn)發(fā)到什么錯誤頁面
1.通過異常類型聲明
<error-page>
<exception-type>java.langException</ exception-type>
<location>錯誤網(wǎng)頁的url</location>
</error-page>
2.通過錯誤編碼聲明(405,500寫法相同)
<error-page>
<error-code>404< /error-code>
<location>錯誤網(wǎng)頁的url</location>
</ error-page>

由于任何地方都可能報錯,所以無法確定相對路徑,所以JSP訪問路徑應該為絕對路徑
并且該路徑不能寫項目名,tomcat會自動補充。

過濾器
解決項目中的一些共性需求,如日志,過濾敏感詞,登錄檢查等。

創(chuàng)建一個過濾器:該類實現(xiàn)了Filter接口,重寫了三個方法 init(),destroy(),doFilter()
init() 初始化方法,destroy( ) 銷毀方法 ,通常不寫內(nèi)容
doFilter():在tomcat啟動時,會自動調(diào)用該方法,傳入ServletRequest,ServletResponse
由于需要獲取session和servlet中的訪問路徑,需要對參數(shù)進行強轉(zhuǎn)為HttpServletRequest
HttpServletResponse

配置webxml
<filter>
<filter-name></filter-name>
<filter-class></filter-class>
</filter>
<filter-mapping>
<filter-name></filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

過濾器原理:

1.通過過濾器統(tǒng)一解決亂碼問題

在過濾器的doFilter方法中設(shè)置編碼的轉(zhuǎn)換,在執(zhí)行chain.doFilter(request, response);之前
將編碼設(shè)置成utf-8
chain.doFilter(request, response);表示將請求交給下一個Filter或者Servlet處理
如果不調(diào)用該方法則請求結(jié)束。

2.通過Filter進行系統(tǒng)校驗,用戶只能通過登錄頁面進入系統(tǒng)
設(shè)置了過濾器之后,所有的請求都會被攔截,也就是登錄的請求也會被攔截
那么就需要將該請求排除攔截的范圍。其他的請求不變。
登錄的用戶會把信息保存在session中,若sesion中沒有數(shù)據(jù) 則該用戶沒有登錄,進行攔截
跳轉(zhuǎn)到登錄頁面。

FileUpload實現(xiàn)文件上傳

boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        System.out.println(isMultipart);
        //1、創(chuàng)建一個DiskFileItemFactory工廠
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //2、創(chuàng)建一個文件上傳解析器
        ServletFileUpload upload = new ServletFileUpload(factory);
        //解決上傳文件名的中文亂碼
        upload.setHeaderEncoding("UTF-8"); 
        upload.setSizeMax(1024 * 1024 * 5);//設(shè)置上傳的文件總的大小不能超過5M
        try {
            //解析請求對象
            List<FileItem> fileList= upload.parseRequest(request);
            //遍歷請求結(jié)果
            Iterator<FileItem> iter = fileList.iterator();
            while(iter.hasNext()){
                FileItem item = iter.next();
                //判斷當前遍歷到的元素是否為普通的表單
                if(item.isFormField()){
                    String name = new String(item.getFieldName().getBytes("iso8859-1"),"utf-8");
                    String value = new String(item.getString().getBytes("iso8859-1"),"utf-8");
                    System.out.println(name);
                    System.out.println(value);
                }else{
                    //圖片的上傳
                    //獲取文件名
                    String fileName = item.getName();
                    System.out.println(fileName);
                    //重命名
                    String newFileName = new Date().getTime()+fileName.substring(fileName.indexOf('.'));
                    //構(gòu)建File對象
                    System.out.println(getServletContext().getRealPath("/images/photo"));
                    File file = new File( getServletContext().getRealPath("/images/photo"),newFileName);
                    item.write(file);

                }
            }
            
        } catch (FileUploadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
文件上傳的問題

上傳的圖片保存在tomcat下的webapps中,并不是本地的項目空間。如果平時測試代碼時需要重新部署項目,這將導致webapps下的項目被項目空間的所替換,之前上傳到服務器中的文件也就消失了。

測試臨時解決辦法:將文件上傳路徑,設(shè)置為項目空間

歸根到底這些問題其實還是因為我們是在調(diào)試的工程中,發(fā)布后肯定是不會出現(xiàn)這些問題的。發(fā)布了之后你的tomcat服務器只有關(guān)閉和打開,而不會對工程重新部署,自然也就不會出現(xiàn)這些問題

上傳圖片文件(圖像)時如何立即顯示
<script type="text/javascript">
  //判斷瀏覽器是否支持FileReader接口
  if (typeof FileReader == 'undefined') {
    alert("<h1>當前瀏覽器不支持FileReader接口</h1>");
  } 
  //選擇圖片,馬上預覽
  function xmTanUploadImg(obj) {
    var file = obj.files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
      var img = document.getElementById("img1");
      console.log(e.target.result);//Date url格式
      img.src = e.target.result;
    }
    reader.readAsDataURL(file);
  }
  </script>
<form action="FileUpdateServlet" method="post" enctype="multipart/form-data">
        <input type="file" name="headr"  onchange="xmTanUploadImg(this)">
        <input type="submit">
        <img alt=""  id="img1">
</form>

Ajax是一種用來改善用戶體驗的技術(shù)。其實質(zhì)是利用瀏覽器提供的ajax對象(XMLHttpRequest) 異步的向服務器發(fā)送請求,服務器響返回數(shù)據(jù),瀏覽器利用這些數(shù)據(jù)進行頁面的局部更新
整個過程,頁面無刷新效果,不打斷用戶的操作。
異步:指的是當ajax對象發(fā)送請求時,瀏覽器不會銷毀當前頁面
提交表單請求時,會銷毀當前頁面(刷新)

獲取ajax對象
function getXhr(){
    var xhr;
    if(window.XMLHttpRequest){
        非IE
     xhr=new XMLHttpRequest();
    }else{
           IE瀏覽器下獲取方式
        xhr=new ActiveXObject("Microsoft.XMLHttp");
    }
    return xhr;
}

觸發(fā)ajax的事件函數(shù)
onreadystatechange:綁定事件的處理函數(shù)
當readyState屬性值發(fā)生改變時,會觸發(fā)readystatechange事件
readyState:有5個值(0,1,2,3,4),表示ajax對象與服務器的通信進度
            當值為4的時候,表示已經(jīng)獲得了服務器返回的數(shù)據(jù)
status:表示服務器返回的狀態(tài)碼 200表示成功
responseText:表示服務器返回的文本數(shù)據(jù)
xhr.send():將請求發(fā)送給服務器,必須寫

 function sendHttpReq(){
    獲取ajax對象
    var xhr=getXhr();
      通過ajax向服務器發(fā)送請求
    xhr.open("get","servlet映射路徑",true);
    xhr.onreadystatechange=function(){
        if(xhr.readyState==4&&xhr.status==200){
            var msg=xhr.responseText;
        }
    };
    
    xhr.send();
}
服務器相應ajax
 PrintWriter pw= response.getWriter();
 pw.print(響應信息);
 pw.close();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Java web筆記 一、HTTP協(xié)議 HTTP(超文本傳輸協(xié)議),它是一種主流B/S架構(gòu)中應用的通信協(xié)議。具有以...
    默羊的筆記本閱讀 603評論 0 0
  • 1.1 Servlet 1.1.1 什么是Servlet Servlet是JavaWeb三大組件之一(Servle...
    海若Hero閱讀 2,172評論 0 5
  • Web服務器 Weblogic(Oracle) WebSphere(IBM) JBoss(Redhat) 以上產(chǎn)品...
    Levi_wen閱讀 375評論 0 0
  • 一 . Tomcat 1.對Tomcat的理解 Tomcat是一個運行JAVA的網(wǎng)絡(luò)服務器,提供能夠讓別人訪問自己...
    Vegetable蔬菜閱讀 933評論 2 1
  • Servlet:Sun公司制訂的一種用來擴展Web服務器功能的組件規(guī)范。當瀏覽器將請求發(fā)送給Web服務器(比如:a...
    南山伐木閱讀 628評論 0 4

友情鏈接更多精彩內(nèi)容