1. 程式人生 > >Servlet進階(一)第一個JSP頁面

Servlet進階(一)第一個JSP頁面

前言

      本章講解JSP的相關知識之JSP初步

方法

1.概念

在以前我們寫網頁的時候,都是用html進行書寫,這種網頁是靜態的,無法和伺服器進行一個互動,那麼怎麼辦呢?JSP技術應運而生,我們在web開發之中,Java和Jsp可以形成完美的配合,使得html網頁功能更加豐富,下面看一下百度的概念:

JSP全名為Java Server Pages,中文名叫java伺服器頁面,其根本是一個簡化的Servlet設計,它 [1]  是由Sun Microsystems公司倡導、許多公司參與一起建立的一種動態網頁技術標準。JSP技術有點類似ASP技術,它是在傳統的

網頁HTML(標準通用標記語言的子集)檔案(*.htm,*.html)中插入Java程式段(Scriptlet)和JSP標記(tag),從而形成JSP檔案,字尾名為(*.jsp)。 用JSP開發的Web應用是跨平臺的,既能在Linux下執行,也能在其他作業系統上執行。

從上面的描述中我們可以發現,其本質上還是使用html。

2.第一個JSP檔案

相信大家已經看出來了,之前的示例中我用到了一個登入頁面,其就是JSP頁面。

我們可以使用IDEA新建一個JSP頁面,檢視它的組成:

它實質上是這樣的:

<%--
  Created by IntelliJ IDEA.
  User: jwang
  Date: 2018/11/22
  Time: 21:31
  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>
    My First JSP Page
</body>
</html>

 除了<%%>包圍的資料,下面都是純粹的html語句,這樣你就建立了第一個JSP頁面!

我們啟動tomcat,對這個頁面進行訪問!

看到這裡,我跟你講,JSP其實不難,你要是會HTML的相關知識,你已經學會一半了! 

附錄

一、Servlet編寫精要

我們知道,執行servlet時我們一直使用的時doPost()方法和doGet()方法來處理前臺過來的各種請求。其實,我們可以直接通過service()方法直接接收所有請求型別。

更改前面的servlet程式碼如下:

package com.jwang.student.servlet;

import com.jwang.student.bo.User;
import com.jwang.student.service.UserService;
import com.jwang.student.service.impl.UserServiceImpl;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/login.do")
public class UserServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            ServletContext servletContext = request.getSession().getServletContext();
            request.setCharacterEncoding("UTF-8");
            UserService userService = new UserServiceImpl();
            User user = new User("01", username, password);
            if (userService.login(user)) {
                servletContext.setAttribute("username",username);
                response.sendRedirect("/success.jsp");
            } else {
                request.getRequestDispatcher("/login.jsp").forward(request, response);
            }
        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

該方法可以處理前臺的各類請求,我們以後就用這個啦!

如果對於post和get請求有單獨的處理方式,可以選擇之前的方法來進行編寫!

二、JSP原理介紹

從百度的相關介紹我們不難發現,JSP是一個簡要的Servlet,接下來聽我慢慢分析!

拿之前的first.jsp為例,當我們訪問localhost:埠號/first.jsp的時候,其預設執行了一個Servlet!

有同學可能糊塗了,這明明就是一個頁面啊,道理上跟訪問頁面應該沒有什麼區別啊!其實不然!

各位請看,訪問.jsp檔案實質上是走了如下的servlet,開啟我們的tomcat目錄下的web.xml

這就一目瞭然了,當我們執行first.jsp實際上執行了這個servlet:

這個Servlet的作用在於將我們的jsp檔案轉化為Java檔案,其實質上是轉化為了一個Servlet:

讓我們看一下轉化後的first.jsp,開啟tomcat路徑下的work資料夾,大概路徑為:work\Catalina\localhost\ROOT\org\apache\jsp

不難發現,我們的first.jsp被轉化為了first_jso.java,我們開啟這個java檔案一探究竟:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/8.5.35
 * Generated at: 2018-11-22 13:39:38 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class first_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    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\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("    My First JSP Page\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}


我們首先發現了這段程式碼:

這正是Servlet反饋給使用者的頁面啊!也就是我們之前看到的那個!

疑問:既然是小型化的Servlet,那麼應該繼承HttpServlet並重寫service()方法啊,可是我們並沒有看到!

但是我們發現了下面的程式碼:

 我們抱有一絲希望的認為,它的父類應該繼承了相關類並且重寫了方法!讓我們去父類看一下吧!
開啟tomcat目錄下的lib資料夾,使用反編譯工具反編譯jasper.jar,找到父類:
驚喜總是在不經意間發生了!

到這裡我們證明了它的確是一個小型化的Servlet!

細心的同學還可以發現,它父類的service()方法,實質上呼叫的是子類的_jspService()方法: