【修真院小课堂】 JSP基本知识
大家好,我是IT修真院西安分院第2期学员,一枚正直善良的java程序员。
今天给大家分享一下,修真院官网java任务二中可能会使用到的知识点:
Servlet和Jsp
一、servlet简介
广义上讲,servlet是一个接口,它定义了一个服务端应用程序的类初始化要做什么,接收到请求时做什么,和销毁是做什么。实现这个接口的就是servleit,但这并不是我们平时所说的那个servlet,我们平时说的servlet是HttpServlet,它继承了GenericServlet,而GenericServlet实现了servlet。
servlet还有自己的生命周期,由容器(比如tomcat)控制,包括一个servlet的实例创建(1.调用构造方法)、初始化(2.调用init方法)、处理请求(3.service方法)、容器关闭是销毁自己(4.destroy方法)。
public interface Servlet { void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); void destroy(); }就一般我们后端开发而言,可以认为一个类继承了HttpServlet,不管是孙子还是曾孙,那么他就是servlet,
比如我们任务二SpringMvc最核心的一个servlet---DispatcherServlet,他是HttpServlet的三世继承者。
public class DispatcherServlet extends FrameworkServlet {
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
所以我们如果自己做servlet开发,只要写一个Java类实现HttpServlet即可。
HttpServlet作为一个抽象类,可以实现部分方法。我们可以看一下它是如何实现service的
servlet在处理请求时,回调用service方法,而service方法会根据请求的种类来调用不同的方法,比如最常见的POST和GET方法。以下为HttpServlet service方法源码,可以看到它会调用自身的doGet和doPost方法,并将对象HttpServletRequest和 HttpServletResponse传入。期间,Tomcat 作为Servlet容器,负责处理客户请求,把请求内容封装为HttpServletRequest传给Servlet,并将Servlet的响应封装为HttpServletResponse传回给客户。
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); long lastModified; if (method.equals("GET")) { lastModified = this.getLastModified(req); if (lastModified == -1L) { this.doGet(req, resp); } else { long ifModifiedSince = req.getDateHeader("If-Modified-Since"); if (ifModifiedSince < lastModified) { this.maybeSetLastModified(resp, lastModified); this.doGet(req, resp); } else { resp.setStatus(304); } } } else if (method.equals("HEAD")) { lastModified = this.getLastModified(req); this.maybeSetLastModified(resp, lastModified); this.doHead(req, resp); } else if (method.equals("POST")) { this.doPost(req, resp); } else if (method.equals("PUT")) { this.doPut(req, resp); } else if (method.equals("DELETE")) { this.doDelete(req, resp); } else if (method.equals("OPTIONS")) { this.doOptions(req, resp); } else if (method.equals("TRACE")) { this.doTrace(req, resp); } else { String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[]{method}; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(501, errMsg); } }
我们可以根据自己的需求重写doGet/doPost或其他方法。然后在web.xml里配置好你的servlet类,部署到容器中既可以访问了。
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_get_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(405, msg); } else { resp.sendError(400, msg); } }
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_post_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(405, msg); } else { resp.sendError(400, msg); } }
二、Jsp
Jsp引入
1. Servlet的作用: 用java语言开发动态资源(区别于静态页面)的技术;
Jsp的作用:用java语言(+html语言)开发动态资源的技术;
先说结论:Jsp就是servlet 。
2. Jsp的特点
1)jsp的运行必须交给容器(如tomcat)。
一般在tomcat的work目录,存放着tomcat服务器运行时对Jsp解析的文件。
2)jsp页面既可以写html代码,也可以写java代码。
(html页面不能写java代码 。而jsp页面可以写java代码)
3. Jsp的执行过程
问题: 访问http://localhost:8080/day12/01.hello.jsp 如何显示效果?
1)访问到01.hello.jsp页面,tomcat扫描到jsp文件,在%tomcat%/work把jsp文件翻译成java源文件
(01.hello.jsp -> _01_hello_jsp.java) (翻译)
2)tomcat服务器把java源文件编译成class字节码文件 (编译)
(_01_hello_jsp.java -> _01_hello_jsp.class)
3)tomcat服务器构造_01_hello_jsp类对象
4)tomcat服务器调用_01_hello_jsp类里面方法,返回内容显示到浏览器。
由于jsp就是个servlet,它具有servlet拥有的所有方法,所以每次请求都会调用jsp的service方法。
第一次访问jsp:
走(1)(2)(3)(4)
第n次访问jsp:
走(4)
注意:
1)如果jsp文件被修改了或jsp的临时文件被删除了,要重新走翻译(1)、编译(2)的过程
演示:删除jsp解析文件,实时访问观察文件的生成
4. 疑问
问题: 为什么Jsp就是servlet!!!
好问题,首先打开我们jsp解析后的Java文件,
注意到tomcat把我们的success.jsp翻译为了<文件名+下划线+后缀名>的Java类,这个类继承了HttpBase类,这个类大概是tomcat自己类,我们可以尝试按照包名去找一下,在tomcat安装目录lib文件夹下,找到这个包:
用压缩文件器打开它,安照包名一层一层找到类,然后放到我们的Idea的web/class下打开它。
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage { private static final long serialVersionUID = 1L; protected HttpJspBase() { }可以看到它是继承了HttpServlet类的。
jsp翻译的java文件:
public final class _01_hello_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
HttpJspBase类:
public abstract class org.apache.jasper.runtime.HttpJspBase extends javax.servlet.http.HttpServlet implements javax.servlet.jsp.HttpJspPage {
结论: Jsp就是一个servlet程序 。
servlet的技术可以用在jsp程序中,但是jsp的技术并不是全部适用于servlet程序!
5.看看这个类里装了什么
其他的它封装的内容我们先不管,我们先看这里
这个out.write()是servlet向浏览器输出字符流的方法,因为浏览器只认识Html的文本,所以它输出的也是Html文本的。那么如何证明呢,我们不妨先访问这个页面http://localhost:8080/success.jsp(请保持tomcat开启状态),访问成功后点击查看源代码,对比发现是一样的。比如上图它先是向浏览器输出了两个回车,发现页面源代码也是两个回车换行。
By LittleSong
For 小课堂