JavaWeb入門學(xué)習(xí)資料整理

一、Listener監(jiān)聽器

1、JavaWeb三大組件之一(Servlet程序、Fiflter過濾器、Listener監(jiān)聽器)

2、Listener是JavaEE的規(guī)范,也就是接口

3、監(jiān)聽器的作用是:監(jiān)聽某事物的變化,回調(diào)函數(shù)反饋處理

二、 ServletContextListener 監(jiān)聽器

1、ServletContextListener 可以監(jiān)聽ServletContext對象的創(chuàng)建和銷毀

2、ServletContext 對象在web工程啟動的時候創(chuàng)建,在web工程停止的時候銷毀

3、監(jiān)聽到web工程的創(chuàng)建和銷毀后都會分別調(diào)用ServletContextListener的回調(diào)方法

三、使用方式

1、創(chuàng)建一個類實現(xiàn)ServletContextListener接口

2、實現(xiàn)兩個方法

3、在web.xml中配置監(jiān)聽器。 如:

<listener>

<listener-class>com.demo.listener.MyServletContextListenerImpl</listener-class>

</listener>

==============================================================================================

一、EL 表達式

Expression Language,表達式語言

作用:代替jsp頁面中的表達式腳本在jsp頁面中進行數(shù)據(jù)的輸出。(更簡潔)

例:

表達式腳本輸出key值:<%=request.getAttribute("key")%><br/>

EL表達式輸出key值:${key}

注:表達式腳本輸出null; EL表達式輸出""空串

二、EL表達式搜索四個域的順序

按從小到大的順序從域中搜索

1、pageContext.setAttribute("key", "pageContext");

2、request.setAttribute("key", "request");

3、session.setAttribute("key", "session");

4、application.setAttribute("key", "application");

三、EL表達式輸出bean、集合、數(shù)組屬性等

${personBeanKey}

${personBeanKey.arrayDatas[1]}

${personBeanKey.listDatas[1]}

${personBeanKey.mapDatas.key1}

注:EL表達式 其實是找尋bean中的get方法去執(zhí)行的。

四、EL運算

1、關(guān)系運算

==和eq是一樣的;!=和ne是一樣的;

<和lt;>和gt;<=和le;>=和ge;

例:if(12==12){};? if(12 eq 12){}

2、邏輯運算

&&和and是一樣的;||和or是一樣的;!和not是一樣。

3、算數(shù)運算

+-*/

/和div是一樣的;%和mod是一樣的

4、empty運算

判斷數(shù)據(jù)是否為空,空輸出true,否則false

例: ${empty dataStr}

注:數(shù)組對象等判空時,元素個數(shù)為零則為空,返回true

5、三元運算

表達式?“true”:“false”

6、“.”點運算和[]中括號運算

例:${personBeanKey.arrayDatas[1]}

中括號處理特殊字符key,如:

key值為a.a.a時,錯誤輸出:${map.a.a.a};正確輸出:${map['a.a.a']}

key值為b+b+b時,錯誤輸出:${map.b+b+b};正確輸出:${map['b+b+b']}

五、EL表達式的11個隱含對象

是EL表達式中自己定義的,可以直接使用。

PageContextImpl pageContext; // 獲取jsp中九大內(nèi)置對象

Map<String, Obejct> pageScope;// 獲取PageContext域中的數(shù)據(jù)

Map<String, Obejct> requestScope;// 獲取Request域中的數(shù)據(jù)

Map<String, Obejct> sessionScope;// 獲取Session域中的數(shù)據(jù)

Map<String, Obejct> applicationScope;// 獲取ServletContext域中的數(shù)據(jù)

Map<String, String> param;// 獲取請求參數(shù)的值

Map<String, String[]> paramValues;// 獲取請求參數(shù)的值,獲取多個值的時候使用

Map<String, String> header;// 獲取請求頭的信息

Map<String, String[]> headerValues;// 獲取請求頭的信息,獲取多個值的時候使用

Map<String, Cookie> cookie;// 獲取當前請求的Cookie信息

Map<String, String> initParam;// 獲取web.xml中配置的<context-param>上下文參數(shù)

注:

1、pageContext獲取到九大內(nèi)置對象可以得到的信息有:

scheme協(xié)議、serverName請求服務(wù)器ip、serverPort請求服務(wù)器端口、

contextPath工程路徑、method請求方法、remoteHost客戶端ip地址、session.id會話的id編號

例:

方式一:${pageContext.request.scheme} 獲取協(xié)議

方式二:

<% pageContext.setAttribute("req", request); %>

${req.scheme}

2、之前說了可以直接${key1};輸出數(shù)據(jù)。但四個域中都有同一個key值時,可以通過上面的對象點key值輸出數(shù)據(jù)。四個域中都有同一個key值時,可以通過上面的對象點key值輸出數(shù)據(jù)。

如:pageScope.key1

3、獲取Cookie的名稱:${cookie.JSESSIONID.name}

獲取Cookie的值:${cookie.JSESSIONID.value}

六、JSTL標簽庫

JSP標準標簽庫

EL表達式主要是為了替換jsp中的表達式腳本,而標簽庫則是為了替換代碼腳本,使得jsp頁面更加簡潔

<c:set />標簽 例:<c:set scope="page" var="key1" value="value1"/> 注:scope 屬性表示設(shè)置保存到哪個域,page指pageContext

<c:if />標簽 例:<c:if test="${12==12}"/> 注:test屬性表示判斷的條件(使用EL表達式輸出)

<c:choose>、<c:when>、<c:otherwise>標簽 多路判斷,類似switch...case...default

例:

<% request.setAttribute("height", 199); %>

<c:choose>

<c:when test="${requestScope.height > 190}">

<h1>大于190</h1>

</c:when>

<c:when test="${requestScope.height > 180}">

<h1>大于180</h1>

</c:when>

<c:otherwise>

<h1>剩下的情況</h1>

</c:otherwise>

</c:choose>

注:

1、choose表示開始選擇判斷, when表示

2、不用像case一樣break;

3、標簽里不能使用html注釋<!-- -->,要使用jsp注釋;<%-- --%>

4、when標簽的父標簽一定要是choose標簽。(標簽嵌套時會用到)

<c:forEach />標簽

例:遍歷1到10(begin 開始遍歷的索引值;end結(jié)束的索引值;step 遍歷的步長值,類似于i+=2)

<c:forEach begin="1" end="10" step="2"var="i">

${i} <br>

</c:forEach>

遍歷數(shù)組(items數(shù)組集合,var輸出對象; varStatus對象獲取到遍歷的數(shù)據(jù)、索引、個數(shù)、是否第一、是否最后、步長等)

<c:forEach items="${requestScope.listDatas}" var="item" varStatus="status">

${item} <br>

</c:forEach>

遍歷Map(itemsMap集合,item表示每一組鍵值對,取鍵item.key,取值item.value)

<c:forEach items="${requestScope.map}" var="item">

${item} <br>

</c:forEach>

注:

1、先導(dǎo)入jstl標簽庫的jar包

2、使用taglib指令在代碼引入<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

七、文件的上傳

1、要有一個form標簽,method=post請求

2、form標簽的encType屬性值必須為multipart/form-data值; 表示提交的數(shù)據(jù)以多段的形式進行拼接,再以二進制形式提交到服務(wù)器

3、在form標簽中使用input type=file添加上傳的文件

4、編寫服務(wù)器代碼接收處理上傳的數(shù)據(jù)

注:

1、數(shù)據(jù)中的boundary 表示每段數(shù)據(jù)的分隔符,

2、瀏覽器會隨機生成一段字符作為每段數(shù)據(jù)的分界符。(比如:------WebKitFormBoundary9d39iEShBIMraATK)

3、分界符后面加-- 就表示結(jié)束了。

4、文件解析框架:

commons-fileupload-1.2.1.jar

commons-io-1.4.jar

jar包中的類:ServletFileupload 用于解析上傳的數(shù)據(jù)

isMultipart() 是否多段

parseRequest() 解析上傳的數(shù)據(jù)

isFormField() 判斷當前這個表單項是否是普通的表單項還是上傳的文件類型

true表示普通類型表單項;false表示上傳的文件類型

getFieldName() 獲取表單項的name屬性值

getString() 獲取當前表單項的值

getName() 獲取上傳的文件名

write(file) 將上傳的文件寫到參數(shù)file所指向的硬盤位置

七、文件的下載

1、獲取要下載的文件名

2、讀取要下載的文件內(nèi)容

3、把下載的文件內(nèi)容回傳給客戶端

4、在回傳前,通過響應(yīng)頭告訴客戶端返回的數(shù)據(jù)類型

5、通過響應(yīng)頭告訴客戶端收到的數(shù)據(jù)是用于下載使用

八、會話跟蹤方案

1、方案一:Cookie技術(shù)

Cookie保存于瀏覽器

優(yōu)點:HTTP協(xié)議中支持的技術(shù),直接用。

缺點:移動端APP無法使用Cookie;不安全,用戶可以自己禁用Cookie; 不能跨域(跨域指的是,前后端分別部署到不同的ip服務(wù)器。)

例:服務(wù)器代碼設(shè)置

設(shè)置Cookie:response.addCookie(new Cookie(COOKIE_KEY, "hahaha"));

獲取Cookie:request.getCookies().getName();cookie.getValue());

2、方案二:Session

Session保存于服務(wù)器,服務(wù)器會話對象Session中保存key、value發(fā)給瀏覽器

優(yōu)點:存在服務(wù)器中,安全的很。

缺點:多個服務(wù)器時無法使用(集群)、Cookie的缺點

Session設(shè)置值:session.setAttribute(SESSION_KEY, "heiheihei");

Session獲取值:request.getSession().getAttribute(SESSION_KEY);

3、方案三:令牌技術(shù)

一段字符串

優(yōu)點:支持PC端、移動端;解決集群環(huán)境下的認證問題;減輕服務(wù)器端的存儲壓力;

缺點:需要自己實現(xiàn)。生成令牌、客戶端存儲令牌、傳輸?shù)椒?wù)端;

JWT令牌:JSON WEB TOKEN

定義了一種簡介的、自包含的格式,用于在通信雙方以json數(shù)據(jù)格式安全的傳輸信息。由于數(shù)字簽名的存在,這些信息是可靠的。

例:共三部分,以點分割。****.*****.****

eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjkzMTQ5Njc4LCJ1c2VybmFtZSI6IkhhaGFoYSJ9.lzPlLTFHzjq_oEyRqC4Jkz-vAvQs-_kX0Ik9UjBS-98

****.*****,前兩段可以通過base64解碼

組成:

第一部分:Header(頭),記錄令牌類型、簽名算法等。例如:{"alg":"HS256", "type":"JWT"}

第二部分:Payload(有效荷載),攜帶一些自定義信息、默認信息等。例如:{"id":"1", "username":"hahaha"}

第三部分:Signature(簽名),防止Token被篡改、確保安全性。將header、payload,并加入指定秘鑰,通過指定簽名算法計算而來。

登錄認證使用令牌技術(shù):

1、客戶端瀏覽器發(fā)起請求,服務(wù)端登錄成功,生成令牌,將令牌返回給客戶端瀏覽器。

2、客戶端瀏覽器保存令牌。后續(xù)每個請求,都攜帶JWT令牌,服務(wù)端每次請求處理之前,先校驗令牌再處理。

客戶端發(fā)送時放在Head的token中:jwt令牌字符

令牌的生成:引入依賴、書寫以下代碼

HashMap<String, Object> claims = new HashMap<>();

claims.put("id", 1); claims.put("username","Hahaha");

String jwtString = Jwts.builder().setClaims(claims)//自定義內(nèi)容(載荷)

.signWith(SignatureAlgorithm.HS256, SIGNING_KEY)//簽名算法,SIGNING_KEY為秘鑰

.setExpiration(new Date(System.currentTimeMillis() + 12 * 3600 * 1000))//12小時有效期,

.compact();

//令牌的獲取

Claims claims =

Jwts.parser().setSigningKey(SIGNING_KEY)//SIGNING_KEY為秘鑰

.parseClaimsJws(jwtString)

.getBody();

九、過濾器Filter

JavaWeb三大組件之一(Servlet程序、Fiflter過濾器、Listener監(jiān)聽器)

過濾器可以把對資源的請求攔截下來,從而實現(xiàn)一些特殊的功能。

比如:

過濾器一般完成一些通用的操作,比如:登錄校驗、統(tǒng)一編碼處理、敏感字符處理等。

Filter快速入門:

1、定義一個Filter類,實現(xiàn)Filter接口,重寫所有方法。

2、配置Filter,F(xiàn)ilter類加上@WebFilter注解,配置攔截資源的路徑。引導(dǎo)類上加@ServletComponentScan開啟Servlet組件支持。

注:

@WebFilter(urlPatterns = "/*") //攔截所有請求:訪問所有資源都會被攔截

@WebFilter(urlPatterns = "/login")//攔截具體路徑

@WebFilter(urlPatterns = "/emps/*")//目錄攔截:/emps目錄下的所有資源

一個Web應(yīng)用中,可以配置多個過濾器,就形成了過濾器鏈。執(zhí)行順序是過濾器類名(字符串)的自然排序。

實操:登錄校驗Filter-流程

1、獲取請求url

2、判斷url中是否包含login,包含則判斷是登錄操作,需要放行。

3、獲取請求頭中的令牌(token)

4、判斷令牌是否存在,如果不存在,返回錯誤結(jié)果(未登錄)。

5、解析token,如果解析失敗,返回錯誤結(jié)果(未登錄)。

6、放行

十、攔截器Interceptor (Spring環(huán)境中的攔截器)

攔截器執(zhí)行流程:瀏覽器--JavaWeb中的Filter--Spring環(huán)境中的DispatcherServlet--Spring環(huán)境中的Interceptor--Spring環(huán)境中的目標資源

概念:動態(tài)攔截方法調(diào)用的機制,類似于Filter過濾器(Filter是JavaWeb的)。Spring框架中提供的,用來動態(tài)攔截控制器方法的執(zhí)行。

作用:攔截請求,在指定的方法調(diào)用前后,根據(jù)業(yè)務(wù)需要執(zhí)行預(yù)先設(shè)定的代碼。

快速入門:

1、定義攔截器類,實現(xiàn)HandlerInterceptor接口,重寫所有方法。

@Component

public class LoginInterceptor implements HandlerInterceptor {}

2、注冊攔截器。

@Configuration

public class WebConfig implements WebMvcConfigurer {

? ? @Autowired

? ? private LoginInterceptor loginInterceptor;

? ? @Override

? ? public void addInterceptors(InterceptorRegistry registry) {

? ? ? ? //指定攔截路徑

? ? ? ? registry.addInterceptor(loginInterceptor).addPathPatterns("/**");

? ? }

}

注:

//指定攔截一級路徑 addPathPatterns("/*");例:攔截/depts、/emps、/login,不攔截/depts/1

//指定攔截任意級路徑 addPathPatterns("/**");例:攔截/depts、/depts/1、/depts/1/2

//指定攔截/depts下的一級路徑 addPathPatterns("/depts/*");例:攔截/depts/1, 不攔截/depts、/depts/1/2

//指定攔截/depts下的任意級路徑 addPathPatterns("/depts/**");例:攔截/depts、/depts/1、/depts/1/2, 不攔截/emps、/login

//指定不攔截哪些路徑 excludePathPatterns("/login");例:不攔截 /login

十一、全局異常處理器

@RestControllerAdvice

public class GlobalExceptionHandler {

? ? @ExceptionHandler(Exception.class)

? ? public Result ex(Exception e) {

? ? ? ? e.printStackTrace();

? ? ? ? return Result.error("服務(wù)繁忙,請稍后再試!");

? ? }

}

十二、谷歌驗證碼的使用Kaptcha

1、導(dǎo)入kaptcha的jar包(kaptcha-2.3.2.jar)

2、在web.xml中配置用于生成驗證碼的servlet程序,也就是KaptchaServlet

3、在表單中使用image使用kaptcha生成的圖片地址。

4、在服務(wù)器獲取谷歌生成的驗證碼。request.getSession().getAttribute(KAPTCHA_SESSION_KEY);

5、獲取之后立馬刪除removeAttribute

6、request.getParam獲取到請求中的驗證碼與谷歌生成的驗證碼比較即可。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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