今天遇到一个有意思的问题,对理解jsp很有帮助(文末附例子)

6 篇文章 0 订阅
5 篇文章 0 订阅

问题是这样的:在一个jsp页面怎么只刷新时间,而不把时间以外的其他部分不刷新。原始代码welcome.jsp大概是这样的:

<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>     
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Spring Boot JSP Example</title>
</head>
<body>
	<h1>Hello, Spring Boot JSP!</h1>
	<%
		
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String date = sdf.format(new Date());
			out.println(date);
			response.setHeader("refresh", "1");
	%>
	
	<p>
		欢迎您,svygh123
	</p>
	<a href="logout.jsp">注销</a>
</body>
</html>

因为代码有了refresh,1,代表了1秒后自动刷新页面,这种页面全局刷新,其实html也有方法实现,就是在header标签下加上以下代码:

<meta http-equiv="refresh" content="1">

而且还可以在后面加上目标页面的地址,就是自动跳转,不加就是刷新本页

response.setHeader("refresh", "1;welcome2.jsp");
<meta http-equiv="refresh" content="1;welcome2.jsp">

要做到局部刷新有2种方法:

第一种方法是用ajaxAsynchronous JavaScript and XML),即异步JavaScript和XML,是一种用于创建更好更快以及交互性更强的Web应用程序的技术。

把打印时间的代码抽离放到一个jsp页面,当做服务端:getServerTime.jsp

<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>获取服务器时间</title>
</head>
<body>
	<%
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String date = sdf.format(new Date());
		out.println(date);
	%>
</body>
</html>

welcome.jsp则改为ajax访问:

<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>欢迎页</title>
</head>
<body>
	<!-- 用一个div显示当前时间 -->
	<div id="nowDiv"></div>
	
	<p>
		欢迎您,svygh123
	</p>
	<a href="logout.jsp">注销</a>
	<script type="text/javascript">
		function getServerTime() {
			var xhr;
			if (window.XMLHttpRequest) {
				// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
				xhr = new XMLHttpRequest();
			} else {
				// IE6, IE5 浏览器执行代码
				xhr = new ActiveXObject("Microsoft.XMLHTTP");
			}
			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4 && xhr.status == 200) {
					document.getElementById("nowDiv").innerHTML = xhr.responseText;
				}
			}
			xmlhttp.open("GET","getServerTime.jsp",true);
			xmlhttp.send();
		}
		
		// 每秒发送一次请求
		setInterval(() => {
			getServerTime();
		}, 1000);
	</script>
</body>
</html>

第二种方法则是将时间显示区域改成iframe,然后刷新iframe:

<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>欢迎页</title>
</head>
<body>
	<iframe id="iframe_id" src="getServerTime.jsp" width="300" height="40" frameborder="0" style="border:none;"></iframe>
	
	<p>
		欢迎您,svygh123
	</p>
	<a href="logout.jsp">注销</a>
	
	<script type="text/javascript">
		// 获取iframe元素
		var iframe = document.getElementById("iframe_id");
	
		// 创建一个定时器函数,让iframe每秒刷新一次
		function refreshIFrame() {
		    // 刷新iframe的内容
		    iframe.contentWindow.location.reload();
		    // 设置定时器,一秒后再次调用刷新函数
		    setTimeout(refreshIFrame, 1000);
		}
	
		// 首次启动定时刷新
		refreshIFrame();
	</script>
</body>
</html>

不过这种方法也会有很明显的刷新痕迹,因此体验最好的还是使用ajax 。

今天的重点是JSP(Java Server Pages),从名字就能理解:java服务器页面。而最终也是这么做的:

核心原理是将HTML、CSS、JavaScript与Java代码混合的JSP页面在运行时转换成Java Servlet,然后执行Servlet来动态生成HTML内容返回给客户端浏览器

以下是JSP的编译过程和原理概述:

JSP编译过程:

  1. 客户端请求

    • 用户通过浏览器发起对JSP页面的请求。
  2. 预处理阶段

    • 当Web服务器接收到对JSP页面的第一次请求时,JSP引擎开始工作。
    • JSP引擎读取JSP文件的内容,并对其进行解析。
    • 解析过程中,将JSP页面中的静态内容(HTML、CSS、JavaScript等)和动态内容(Java代码片段、JSP标签等)分离出来。
    • 动态内容会被翻译成Java代码,比如JSP表达式会被转换成out.println()方法的调用,JSP脚本元素和声明会被转换为Servlet类的方法体。
  3. 编译阶段

    • JSP引擎将预处理阶段生成的Java源代码编译成一个Java Servlet类。
    • 编译后的Servlet类通常会继承自javax.servlet.http.HttpServlet或者专门针对JSP设计的基类(如org.apache.jasper.runtime.HttpJspBase)。
    • 编译得到的Servlet类文件(.java)随后被编译器编译成字节码文件(.class)。
  4. 加载和执行阶段

    • Web容器(如Tomcat)加载编译好的Servlet类,并实例化该类的对象。
    • 当再次收到对该JSP页面的请求时,Web容器调用Servlet对象的生命周期方法(如init()service()等)来处理请求。
    • Servlet根据JSP页面中的原始逻辑,执行必要的业务处理,并动态生成HTML响应内容。
    • 生成的HTML内容随HTTP响应发送回客户端浏览器。
  5. 缓存与重编译

    • 如果JSP页面未发生变化,Web容器会直接使用已编译好的Servlet来处理后续请求,无需重复编译。
    • 若JSP文件被修改,Web容器会检测到文件变动并重新触发编译过程。

看个例子:

我们建一个javaweb项目jsptest,然后新建一个welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
	<%
		out.println("测试理解jsp编译原理");
	%>
</body>
</html>

一般jsp编译会在这个路径能找到:apache-tomcat-8.5.93/work/Catalina/localhost/jsptest(最后是项目名称

启动项目之后是这样的

说明jsp文件还没有编译

访问一下:http://localhost:8080/jsptest/welcome.jsp

再看文件夹

已经编译出来了

welcome_jsp.java核心代码如下:

package org.apache.jsp;

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

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

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

    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>\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta charset=\"UTF-8\">\r\n");
      out.write("<title>首页</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("	");

		out.println("测试理解jsp编译原理");
	
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      ......
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

其中out.write就是响应给客户端的内容,再对照上面的JSP编译过程,更容易理解。

那么springboot内嵌的tomcat,编译的jsp在哪里呢?

问题来源icon-default.png?t=N7T8https://ask.csdn.net/questions/8098969

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

svygh123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值