JavaWeb(三)JSP概述

一、JSP概述

1.1、JSP简介

  一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。JSP是一种Java servlet,主要用于实现JavaWeb应用程序的用户界面部分。

  网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。

  JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。

  简单的说就是:JSP(Java Server Pages)是以Java语言为基础的动态网页开发技术。它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。JSP实际上就是Servlet。

  从特点分析:

    Servlet特点:在Java源码中嵌入html源码

    JSP特点:在html源码中嵌入java代码

  总结分析:servlet:擅长java代码的编写,JSP:擅长页面显示。

JSP就是Servlet

  1)tomcat获得JSP文件后,先将JSP转成servlet,变成xxx.java(servlet源码)

    D:\java\tomcat7.0\apache-tomcat-7.0.53\apache-tomcat-7.0.53\work\Catalina\localhost\test01\org\apache\jsp

       |------------------------------------------------------------------------|   |---------|----------|-------|-----------------|

        tomcat安装目录                    引擎  主机 项目  固定包名  这个之下就是存放着jsp变成的servlet文件.java和编译文件.class 

  2)tomcat将java文件编译成class文件

  3)tomcat运行class文件,并将结果输出到浏览器。 

  注意:  

  JSP页面内容主要包括两部分:

    静态部分:标准的HTML标签、静态的页面内容。这些内容与静态HTML页面同样;     动态部分:受Java程序控制的内容,这些内容由Java脚本动态生成。

  如:

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<html>
<head>
<title>欢迎</title>
</head>
<body>
欢迎学习Java Web知识。如今时间是:
<%out.println(new java.util.Date());%>
</body>
</html>

  当中放在<%和%>之间的代码便是Java脚本,动态部分,这样就把Java代码嵌入HTML页面中,构成一个动态的JSP页面。   

1.2、为什么使用JSP

  JSP程序与CGI程序有着相似的功能,但和CGI程序相比,JSP程序有如下优势:

    1)性能更加优越,因为JSP可以直接在HTML网页中动态嵌入元素而不需要单独引用CGI文件。

    2)服务器调用的是已经编译好的JSP文件,而不像CGI/Perl那样必须先载入解释器和目标脚本。

    3)JSP基于Java Servlet API,因此,JSP拥有各种强大的企业级Java API,包括JDBC,JNDI,EJB,JAXP等等。

    4)JSP页面可以与处理业务逻辑的 Servlet 一起使用,这种模式被Java servlet 模板引擎所支持。

  最后,JSP是Java EE不可或缺的一部分,是一个完整的企业级应用平台。这意味着JSP可以用最简单的方式来实现最复杂的应用。

1.3、JSP工作原理

  分析:  

    JSP文件必须在JSPserver内运行;     JSP文件必须生成Servlet才干运行;     每一个JSP 页面的第一个訪问者速度非常慢,由于要等待JSP编译成Servlet;     JSP页面的訪问者无需安装不论什么client。甚至不须要能够运行Java的运行环境,由于JSP页面输送到client的是标准HTML页面。

1.4、JSP运行流程

  网络服务器需要一个JSP引擎(Tomcat中的JSP引擎就是一个Servlet程序,它负责解释和运行JSP页面。),也就是一个容器来处理JSP页面。容器负责截获对JSP页面的请求使用内嵌JSP容器的Apache来支持JSP开发。

  JSP容器与Web服务器协同合作,为JSP的正常运行提供必要的运行环境和其他服务,并且能够正确识别专属于JSP网页的特殊元素。

  JSP处理流程:  

     就像其他普通的网页一样,您的浏览器发送一个HTTP请求给服务器。Web服务器识别出这是一个对JSP网页的请求,并且将该请求传递给JSP引擎。通过使用URL或者.jsp文件来完成。

    JSP引擎从磁盘中载入JSP文件,然后将它们转化为servlet。这种转化只是简单地将所有模板文本改用println()语句,并且将所有的JSP元素转化成Java代码。JSP引擎将servlet编译成可执行类,并且将原始请求传递给servlet引擎。

    Web服务器的某组件将会调用servlet引擎,然后载入并执行servlet类。在执行过程中,servlet产生HTML格式的输出并将其内嵌于HTTP response中上交给Web服务器。Web服务器以静态HTML网页的形式将HTTP response返回到您的浏览器中。

    最终,Web浏览器处理HTTP response中动态产生的HTML网页,就好像在处理静态网页一样。

     一般情况下,JSP引擎会检查JSP文件对应的servlet是否已经存在,并且检查JSP文件的修改日期是否早于servlet。如果JSP文件的修改日期早于对应的servlet,那么容器就可以确定JSP文件没有被修改过并且servlet有效。

    这使得整个流程与其他脚本语言(比如PHP)相比要高效快捷一些。

    总的来说,JSP网页就是用另一种方式来编写servlet而不用成为Java编程高手。除了解释阶段外,JSP网页几乎可以被当成一个普通的servlet来对待。

1.5、JSP生命周期

  编译阶段:servlet容器编译servlet源文件,生成servlet类。

  初始化阶段:加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法。

  执行阶段:调用与JSP对应的servlet实例的服务方法。

  销毁阶段:调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例。

1.6、简单的使用JSP

  创建一个jsp,查看其转换后的servlet代码。

  1)NewFile.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    faker
</body>
</html>

   2)NewFile_jsp.java

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/7.0.53
 * Generated at: 2017-02-22 02:09:08 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 NewFile_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  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 javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;

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

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
  }

  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 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("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
      out.write("<title>Insert title here</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\tfaker\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { 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);
    }
  }
}

  可以看到public final class NewFile_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent

  NewFile_jsp.java继承自HttpJspBase。来看看HttpJspBase的源码。

  3)HttpJspBase.java

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jasper.runtime;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;

import org.apache.jasper.compiler.Localizer;

/**
 * This is the super class of all JSP-generated servlets.
 *
 * @author Anil K. Vijendran
 */
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
    
    private static final long serialVersionUID = 1L;

    protected HttpJspBase() {
    }

    @Override
    public final void init(ServletConfig config) 
        throws ServletException 
    {
        super.init(config);
        jspInit();
        _jspInit();
    }
    
    @Override
    public String getServletInfo() {
        return Localizer.getMessage("jsp.engine.info");
    }

    @Override
    public final void destroy() {
        jspDestroy();
        _jspDestroy();
    }

    /**
     * Entry point into service.
     */
    @Override
    public final void service(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException 
    {
        _jspService(request, response);
    }
    
    @Override
    public void jspInit() {
    }

    public void _jspInit() {
    }

    @Override
    public void jspDestroy() {
    }

    protected void _jspDestroy() {
    }

    @Override
    public abstract void _jspService(HttpServletRequest request, 
                                     HttpServletResponse response) 
        throws ServletException, IOException;
}

  public abstract class HttpJspBase extends HttpServlet implements HttpJspPage 

  看到了一个熟悉的类,HttpServlet,我们编写Servlet时就是继承自该类,这里也是继承HttpServlet,并且HttpJspBase的源码会发现,

  生命周期也是有init()方法,service()方法,destory()方法,相当于_jspService()方法就是servlet的service()方法的执行,所以说JSP也是一个servlet。

  4)我们在JSP写的所有html代码,都会被转换为servlet中的out.write(html)代码来输出。看图:

1.7、JSP概述总结

  对于jsp转换成的servlet源码,之后我们会在进行详细分析,现在只需要知道jsp中的内容在servlet中被转换成什么了,在哪里被转换了即可。

  注意:jsp 生成java源码,默认第一次生成,之后直接执行,除非内容修改,具体点说,由于JSP只会在客户端第一次请求的时候被编译,因此第一次请求JSP时会感觉比较慢,而之后的请求因为不会编译JSP,

    所以速度就快多了,如果将Tomcat保存的JSP编译后的class文件删除,Tomcat也会重新编译JSP。在开发Web程序的时候经常需要修改JSP,Tomcat能够自动检测到JSP程序的改动,如果检测到JSP源代码发生了改动,

    Tomcat会在下次客户端请求JSP时重新编译JSP,而不需要重启Tomcat,这种自动检测功能默认是开启的,检测改动会消耗少量的时间,在部署web应用程序的时候可以在web.xml中将它关掉。

    这也就是为什么我们能够在jsp页面直接修改内容,而不用重新启动服务器的原因。

    因为JSP就是servlet,那么生命周期也就是跟serlvet一样。

    JSP和servlet有一点区别就在于:jsp是先部署后编译,而servlet是先编译后部署。

  从上面分析得出:    

    Servlet:控制器。重点编写java代码逻辑 (获取表单数据、处理业务逻辑、分发转向)     JSP:代码显示模板。重点在于显示数据

二、JSP基本语法

2.1、JSP模板数据 

   就是JSP中的HTML代码,它的内容给是固定的,无论程序如何运行模版数据输出到客户端浏览器时都不会发生改变,当我们创建一个JSP时,模版就已经固定了。

    元素:JSP中的java部分,包括脚本(JavaScript,或者java代码)以及JSP指令(Directive)与JSP标签(Tag)等,元素决定着程序的流程,元素是不会显示到浏览器的。

2.2、JSP脚本

  1)使用<% 编写java代码 %>,中间java代码必须遵循Java语法

      来看看,jsp变为servlet时的代码是如何编写的

      在JSP中JSP指令(后面会讲):  

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

        这句代码在servlet就变为了:

          response.setContentType("text/html; charset=UTF-8");//这句代码的意思就是通知tomcat和浏览器都使用UTF-8码表,并且发送回浏览器的数据类型是text/html。

          这是有JSP指令中画红色部分代码转变的,而指令中的pageEncoding="UTF-8"的意思是JSP转换为Servlet时采用UTF-8码表编码,因为可能JSP中包含中文。

      对于JSP模版数据来说,就原封不动的使用out.write()来输出到浏览器。

      而对于JSP元素来说,就会变成普通的java代码,因为在servlet中,就可以直接编写java代码。

  2)使用<%=xxx %>来输出结果

      使用<%=result %>来输出结果,servlet中就会将其转换为out.print(result)进行输出。输出各种类型数据:int、double、boolean、String、Object等。

  3)注释   

      <%-- --%>:jsp注释

      // :java单行注释

      /*  */ :Java多行注释

      <!-- -->:这个注释,会发送到浏览器端的源码中显示

      注释分别在servlet中如何显示:

        在servlet中

      总结:JSP注释不会在servlet文件中显示,而java注释则会,但其所有的注释到了浏览器端,都不会出现在源码中,只有<!-- -->这个注释会到浏览器的网页源码中去。

  4)JSP中申明方法与属性(全局变量)  使用<%!  方法、属性%>

      在JSP中编写方法或者属性时,使用<%! %>括起来

  5)在JSP中使用if语句,或者使用for循环,whilt循环等都可以实现,也就是编写脚本而已。 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java Web

使用RESTful风格开发Java Web

REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移),REST 是一种体系结构,而 HTTP 是一种包...

2245
来自专栏java闲聊

Netty入门(一)

在文章开始之前首先明确一个问题,为什么要使用Netty,Netty解决了什么问题,围绕着这个问题我们开始本篇文章的学习

1422
来自专栏AI-vell

java轻量RESTful api服务搭建(jersey+jetty)

由于开始要搭建一个java + python的服务,java端提供数据库增删改查逻辑供python端调用,第一时间想到了用REST(Representation...

4817
来自专栏流柯技术学院

linux下安装rzsz

wget http://freeware.sgi.com/source/rzsz/rzsz-3.48.tar.gz

4701
来自专栏王大锤

iOS AFNetworking “Request failed: unacceptable content-type: text/html”问题

4097
来自专栏技术翻译

使用Spring Cloud Netflix的Kotlin微服务:第2部分

在本系列的第1部分中,我们使用Kotlin介绍了Spring Cloud。我们讨论了Config Server,Discovery Server(Eureka)...

2212
来自专栏Ryan Miao

SpringCloud学习5-如何创建一个服务提供者provider

1273
来自专栏三丰SanFeng

无锁编程(六) - seqlock(顺序锁)

seqlock(顺序锁) 用于能够区分读与写的场合,并且是读操作很多、写操作很少,写操作的优先权大于读操作。 seqlock的实现思路是,用一个递增的整型数表...

2297
来自专栏JMCui

浅析 SpringMVC 原理和配置.

一、原理       Spring MVC基于模型-视图-控制器(Model-View-Controller,MVC)模式实现,它能够帮你构建像Spring框架...

3839
来自专栏后端云

部署实时OpenStack实例

最近的OpenStack nova版本增加了对实时实例的支持,即提供实时应用所需的确定性和性能保证的实例。这项工作在OpenStack Ocata发行版中最终标...

3073

扫码关注云+社区

领取腾讯云代金券