JSP——JSP介绍以及运行原理

24 篇文章 15 订阅
5 篇文章 1 订阅

一. JSP入门

1.1 JSP技术介绍

(1)为什么会出现JSP(Java Server Pages)技术?

程序员在开发过程中,发现Servlet做界面非常不方便,所以产生了jsp技术。JSP其实是对Servlet进行了包装而已。
jsp + java类(service、javabean)+ servlet,就会构成mvc的开发模式,mvc模式是目前软件公司中相当通用的开发模式。

(2)JSP是什么?
1.jsp运行在服务器
2.jsp的基础是Servlet(相当于对Servlet进行了一个包装而已)
3.jsp是一个综合技术,如下公式:

jsp = html + java片段 + JSP标签(语法) + javascript(css)

(3)JSP的特点:

JSP的全称是Java Server Pages,它和Servlet技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。

jsp这门技术的最大的特点在于,写jsp就像在写HTML,但:

  • 它相对于html而言,html只能为用户提供静态数据,而jsp技术允许在页面中嵌套java代码,为用户提供动态数据。
  • 相比Servlet而言,Servlet很难对数据进行排版,而jsp除了可以用java代码产生动态数据的同时,也很容易对数据进行排版。

1.2 快速入门

假设我们要用jsp技术显示当前的时间。
我们在MyEclipse中新建Web项目,名字为JSP1,然后在WebRoot文件夹下,也就是Web应用的根目录下新建jsp文件,命名为showTime.jsp,这个jsp的代码如下:

<%@page import="java.util.Date"%>
<%@page language="java" pageEncoding="UTF-8"%>
<!-- lanuage表示嵌在JSP的的片段语言是什么,pageEncoding表示本页面的编码方式是什么 -->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>showTime</title>
    <!-- 控制让浏览器不要缓存 -->
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">   
    <!-- keywords是让搜索引擎看的 --> 
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <body>
    <% 
        // 在<% 之间可以写我们的Java代码,就和我们在Java文件中写Java代码是一样的
        // 为什么可以直接使用out对象,因为out是jsp的内置对象
        // 内置对象就是不需要我们创建就能使用的对象,jsp有9大内置对象
        out.println("当前时间是:"+new Date().toLocaleString());
     %>
  </body>
</html>

可以看到我们在html的代码中,使用了<% %>符号嵌入了java代码,并且使用了jsp中的out这个内置对象,在jsp中,内置对象就是不需要我们创建就能使用的对象,后面会介绍到jsp有9大内置对象。

【要注意的是】

  • JSP无需配置,直接使用。如果你修改了JSP文件,或者在Web应用新添加了JSP文件,都不需要重新reload该Web应用。
  • 访问方法:http://ip:8080/Web应用名/JSP文件路径

我们访问该jsp页面,可以看到运行结果:

showTime.jsp运行结果

1.3 原理细节分析

1.3.1 Web服务器是如何调用并执行一个jsp页面的?

我们要知道jsp只是对Servlet的一层封装。所以它肯定和Servlet的关系密切。而实际上,Jsp页面也正是先翻译成Servlet,然后再编译加载进内存的。看如下jsp的运行过程:

JSP的运行过程

如果是第一次访问该jsp文件,web服务器就会把showTime.jsp翻译成一个Servlet:showTime_jsp.java,再将其编译成一个showTime_jsp.class,然后把class加载到内存。
如果是第二次或是以后访问,它就会直接访问内存中的实例了。

我们可以在Tomcat的安装目录下找到这个被服务器翻译成的Servlet:showTime_jsp.java。在Tomcat根目录下的work文件夹中,我们一层一层向下找,可以找到如下:

showTime_jsp.java文件

从这个文件夹中,我们可以看到showTime_jsp.java,并且也能看到它编译成的class文件。我们可以打开看一下这个文件的代码,比较复杂但是其实和我们之前写的Servlet差不多,它导入的包也都是servlet的包,然后加上我们用到的java.util.Date包,如下:

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.Date;

我们可以找到最关键的代码,也就是_jspService这个方法:

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("<!-- lanuage表示嵌在JSP的的片段语言是什么,pageEncoding表示本页面的编码方式是什么 -->\r\n");
      out.write("\r\n");
      out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
      out.write("<html>\r\n");
      out.write("  <head>\r\n");
      out.write("    <title>showTime</title>\r\n");
      out.write("    <!-- 控制让浏览器不要缓存 -->\r\n");
      out.write("\t<meta http-equiv=\"pragma\" content=\"no-cache\">\r\n");
      out.write("\t<meta http-equiv=\"cache-control\" content=\"no-cache\">\r\n");
      out.write("\t<meta http-equiv=\"expires\" content=\"0\">   \r\n");
      out.write("\t<!-- keywords是让搜索引擎看的 --> \r\n");
      out.write("\t<meta http-equiv=\"keywords\" content=\"keyword1,keyword2,keyword3\">\r\n");
      out.write("\t<meta http-equiv=\"description\" content=\"This is my page\">\r\n");
      out.write("  </head>\r\n");
      out.write("  <body>\r\n");
      out.write("    ");

        // 在<% 之间可以写我们的Java代码,就和我们在Java文件中写Java代码是一样的
        // 为什么可以直接使用out对象,因为out是jsp的内置对象
        // 内置对象就是不需要我们创建就能使用的对象,jsp有9大内置对象
        out.println("当前时间是:"+new Date().toLocaleString());

      out.write("\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);
    }
  }

可以看到代码中的许多out.write()正是我们所写的jsp页面的内容。这也就印证了我们上面所述的结论:jsp页面是先被服务器翻译成Servlet代码,之后再编译加载进内存运行的。

所以第一次访问一个JSP页面速度比较慢,之后就会变快了。
假设某个JSP文件被修改了,那么之后的再次访问就相当于第一次访问

【注意点】
这里要特别注意的是,因为我们的服务器真正运行的是这个showTime_jsp.java文件,所以如果在测试的时候报错了,是报的这个文件的错,报错指出的错误行也指的是showTime_jsp.java这个文件的错误行,而并不是showTime.jsp这个文件的错误行。这对于我们调试代码很重要!


1.3.2 Jsp页面中的Java代码服务器是如何执行的?

假设我们在一个jsp的文件中写如下代码:

<body>
    <% 
        int i = 90;
        int j = i + 100;
     %>
     <h1>测试</h1>
     <%
        out.println("i="+i+"<br>");
        out.println("j="+j);
      %>
 </body>

可以看到,我们使用了两个<% %>符号嵌入了两段java代码,并且第二段java代码使用了第一段java代码中定义的变量,这样会报错吗?

【答案】:不会的,我们可以查看服务器翻译的对应于这个jsp文件的Servlet文件,找到那个最重要的_jspService方法,就可以看到,这几句代码都在该方法中,而定义的 i 和 j 变量不过是该方法的两个局部变量,当然可以被之后的语句使用了。

【结论】:如果有多个<% %>这样包含的java片段,其实是相当于一个大的java片段,在这中间定义的变量会成为_jspService函数的局部变量。


1.3.3 Web服务器在调用Jsp时,会给Jsp提供一些什么Java对象?

9个内置对象,后面会介绍到。我们现在已经使用了out这个对象,它其实就是相当于Servlet中的PrintWriter对象。

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
JSP(JavaServer Pages)是一种服务器端的动态网页开发技术,它可以将 Java 代码嵌入 HTML 页面中,从而实现动态网页的生成。 JSP 的基本原理是将 JSP 页面翻译成 Servlet,在服务器端执行 Servlet 代码,再将执行结果返回给客户端。因此,我们在使用 JSP 开发网页时,需要先了解 Servlet 的相关知识。 JSP 的语法基本上就是 HTML 标签加上 Java 代码。以下是一些基本的 JSP 标签: 1. <% ... %>:嵌入 Java 代码,可以用于定义变量、写循环、判断语句等。 2. <%= ... %>:输出 Java 代码的执行结果。 3. <%-- ... --%>:注释,不会被翻译成 Servlet。 4. <jsp:include ... />:包含其他 JSP 页面或 HTML 页面。 5. <jsp:forward ... />:将请求转发到其他资源(JSP 页面、Servlet 或 HTML 页面)。 6. <jsp:useBean ... />:创建 JavaBean 对象。 7. <jsp:setProperty ... />:为 JavaBean 对象设置属性。 8. <jsp:getProperty ... />:取得 JavaBean 对象的属性值。 在 JSP 页面中,我们还可以使用 EL 表达式和 JSTL 标签库来简化代码编写,提高开发效率。 EL(Expression Language)表达式是一种简化的表达式语言,可以用于取值、赋值、计算等操作。例如,${name} 表示取得名为 name 的变量的值。 JSTL(JavaServer Pages Standard Tag Library)是一套标签库,提供了循环、条件判断、格式化、国际化等常用功能的标签。例如,<c:forEach> 标签可以用于循环遍历集合,<c:if> 标签可以用于条件判断。 除了以上标签库,JSP 还支持自定义标签库。我们可以通过编写标签处理器来扩展 JSP 的功能。 JSP 的优点是可以将 Java 代码嵌入 HTML 页面中,使得网页的开发更加灵活和方便。但是,由于 JSP 页面需要翻译成 Servlet,因此会增加服务器的负担和响应时间。此外,JSP 页面中夹杂着 Java 代码,也不利于代码的维护和调试。因此,在开发大型网站时,建议使用 MVC 设计模式,将业务逻辑和视图分离,使得代码更加清晰和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值