Servlet進階(一)第一個JSP頁面
前言
本章講解JSP的相關知識之JSP初步
方法
1.概念
在以前我們寫網頁的時候,都是用html進行書寫,這種網頁是靜態的,無法和伺服器進行一個互動,那麼怎麼辦呢?JSP技術應運而生,我們在web開發之中,Java和Jsp可以形成完美的配合,使得html網頁功能更加豐富,下面看一下百度的概念:
JSP全名為Java Server Pages,中文名叫java伺服器頁面,其根本是一個簡化的Servlet設計,它 [1] 是由Sun Microsystems公司倡導、許多公司參與一起建立的一種動態網頁技術標準。JSP技術有點類似ASP技術,它是在傳統的
從上面的描述中我們可以發現,其本質上還是使用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()方法: