javaweb知識點

1.HTTP超文本傳輸協議

作用:規範瀏覽器與服務器進行數據交互的格式,解決不同版本的瀏覽器與不同版本的服務器數據交互的問題
數據格式:鍵值對(key-value)
特點:(1)簡單快速 :請求資源只需要輸url即可,HTTP服務器規模小,速度快
(2)靈活:HTTP允許傳輸任意類型的數據對象,用Content-Type標記
(3)無連接:服務器處理完客戶請求,並收到客戶的應答,就關閉連接(HTTP1.1版本後支持可持續連接)
(4)無狀態:發送完數據後,不會記錄任何信息,如果後續處理需要前面的信息,則它必須重傳 -->可以用cookie與session保存狀態
HTTP有7中請求方式,常用的有GET,POST
請求的數據格式
請求行: 請求方式 請求url 協議/版本(HTTP/1.1)
請求頭:鍵值對格式 例如 User-Agent:Mozilla/5.0 (使用的火狐瀏覽器)
空行
請求體:包含一些請求參數,例如 nam=zhangsan,如果爲GET請求,則請求體爲空,參數拼接在url後面
響應的數據格式
響應行:協議/版本 狀態碼 狀態碼描述
響應頭:鍵值對格式
空行
響應體:傳輸的數據 例如JSON數據

2.兩種請求方式GET與POST的比較

GET:請求參數在請求url後進行拼接,不安全,瀏覽器對url長度有限制,所以GET請求不能攜帶大量的數據
POST:請求參數在請求體中發送,安全,適合數據量大的發送

3.中間件Tomcat

服務器軟件就是代碼編寫的一個可以根據用戶請求實時的調用執行對應的邏輯代碼的一個容器
作用:負責實時根據用戶請求給出響應

4.Servlet(javaweb容器)

Servlet(Server Applet)是用Java編寫的運行在服務器端的小程序
Servlet本質是接口,定義了被Tomcat識別的規則,自定義類要去實現Servlet接口才能被Tomcat識別 
訪問url:協議://IP:端口/虛擬項目名/servlet的別名 (sevlet別名即url-pattern的值,通過url-pattern的值,找到servlet-class全類名,通過反射造對象)

— 
      實現             繼承
Servlet接口<————GenericServlet抽象類<————HttpServlet抽象類
Servlet中有5個抽象方法(init、getServletConfig、service、getServletInfo、destroy),而我們通常只需要重寫service()方法,GenericServlet抽象類只需重寫service()方法(根據請求的不同調用doGet()與doPost()方法),其餘的方法都默認做了空實現,GenericServlet比Servlet更常用,HttpServlet抽象類重寫了service()方法,並在service()方法中封裝了對請求方式的判斷,我們只需要重寫doGet()與doPost()等方法來處理各種請求,HttpServlet比GenericServlet更常用。


Servlet的生命週期
(1)默認情況
從第一次被調用到服務器關閉(服務器啓動,將web.xml文件加載到內存,當第一次有用戶輸入servlet的訪問路徑時,由請求地址中的uri對比web.xml的url-pattern找到對應的servlet並將其加載進內存,服務器關閉之後,就沒有佔用內容的必要了,銷燬即釋放資源)
(2)配置<loadOnStartup>0或正數</loadOnStartup>
從服務器啓動到服務器關閉(只要服務器一啓動,就會將servlet加載到內存)
Servlet的三個方法
init():對servlet進行初始化的方法,在servlet第一次加載進內存的時候被調用,只執行一次
service():處理請求,提供服務,執行多次,訪問一次sevlet就執行一次
destroy():在servlet被銷燬時執行,即服務器關閉時


自定義servlet使用流程
設置請求編碼格式request.setCharacterEncoding(“utf-8”)
設置相應編碼格式response.setContentType(“text/html;charset=utf-8”)
獲取請求信息
處理請求信息
響應處理結果

5.request和response對象

服務器接收到一個請求,就會創建一個request對象存放請求信息,並調用service(request,response)方法將request對象作爲實參傳遞,request與response對象是由服務器創建的,我們可以獲取request裏封裝的請求消息,也可以設置response裏的相應消息

6.請求轉發(forward)與重定向(redirect)

請求轉發:從客戶端接收請求並將其發送到服務器上的任何資源(例如servlet,jsp,html),服務器內部的資源跳轉方式

request.getRequestDispatcher("xxx.html").forward(request,response);

重定向:當前servlet無法處理,交給其他資源處理,狀態碼302

//本地資源 路徑使用uri
response.sendRedirect(request.getContextPath()+"/xxx.html");
//網絡資源 路徑使用url
response.sendRedirect("http://www.baidu.com");

請求轉發特點
(1)一次請求,即一個request對象,數據可以在request域中傳遞
(2)只能轉發到當前服務器的內部資源
(3)瀏覽器地址欄路徑不會發生變化
重定向特點
(1)二次請求,即兩個request對象,數據不可以在request域中傳遞
(2)可以訪問其他服務器的資源
(3)瀏覽器地址欄路徑發生變化(刷新頁面不會導致表單重複提交)

7.會話技術之cookie和session

瀏覽器第一次給服務器發送請求,會話建立,直到一方斷開連接,則一次會話結束
一次會話中包含多次請求和響應,在一次會話的範圍內共享數據,解決了發送的不同請求的數據共享問題(HTTP的無狀態問題)
Cookie:數據保存在客戶端(存儲在瀏覽器的運行內存)

//創建cookie
Cookie cookie = new Cookie("name","zhangsan");
//發送cookie
response.addCookie(cookie);

//獲取cookie
Cookie[] cookies = request.getCookies();

Session:數據保存在服務端(存儲在服務器的運行內存)
原理:用戶第一次訪問服務器,服務器會創建一個session對象給此用戶,並將此session對象的唯一標識(JSESSIONID)使用Cookie技術存儲到瀏覽器中,保證用戶的其他請求能夠獲取同一個session對象,也保證了不同請求能夠獲取到共享的數據

//創建session
 HttpSession session = request.getSession();
//綁定數據
 session.setAttribute("name","zhansan");
 
//獲取session
//JESSIONID存儲在Cookie的臨時存儲空間中,瀏覽器關閉即失效
//如果請求中有JESSIONID,則返回其對應的session對象
//如果請求中沒有JESSIONID或者session對象失效了,則創建新的session對象,並將其JESSIONID作爲cookie的數據存儲到瀏覽器內存中
 HttpSession session = request.getSession();

Cookie的生命週期
(1)當瀏覽器被關閉,cookie就消失了
(2)持久化存儲:調用cookie對象的setMaxAge(int seconds)方法,會將Cookie數據寫到硬盤的文件中,seconds過後,cookie數據被刪除。setMaxAge(0):刪除cookie信息
Cookie的作用範圍
默認同一個服務器的不同項目不能共享,調用cookie對象的setPath("/")後,同一服務器不同項目可以共享,如果調用setDomain(String path),設置的一級域名相同,那麼多個服務器之間的cookie可以共享
Session的生命週期
(1)當服務器非正常關閉,session就銷燬
服務器正常關閉不銷燬session,()session會存到服務器的硬盤中,也就是會在CATALINA_BASE\work\Catalina\localhost\項目名稱下面生成一個文件SESSIONS.ser(執行序列化),當服務器再次啓動的時候會加載此文件(反序列化),所以如果session中存放了java對象,就要讓java類實現Serializable接口,標記爲可序列化類:
(2)session的默認銷燬時間爲30分鐘(tomcat或項目的web.xml中可改)
(3)session對象調用invalidate()方法,session被銷燬,強制銷燬不推薦
(4)當瀏覽器關閉時,sessionId失效,但是session沒有被銷燬
Session的小問題
問題:服務端不關閉,瀏覽器關閉,兩次請求獲取的session不是同一個的問題(因爲cookie沒了)
解決:我們可以創建一個新的Cookie,該Cookie的名字爲JESSIONID,path爲web應用的虛擬路徑,並設置setMaxAge()的毫秒值,讓Cookie保存在客戶端的硬盤中,這時即使多次對瀏覽器進行關開操作是不會清除客戶端硬盤文件的。所以,Cookie就不丟失了,SessionId也不會隨瀏覽器關閉而丟失。
具體代碼實現:

Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setPath(request.getContextPath()+"/");
cookie.setMaxAge(1000*60*30);
response.addCookie(cookie);

Cookie和Session的區別
(1)session存儲在服務端,cookie存儲在客戶端
(2)cookie的大小與同一域名下的數量受到限制,session存儲數據不受限制
(3)session存儲數據在服務端,相對安全
(4)session依賴cookie

8.ServletContext對象

ServletContext對象由服務器創建,一個項目只有一個對象,不管在項目的任意位置進行獲取得到的都是同一個對象
ServletContext對象解決了不同用戶的數據共享問題,將servlet放入容器統一管理

//獲取ServletContext對象
//獲取方式1
ServletContext c1 = this.getServletContext();
//獲取方式2
ServletContext c2 = this.getServletConfig().getServletContext();
//獲取方式3
ServletContext c3 = request.getServletContext();
//獲取方式4
ServletContext c4 = request.getSession().getServletContext();

ServletContext的生命週期:服務器啓動到服務器關閉
ServletContext的作用域:項目內


9.JSP(Java Server Pages)

JSP:Java服務器端頁面,本質上是servlet,是一種動態網頁技術(數據會發生改動),既可以定義html標籤,也可以書寫java代碼
JSP的訪問原理
首先看tomcat文件下的全局配置文件web.xml

 <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
 </servlet>
<servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

可以看到把*.jsp與JspServlet作了映射,因爲tomcat底層只能識別servlet,當瀏覽器發起對JSP的請求之後,請求被服務器接收,就執行JspServlet,JspServlet通過IO讀寫操作將xxx.jsp文件轉譯成爲對應的java文件xxx_jsp.java(本質爲Servlet,繼承了HttpServlet),然後執行轉譯好的java文件(編譯運行),找到父類的service()方法,執行其_jspService()方法(tomcat只能識別service()方法)
在這裏插入圖片描述JSP腳本(java代碼)

1.<%代碼%>  局部代碼塊 轉譯到xxx_jsp.java的_jspService()方法中
2.<%!代碼%> 全局代碼塊 轉義爲xxx_jsp類的成員變量/方法
3.<%=代碼%>  轉譯爲xxx_jsp.java的_jspService()方法中的一條語句:out.print("代碼")

JSP靜態/動態引入公共模板
靜態引入:當前的jsp文件與引入的jsp文件轉譯成一個java文件(用的include指令)

<%@ include file="模板jsp相對路徑"%>

動態引入:當前的jsp文件與引入的jsp文件分別轉譯爲各自的java文件,而動態性體現在當前jsp文件轉譯好的java文件中(_jspService()方法中)調用引入的jsp文件轉譯的java文件

<jsp:include page="模板jsp相對路徑"></jsp:include>

區別:靜態引入的結果是把其他jsp引入當前jsp,兩者和爲一體,動態引入是兩者獨立,直到輸出時才合併,靜態引入兩文件不允許聲明同名變量,動態引入允許兩文件中聲明同名變量


JSP九大內置對象
jsp文件在轉譯成其對應的servlet文件時,在_jspService()方法中自動聲明的對象,所以可以直接使用
(1)request
封存當前請求數據的對象,由tomcat服務器創建 作用域:一次請求
(2)response
響應對象,用於響應請求處理結果給瀏覽器
(3)session
存儲用戶的不同請求之間的共享數據 作用域:一次會話
(4)application
ServletContext對象 作用域:項目內
(5)PageContext
頁面上下文對象,封存了其他內置對象 (獲取內置對象),作用域:當前頁面
(6)out
響應對象,Jsp內部使用,帶有緩衝區的響應對象,效率高於response對象
(7)page
代表當前Xxx_jsp類的對象,等同於this
(8)config
ServletConfig對象,獲取web.xml中的配置數據
(9)exception
存儲異常信息 添加<%@ page isErrorPage=“true”%>纔會創建exception對象


四個域對象
PageContext:當前頁面。解決了當前頁面內的數據共享問題,一般用於獲取其他內置對象
request:一次請求。一次請求的servlet的數據共享。通過請求轉發,將數據流轉給下一個servlet
session:一次會話。一個用戶的不同請求的數據共享。將數據從一次請求流轉給其他請求
application:項目內。不同用戶的數據共享。將數據從一個用戶流轉給其他用戶

10.EL表達式與JSTL標籤

EL(Expression Language) 表達式語言
作用:替代與簡化JSP中java代碼(從域對象中獲取值)的編寫
格式${域名稱.鍵名},域名稱可省,如果省略,優先從最小的域中查找是否有該鍵對應的值
域對象    域名稱
pageContext–>pageScope
request–>requestScope
session–>sessionScope
application–>applicationScope

//獲取域中存放的值
//獲取變量值
${requestScope.user}
//獲取對象中的值
${sessionScope.user.name}
//獲取list集合中的元素
${list對象[索引]}
//獲取map集合中的鍵(key)
${map對象.鍵名}
//根據鍵獲取map集合中的值(value)
${map對象["鍵名"]}
//判斷list集合是否空,返回boolean值
${empty list}

//EL表達式獲取url拼接的參數
 ${param.鍵名}
 //EL表達式動態獲取虛擬項目名(重要)
 ${pageContext.request.contextPath}

JSTL(JSP Standard Tag Library) JSP的標準標籤庫
作用:簡化和替換JSP頁面的java代碼的編寫,對EL的擴展,能對EL中取出的值進行判斷/遍歷操作

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
//使用if判斷
<c:if test="${list[0].age eq 18}">
alert("18");
</c:if>
//使用forEach遍歷集合
<c:forEach items="${list}"  var="obj">
 alert(${obj.name});
</c:forEach>
//日期格式化
<fmt:formateDate pattern="yyyy-MM-dd" value="${now}" />
11.AJAX異步刷新技術

AJAX(Asychronous JavaScript and XML),允許瀏覽器與服務器通信而無須刷新當前頁面的技術叫AJAX,是一種局部刷新技術(通過js的dom操作局部刷新)
同步:服務器發送請求,在等待服務器響應時,用戶不可以對頁面進行操作
異步:瀏覽器不需要等待服務器的響應,在服務器處理請求的過程中,瀏覽器可以進行其他操作,這樣可以使得用戶的體驗更佳
格式$.get(url,[data],[callback],[type])
[type]指的是服務器傳過來的數據的格式,可以爲"text"、"json"等等

//Jquery寫法一
$.get("xxxServlet",{},function(data){對data的操作},"json");
//Jquery寫法二
$.ajax({
url:"xxxServlet",
type:"GET",
async:true, 
dataType:"json",  
data:{"username":jack,"age"=23},
success:function(data){對data的操作}
});

data就是服務器傳過來的數據,這個data形參名是自定義的,async:true就是異步,async:false就是同步

12.Filter過濾器

作用:當訪問服務器的資源時,過濾器可以將請求攔截下來,完成一些特殊的功能
Filter的生命週期:服務器啓動到服務器關閉
Filter的三個方法
init():對filter進行初始化的方法,在服務器啓動的時候被調用,只執行一次
doFilter():攔截請求的方法,實現對資源的管理,需要手動對資源放行
destroy():在filter被銷燬時執行,即服務器關閉時
Filter的應用
(1)統一編碼格式
(2)session管理,登陸驗證,判斷是否有session或sesson是否失效
(3)資源管理:敏感字符過濾(和諧),統一水印
過濾器實現統一編碼格式的具體代碼

//統一編碼格式
//解決全站亂碼問題,處理所有的請求
@WebFilter("/*")
public class CharchaterFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse rep, FilterChain filterChain) throws IOException, ServletException {
        //將父接口轉爲子接口
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) rep;
        //獲取請求方法
        String method = request.getMethod();
        //解決post請求中文數據亂碼問題
        if(method.equalsIgnoreCase("post")){
            request.setCharacterEncoding("utf-8");
        }
        //處理響應亂碼
        response.setContentType("text/html;charset=utf-8");
        //放行資源
        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {
    }
}
13.Listener監聽器

作用:監聽作用域對象request,session,servletContext的創建、銷燬和內容的改變,並進行一些操作
監聽request的基本使用

@WebListener
public class MyListener implements ServletRequestListener, ServletRequestAttributeListener {
    private static int num=1;
    //監聽request被銷燬的時候
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("銷燬");
    }
    //監聽request被創建的時候
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("創建");
    }

    //監聽往request中添加數據的時候
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("添加第"+num+++"個數據");
        System.out.println(servletRequestAttributeEvent.getName());
        System.out.println(servletRequestAttributeEvent.getValue());
    }

    //監聽從request中移除數據的時候
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("移除");
    }
    
    //監聽request中的值被替換的時候
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        System.out.println("替換");
    }
}

監聽器實現統計網站在線人數的具體代碼
JSP中使用${applicationScope.count}顯示在線人數

@WebListener
public class MyListener implements HttpSessionListener, ServletContextListener {

    //監聽session的創建
    //一旦有人在網頁登陸,就會創建一個session對象
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
         //獲取SerlvetContext對象
        ServletContext sc = httpSessionEvent.getSession().getServletContext();
        //獲取在線人數count
        int count = (int)sc.getAttribute("count");
        //存儲
        sc.setAttribute("count",++count);
    }

    //監聽session的銷燬
    //一旦有人退出網頁賬戶(強制銷燬session,session.invalidate()),就會銷燬一個session對象
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        //獲取SerlvetContext對象
        ServletContext sc = httpSessionEvent.getSession().getServletContext();
        //獲取在線人數count
        int count = (int)sc.getAttribute("count");
        //存儲
        sc.setAttribute("count",--count);
    }

    //application對象初始化(服務器啓動,application對象被創建)
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
         //獲取application對象
        ServletContext sc = servletContextEvent.getServletContext();
        //在application對象中存儲變量統計在線人數,設置初值0
        sc.setAttribute("count",0);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}

總結:這種方式統計網站在線人數存在一個漏洞,用戶如果點x退出的頁面,session不會被銷燬,即人數count不會被減一,解決方案:在所有的客戶端頁面裏使用js的window.onclose來監視瀏覽器的關閉動作,然後向服務器發送一個請求來關閉Session

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章