jsp学习2(jsp的指令)

jsp的指令

jsp中有三大指令,分别是:

  • page指令,最复杂,也是最常用的
  • include —>静态包含,这个和requestDispatcher.include区别是后者是动态包含
  • taglib -->导入标签库

在jsp文件中使用指令的格式为:<%@指令名 属性名=属性值 %>,这里主要重点讲解page指令的常用属性:

1、pageEncoding和contentType
pageEncoding表示用来设置当前的jsp文件的编码,也即服务端将当前的jsp文件编译成为.java文件的编码。
而contentType则是设置当前的jsp文件的编码,同时会设置响应头Context-Type的编码为这个属性对应的值。
两者的关系是互为补充的,即只要我们设置其中一个属性的值,例如我们设置了pageEncoding的值为utf-8,那么即使我们没有写contentType,那么就会自动设置contentType的值为pageEncoding的值。
如果我们两个属性都没有设置,那么就会默认为iso编码。
2、isErrorPage和errorPage
errorPage的值用来表示如果当前的jsp文件发生了异常,那么就会转发到这个属性对应的jsp文件中。
而isErrorPage则是用来判断当前的jsp文件是否是处理异常的,如果为true,那么当前的jsp文件是处理异常的,此时这个jsp文件就可以使用exception内置对象,但是如果为false,那么这个jsp文件不可以使用exception内置对象。
值得注意的是,如果我们在errorPage值对应的jsp文件中设置了isErroPage属性的值为true,那么运行设置errorPage属性的jsp文件的时候,就会发现接收到的状态码为500,否则,如果errorPage值对应的jsp文件中并没有设置isErrorPage或者值为false,那么运行设置errorPage属性的jsp文件的时候,就会发现接收到的状态码为200。
3、autoFlush和buffer
autoFlush:表示当前的jsp文件的缓冲池满的时候是否会自动刷新,如果为true,则会自动刷新,否则不会,此时满的时候会抛出异常.
buffer:设置jsp文件的缓冲池,默认情况下是8kB.
4、isELIgnore:判断当前的jsp文件是否忽略EL表达式,如果为false,那么不会忽略,即支持EL表达式
5、import:用来导包的,可以在指令中设置多个import属性,也可以将多个import的值写到同一个import中,此时各个值需要用逗号分开。
6、其他:
language:表示当前的jsp文件支持的语言
info:表示信息
isThreadSafe:判断是否支持并发,如果为false,说明不是线程安全,也即支持并发,否则为true,说明线程安全,支持的是单线程。
extends:表示这个jsp文件生成的java文件将会继承extends的值。    

这里主要验证errorPage和isErrorPage:


<!-- error1.jsp -->
<%@ page contentType="text/html;charset=UTF-8" errorPage="error2.jsp"  language="java"%>
<html>
<head>
    <title>验证errorPage属性</title>
</head>
<body>
    <%
        /*
        值得注意的是,如果在处理异常的jsp文件中有设置isErrorPage属性为true的时候,
        那么这时候发送500的状态码.
        但是如果我们没有设置isErrorPage的属性,或者值为false的时候,那么就会将发送
        200的状态码。
        所以说明了,某个jsp文件作为errorPage属性的值的时候(即error2.jsp),这个jsp文件并不一定要求
        设置isErrorPage属性的。但是如果设置了isErrorPage属性为true,那么就可以使用
        jsp中的exception内置对象,否则,如果为false,是不可以使用exception内置对象的。
         */
        int a = 10 / 0;//出现异常,将根据errorPage属性,转发导对应的jsp文件
    %>
</body>
</html>

<!-- error2.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
    <title>处理异常的jsp文件</title>
</head>
<body>
<%
    out.println("使用了isErrorPage内置对象,所以可以使用exception内置对象");
    out.println();
    out.println(exception.toString());
%>
    <h1>这是处理异常的jsp文件,出现异常的jsp文件将会转发导这个jsp文件</h1>
</body>
</html>

测试结果:
在这里插入图片描述
如果我们在error2.jsp中没有设置isErrorPage的属性为true,那么这时候状态码就是200.

当然,在web.xml中也可以配置error-page的信息,例如下面的例子:

<error-page>
    <!--
    如果jsp文件中发生了java.lang.ArithmeticException,那么就会转发导
    location对应的jsp文件中
    -->
    <exception-type>java.lang.ArithmeticException</exception-type>
    <location>/jsp/error2.jsp</location>
</error-page>
<error-page>
     <!--如果状态码为500,那么转发导jsp目录下的error2.jsp-->
     <error-code>500</error-code>
     <location>/jsp/error2.jsp</location>
</error-page>

jsp中的include指令是一个静态包含,含有file的属性,对应的值是我们需要请求包含的jsp文件对应的路径.他和requestDispatcher.include的区别是:前者是一个静态包含,并且两个jsp文件将会共同生成一个.java文件,而在requestDispatcher.include中,则是两个servlet对象分别生成2个.java文件,然后将两者的内容进行合并

验证jsp中利用include来静态包含的时候,将2个jsp文件合并到了同一个.java文件中:

<!-- include1.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学习jsp中的include指令</title>
</head>
<body>
    <p>
        jsp中&lt;%@include 属性名=属性值 %&gt;是一个静态包括,<br>
        和requestDispatcher.include的区别是后者是动态包括的。<br>
        并且jsp中的include是将两个jsp文件最后合并成为了一个.java文件,<br>
        而在requestDispatcher.include则是两个jsp文件分别生成对应的.java文件<br>
        然后把两者的结果进行合并的。<br>
    </p>

    <%
        out.print("这是include1");
    %>
    <%@include file="/jsp/include2.jsp" %> <!--file表示请求包括时对应的jsp文件-->
</body>
</html>

<!--include2.jsp-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学习jsp中的include指令</title>
</head>
<body>
    <%
        out.print("这是include2");
    %>
</body>
</html>

测试结果:
在这里插入图片描述
当然在jsp中也有动态标签,例如:

  • jsp:include,动态包含,此时作用和requestDispatcher.include的作用时一样的,并且2个jsp文件分别编译成为.java文件,将内容进行合并而已。对应的格式为:
    <jsp:include page="请求包含的jsp文件路径">
      <!--在这个标签下面,还可以写jsp:param子标签,用于传递参数-->
      <jsp:param name="参数名字" value="参数的值"></jsp:param>
    </jsp:include>
    
  • jsp:forward:用于请求转发,和requestDispatcher.forward的作用一样,同样是留头不留体

测试jsp:include的代码:

<!-- include3.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学习jsp中的动态标签</title>
</head>
<body>
    <p>
       jsp中使用动态标签格式为:&lt;%@jsp:指令 属性名=属性值 %&gt;<br>
       例如我们需要利用jsp的include是动态包括,那么应该是下面的格式:<br>
       &lt;jsp:include page="包含的jsp文件路径" &gt;&lt;/jsp:include&gt;<br>
        这样这两个jsp文件就是动态包含的关系,分别生成对应的.java文件,然后<br>
        将结果进行合并,这时候requestDispatcher.include是一样的效果的。<br>
        此外在这个标签中还可以添加子标签:jsp:param,用于在请求包括中传递的参数<br>
        &lt;jsp:param name="xxx" value = "yyy" &gt;<br>
    </p>
    <%
        out.println("这是include3");
    %>
    <jsp:include page="/jsp/include4.jsp">
        <jsp:param name="username" value="zhangshan"/>
    </jsp:include>
</body>
</html>

<!-- include4.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学习jsp中的动态包括</title>
</head>
<body>
    <%
        String username = request.getParameter("username");
        out.println("这是include4,参数username = " + username);
    %>
</body>
</html>

测试结果:
在这里插入图片描述

jsp中的九大内置对象:

out --->相当于response.getWriter()
request ---> HttpServletRequest
session ---> HttpServletSession
exception ---> Throwable
response ---> HttpServletResponse
application ---> ServletContext
config ---> ServletConfig
page --->表示的是当前的jsp文件,可以使用this,是一个Object对象
pageContext ---> PageContext,表示的是当前的jsp页面和当前的jsp页面中使用的标签之间共享数据

这里主要来将pageContext内置对象。在Servlet中只有三个域对象(request,session,servletContext),但是在jsp中,则有四个域对象,比Servlet多个了pageContext.所以pageContext也有getAttribute,setAttribute,removeAttribute的方法。

  • setAttribute(“xxx”,“xxx_value”,scope),其中的scope表示对应的域对象,需要利用PageContext获取它的静态成员来获得,例如是在request域中设置,则是PageContext.REQUEST_SCOPE(是一个int类型的值)
  • getAttribute(“xxx”,scope):获取scope对应的域对象的xxx的值
  • removeAttribute(“xxx”,scope):删除scope对应的域对象中xxx属性
  • findAttribute(“xxx”):进行全域查找xxx的值,但是从小到大进行查找,pageContext < request < session < application,所以pageContext会优先查找。

此外,pageContext含有方法,可以获取其他的8个内置对象。并且pageContext可以获取其他域对象的属性的值,例如getAttribute(“xxx”,“需要获取的域对象名字”),或者setAttribute(“xxx”,“xxx_value”,“其他的域对象”)

值得注意的是,pageContext还可以进行全域查找findAttribute(“xxx”),从小到大进行查找,如果没有办法在pageContext域中找到xxx的值,那么就会在request中查找,如果还是没有找到,则在session,还是找不到,则在application中。

⭐由于pageContext表示的是当前的jsp页面和当前的jsp页面共享标签的值,所以上面中的功能需要保证代理的域对象是在当前的jsp中