整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          深入理解JSP

          一章 JSP

          1、概述

          1.1 JSP引入

          在前面的登錄案例中,登錄失敗后為了能夠響應登錄的錯誤信息。我特意創建了一個LoginErrorServlet用來動態地拼接錯誤信息。

          【代碼如下】

          1. LoginErrorServlet:登錄失敗,手動拼接login.html頁面,并將錯誤信息動態地添加進去。
          arduino復制代碼       //3.給瀏覽器生成響應信息
                  boolean result = service.login(username,password);
                  String msg = result ? "用戶登陸成功" : "用戶登陸失敗";
                  request.setAttribute("msg",msg);
                  if (result){
                      //登陸成功
                      response.sendRedirect("/success.html");
                  }else {
                      //登陸失敗
                      //轉發到處理錯誤的servlet中
                    request.getRequestDispatcher("/loginErrorServlet").forward(request,response);
                  }
          

          2. LoginErrorServlet:手動拼接html頁面,動態展示登錄錯誤信息。

          scss復制代碼@Override
              protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  //響應給用戶
                  response.setContentType("text/html;charset=utf-8");
                  //接收錯誤的信息
                  String msg = (String) request.getAttribute("msg");
                  //獲取輸出流
                  PrintWriter writer = response.getWriter();
                   //拼接登錄的html頁面
                  response.getWriter().print("<html>");
                  response.getWriter().print("<body>");
                  response.getWriter().print("<form action='loginInterServlet' method='post'>");
                  response.getWriter().print(" <font style='color: red'>"+msg+"</font><br/>");
                  response.getWriter().print("用戶名:<input type='text' name='username'/><br/>");
                  response.getWriter().print("密碼:<input type='password' name='password'/><br/>");
                  response.getWriter().print("<input type='submit' value='登錄'/>");
                  response.getWriter().print("</form>");
                  response.getWriter().print("</body>");
                  response.getWriter().print("</html>");
              }
          

          說明:上述雖然能夠達到我的需求。但是他有以下兩個缺點:

          1. 拼接麻煩開發效率低;
          2. 閱讀性差,代碼難以維護;

          問題:思考既然以前在servlet有上述缺點,為什么還要使用拼接呢?

          因為如果我們想在html頁面顯示錯誤的信息,我們只能采用這種方式,html頁面不能夠書寫java代碼。而我們既不采用上述拼接標簽的方式,還想實現簡單的效果。我們可以使用jsp技術,在jsp中可以書寫java代碼同時還可以書寫html標簽。這樣 就能夠使用jsp技術在客戶端和服務端直接進行數據交互了。

          1.2 JSP是什么

          JSP全名為Java Server Pages,中文名叫java服務器頁面,其本質是一個Servlet ,它是由Sun 公司倡導、許多公司參與一起建立的一種動態網頁 技術標準。其實就是一個既能書寫Servlet代碼又能書寫HTML代碼的文件。

          1.3 創建JSP文件

          sql復制代碼在web目錄下,新建一個jsp文件,點擊鼠標右鍵New --- JSP---給這個文件取個名字。
          

          【圖1 創建JSP】

          文件內容如下:

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          
          </body>
          </html>
          

          1.4 在JSP中書寫代碼

          jsp中既可以書寫java代碼,同時還可以書寫html標簽。我們完成練習如何在jsp頁面中書寫java代碼。

          【需求】

          1. 在jsp頁面上獲取當前日期,并將其格式化成字符串"yyyy-MM-dd HH:mm:ss";
          2. 將這個字符串展示在瀏覽器上;

          說明:

          1)jsp中的注釋:<%--注釋內容--%>,添加注釋的快捷鍵是:ctrl+/;

          2)在jsp中書寫代碼有三種方式,我們這里先介紹一種,格式:

          <%java代碼%>

          【參考代碼】demo01.jsp

          arduino復制代碼<%@ page import="java.util.Date" %>
          <%@ page import="java.text.SimpleDateFormat" %><%--
            Created by IntelliJ IDEA.
            Date: 2018-01-09
            Time: 19:15
            To change this template use File | Settings | File Templates.
          --%>
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <%--
                  jsp中的注釋
                  【需求】
                  1. 在jsp頁面上獲取當前日期,并將其格式化成字符串"yyyy-MM-dd HH:mm:ss";
                  2. 將這個字符串展示在瀏覽器上;
              --%>
              <%
                  //獲取當前系統時間
                  Date d = new Date(); 
                  //創建日期格式化解析器對象
                  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                  //使用日期格式化解析器對象調用方法格式化日期對象d
                  String s_date = sdf.format(d);
                  //控制臺輸出
                  System.out.println("s_date = " + s_date);
                  //將這個字符串展示在瀏覽器上
                  response.getWriter().print(s_date);
              %>
          </body>
          </html>
          

          【運行結果】啟動tomcat,并且訪問這個jsp頁面。

          在瀏覽器看到 format格式的日期:

          【控制臺輸出】

          ini復制代碼s_date = 2018-01-09 19:28:22
          

          2、JSP的運行原理

          通過上面的jsp初體驗, 我們看到jsp中既可以編寫java代碼也可以直接編寫html代碼,相對servlet更加方便.并且我們通過瀏覽器訪問到的jsp頁面,最后在瀏覽器中看到了響應到瀏覽器中的結果。那么整個過程的執行流程是怎樣的呢,我們可以參考如下圖:

          通過上面的執行流程,我們可以找到jsp生成的.java源文件,這樣就可以知道jsp的真正原理,同時可以看下jsp為什么是servlet。

          如何查看生成的.java源文件呢?

          我們可以到tomcat中查看一下上面案例中的jsp頁面是怎么樣的一種存在。IDEA借助tomcat發布web項目的機制:動態發布(為每一個web項目創建一個單獨的發布文件)。我們可以通過tomcat其中日志中的CATALINA_BASE路徑找到我們當前這個JSP頁面在tomcat中的位置:

          【圖1 IDEA發布項目的路徑】

          找到這個目錄后,會看到以下3個文件夾:

          【圖2 文件目錄】

          我們打開C:\Users\admin.IntelliJIdea2017.3\system\tomcat\Tomcat_8_5_311_day05目錄發現有兩個文件:

          【圖3 JSP被翻譯后的代碼】

          打開demo01_jsp.java文件后,代碼如下所示:

          我們可以看到當前的jsp文件被翻譯成了一個類,這個類繼承HttpJspBase類,那么這個HttpJspBase類又是什么?

          注意:jsp的翻譯由服務器完成,HttpJspBase類一定也是tomcat服務器的內容,所以我們需要找到org.apache.jasper.runtime.HttpJspBase這個類,這個類可以到tomcat的安裝目錄下的lib文件夾下找到jasper.jar,將其解壓,找如下目錄:org\apache\jasper\runtime,找到HttpJspBase.class。

          使用反編譯工具打開,如下所示:

          通過觀察源碼,根據我們所學習的繼承關系,我們發現JSP其實底層就是一個servlet。通過觀察源碼,我們發現我們剛剛編寫的所有代碼都在該Servlet里面的service方法內部。

          swift復制代碼public final class demo01_jsp extends org.apache.jasper.runtime.HttpJspBase {
               
               public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
                throws java.io.IOException, javax.servlet.ServletException {
              try {
                response.setContentType("text/html;charset=UTF-8");
                pageContext = _jspxFactory.getPageContext(this, request, response,
                          null, true, 8192, true);
                _jspx_page_context = pageContext;
                application = pageContext.getServletContext();
                config = pageContext.getServletConfig();
                session = pageContext.getSession();
                out = pageContext.getOut();
                _jspx_out = out;
          
                out.write('\r');
                out.write('\n');
                out.write("\r\n");
                out.write("\r\n");
                out.write("<html>\r\n");
                out.write("<head>\r\n");
                out.write("    <title>Title</title>\r\n");
                out.write("</head>\r\n");
                out.write("<body>\r\n");
                out.write("    ");
                out.write("\r\n");
                out.write("    ");
          
                  //獲取當前系統時間
                  Date d = new Date();
                  //創建日期格式化解析器對象
                  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                  //使用日期格式化解析器對象調用方法格式化日期對象d
                  String s_date = sdf.format(d);
                  //控制臺輸出
                  System.out.println("s_date = " + s_date);
                  //將這個字符串展示在瀏覽器上
                  response.getWriter().print(s_date);
              
                out.write("\r\n");
                out.write("</body>\r\n");
                out.write("</html>\r\n");
              } catch (java.lang.Throwable t) {
                。。。。
            }
          }
          

          總結:

          1.<% %>中書寫的代碼被直接解析成java代碼;

          2.jsp之所以可以編寫html代碼,其實本質上也是類似我們使用Servlet直接輸出的。也就是說底層還是像我們之前做法一樣進行標簽拼接。html部分都被out.write("")方法以字符串的形式拼接,然后響應給瀏覽器;

          3.在這個java文件中有個_jspService,這個方法有兩個參數request,response;

          4.由于我們自己編寫的代碼全部都落入到了service方法內部一開始就已經聲明了request,response,session,application(ServletContext)等對象了,這些對象成為之jsp內置對象。

          3、JSP中書寫java代碼的三種方式

          在JSP頁面的body標簽中,可以直接書寫html代碼和JS代碼。但是,如果在JSP頁面中書寫java代碼。必須遵循固定的格式,才能夠生效;JSP頁面中書寫java代碼有三種方式:1.腳本片段;2.腳本聲明;3.腳本表達式;

          方式一:腳本片段

          腳本片段指的是一段java代碼。書寫格式:<% java 代碼 %>

          【示例】 demo02.jsp

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          <%
              //書寫java代碼,向瀏覽器輸出數據
              response.getWriter().println("hello jsp");
          %>
          </body>
          </html>
          
          

          【被翻譯后的源碼】

          swift復制代碼 out.write("\r\n");
           out.write("    ");
           response.getWriter().println("hello jsp");
           out.write("\r\n");
          

          【頁面結果】:

          方式二:腳本聲明

          erlang復制代碼腳本片段雖然可以嵌入java代碼,但是如果,我們要給當前的jsp中定義一些成員方法或者成員變量,就需要一個新的技術——腳本聲明.
          

          說明:通過查看jsp的源代碼我們發現,腳本片段的代碼都會存在service方法中,而方法中是不可以定義一個方法的。

          腳本聲明的格式:<%! 書寫Java代碼 %>

          【示例一】聲明成員變量 demo03.jsp

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          <%!
              int num = 10;
              public void method(){}
          %>
          </body>
          </html>
          
          

          【被翻譯后的代碼】成員變量

          方式三:腳本表達式

          雖然腳本聲明和腳本片段已經可以書寫Java代碼了,但是如果我們要使用java代碼向頁面輸出一些內容,還是需要 使用原來的response對象,比較繁瑣,因此,我們需要一個更加簡便的方式,可以代替response向頁面輸出內容 ——這個就是腳本表達式。

          腳本表達式的格式:<%= 向瀏覽器輸出的內容 %> 等價于:out.print( 向瀏覽器輸出的內容)

          【示例】在頁面輸出信息

          bash復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          <%="我愛摸魚"%>
          <%="上海程序員摸魚"%>
          <%
          response.getWriter().print("response");
          %>
          </body>
          </html>
          
          

          注意:

          上面代碼中,我們書寫代碼的順序是先:

          arduino復制代碼<%="我愛摸魚"%>
          <%="上海程序員摸魚"%>
          

          再:

          vbscript復制代碼response.getWriter().print("response");
          

          可是瀏覽器查看數據的結果是

          vbscript復制代碼response 我愛摸魚 上海程序員摸魚
          

          原因:response.getWriter()獲取的輸出流是:PrintWriter。而腳本表達式<%=%> 等價于:out.print( 向瀏覽器輸出的內容).并且這種方式獲取的輸出流是:JspWriter。其實導致上述輸出結果前后順序就是PrintWriter和JspWriter。

          JspWriter:將輸出的內容先放到jsp內置的緩沖區中,然后再刷新輸出。

          PrintWriter:是不使用jsp內置的緩沖區,直接將內容寫到網頁中。

          總結:

          1.不要同時使用腳本表達式和response同時往頁面輸出信息,會出現順序不一致。現象:response會出現在最前面。使用一種輸出即可。

          2.腳本表達式<%= str %> :在頁面輸出內容,在service方法中起作用;

          3.腳本片段<% %> :在service方法中,原樣輸出的代碼片段;屬于局部為,放在_jspService方法中

          4.腳本聲明:<%! String str = "程序員" %> :定義成員變量;

          4、JSP的三大指令

          4.1 指令概述

          JSP指令(directive)是為JSP引擎而設計的,它們并不直接產生任何可見輸出效果,而只是告訴引擎如何處理JSP頁面中的其余部分。

          指令用來聲明JSP頁面的一些屬性,比如編碼方式,文檔類型。我們在servlet中也會聲明我們使用的編碼方式和響應的文檔類型的,而JSP就是用指令來聲明的。

          【1】JSP頁面的3大指令

          css復制代碼a)  page:頁面
          <%@page contentType="text/html;charset=utf-8" %>
              說明:聲明jsp頁面的編碼方式
          b)  taglib:引入標簽庫
          c)  include:包含
          

          【2】指令的格式

          swift復制代碼<%@指令名 屬性名="屬性值"%>
          

          4.2 taglib指令

          【作用】

          復制代碼用于在JSP頁面中導入JSTL標簽庫;
          

          【格式】

          ini復制代碼<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          說明:表示引入外部的jstl標簽庫的。
          prefix="c" 表示前綴
          uri="http://java.sun.com/jsp/jstl/core" 表示jstl標簽庫的地址
          

          4.3 include指令

          【作用】

          復制代碼在一個JSP頁面中靜態包含另外一個JSP頁面;
          

          【格式】

          ini復制代碼<%@include file="URL" %> 指定要導入頁面的地址
          

          【使用示例】

          需求:課后的原型中的頁面放到web文件夾下面。然后打開主頁index.jsp.在主頁中引入header.jsp頁面。

          xml復制代碼<!--引入頭部-->
          <div id="header">
              <%@include file="header.jsp"%>
          </div>
          

          【效果】

          小結

          三大指令是什么?分別的作用是?

          1. page:設置網頁上一些屬性
          2. taglib:導入標簽庫
          3. include:包含另一個JSP頁面

          5、page指令

          5.1、page指令概述

          【1】page指令的作用

          page是jsp中必須使用的一個指令,用于設置JSP上各種頁面的屬性,告訴tomcat如何將一個JSP翻譯成Servlet

          【2】語法格式

          css復制代碼<%@page 屬性名="屬性值" %>
          

          可以放在JSP中任何位置,一般建議放在頁面的最頂部

          5.2、page指令的屬性

          【1】導包相關屬性:

          ini復制代碼language="java" 當前頁面使用的語言,不寫默認是java
          import="java.util.*" 導入java.util下所有類,導包
          

          方式一: 每個page指令導入一個類

          less復制代碼<%@page import="java.text.SimpleDateFormat"%>
          <%@page import="java.util.Date"%>
          

          方式二: 一個page指令的import屬性導入所有的包,包之間使用逗號分隔

          ini復制代碼<%@page import="java.util.Date,java.text.SimpleDateFormat"%>
          

          作用:相當于導包

          【代碼演示】

          ini復制代碼<%--<%@ page import="java.util.Date" %>
          <%@ page import="java.text.SimpleDateFormat" %>
          <%@ page import="java.util.ArrayList" %>--%>
          <%@ page import="java.util.*,java.text.SimpleDateFormat" %>
          
          <%--
            Created by IntelliJ IDEA.
            Date: 2018-10-10
            Time: 14:59
            To change this template use File | Settings | File Templates.
          --%>
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          <%
              //創建日期對象
              Date date = new Date();
              SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
              ArrayList<String> list = new ArrayList<>();
          %>
          </body>
          </html>
          
          

          【2】與編碼相關屬性:

          ini復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java"%>
          

          【作用】設置響應編碼

          vbscript復制代碼response.setContentType("text/html;charset=UTF-8");
          

          【3】與錯誤相關

          相關屬性:

          ini復制代碼1、errorPage="錯誤頁面的URL":
              用于指定如果當前頁面出錯,轉發到哪個頁面去:<%@ page language="java"  errorPage="error.jsp"%>
          
          2、isErrorPage="false":默認是false,指定true表示是錯誤頁面
              當前這個頁面是否是一個錯誤頁面,錯誤頁面可以多使用一個內置對象。exception:<%@ page isErrorPage="true"%>
          

          錯誤頁面跳轉的3種設置:

          1、通過page指令的errorPage屬性指定:如果頁面出錯,轉發到error.jsp這個頁面

          ini復制代碼<%@ page errorPage="error.jsp"%>
          

          代碼演示:

          typescript復制代碼<%--跳轉到錯誤頁面--%>
          <%@page errorPage="../error.jsp" %>
          
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          <%
              int i = 1 / 0;
          %>
              hello world
          </body>
          </html>
          
          typescript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <%--聲明是錯誤頁面--%>
          <%@page isErrorPage="true" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h2>錯誤頁面</h2>
              <%=exception.getMessage()%>
          </body>
          </html>
          

          頁面效果:

          2、通過web.xml文件指定錯誤碼:響應狀態碼為404則跳轉到404.jsp頁面

          如果不指定,那么按照以前報錯方式,會出現如下錯誤頁面:

          我們可以在web.xml進行配置跳轉到更加好看一些的頁面。

          xml復制代碼<!-- 指定錯誤頁面 -->
          <error-page>
              <!-- 指定錯誤碼 -->
              <error-code>404</error-code>
              <!-- 出錯以后跳轉到哪個頁面 -->
              <location>/404.jsp</location>
          </error-page>
          

          404.jsp頁面代碼:

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <img src="/404.jpg"/>
          </body>
          </html>
          

          3、通過web.xml文件指定錯誤類型:發生空指針,則跳轉到null.jsp頁面

          xml復制代碼<!-- 指定錯誤的類型 -->
          <error-page>
              <exception-type>java.lang.NullPointerException</exception-type>
              <location>/null.jsp</location>
          </error-page>
          
          

          demo02.jsp

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <%
                  String s = null;
                  s.length();
              %>
          </body>
          </html>
          

          報空指針異常后的頁面:null.jsp

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h2>發生空指針異常了</h2>
          </body>
          </html>
          

          瀏覽器效果:

          page指令小結:

          屬性名

          作用


          language="java"

          指定JSP頁面使用語言


          **import="{package.class

          package.*}"**

          導入包: 1. 每個import包入一個包 2. 一個import導入多個包,使用逗號分隔

          errorPage="relative_url"

          當前頁面出錯,轉發到哪個錯誤頁面


          **isErrorPage="true

          false"**

          當前是否是一個錯誤頁面

          contentType="mimeType [ ;charset=characterSet ]"

          指定頁面類型和編碼,不指定會有亂碼


          **isELIgnored="true

          false"**

          是否忽略EL表達式,true表示EL不起作用

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="true"%>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
          ${3*5}
          </body>
          </html>
          

          6、JSP常用動作標簽

          6.1、什么是動作標簽

          JSP動作標簽利用XML語法格式的標記來控制Servlet引擎的行為 。利用JSP動作標簽可以動態包含其他jsp頁面、把用戶跳轉到另外的頁面、為Java插件生成HTML代碼。

          6.2、常用動作標簽

          JSP頁面動作標簽很多,常用的主要有以下3種:

          makefile復制代碼<jsp:include/>:動態包含
          <jsp:forward/>:跳轉 類似之前學習的轉發技術
          <jsp:param/>:參數設置
          

          6.3、常用標簽使用

          【1】<jsp:include>

          【作用】

          復制代碼用于一個JSP頁面動態包含另一個JSP頁面
          

          【語法】

          ini復制代碼<jsp:include page="URL"/> URL是被包含的JSP頁面
          

          【使用示例】

          a.jsp

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h1>我是A頁面</h1>
              <%int m1=10; %>
          
              <!-- 靜態包含: -->
              <%@include file="b.jsp" %>
          
              <!-- 動態包含 -->
              <%-- <jsp:include page="b.jsp"/> --%>
          </body>
          </html>
          

          b.jsp

          javascript復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h2>我是B頁面</h2>
              <%int m=20; %>
          </body>
          </html>
          

          【動態包含和靜態包含】


          靜態包含include指令

          動態包含include動作

          語法格式

          <%@include file="URL"%>

          <jsp:include page="URL"/>

          包含的方式

          靜態包含包含的是頁面的內容。如果A包含B,則先將B的頁面內容復制到A頁面中,再運行A頁面。 B頁面中不能出現與A頁面同名的變量

          動態包含包含的是頁面的執行結果,如果A包含B,則先將B執行,再將B執行的結果包含到A頁面中,執行A頁面。 B頁面中可以出現與A頁面中同名的變量

          生成Servlet個數

          只能生成了一個Servlet

          生成了兩個Servlet

          說明:

          如果只是引入jsp,不需要改變,那么使用靜態引入。如果引入的jsp頁面是變化的,那么使用動態引入。

          【2】<jsp:forward>

          用于頁面的轉發,與request.getRequestDispatcher("/URL").foward(request,response);功能一樣的

          ini復制代碼<jsp:forward page="URL"/> 轉發
          

          【3】<jsp:param>

          用于給<jsp:forward>和<jsp:include>提供參數

          ini復制代碼<jsp:param value="張三" name="user"/>
          

          forward和param動作

          目標

          1. forward作用
          2. param的功能

          forward

          1. 功能:用于轉發,相當于request.getRequestDispatcher("/URL").forward(request, response)
          2. 語法
          ini復制代碼<jsp:forward page="/頁面地址"/>
          

          param

          1. 功能:給forward和include提供參數名和值
          2. 語法:做為子標簽存在
          3. 需求:在c.jsp頁面中使用轉發標簽forward轉發到d.jsp頁面。
          4. c.jsp頁面
          javascript復制代碼<%--
            Created by IntelliJ IDEA.
            Date: 2018-10-10
            Time: 16:41
            To change this template use File | Settings | File Templates.
          --%>
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h2>c頁面</h2>
              <%
                  //解決中文亂碼問題 <jsp:param name="username" value="張三"/> 是在d.jsp后面攜帶數據跳轉到d.jsp頁面的,通過瀏覽器的,需要先按照UTF-8編碼之后在進行傳遞。然后在d.jsp頁面使用request.getParameter("username")獲取數據
                  request.setCharacterEncoding("UTF-8");
                  //向域對象request中存儲數據
                  request.setAttribute("age",19);
              %>
              <%--轉發動作,攜帶的參數,可以在d.jsp上接收這參數,通過瀏覽器轉發過去的,所以要想獲取param攜帶的數據必須使用getParameter()方法獲取數據--%>
              <jsp:forward page="d.jsp">
                  <jsp:param name="username" value="張三"/>
              </jsp:forward>
          </body>
          </html>
          
          

          d.jsp頁面:

          javascript復制代碼<%--
            Created by IntelliJ IDEA.
            Date: 2018-10-10
            Time: 16:41
            To change this template use File | Settings | File Templates.
          --%>
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h2>d頁面</h2>
              <%--獲取request域對象中的數據--%>
              <%=request.getAttribute("age")%>
              <%--獲取轉發param標簽通過瀏覽器攜帶的數據--%>
              <%=request.getParameter("username")%>
          </body>
          </html>
          
          

          案例演示

          1. 從c.jsp轉發到d.jsp
          2. c在請求域中添加鍵和值,d看能夠得到值并且輸出
          3. c轉發的時候帶參數,username和age,在d中獲取并且輸出
          4. 漢字亂碼問題的解決
          5. 轉發,url地址欄并沒有發生改變

          效果

          小結

          1. forward作用:在JSP頁面上實現轉發
          2. param的功能:在轉發的時候提供其它的參數名和參數值

          7、JSP頁面常用對象

          我們發現,我們在JSP頁面中書寫的代碼最終都會翻譯到_jspService()方法中,我們發現這個方法中有兩個形參:HttpServletRequest對象HttpServletResponse對象 。所以說,JSP的本質就是一個Servlet。我們可以直接在JSP頁面上使用這兩個對象。

          【需求】登錄頁面改造

          改造登錄后的頁面,用戶登陸失敗以后,跳轉到login.jsp,在jsp頁面中動態顯示用戶登陸錯誤中的信息。

          【思路】

          1. 登錄失敗后直接轉發到一個jsp頁面;
          2. 在jsp頁面上使用request對象獲取request中的值;

          【LoginServlet代碼】

          說明:LoginServlet中,登錄失敗之后,直接轉發到login.jsp頁面。

          ini復制代碼protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  //解決中文亂碼問題
                  request.setCharacterEncoding("utf-8");
                  //獲取用戶名和密碼
                  String username = request.getParameter("username");
                  String password = request.getParameter("password");
                  UserServiceInter service = new UserServiceInterImpl();
                  boolean result = service.login(username,password);
                  String msg = result ? "用戶登陸成功" : "用戶登陸失敗";
                  request.setAttribute("msg",msg);
                  if (result){
                      response.sendRedirect("/success.html");
                  }else {
                      //轉發到login.jsp頁面
                      request.getRequestDispatcher("/login.jsp").forward(request,response);
                  }
              }
          

          【login.jsp頁面】

          xml復制代碼<%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="utf-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
              <meta name="viewport" content="width=device-width, initial-scale=1">
              <title>登錄頁面</title>
          
              <link href="css/bootstrap.min.css" rel="stylesheet">
              <link href="css/login.css" rel="stylesheet">
              <script src="js/jquery.js"></script>
              <script src="js/bootstrap.js"></script>
          </head>
          <body>
          <%
              String msg = (String) request.getAttribute("msg");
          %>
          <div class="container text-center">
              <form class="form-signin" action="/loginInterServlet" method="get">
                  <h2 class="form-signin-heading">登錄頁面</h2>
                  <font color="red"><%=msg%></font>
                  <input type="text"  name="username" class="form-control" placeholder="用戶名" required autofocus>
                  <input type="password"  name="password" class="form-control" placeholder="密碼" required>
                  <button class="btn btn-lg btn-primary btn-block" type="submit">登錄</button>
              </form>
          </div>
          </body>
          </html>
          

          說明:上述代碼中:

          css復制代碼<font color="red"><%=msg%></font>
          

          能夠使用msg獲取數據,因為編譯之后存在于同一個類中,編譯jsp如下所示:

          效果圖:瀏覽器訪問login.html頁面

          登錄密碼輸入錯誤:

          小結:

          • JSP作用:給瀏覽器生成響應信息;
          • JSP特點:動態網頁,html+java,由服務器來運行的。本質上是一個Servlet;
          • 書寫Java代碼的三種方式:
            • 腳本片段:java代碼片段,在service方法中起作用。格式:<% System.out.println("hello") %>;
            • 腳本表達式:直接在頁面輸出內容,在service方法中起作用,等價于out.print(內容)。格式:<%= "上海打工摸魚"%>
            • 腳本聲明:定義成員變量,方法。在當前類中都起作用。<%!int a=10;%>
          • JSP頁面常用的對象:request,response;

          壓圖片

          徹底解決亂碼

          1.1 @ResponseBody 注解亂碼

          這種亂碼是由于JSON字符串和對象進行序列號和反序列化的時候用出現的問題,String轉換的時候默認用的編碼是ISO-8859-1。

          解決辦法1: 在 @RequestMapping 請求映射的注解中屬性 produces="text/html;charset=UTF-8"

          解決辦法2: 一勞永逸的辦法 在spring配置中配置下

          <mvc:annotation-driven >

          <mvc:message-converters register-defaults="true">

          <bean class="org.springframework.http.converter.StringHttpMessageConverter">

          <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>

          </bean>

          </mvc:message-converters>

          </mvc:annotation-driven>

          解決辦法3: 如果還不能解決GET出現的亂碼,就在JSP頁面添加配置:

          <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

          1.2 數據庫亂碼

          創建數據庫的時候,一般都會選擇 UTF-8的字符編碼方式來創建數據庫。一般不會出現來亂碼問題,但是在配置 jdbc的時候,不注意沒有添加上配置,也可能出現亂碼:

          jdbc.url= jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8

          1.3 control 層編碼格式問題

          如果使用:request.setCharacterEncoding("UTF-8");

          響應也使用:response.setContentType("application/json;charset=UTF-8");

          1.4 IDE默認編碼問題

          IDEA默認時UTF-8,eclipse則是GBK

          eclipse需要配置下IDE默認編碼: General->Workspace->Text file encoding

          1.5 tomcat 出現亂碼情況

          tomcat 一般會先亂碼情況,但是tomcat也可以配置,可以預防這種亂碼的可能性。 在conf -> server.xml 中進行配置

          <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" /> -

          1.6 tomcat 如還繼續出現亂碼,繼續處理

          這次在啟動腳本中添加 utf-8編碼方案,來徹底解決亂碼問題

          windows catalina.bat:

          set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dfile.encoding="UTF-8"

          linux catalina.sh:

          JAVA_OPTS="-Dfile.encoding=UTF-8"


          臺PHP頁面(頁面編碼為UTF-8或者已經把字符轉為UTF-8)使用json_encode將PHP中的array數組轉為JSON字符串。例如:

          <?php
          $testJSON=array('name'=>'中文字符串','value'=>'test');
          echo json_encode($testJSON);
          ?>

          查看輸出結果為:
          {“name”:”\中\文\字\符\串″,”value”:”test”}
          可見即使用UTF8編碼的字符,使用json_encode也出現了中文亂碼。解決辦法是在使用json_encode之前把字符用函數urlencode()處理一下,然后再json_encode,輸出結果的時候在用函數urldecode()轉回來。具體如下:



          <?php
          $testJSON=array('name'=>'中文字符串','value'=>'test');
          //echo json_encode($testJSON);
          foreach ( $testJSON as $key => $value ) {
          $testJSON[$key] = urlencode ( $value );
          }
          echo urldecode ( json_encode ( $testJSON ) );
          ?>

          查看輸出結果為:

          {“name”:”中文字符串”,”value”:”test”}
          到此,成功地輸出了中文字符。隨意使用json_encode吧。這樣子在PHP后臺輸出的JSON字符串在前臺javascript中Ajax接收后eval出來也不會出現中文亂碼,因為js在處理JSON格式數據是也是以UTF8的形式進行的,與PHP類似,故接收PHP頁面的JSON字符串不會出現問題。


          主站蜘蛛池模板: 国产成人精品一区二区三区免费| 国产吧一区在线视频| 一本大道东京热无码一区| 国产精品一区视频| 亚洲成av人片一区二区三区| 亚洲国产欧美一区二区三区| 久久久91精品国产一区二区三区| 国产精品亚洲一区二区三区| 亚洲日韩国产一区二区三区在线 | 国产免费伦精品一区二区三区| 国产福利一区二区三区在线观看 | 丝袜人妻一区二区三区网站| 在线精品亚洲一区二区| 人妻激情偷乱视频一区二区三区| 精品人妻少妇一区二区三区在线 | 精品亚洲福利一区二区| 波多野结衣久久一区二区| 亚洲一区电影在线观看| 久久久久无码国产精品一区| 亚洲中文字幕无码一区| 中文字幕日韩人妻不卡一区| 香蕉视频一区二区| 久久精品无码一区二区三区日韩| 无码精品人妻一区二区三区免费| 在线精品日韩一区二区三区| 日韩一区二区三区不卡视频| 国产成人一区二区三区精品久久| 手机福利视频一区二区| 在线不卡一区二区三区日韩| 成人精品一区二区激情| 国产福利一区二区| 无码人妻久久一区二区三区蜜桃| 亚洲国产成人久久一区WWW | 亚洲国产成人久久一区WWW | 国产一区二区三区高清在线观看 | 精品国产一区二区三区久久久狼| 在线观看亚洲一区二区| 一区二区三区视频| 精品视频一区在线观看| AV怡红院一区二区三区| 亚洲AV无码一区东京热久久|