Web階段:第十二章:JSP動態(tài)頁面

1.什么是Jsp?
jsp是java server page,java的服務器頁面。
2.為什么要學習jsp技術
因為jsp技術可以很好的解決在Servlet程序中回傳數據是html內容,這個問題。

在Servlet程序中回傳html數據,為什么是個問題?

public class PrintHtml extends HttpServlet {
    private static final long serialVersionUID = 1L;    
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // 解決響應亂碼
        response.setContentType("text/html; charset=UTF-8");            
        // 回傳一個html頁面的數據
        PrintWriter writer = response.getWriter();
        writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
        writer.write("<html>\r\n");
        writer.write("    <head>\r\n");
        writer.write("        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
        writer.write("        <title>Insert title here</title>\r\n");
        writer.write("    </head>\r\n");
        writer.write("    <body>\r\n");
        writer.write("        這是hello的html頁面\r\n");
        writer.write("    </body>\r\n");
        writer.write("</html>");
    }
}

可以看到創(chuàng)建一個html頁面非常繁瑣

3.如何創(chuàng)建一個jsp動態(tài)頁面。

 


4.如何修改jsp頁面的默認編碼?

 


小結:
html和jsp一樣。都在放在webContent目錄下
WebContent
a.html =====>>>> http://ip:port/工程名/a.html
b.jsp =====>>>> http://ip:port/工程名/b.jsp

5.jsp的本質是什么。
jsp本質上,也是一個Servlet程序。

當我們第一次訪問jsp頁面的時候,Tomcat服務器會把jsp翻譯成為java源文件,然后保存到Tomcat服務器的work目錄下。
雙擊Tomcat v7.0 Server at localhost [Started ,Synchronized],彈出如下窗口

 


jsp生成的class文件和java源文件

 


我們打開a_jsp.java源文件,不難發(fā)現生成的這個類繼承了HttpJspBase類。

 


然后我們再通過查看源代碼發(fā)現,HttpJspBase又繼承了HttpServlet程序。所以生成的類本質上也是一個Servlet程序。

 


jsp翻譯成為Servlet源文件,全名規(guī)則(了解大概):
a.jsp 翻譯之后命名的全名為:a_jsp.java
b.jsp 翻譯之后命名的全名為:b_jsp.java

源文件名.jsp 翻譯之后是: 源文件名_jsp.java

6.jsp的三種語法
a)jsp頭部的page指令

<%@ page language=“java” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>

i.language屬性 值只能是java。表示jsp翻譯之后是java源文件。
ii.contentType屬性 返回的內容類型。response.setContentType的參數值。
iii.pageEncoding屬性 是當前jsp頁面的字符集
iv.import屬性 可以在jsp頁面中導入需要的包和類。
v.autoFlush屬性 設置jsp中的out輸出流是否自動刷新 默認是true(一般都不會修改自動刷新為false),
當jsp中out輸出流的緩沖區(qū)滿了之后,就會自動刷新。
vi.buffer屬性 設置jsp中的out輸出流的緩沖區(qū)大小。默認是8kb

 


vii.errorPage屬性 設置當jsp運行時出錯,就自動跳轉的頁面。
viii.isErrorPage屬性 設置當前jsp是否是錯誤頁面,默認是false,表示不啟動異常對象。設置為true,可以啟用Exception異常對象
ix.session 屬性 設置訪問jsp的時候,是否創(chuàng)建Session會話對象。默認是true.
x.extends 屬性 extends繼承屬性是預留給服務器廠商使用的。(基本都不會動)

b)jsp中的三種腳本
i.聲明腳本(幾乎不用)
聲明腳本的格式: <%! 聲明代碼 %>

聲明腳本可以聲明在類的內部定義的代碼。

1.我們可以定義全局變量。
2.定義static靜態(tài)代碼塊
3.定義方法
4.定義內部類

測試代碼:

   

  1. <body>
  2. <!-- 1.我們可以定義全局變量。 -->
  3. <%!
  4. int i = 0;
  5. private static Map<String,Object> map = new HashMap<String,Object>();
  6. %>
  7. <!-- 2.定義static靜態(tài)代碼塊 -->
  8. <%!
  9. static {
  10. map.put("key1", "value1");
  11. map.put("key2", "value2");
  12. map.put("key3", "value3");
  13. }
  14. %>
  15. <!-- 3.定義方法 -->
  16. <%!
  17. public void abc(){
  18. System.out.println("國哥真帥!");
  19. }
  20. %>
  21. <!-- 4.定義內部類 -->
  22. <%!
  23. private static class A {
  24. private String name;
  25. }
  26. %>
  27. </body>

 

 


ii.表達式腳本
表達式腳本的格式:<%=表達式 %>

表達式腳本可以在jsp頁面中輸出數據。
表達式腳本都會被翻譯到_jspService方法中
表達式腳本翻譯之后都是out.print進行輸出
表達式腳本中的表達式不能以分號結尾
由于表達式腳本翻譯之后都在_jspService方法中,所以在_jspService方法中的對象都可以在表達式腳本中直接使用。

1.輸出整型
2.輸出浮點型
3.輸出字符串
4.輸出對象

 


iii.代碼腳本
代碼腳本的格式是: <% 代碼腳本 %>
代碼腳本可以寫以方法中可以寫的任何代碼。
代碼腳本翻譯之后都在_jspService方法中

1.代碼腳本----if 語句
2.代碼腳本----for 循環(huán)語句
3.翻譯后java文件中_jspService方法內的代碼都可以寫

 


c)jsp中的三種注釋
i.html注釋
<!-- html注釋 -->
翻譯之后是out.write輸出到客戶端。

ii.java注釋
// 單行注釋
/* 多行注釋 */
Java 注釋 翻譯之后會原封不動翻譯到源代碼中

iii.jsp注釋
<%-- 這是jsp注釋 --%>
jsp注釋 在翻譯的時候,會被忽略掉

7.jsp九大內置對象

 


8.jsp四大域對象
pageContext ====>>>> request ====>>>>> session =====>>>>> application
域對象 數據操作范圍
pageContext 當前jsp頁面
request 同一次請求
session 同一次會話(打開瀏覽器,訪問服務器之后會話就打開了,只要瀏覽器不關。會話都在)
application 一個web工程

四個域的數據操作范圍從小到大分別是:pageContext====>>>request====>>>session=====>>>>application

四個域都可以用來保存數據,如何挑選使用?
四個域從小到大進行優(yōu)先選擇。

Context1.jsp頁面

 

  1. <body>
  2. <h1>Context1.jsp頁面</h1>
  3. <%
  4. pageContext.setAttribute("key", "pageContextData");
  5. request.setAttribute("key", "requestData");
  6. session.setAttribute("key", "sessionData");
  7. application.setAttribute("key", "applicaionData");
  8. %>
  9. pageContext域:<%=pageContext.getAttribute("key") %><br/>
  10. request域:<%=request.getAttribute("key") %><br/>
  11. session域:<%=session.getAttribute("key") %><br/>
  12. application域:<%=application.getAttribute("key") %><br/>
  13. <%
  14. // request.getRequestDispatcher("/Context2.jsp").forward(request, response);
  15. %>
  16. </body>

   

Context2.jsp頁面

  1. <body>
  2. <h1>Context2.jsp頁面</h1>
  3. pageContext域:<%=pageContext.getAttribute("key") %><br/>
  4. request域:<%=request.getAttribute("key") %><br/>
  5. session域:<%=session.getAttribute("key") %><br/>
  6. application域:<%=application.getAttribute("key") %><br/>
  7. </body>

  

9.jsp中的out輸出和response.getWriter輸出的區(qū)別

 


現在我們都知道out和response都可以往頁面上輸出數據。
通過觀察jsp翻譯之后的源碼我們發(fā)現,都是使用out進行輸出。所以我們以后也是統(tǒng)一使用out進行輸出操作。
out.write 可以輸出字符串
out.print 可以輸出任意數據
深入淺出:統(tǒng)一使用out.print進行輸出

10.jsp的常用標簽
a)jsp靜態(tài)包含

  1. <%--
  2. <%@ include file="" %> 是靜態(tài)包含。
  3. 靜態(tài)包含地址中打頭的斜杠,
  4. 表示http://ip:port/工程名/ 映射到代碼的WebContent目錄
  5. 靜態(tài)包含,其實本質上,只是把被包含的jsp頁面的內容。原封不動的拷貝到被包含的位置執(zhí)行。
  6. 靜態(tài)包含,不會翻譯被包含的jsp文件。
  7. --%>
  8. <%@ include file="/include/footer.jsp" %>

 

b)jsp標簽-動態(tài)包含

  1. <%--
  2. <jsp:include page=""></jsp:include> 是動態(tài)包含
  3. 動態(tài)包含地址中打頭的斜杠,
  4. 表示http://ip:port/工程名/ 映射到代碼的WebContent目錄
  5. 動態(tài)包含,會把被包含的jsp頁面也翻譯成為servlet程序。
  6. 動態(tài)包含,會翻譯成為如下語句:
  7. JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
  8. 等價于把request,response,out對象傳遞給footer.jsp所翻譯出來的Servlet去執(zhí)行使用。
  9. 動態(tài)包含,還可以傳遞參數
  10. --%>
  11. <jsp:include page="/include/footer.jsp">
  12. <jsp:param value="wzg168" name="username"/>
  13. <jsp:param value="123456" name="password"/>
  14. </jsp:include>

 

動態(tài)包含底層原理:
 

 

c)jsp標簽-轉發(fā)
<jsp:forward page="/Context2.jsp"></jsp:forward>
請求轉發(fā)功能,
跟request.getRequestDispatcher("/Context2.jsp").forward(request, response);代碼功能完全一樣
11.靜態(tài)包含和動態(tài)包含的區(qū)別

 

隨著整個javaEE技術的不斷升級,那么jsp這種技術,在整個javaEE體系中的定位慢慢發(fā)生變化。
jsp的定位慢慢就變成了,只是用來輸出html頁面數據而已。所以一般情況下。都使用靜態(tài)包含。

jsp的練習題
練習一:在jsp中輸出10*10的表格

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. <style type="text/css">
  9. table{
  10. width: 500px;
  11. border: 1px solid red;
  12. border-collapse: collapse;
  13. }
  14. th , td{
  15. border: 1px solid red;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <table>
  21. <% for (int i = 1; i <= 10; i++) { %>
  22. <tr>
  23. <% for (int j = 1; j <= 10; j++) { %>
  24. <td><%=i + "," + j %></td>
  25. <% } %>
  26. </tr>
  27. <% } %>
  28. </table>
  29. </body>
  30. </html>

 

練習二:在jsp中輸出九九乘法口訣表

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. <center>
  11. <h1>九九乘法口訣表</h1>
  12. <table width="600">
  13. <% for(int i = 1; i < 10; i++){ %>
  14. <tr>
  15. <% for(int j = 1; j <= i ; j++){ %>
  16. <td><%=j + "x" + i + "=" + (j*i) %></td>
  17. <% } %>
  18. </tr>
  19. <% } %>
  20. </table>
  21. </center>
  22. </body>
  23. </html>

  

練習三:jsp輸出一個表格,里面有20個學生信息。
請求轉發(fā)的流程示例:

 


Student類

public class Student {

    private Integer id;
    private String name;
    private String phone;
    private String email;

    public Student(Integer id, String name, String phone, String email) {
        super();
        this.id = id;
        this.name = name;
        this.phone = phone;
        this.email = email;
    }

    public Student() {
        super();
    }

   

SearchStduent程序

public class SearchStudent extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // 獲取請求參數
        // 查詢學生信息
        // 得到多個學生信息
        List<Student> stus = new ArrayList<Student>();
        for (int i = 1; i < 21; i++) {
            stus.add(new Student(i,"name"+i, "phone"+i,"email"+i));
        }
        // 把學生信息保存到request域中
        request.setAttribute("stus", stus);
        // 請求轉發(fā)到jsp頁面中輸出數據
        request.getRequestDispatcher("/test/showStudent.jsp").forward(request, response);
    }

}

   

showStudent.jsp頁面

  1. <%@page import="java.util.ArrayList"%>
  2. <%@page import="com.atguigu.pojo.Student"%>
  3. <%@page import="java.util.List"%>
  4. <%@ page language="java" contentType="text/html; charset=UTF-8"
  5. pageEncoding="UTF-8"%>
  6. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  7. <html>
  8. <head>
  9. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  10. <title>Insert title here</title>
  11. <style type="text/css">
  12. table{
  13. width: 500px;
  14. border: 1px solid red;
  15. border-collapse: collapse;
  16. }
  17. th , td{
  18. border: 1px solid red;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <%
  24. List<Student> stus = (List<Student>) request.getAttribute("stus");
  25. %>
  26. <table>
  27. <tr>
  28. <th>編號</th>
  29. <th>姓名</th>
  30. <th>電話</th>
  31. <th>郵箱</th>
  32. <th>操作</th>
  33. </tr>
  34. <% for (int i = 0; i < stus.size(); i++) { %>
  35. <% Student stu = stus.get(i); %>
  36. <tr>
  37. <td><%=stu.getId() %></td>
  38. <td><%=stu.getName() %></td>
  39. <td><%=stu.getPhone() %></td>
  40. <td><%=stu.getEmail() %></td>
  41. <td>修改、刪除</td>
  42. </tr>
  43. <% } %>
  44. </table>
  45. </body>
  46. </html>

 

12、什么是Listener監(jiān)聽器?
Listener監(jiān)聽器是JavaWeb的三大組件之一,
三大組件分別是:Servlet程序、Filter過濾器、Listener監(jiān)聽器

Listener監(jiān)聽器,顧名思義,它監(jiān)聽某個事物狀態(tài)變化,然后反饋給用戶信息。
1、監(jiān)聽事物狀態(tài)變化
2、反饋用戶結果

12.1、ServletContextListener監(jiān)聽器
ServletContextListener監(jiān)聽器,監(jiān)聽ServletContext對象的創(chuàng)建和銷毀。

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

如何使用ServletContextListener監(jiān)聽器,步驟如下:
1、編寫一個類去實現ServletContextListener監(jiān)聽器接口
2、到web.xml中去配置監(jiān)聽器

ServletContextListenerImpl 代碼:

public class ServletContextListenerImpl implements ServletContextListener {
    /**
     * ServletContext對象創(chuàng)建并初始化就馬上調用此contextInitialized方法
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext對象被創(chuàng)建啦啦啦…………");
    }

    /**
     * 當ServletContext對象被銷毀之后,就會馬上調用contextDestroyed方法
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext對象被銷毀啦啦啦…………");
    }
}

web.xml中的配置:

  1. <!-- listener標簽配置監(jiān)聽器 -->
  2. <listener>
  3. <!-- listener-class配置監(jiān)聽器的全類名 -->
  4. <listener-class>com.atguigu.listener.ServletContextListenerImpl</listener-class>
  5. </listener>