zoukankan      html  css  js  c++  java
  • Jsp入门实战上

    前面讲了servlet入门实践现在开始介绍jsp入门实践,开发环境的搭建请参考我前面的tomcat的文章,jsp入门教程分为上下两部分,第一部分简单讲解:jsp语法的规范,以及三大编译指令,七个动作指令和九大内置对象,生命周期讲解等。

    全部代码下载:链接

    1.jsp简介:

    JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它[1] 是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML(标准通用标记语言的子集)文件(.htm,.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。
    第一个jsp程序:

    1. 在eclipse中建立动态web工程
    2. 在WebContent上右击建立jsp文件
    3. 在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>
    <%
      out.print("hello peace");
    %>
    </body>
    </html>
    
    1. 在浏览器中输入如下:http://localhost:8080/工程名/NewFile.jsp
      显示如下:
      01
    2. JSP作为servlet的变体,jsp的文件会被翻译成servlet文件:文件位置为Tomcat按住给你目录:apache-tomcat-7.0.64/work/Catalina/localhost/stuJsp/org/apache/jsp
      02
      打开java文件可以看到该文件根servlet的文件类似:有_jspInit(),jspDestroy(),_jspService()方法。并将jsp文件中的代码生成了_jspService()方法中的代码
      03

    2.JSP语法:

    2.1.JSP脚本:

        脚本程序,就是为了在HTML中穿插java代码,可以包含任意语法真确的java语句,变量,方法或表达式。生成servlet源码时该处的代码被放到_jspService()方法中

    1. 脚本程序的语法:
      <% 代码片段 %>
      就像第一个jsp程序那样
    <%
      out.print("hello peace");
    %>
    
    1. 注意:脚本中不能出现标签和jsp元素,记住只能写java就行;但是可以穿插写:如下:
    <%
      for(int i=0;i<5;i++)
      {
        out.print("hello peace"+i);
    %>
      <br/>
     <%
       out.print("换行符穿插在中间了,一样会被循环输出");
      }//for循环结束
     %>
    

    2.2.JSP声明:

        一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们。生成servlet源码时该处的代码成为类的属性和方法;

    1. JSP声明的语法:
      <%! declaration; [ declaration; ]+ ... %>
    2. 演示如下:
    <%! private int i=10; %> 
     <%!
        public void test(){
    	 int a=0;
    	 int b=2;
    	 a=a+b;
    	 System.out.print(a);
     }
     %>
    
    1. 查看生成的servlet文件可以知道刚才在jsp声明的变量和方法,成为了相应的属性和方法

    2.3JSP表达式:

        一个JSP表达式中包含的脚本语言表达式,先被转化成String,然后插入到表达式出现的地方,作用相当于脚本中的out(输出)
    由于表达式的值会被转化成String,所以您可以在一个文本行中使用表达式而不用去管它是否是HTML标签。
    表达式元素中可以包含任何符合Java语言规范的表达式,但是不能使用分号来结束表达式。
    生成servlet源码时该处的代码被放到_jspService()方法中

    1. JSP表达式的语法格式
      <%= 表达式 %>
    2. 演示如下:
    <%--在脚本处声明的变量是局部变量不能带有修饰符 --%>
    	<%
    	  String nick="sisi";
    	  int a=10,b=10;
    	%>
    	3.jsp表达式:<br/>
    	<%--表达式可以输出相当于out.write 不需要分号结束--%>
    	  <%=(a-b) %>
    	  <%=nick %>
    	  <hr/>
    

    2.4JSP注释:

        JSP注释不会出现在html的源码中 可以用来注释jsp的代码,html注释会出现在html的源码中;

    1. JSP注释的语法格式:
      <%-- 这里可以填写 JSP 注释 --%>
    2. 演示如下:
     1.jsp注释:<br/>
      <%-- 这些注释不会出现在html的源码中 可以用来注释jsp的代码--%>
    

    3.三大编译指令:

    JSP编译指令用来设置与整个JSP页面相关的属性;
    主要有三大编译指令:

    <%@ page ... %>    定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等
    <%@ include ... %>    包含其他文件
    <%@ taglib ... %>    引入标签库的定义,可以是自定义标签
    

    3.1page指令介绍:

    Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令。

    1. Page指令的语法格式:
      <%@ page attribute="value" %>
    2. 属性:
      04
    3. 演示如下:
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" import="java.util.Random"%>
    

    3.2include指令介绍:(静态包含)

    JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。

    1. Include指令的语法格式如下:
      <%@ include file="url" %>
    2. Include指令中的文件名实际上是一个相对的URL。如果您没有给文件关联一个路径,JSP编译器默认在当前路径下寻找。
    3. 演示如下:
    <%--  1.原理是把被包含的页面(header.jsp)
    的内容翻译到包含页面(index.jsp)中,合并成翻译成一个java源文件,
    再编译运行!!,这种包含叫静态包含(源码包含)
      2.被包含页面中不需要出现全局的html标签了!!!
    (如html、head、body)--%>
    <%@include file="/common/header.jsp"%>
    

    3.3taglib指令介绍:

    JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。

    1. taglib指令的语法:
      <%@ taglib uri="uri" prefix="prefixOfTag" %>
    2. uri为属性确定的标签位置,prefix属性指定标签库的前缀。此处后面会进一步介绍;
    3. 演示如下:
    自己定义的标签库
    <%@ taglib uri="http://rlovep.com" prefix="rlovep" %>
    

    4.七大动作指令介绍:

    动作指令与编译指令不同,编译指令时通知servlet引擎的处理消息,而动作指令只是运行时的动作。编译指令在将JSP编译成Servlet时起作用,而处理指令通常可替换成JSP脚本,它只是JSP脚本的标准化写法。
    (1)JSP:forward 执行页面转向,将请求的处理转发到下一个页面。
    (2)JSP:param 用于传递参数,必须与其他支持参数的标签一起使用
    (3)JSP:include 用于动态引入一个JSP页面
    (4)JSP:plugin 用于下载JavaBean或者Applet到客户端执行
    (5) JSP:useBean 创建一个Javabean实例
    (6) JSP:setProperty 设置JavaBean实例的属性值
    (7)JSP:getProperty 获取JavaBean实例的属性值

    4.1jsp:forward指令

    jsp:forward动作把请求转到另外的页面。jsp:forward标记只有一个属性page。

    1. 语法格式如下所示:
      <jsp:forward page="Relative URL" />
    2. page属性:page属性包含的是一个相对URL。page的值既可以直接给出,也可以在请求的时候动态计算,可以是一个JSP页面或者一个 Java Servlet.
    3. 执行forward指令时,用户请求的地址依然没有发生改变,仍然是一次请求,但页面内容完全变为被forward目标页的内容。执行forward指令转发请求时,客户端的请求参数不会丢失。类似于servlet中的
      getRequestDispatcher("/GetData").forward(request, response);
    4. 可以附带增加额外的请求参数:配合JSP:param动作指令
    <%--转发 jsp:foward
        参数 jsp:param
    <jsp:forward page="/action2.jsp">
    	<jsp:param value="peace" name="name"/>
    	<jsp:param value="123456" name="pass"/>
    </jsp:forward>
    --%>
    

    4.2jsp:include指令(动态包含)

    jsp:include>动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面

    1. 语法格式如下:
      <jsp:include page="relative URL" flush="true" />
    2. 前面介绍过include的编译指令与前面不同的是这里的是动态包含,静态包含是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。如果被包含的页面是jsp一样会另一个生成servlet;
    3. 属性介绍:
      page:被包含页面的url
      flush:布尔属性,定义在包含资源前是否刷新缓存区。
    4. 可以附带增加额外的请求参数:配合JSP:param动作指令
    <%--动态包括 --%>
    动态包括:
    <jsp:include page="/common/header1.jsp">
         <jsp:param value="lucc" name="name"/>
    </jsp:include>
    

    05

    4.3jsp:userBean,setProperty,getProperty指令

    这三个指令都是与JavaBean相关的指令,其中userBean指令用于在JSP页面中初始化一个java实例,setProperty指令用于为JavaBean实例的属性设置值;getProperty指令用于输出JavaBean实例的属性。

    1. jsp:useBean动作简单的语法为:
      <jsp:userBean id="name" class="classname" scope="page|request|session|application"/>
      其中,id属性是JavaBean的实例名,class属性确定JavaBean的实现类。scope属性用于指定JavaBean实例的作用范围。
    2. jsp:setProperty的语法格式:
      <jsp:setProperty name="BeanName" property="propertyName" value="propertyValue"/>
      其中,name属性是要确定JavaBean的实例名,property属性要确定设置属性的属性名,value属性时要确定属性名对应的值。
    3. jsp:getProperty的语法格式:
      <jsp:getProperty name="BeanName" name="propertyName"/>
      其中,name属性时要确定JavaBean的实例名,name属性是指定要获取的属性名对应的值。
    4. 演示如下:
    <%--useBean setProperty getProperty --%>
    <%--创建Student的实例 
    实例名称为student
    属性范围为page
    --%>
    <hr/>
    <jsp:useBean id="student" class="com.rlovep.entity.Student" scope="page"/>
    <%--设置student的name值 --%>
    <jsp:setProperty name="student" property="name" value="peace"/>
    <%--输出 student的name值--%>
    name:<jsp:getProperty name="student" property="name" />
    

    4.3jsp:param,plugin指令

    param用于设置参数值,这个指令本身不能单独使用,因此单独的param指令没有实际意义,param指令可以与以下指令结合使用
    jsp:include jsp:forward jsp:plugin。使用方法上面已经介绍;
    plugin指令主要用于下载服务器端的JavaBean或Applet到到客户端执行,由于程序在客户端执行,因此客户端必须安装虚拟机。该指令用处较少,不做介绍;

    4.4整体演示如下:

    需要建立,action.jsp本文件,以级转发页面action2.jsp,被包含页面/common/header1.jsp,JavaBean:Student类

    <%--转发 jsp:foward
        参数 jsp:param
    <jsp:forward page="/action2.jsp">
    	<jsp:param value="peace" name="name"/>
    	<jsp:param value="123456" name="pass"/>
    </jsp:forward>
    --%>
    <%--动态包括 --%>
    动态包括:
    <jsp:include page="/common/header1.jsp">
         <jsp:param value="lucc" name="name"/>
    </jsp:include>
    <%--useBean setProperty getProperty --%>
    <%--创建Student的实例 
    实例名称为student
    属性范围为page
    --%>
    <hr/>
    <jsp:useBean id="student" class="com.rlovep.entity.Student" scope="page"/>
    <%--设置student的name值 --%>
    <jsp:setProperty name="student" property="name" value="peace"/>
    <%--输出 student的name值--%>
    name:<jsp:getProperty name="student" property="name" />
    

    5. 9大内置对象介绍

    JSP脚本中包含9个内置对象,这9个内置对象都是Servlet API接口的实例,只是JSP规范对他们默认进行了初始化(由JSP页面对应的Servlet的_jspService()方法来创建这些实例)。也就是它们已经是对象,可以直接使用。
    06
    JSP初始化该9个对象的地方可以通过生成的servlet类看到如下:
    07
    request、response两个对象是_jspService()方法的形参,当Tomcat调用该方法时会初始化这两个对象。而page、pageContext、application、config、session、out都是_jspService()方法的局部变量,由该方法完成初始化。

    5.1稍简单再介绍:详细介绍可以观看我的Servlet入门实践

    1. application:javax.servlet.ServletContext的实例,该实例代表JSP所属的Web应用本身,可用于JSP页面,或者在Servlet之间交换信息。常用的方法有getAttribute(StringattName)、setAttribute(String attName , String attValue)和getInitParameter(StringparamName)等。
    2. config:javax.servlet.ServletConfig的实例,该实例代表该JSP的配置信息。常用的方法有getInitParameter(StringparamName)和getInitParameternames()等方法。事实上,JSP页面通常无须配置,也就不存在配置信息。因此,该对象更多地在Servlet中有效。
    3. exception:java.lang.Throwable的实例,该实例代表其他页面中的异常和错误。只有当页面是错误处理页面,即编译指令page的isErrorPage属性为true时,该对象才可以使用。常用的方法有getMessage()和printStackTrace()等。
    4. out:javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流,用于输出内容,形成HTML页面。
    5. page:代表该页面本身,通常没有太大用处。也就是Servlet中的this,其类型就是生成的Servlet类,能用page的地方就可用this。
    6. pageContext:javax.servlet.jsp.PageContext的实例,该对象代表该JSP页面上下文,使用该对象可以访问页面中的共享数据。常用的方法有getServletContext()和getServletConfig()等。这个对象存储了request对象和response对象的引用。application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。PageContext类定义了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext 类。其中一个重要的方法就是removeArribute(),它可接受一个或两个参数。比如,pageContext.removeArribute("attrName")移除四个scope中相关属性,但是下面这种方法只移除特定scope中的相关属性:
      pageContext.removeAttribute("attrName", PAGE_SCOPE);
    7. request:javax.servlet.http.HttpServletRequest的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象里。这是一个常用的对象,获取客户端请求参数必须使用该对象。常用的方法有getParameter(String paramName)、getParameterValues(StringparamName)、setAttribute(String 8. 8/ attrName,Object attrValue)、getAttribute(StringattrName)和setCharacterEncoding(String env)等。
    8. response:javax.servlet.http.HttpServletResponse的实例,代表服务器对客户端的响应。通常很少使用该对象直接响应,而是使用out对象,除非需要生成非字符响应。而response对象常用于重定向,常用的方法有getOutputStream()、sendRedirect(java.lang.String location)等。
    9. session:javax.servlet.http.HttpSession的实例,该对象代表一次会话。当客户端浏览器与站点建立连接时,会话开始;当客户端关闭浏览器时,会话结束。常用的方法有:getAttribute(String attrName)、setAttribute(StringattrName, Object attrValue)等。

    5.2四个域对象:

    1. 四个域对象:
      pageContext-------- page域
      request -------- request域
      session-------- session域
      application --------context域
    2. 域对象作用:
      保存数据 和 获取数据 ,用于数据共享。
    3. 域对象方法:
      setAttribute("name",Object) 保存数据
      getAttribute("name") 获取数据
      removeAttribute("name") 清除数据
    4. 域对象作用范围:
      page域: 只能在当前jsp页面中使用(当前页面)
      request域: 只能在同一个请求中使用(转发)
      session域: 只能在同一个会话(session对象)中使用(私有的)
      context域: 只能在同一个web应用中使用。(全局的)

    5.3 整体演示如下:

    <%@ 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>
    <%--out对象:对应jspwriter
     --%>
    <%
      /* for(int i=0;i<=1024;i++){
    	  out.write("a");
      }
    System.out.println("当前缓存区大小:"+out.getBufferSize());
    System.out.println("剩余缓存区大小:"+out.getRemaining()); */
    //如果不刷新则,123先输出;
    //out.flush();
    response.getWriter().write("123");
    %>
    <%--
    application对象:对应servlet中的context
    存储的属性,是整个应用共享的;同样可以获得配置参数;
     --%>
    <%
    //存储属性
    application.setAttribute("name", "peace");
    %>
    <%=application.getInitParameter("keys") %>
    <%--
    config对象:对应servlet中的config
    用处不是很大
     --%>
     <%=config.getServletName() %>
     <%--
    exception对象:在错误页面中有效,可以获得异常属性
    亲发生错误:该对象只有当编译指令page的isErrorPage="true"才有效
    <%=exception.getMessage() %>
     --%>
     <%--
    request对象:对应servlet中的request
     --%>
     <%=request.getLocalName() %>
     <%--
    response对象:对应servlet中的response
     --%>
    <%
    	response.getWriter().println("hello respose");
    %>
    <%--
    session对象:对应servlet中的session
     --%>
     <%
     	session.setAttribute("pass", "567");
     %>
     <%--
    pagecontext对象:jsp的页面对象
    可以获得其他八个对象:
     --%>
     <%
     	//获得其他对象
        response.getWriter().write("是否相等?"+(out==pageContext.getOut())+"<br/>");
     %>
     <%--可以往不同的域中存对象 --%>
     <%
     	pageContext.setAttribute("message", "wang");
     	pageContext.setAttribute("age", "22", PageContext.REQUEST_SCOPE);
     	pageContext.setAttribute("qq", "374126165", pageContext.SESSION_SCOPE);
     	pageContext.setAttribute("tl","1881679",pageContext.APPLICATION_SCOPE);
     	//重定向到另一个页面取得数据:
     	response.sendRedirect(request.getContextPath()+"/pageget.jsp");
     	//删除存储的对象
     	pageContext.removeAttribute("age",PageContext.REQUEST_SCOPE );
     %> 
    </body>
    </html>
    

    6.JSP生命周期讲解:

    理解JSP底层功能的关键就是去理解它们所遵守的生命周期。JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。

    6.1JSP执行过程:

    访问:http://localhost:8080/工程名/NewFile.jsp

    1. 访问到NewFile.jsp页面,tomcat扫描到jsp文件,在/work/Catalina/localhost/stuJsp/org/apache/jsp把jsp文件翻译成java源文件
      (NewFile.jsp -> NewFile_jsp.java) (翻译)
    2. tomcat服务器把java源文件编译成class字节码文件 (编译)
      (NewFile_jsp.java ->NewFile_jsp.class)
    3. tomcat服务器构造NewFile_jsp类对象
    4. tomcat服务器调用NewFile_jsp类里面方法,返回内容显示到浏览器。

    第一次访问jsp:走(1)(2)(3)(4)
    之后的访问:走(4)
    注意:jsp文件修改了或jsp的临时文件被删除了,要重新走翻译(1)和编译(2)的过程

    6.2JSP生命周期:

    1. JSP编译:
      当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。编译为servlet;
    2. JSP初始化:
      容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。你可以重写该方法:在jsp声明段
    <%! 
    public void jspInit(){
        initVar++;
       System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
    }
    %>
    
    1. JSP执行:
      这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。每一次服务请求都会执行_jspService()方法。
    2. JSP清理:
      JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切,一般只有在容器停止部署该工程才执行:jspDestroy()方法 你可以进行重写
    <%!
     public void jspDestroy(){ 
              destroyVar++;   
            System.out.println("jspDestroy(): JSP被销毁了"+destroyVar+"次"); 
      } %>
    
    1. JSP与servlet的生命周期对比
    Servlet的生命周期:
        1)构造方法(第1次访问)
        2)init方法(第1次访问)
        3)service方法
        4)destroy方法
    Jsp的生命周期:
        1)翻译: jsp->java文件
        2)编译: java文件->class文件(servlet程序)
        3)构造方法(第1次访问)
        4)init方法(第1次访问):_jspInit()
        5)service方法:_jspService()
        6)destroy方法:_jspDestroy()
    

    6.3演示如下:

    <%@ 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>
    <%! 
      //记录执行次数:
      private int initVar=0;
      private int serviceVar=0;
      private int destroyVar=0;
    %>
    <%!
      public void jspInit(){
        initVar++;
        System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
      }
      public void jspDestroy(){
        destroyVar++;
        System.out.println("jspDestroy(): JSP被销毁了"+destroyVar+"次");
      }
    %>
    <%
      serviceVar++;//
      System.out.println("_jspService(): JSP共响应了"+serviceVar+"次请求");
      //对各个的执行次数计数
      String content1="初始化次数 : "+initVar;
      String content2="响应客户请求次数 : "+serviceVar;
      String content3="销毁次数 : "+destroyVar;
    %>
    <%-- 输出显示 --%>
    <h1><%=content1 %></h1>
    <h1><%=content2 %></h1>
    <h1><%=content3 %></h1>
    </body>
    </html>
    

    显示如下:
    08
    来自一条小鲨鱼wpeace(rlovep.com)

  • 相关阅读:
    2019南昌网络赛-I(单调栈+线段树)
    poj3250(单调栈模板题)
    poj2528(线段树+离散化)
    poj2828(线段树查找序列第k小的值)
    Seikimatsu Occult Tonneru(网络流,状态数(建不建边)不多时,可考虑直接进行枚举
    A. Coffee Break(思维题,类似于邻接表的head数组用法)
    E. Paint the Tree(树形dp)
    cdq分治学习
    2018SEERC Points and Rectangles (CDQ分治)
    SEERC 2018 Inversion
  • 原文地址:https://www.cnblogs.com/onepeace/p/5039240.html
Copyright © 2011-2022 走看看