javaweb回顾第七篇jsp

1:为什么会有JSP

jsp全名(java server pages)中文叫做java服务器页面。在Servlet那一篇我们发现用Servlet可以生成动态页面,但是我们却在Servlet中却写了大量的html标签,此外在Servlet中我们不得不将大量静态显示内容和动态生产内容混合在一起,使得我们网页编辑人员和程序员无法一起进行研发,这样会大大增加开发的效率,有人会说为什么不用ajax,因为在那个时候并没有ajax。所以为了克服这些问题,SUN公司就推出了JSP。

2:JSP的运行机制

我们先来写一个非常简单的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>jsp</title>
</head>
<body>
<%
  out.print("Hello Jsp");
%>
</body>
</html>

 这是一个非常普通的jsp如果我们打开tomcat服务器然后在服务器输入http://localhost:8080/jsp-test/index.jsp它就会显示Hello Jsp

当然这不是我说的重点,然后我们打开jsp编译后的文件(位置在.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\jsp-test\org\apache\jsp)里面有2个文件一个是index_jsp.java另一个是index_jsp.class。这2个文件就是当我们访问jsp的时候由jsp(web)容器产生。现在我们看下index_jsp.java的内容

package org.apache.jsp;

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

public final class index_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>jsp</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");

  out.print("Hello Jsp");

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

 看到这个页面我相信大家很熟悉,可能会说这不是Servlet吗?我们可以理解成动态的Servlet,其中_jspInit、_jspService、_jspDestroy分别对应的是Servlet中的init、service、destroy,他们具有相同的功能,他的优点显而易见的,就不需要我们在Servlet中去写上面我用黑体加重的代码。这样一来就加快了我们开发的效率。这样一来我们就很容易理解jsp生成的过程。如下图

 然后我们在来分析一下Servlet和Jsp的区别

1:Jsp第一次需要编译成Servlet(只编译一次)

2:Jsp是Java和HTML可以组合成一个扩展名为.jsp的文件而Servlet直接从Html分离出来

3:侧重点不同,SP侧重于视图,Servlet主要用于控制逻辑。

3:JSP语法

3.1:指令元素

指令元素:主要用于为转换阶段提供整jsp页面的相关信息,指令元素不会产生任何的输出到当前的输出流中(说白了就是定义一些关于JSP相关的信息)

3.1.1:page指令

page指令作用于整个jsp页面,定义了许多和页面相关的属性,那么我们来看看这些属性

在我们生成的jsp页面常常会有这条代码<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

这上面几个属性就是指令元素 language表示开发的语言,contentType表示文本类型,charset和pageEncoding都表示编码的格式

在将jsp转成Servlet以后我们可以在_jspService的方法中可以发现response.setContentType("text/html; charset=UTF-8");那么我们在来看其他的指令元素

<%@ page import="" %>这是是导入java的类和我们在开发中引用类的作用是一样的,加入这个指令元素以后生成的Servlet就导入这个类。

<%@ page isELIgnored="true" %>用的比较多,表示是否启动EL表达式 如果是Servlet2.3以前的版本默认是true,2.4以后的版本默认是false

<%@ page session="true" %>是否启动Session 如果是false那么Session在这个jsp就是无效的 默认是true

<%@ page errorPage="" %> 出现错误以后的指向的错误页,此时web.xml配置的对这个就无效了

<%@ page isErrorPage="false" %> 指定这个JSP是否是别的页面的错误页 默认是false

<%@ page buffer="8kb" %> 指定out对象使用缓冲区的大小 默认值为8kb,none就是不设置缓冲区。

当然还有一些指令元素就不一一说了可以自己查阅一下,大家记住这些指令元素的范围只能是当前页面。

3.1.2:include指令

从字面意思我们知道include就是包含的意思,那么这个指令元素到底干嘛的呢,它主要用于JSP页面中静态包括一个文件,这个文件可以是一个html,一个jsp页面,一个文本文件,一段java代码,我们来看看运行结果

先写一个简单的jsp页面

1 <html>
2 <head>
3 <title>我是一个jsp静态文件</title>
4 </head>
5 <body>i am myinclede.jsp
6 </body>
7 </html>

然后我们在index.jsp中引用

1 <%@ include file="myinclude.jsp" %>

运行结果如下

如果要是一段代码呢然后我们把myinclede.jsp修改成如下

 1 <%@ page import="java.util.*" %>
 2 <html>
 3 <head>
 4 <title>我是一个jsp静态文件</title>
 5 </head>
 6 <body>
 7 <%
 8 out.print(new Date().toLocaleString());
 9 %>
10 </body>
11 </html>

我们在此运行结果如下

3.1.3:taglib指令

这个指令用户自定义标签

tablib有三个属性分别是uri、tagdir、prefi,这个在以后的自定义标签中详细讲解(暂时简单介绍)

3.2:脚本元素

 脚本元素包括三个部分分别为声明、脚本段、表达式

3.2.1:声明

这个和在java代码中声明一个变量或方法一样,我们来看下它的写法

<%! int i=1; %>
<% out.print(i); %>

声明以后我们就可以直接使用这个变量了,记住声明要在%后面要加上!

当然你也可以声明一个方法如下

<%! public String getUserName(){
return "zhangsan";
} %>
<% out.print(getUserName());%>

注意:使用<%! %>声明的变量在jsp容器转换成Servlet类是将该类的实例变量或者类变量(声明时会加上static关键字)所以要注意线程安全问题

3.2.2:脚本段

脚本段是在请求处理期间要执行的java代码<% %>里面的代码,这个就不多说了<% out.print(getUserName());%>就算。

3.2.3:表达式

表达式脚本元素是java语言完成的表达式,在请求计算这些完整表达式时会把结果转成字符串,插入当前的输入流中,表达式以<%=开始 %>结束

比喻姓名:<%= "张三"%>这个就是一个表达式(这个后面不需要添加如何符号)

3.3:动作元素

与 JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的。标准的jsp动作元素主要有20种,下面我主要拿常用的说一下

1:<jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>

<jsp:useBean>动作用来加载一个将在JSP页面中使用的JavaBean,它的属性有id为对象对一个名,class指定Bean的完整包名,scope表示这个对象的范围

<jsp:setProperty>主要来设置对象值,其中name就是bean对象名,

<jsp:getProperty>主要来获取对象的,我们来看下例子

public class UserBean {
    private String userName;
    private String realName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }
<body>
    <jsp:useBean id="user" class="com.lp.beans.UserBean" scope="session"></jsp:useBean>
    <jsp:setProperty property="userName" name="user" value="zhangsan" />
    <jsp:setProperty property="realName" name="user" value="张三"/>
    用户名:<jsp:getProperty property="userName" name="user" />
    真实姓名:<jsp:getProperty property="realName" name="user" />
</body>

运行结果:

2:<jsp:forward page=""></jsp:forward>这个和上面那个forward作用相同,跳转地址的。

3:<jsp:include page=""></jsp:include>包含页面,作用上面也有提及

其他的我这里不做提及,现在开发用这个估计是不多了,想了解的可以自己看看

 4:jsp九大内置对象

在Servlet中我们看到有许多对象比喻Request,response等那么Jsp中有吗,我们说过Jsp是动态的Servlet当然会有这些,我们来看看Jsp的9中内置对象

4.1:request

4.2:response

4.3:out,out的对象是JspWriter

4.4:page是jsp转换成Servlet以后的实例object page=this;

4.5:pageContext来获取当前页面所有的属性

4.6:application是javax.servlet.ServletContext的实例。

4.7:config是javax.servlet.ServletConfig实例

4.8:session

4.9:exception这个表示异常处理

这个我们一看应该都会明白

5:对象和范围

jsp4种范围

5.1:request:只在请求一次service有效

5.2:page只在当前页有效,跳出此页就无效

5.3:Session在整个会话期间有效

5.4:application在整个应用程序中有效,知道服务器关闭

 

posted @ 2016-07-31 22:10  朝向远方  阅读(493)  评论(0编辑  收藏  举报