常规JSP

  1. JSP页面最终会由容器来生成Servlet类的,比如Tomcat容器生成JSP的Servlet类放在work目录里。因此在JSP里可以用很多简化的语法供容器使用,这篇就来整理一下。

    JSP语法

    • scriptlet:<% %>
      可以在里面写Java代码,如<%out.print("27");%>;
    • 指令:<%@ %>
      可以在页面转换时向容器给出特殊的指示;它有三个指令:page、include和taglib;而指令又有很多属性如import是page的属性:<%@ page import="foo.*,java.util.*"%>;
    • 表达式:<%= %>
      表达式会成为out.println()或out.print()的参数,因此<%=27%>等价于<%out.print(27);%>;
    • 声明:<%! %>
      是JSP转换成Servlet类的声明,因此可以声明类变量(静态变量)、实例变量、方法等;
    • 注释:<%-- %>
      就像Java代码中的注释一样,在把JSP转换成Servlet时会把注释去掉;
  2. 隐式对象

    JSP的隐式对象不仅仅有out,还有一些其他的:

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out;
    final java.lang.Object page = this;
    final javax.servlet.http.HttpServletRequest request;
    final javax.servlet.http.HttpServletResponse response;

    JSP生成的Servlet

    在Tomcat的work目录里我们可以看到由JSP生成的Servlet类,该类继承org.apache.jasper.runtime.HttpJspBase,其中有以下三个方法

    _jspInit()
    _jspDestroy()
    _jspService()

    他们分别由父类的init()、destroy()和service()方法调用;前面都带有"_"号,表明我们不能去覆盖他们,下划线的意思是“不要碰我!”.如我用的是Tomcat7,在JSP中:

    <%! public void _jspDestroy(){
    int i=5;
    }%>

    会报异常:

    org.apache.jasper.JasperException: Unable to compile class for JSP:

  3. 初始化JSP

    通常,我们会把初始化参数分配给单独的servlet或JSP页面。这个指定的servlet或者JSP页面通过ServletConfig的 getInitParameter方法来读取这些参数。但在某些情况下,需要提供系统范围内的初始化参数,任何servlet或者JSP页面可以通过 ServletContext的getInitParameter方法来读取这些初始化参数。但并不推荐这样做,通常是使用MVC架构,在C中非常合适。

    为JSP配置初始化参数是在<servlet>标记中增加一个<jsp-file>元素

    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
    <display-name>Archetype Created Web Application</display-name>
    <context-param>
    <param-name>qq</param-name>
    <param-value>38602359</param-value>
    </context-param>
    <servlet>
    <servlet-name>index</servlet-name>
    <!-- 与Servlet的不同,使用的是jsp-file和URL -->
    <jsp-file>/index.jsp</jsp-file>
    <init-param>
    <param-name>email</param-name>
    <param-value>kevin@oseye.net</param-value>
    </init-param>
    </servlet>
    </web-app>

    而index.jsp

    <%@page import="java.util.Enumeration"%>
    <html>
    <body>
    <h2>Hello World!</h2>
    <%=config.getInitParameter("email")%><br>
    <%=getServletConfig().getInitParameter("email")%><br>
    <%=application.getInitParameter("qq")%><br>
    <%=getServletContext().getInitParameter("qq")%>
    </body>
    </html>

    但输出

    Hello World!
    null
    null
    38602359
    38602359

    可见并为取到JSP的初始化参数,但如果我在web.xml设置<servlet-mapping>就能取到

    <servlet-mapping>
    <servlet-name>index</servlet-name>
    <url-pattern>/index.jsp</url-pattern>
    </servlet-mapping>

    这是为什么呢?没明白,先留着!

  4. JSP属性

    JSP比普通的Servlet多了一个作用域,共有4个作用域

    而pageContext的setAttribute和getAttribute都有重载,就多了一个int类型的作用域设置

    public static final int PAGE_SCOPE = 1;
    public static final int REQUEST_SCOPE = 2;
    public static final int SESSION_SCOPE = 3;
    public static final int APPLICATION_SCOPE = 4;

    只能取到相应的作用域的属性,但pageContext还有一个方法findAttribute,它从最严格的作用域查起,逐步转向不那么严格的作用域,也就是先在请求作用域查找,再查找会话作用域,最后查找应用作用域,只要在一个作用查到就停止。例如

    <html>
    <body>
    <h2>Hello World!</h2>
    <%pageContext.setAttribute("name", "kevin",PageContext.REQUEST_SCOPE); %>
    pageContext: <%=pageContext.getAttribute("name") %><br>
    session: <%=session.getAttribute("name") %><br>
    application: <%=application.getAttribute("name") %><br>
    request: <%=request.getAttribute("name") %><br>
    find: <%=pageContext.findAttribute("name") %><br>
    </body>
    </html>

    输出

    Hello World!
    pageContext: null
    session: null
    application: null
    request: kevin
    find: kevin

  5. page指令

    page指令的属性有import、contentType、isThredSafe、Sessioin、buffer、autoflush、extends、info、errorpage、isErrorPage、language、pageEncoding等。格式:

    <%@ page page_directive_attr_list %>
    1. import属性指定由Servlet导入的package。

      <%@ page import="package.class" %>
    2. isThreadSafe属性控制从JSP页中产生的Servlet是否将实现SingleThreadModel接口。isThreadSafe属性的使用采用以下两种格式之一,前者是缺省的:
      <%@ page isThreadSafe = "True" %>
      <%@ page isThreadSafe = "false" %>
    3. session属性控制页面是否参与HTTP会话。
      –缺省值true,表明页面将加入一个HTTPsession;
      –设置为false,表明不会自动使用任何会话;
    4. buffer属性指明JspWriter的缓冲区大小。buffer属性采用以下两种格式之一:
      <%@ page buffer="sizekb" %>
      <%@ page buffer="none" %>
    5. autoFlush属性配合输出缓冲区 buffer属性使用。控制输出缓冲区在装满时是否应该清除,或者当缓冲区溢出时是否应给出异常处理。
    6. extends属性指定为JSP页生成的Servlet的超类。
      <%@ page extends= "package.class" %>
    7. info属性定义一个通过getServletInfo方法可以从Servlet中检索到的串。
      <%@ page info= "some infomation" %>
    8. isErrorpage属性指明当前页是否能充当其他JSP页面的错误页。缺省值为false。
    9. errorpage属性指明如果抛出一个异常,而异常没有被捕获时,此错误处理所指向的URL。
    10. contentType属性指明字符编码和JSP响应的MIME类型。contentType属性的缺省值为text/html ;charset属性的缺省值为 ISO-8859-1
      <%@ page contentType="TYPE" %>
      <%@ page contentType="TYPE; charset=CHARSET" %>
    11. pageEncoding属性定义了页的编码字符。除非指定page指令的contentType属性,否则缺省值为 ISO-8859-1。
    12. language属性指定将要使用的程序设计语言。

无脚本JSP

使用scriptlet、表达式和声明不仅代码混了难以维护,而且不利于页面设计人员和服务器开发人员的分工合作,因此这里介绍EL(表达式语言)、标准动作和JSTL。

  1. 标准动作
    JSP动作使用格式为:<jsp:标记名>,利用XML语法格式的标记来控制Servlet引擎的行为。这些jsp标签动作元素是在用户请求阶段执行的,这些标准动作元素是内置在jsp文件中的,所以可以直接使用。有以下动作元素

    <jsp:useBean> //定义jsp页面使用一个JavaBean实例;
    <jsp:setProperty> //设置一个JavaBean中的属性值;
    <jsp:getProperty> //从JavaBean中获取一个属性值;
    <jsp:include> //在JSP页面包含一个外在文件;
    <jsp:forward> //清空缓冲区把到达的请求转发另一个页面进行处理;
    <jsp:param> //用于传递参数值;
    <jsp:plugin> //用于指定在客户浏览器中插入插件的属性;
    <jsp:params> //用于向HTML页面的插件传递参数值;
    <jsp:fallback> //指定如何处理客户端不支持插件运行的情况;

    这里要稍作解释JavaBean的概念,到底什么是bean法则呢?
    就是遵循”古老“JavaBeans规范的法则。我们说的是JavaBean,而不是企业JavaBean(EJB),这两个东西完全不相干(要搞清楚)。普通的非企业JavaBean规范定义了一个类怎么才算是JavaBean。尽管这个规范确实很复杂,不过,结合JSP和servlet使用bean时,你只要知道以下规则就行了(只列出了与使用servlet和JSP相关的规则):

    • 必须有一个无参公共构造函数;
    • 必须按命名约定来命名公共的获取方法和设置方法,首先是"get"(或者如果是一个布尔性质,获取方法的前缀是"is")和"set",如getName何setName。要获得性质名,先去掉get和set,并把首字母小写。
    • 设置方法的参数类型和获取方法的返回类型必须一样,如String getName()和void setName(String name)。
    • 性质名和类型是由get和set方法推导得出,而不是得自于类中的一个成员。
    • 结合JSP使用时,性质类型必须是String,或者是一个基本类型。如果不是这样,尽管也许是一个合法的bean,可如此一来,你可能还得使用脚本。

    例如我有一个JavaBean

    package net.oseye;
    
    public class Person{
    private String name;
    private int age; public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getAge() {
    return age;
    }
    public void setAge(int age) {
    this.age = age;
    }
    }

    再servlet的doGet()中

    Person p=new Person();
    p.setName("kevin");
    p.setAge(22); request.setAttribute("person", p); RequestDispatcher view=request.getRequestDispatcher("/index.jsp");
    view.forward(request, response);

    然后在index.jsp中使用脚本可能是这样的

    <%
    Person p=(Person)request.getAttribute("person");
    if(p!=null){
    out.print(p.getName());
    }else{
    out.print("null");
    }
    %>

    而如果使用JSP标准动作是

    <jsp:useBean id="person" class="net.oseye.Person" scope="request" />
    <jsp:getProperty property="name" name="person"/>

    对标准动作的一点点说明(最好查看Tomcat/work目录生成的java文件更好来理解):

    <jsp:useBean id="person" class="net.oseye.Person" scope="request" />
    • id为属性名,class为属性值的类型,scope为属性作用域;
    • 如果属性不存在person,则创建一个新的属性,是class的示例对象;因此它也可以有体来设置性质值
      <jsp:useBean id="person2" class="net.oseye.Person" scope="request">
      <jsp:setProperty property="name" name="person2" value="kevin2"/>
      </jsp:useBean>
      <%=((Person)request.getAttribute("person2")).getName()%>

      带体的只有找不到相应的属性时才创建。

    • 如果建立多态JavaBean的话使用type属性,含义是
      type id=new class();

      type是引用类型,而class为对象类型,因此type可以是接口、抽象类、父类等等,如果没有type其实默认的是type和class一样。如果只有type,而没有class,属性bean必须存在。

    • scope默认为“page”。
    <jsp:param>

    param是用于接收form表单提交的参数,如果表单元素名和JavaBean的性质名不同,则需要使用param,如form表单

    <form method="get" action="http://localhost:8080/mytest/Index">
    <input name="username" type="text" value="Anders" />
    <input type="submit" name="Submit" value="提交" />
    </form>

    在index.jsp中

    <jsp:useBean id="person" class="net.oseye.Person" scope="request">
    <jsp:setProperty property="name" name="person" param="username" />
    </jsp:useBean>

    如果表单的元素名称和JavaBean的姓名相同,就可以省略param参数,如果表单的元素与JavaBean的性质完全匹配还可以在property使用通配符

    <jsp:useBean id="person" class="net.oseye.Person" scope="request">
    <jsp:setProperty property="*" name="person" />
    </jsp:useBean>
  2. EL
    如在表中动作中所说,如果JavaBean的性质类型不是String的话,尽管它是一个合法的JavaBean但仍需要使用脚本,其实还有一种方式就是EL(express language)。EL语法相当简单,格式是:

    ${firstThing.secondThing}

    其中firstThing可以是隐式对象:pageScope、requestScope、sessionScope、applicationScope、pageContext、param、paramValues、header、headerValues、cookie、initParam,或属性
    pageScope属性、requestScope属性、sessionScope属性、applicationScope属性。
    访问映射值或性质时可以使用点号(.),但除了性质和映射值外还有很多的其他特殊的,随意最通用的是中括号([]),如在servlet中

    Person p=new Person();
    p.setName("kevin");
    p.setAge(22);
    request.setAttribute("person", p);
    RequestDispatcher view=request.getRequestDispatcher("/index.jsp");
    view.forward(request, response);

    在JSP中

    <%@page isELIgnored="false" %>
    <html>
    <body>
    ${person.name}<br>
    ${person["name"]}<br>
    ${10+10 }
    </body>
    </html>

    PS:由于版本的不同,可能默认启用了EL,或者默认没启用EL,如果默认没启用需要手动启用,所以第一行不能少的,当然也可以在DD文件中配置。而且EL还可以自定义函数,这点先不深入了。

  3. JSTL
    JSTL全名为JavaServer Pages Standard Tag Library。JSLT标签库,是日常开发经常使用的,也是众多标签中性能最好的。需要添加JSTL的JAR包

    <dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
    </dependency>

    然后在JSP文档中添加声明

    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    然后就可以使用JSTL了

    <c:out value="dddd"></c:out>
    • 常用的标签:如<c:out>、<c:remove>、<c:catch>、<c:set>等;
    • 条件标签:如<c:if><c:when>、<c:choose>、<c:otherwise>等;
    • URL标签:如<c:import>、<c:redirect>和<c:url>等;
    • XML标签:如<xml:out>等;
    • 国际化输出标签:如<fmt:timeZone>等;
    • SQL标签:如<sql:query>、<sql:update>、<sql:transaction>等;

    当然,如果JSTL不够用的话,还可以定制一些JSTL,定制JSTL暂时不深入。

PS:include指令、<jsp:include>标准动作和JSTL的不同:前者是在编译期复制,后者是在执行期复制。

深入JSP学习的更多相关文章

  1. JSP学习网站

    JSP学习网站 http://www.yiibai.com/jstl/ http://www.w3cschool.cc/jsp/jsp-jstl.html

  2. JSP学习笔记

    JSP学习笔记 Jsp网页主要分为Elements与Template Data两部分. Template Data:JSP Container不处理的部分,例如HTML内容 Elements:必须经由 ...

  3. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  4. JSP 学习二

    在基于昨天对JSP学习的基础上,今天我们来学习JSP的指令和JSP 对中文的处理. 一.JSP指令简介 JSP 指令是为JSP引擎而设计,它并不直接产生任何可见的输出,而只是告诉引擎如何处理JSP页面 ...

  5. java web jsp学习笔记--概述-常用语法,指令,动作元素,隐式对象,域对象

     JSP学习笔记 1.什么是jsp JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP/Servlet规范.JS ...

  6. (转) jsp学习笔记

    fromhttp://www.cnblogs.com/tao975/p/4445070.html 什么是JSP JSP的优势 JSP的劣势 JSP与PHP的比较 JSP工作原理 JSP的九大内置对象 ...

  7. jsp学习:jsp学习阶段性总结2019.9.21

    Jsp学习 jsp语法格式: 脚本程序:<% 代码片段 %> jsp声明:<%! declaration; [ declaration; ]+ ... %> 表达式:<% ...

  8. JSP学习(1)

    JSP学习(1) 什么是Web应用程序 可以Web访问呢的应用程序,用户只需要浏览器即可访问 静态网页与动态网页 静态网页:网页中内容固定 动态网页:内容通过程序动态显示,自动更新 Java Web应 ...

  9. JSP学习(4)

    JSP学习(4) JavaBean简介 符合某种规范的Java类.使用JavaBean的好处是解决了代码重复编写,减少代码冗余,功能区分明确,提高代码的可维护性 JavaBean设计原则 JSP动作元 ...

  10. JSP学习(5)

    JSP学习(5) 保存用户状态的两大机制 session对象 Cookie Cookie简介 是Web服务器保存在客户端的一系列文本信息 典型应用 判断注册用户是否已经登录 购物车处理 作用 对特定对 ...

随机推荐

  1. 后台邮箱配置SMTP函数,如何把发件人设置为自定义昵称

    默认的php的mail函数,太坑爹! 用PHPCMS配置好SMTP后,虽然能发送邮件. 但是收件人一项,显示的是邮箱地址@前面的内容. 今天研究了一下午,终于在一个论坛里找到了答案. 原来PHPCMS ...

  2. MFC中在基于对话框的窗体中使用CFileDialog导致菜单栏变灰的解决方案

    CSDN的博客编辑器实在是难用……转战博客园 直接把CSDN发的搬过来了 ————————————————————————————我是分割线———————————————————————————— 第 ...

  3. 天兔(Lepus)监控邮件推送安装配置

    好吧,我承认官网的邮件配置教程我又没看懂,这里记录下我的配置方法 [root@HE3]# vi /usr/local/lepus/test_send_mail.py #!/usr/bin/envpyt ...

  4. easyUI resizable组件使用

    easyUI resizable组件使用: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  5. easyUI draggable组件使用

    easyUI draggable组件使用: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  6. css3 小图标提示特效

    最近的计划,就是每天来几个特效,当然这里有限制,在什么候选区只能放一个,还每天有限制发布的,哎, 啊 终于写完了,看到一个挺好玩的东西,想到能不能用网页的特效做出来,试试呗!不过,一想肯东有很多的 相 ...

  7. Codeforces758B

    B. Blown Garland time limit per test:1 second memory limit per test:256 megabytes input:standard inp ...

  8. 抽象类 abstract 和 接口 interface 类的区别

    在看一些框架的优秀改良时,都会设计一层base层,并且 base里面一般都是 abstract 类,然后 就找了为什么做的原因.发现: PHP5支持抽象类和抽象方法.抽象类不能直接被实例化,你必须先继 ...

  9. 内功心法 -- java.util.ArrayList<E> (3)

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------下文主要对java.util ...

  10. Android安卓身份证识别SDK

    一.Android安卓身份证识别SDK应用背景 这些年,随着互联网金融的极速发展,第三方支付.理财.P2P网贷.征信等APP应用成爆发式的增长,在众多APP中都涉及到对身份证信息的录入,如第三方支付. ...