JSP-讲解(生成java类、静态导入与动态导入)

简介: 一、JSP技术简介JSP是Java Server Page的缩写,它是Servlet的扩展,它的作用是简化网站的创建和维护。 JSP是HTML代码与Java代码的混合体。 JSP文件通常以JSP或JSPX的扩展名。

一、JSP技术简介

JSP是Java Server Page的缩写,它是Servlet的扩展,它的作用是简化网站的创建和维护。
JSP是HTML代码与Java代码的混合体。
JSP文件通常以JSP或JSPX的扩展名。
JSP拥有自己的语法。
JSP形式上像HTML,但本质上是Servlet。
JSP的出现,使得将Web开发中的HTML与业务逻辑代码有效分离成为可能。通常JSP只负责生成动态的HTML文档,而业务逻辑由其他Java组件如JavaBean来实现。JSP可以通过Scriptlet来访问这些组件。
<% %>

Tomcat首次访问JSP的过程图示:

首先来看下,我们用Tomcat发布这个一个web : index.jsp的代码是:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

  </head>

  <body>
    <h1>演示JSP技术</h1>
    <%
        String name = "jack";
        HttpSession s = request.getSession();
        ServletConfig cfig = getServletConfig();
        ServletContext aa = getServletContext();
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        session.setAttribute("a","aabbcc");         
        request.setAttribute("req", "request"); 
     %>
    <h1>这里用文字隔一下</h1>

    <%
        out.println("name="+name);//注解1:上面jsp中定义了name变量,所以这里能访问,至于为什么能访问,去看下底层代码就知道了
        out.println(session.getAttribute("a"));     
     %>

    <br/>
    <!-- 我们在这里就调用sum函数,和输出age -->
    sum=<%=sum(100) %><br/>
    age=<%=age %>

    <%!
    //下面是加了"!"号的内容
        int age = 25;
        int sum(int n){
            int s=0;
            for(int i=0;i<=n;i++){
                s+=i;
            }
            return s;
        }
     %>
  </body>
</html>

运行的结果是这样的:

为什么会这样的呢。我们来看Tomcat帮我们生成的java源代码(无论jsp怎么写,别人访问我们的网站的时候,tomcat会临时去读我们的jsp,然后再生成对应的.java文件):
我的tomcat安装在D盘下,myJspDemo是我的项目名,
D:\apache-tomcat-7.0.30\work\Catalina\localhost\myJspDemo\org\apache\jsp 这个目录下面会生成:index_jsp.java文件,我们打开它,

我只贴出与我刚写的jsp有关的代码图片了,不然太长了。

看完第一张图片,有没有感觉到什么~

再看第二张~~是不是一下子就懂了,原来jsp<% %>中的字符就只是原样写进java代码中啊~

<% %>中的字符是写进servlet()方法中的!!!!

而<%! %>中的字符是写进类的,和方法一个级别,变量就是成员变量!—-用这个有一个好玩的东西哦,自己再写一个servlet进去,覆盖tomcat的 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)类!也就是运行后,自己写的jsp完全不会再运行,只会运行自己的servlet中的内容了(方法名字取和tomcat一样_jspService,里面的变量用HttpServletRequest 的父类,就可以实现覆盖啦)。有趣吧,嘿嘿,不过只是画蛇添足啦,没必要这样,我只是想说明一个,就是用了<%! %>,这个中的变量,方法 的作用域就是整个类了!(写内部类都行)

<%=age %> 底层是把该名翻译成:out.print(age );

静态导入:

在index.jsp的<%! %>之后插入:

 <h2>--从这里开始导入包含页--静态导入,合成一个类,可以共享:局部变量、request和response对象等等</h2>
     <!-- 静态导入: 
     -->
     <%@include file="jsps/a.jsp" %>

/jsps/a.jsp:

这个写出来,myEclipse会报错的,但是没关系,这是myEclipse的智能识别问题,它无法识别那个变量名。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    <h1>a.jsp...开始</h1>
    <%
        out.println("name="+name);  //局部变量,可以访问 
        out.println("age="+age);    //全局变量,可以访问 
        out.println("sum="+sum(100));//方法,可以访问
        out.println(session.getAttribute("a"));//可以访问
    %>
    <h1>a.jsp...结束</h1>

演示结果:


看下tomcat帮我们把这个a.jsp的代码生成到哪了:

很明显,和index.jsp的生成在一个类中了,而且是servlet方法中!

所以,通过这个,我们就很容易理解为什么能够访问到name,age变量和sum()方法了吧。

解释一下:

静态导入其实就是把另外导入的jsp中的代码(相当于除了jsp的头,其他的全部原样拷过来)(采用jsp的方式翻译后的)直接插入到当前 _jspServlet()中的对应的位置!
jsp的方式翻译:html代码(包括html、body等标记、DOCTYPE约束)是采用 out.write()封装。jsp中写的java代码,就原样拷入!

动态导入:

index.jsp中在静态导入演示之后添加:

<h2>以下演示动态导入(包含)---生成两个独立的jsp类,只能够共享:request对象(输出结果是合并成一个页面显示的)</h2>
    <jsp:include page="jsps/b.jsp"></jsp:include>

    <%
        out.println("<br/>");
        out.println("index中的request="+request); 
        out.println("<br/>");
        out.println(request.getAttribute("req")); 
    %>
    <h2>这是index.jsp的结尾</h2>

b.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>这是被动态导入的页面</title>
  </head>

  <body>
    <h1>这是被jsp:include(动态导入)的页面</h1>
    <%
        out.println("b.jsp中的session.getAttribute(a)="+session.getAttribute("a"));
        out.println("<br/>");
        out.println("b.jsp中的request="+request);
        out.println("<br/>");
        out.println(request.getAttribute("req")); 
     %>

  </body>
</html>

演示结果:

index_jsp.java:

可以很明显的看到,b.jsp中内容并没有生成在这里。

而是重新生成了一个类:

自然,b.jsp中的代码是在这个类中生成了,至于为什么不能访问那些局部变量和成员变量,懂Java的人很容易理解了吧!

所以,静态导入和动态导入,
区别是:静态导入不另外生成java类,而是在当前导入的类中生成java代码,而动态导入,会另外再生成java类,这也是为什么访问静态导入的网站运行会比动态导入的网站运行快的原因。
静态导入时导入所有,编译指令会起作用。
而动态导入时被导入页面的编译指令则失去作用,只是插入被导入页面的body内容。

实际应用:

使用包含引入页面统一的元素,如网头和网脚。
使用<%@ include file = url %><jsp:include page=url/>都可以。
使用包含引用用户是否已经登录的验证。
必须使用<%@ include file=url%>静态包含。
因为在同一个servlet中执行了redirect后面的代码将不会再执行。
而动态包含无论目标页面如何操作,都会再返回到源页再执行后面的代码。

JSP的注释语句:

<%- - 在这儿输入注释 - - %>
目录
相关文章
|
2月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
166 57
|
21天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
2月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
70 8
|
2月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
2月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
145 4
|
2月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
90 2
|
2月前
|
Java Android开发
Eclipse 创建 Java 类
Eclipse 创建 Java 类
32 0
|
Java 开发者
Java 基础新特性(静态导入)|学习笔记
快速学习 Java 基础新特性(静态导入)
112 0
|
8天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
48 17
|
19天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者