什么是JSP?

  JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。
  JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。JSP虽然是在JAVA上的一种应用,但是依然有其自己扩充的语法,而且在JSP中,所有的JAVA语句都可以使用。

Web服务器是如何调用并执行一个jsp页面的?

  浏览器向服务器发请求,不管访问的是什么资源,其实都是在访问Servlet,所以当访问一个jsp页面时,其实也是在访问一个Servlet,服务器在执行jsp的时候,首先把jsp翻译成一个Servlet,所以我们访问jsp时,其实不是在访问jsp,而是在访问jsp翻译过后的那个Servlet

Jsp最佳实践

  Jsp最佳实践就是jsp技术在开发中该怎么去用。

  不管是JSP还是Servlet,虽然都可以用于开发动态web资源。但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。其原因为,程序的数据通常要美化后再输出:让jsp既用java代码产生动态数据,又做美化会导致页面难以维护。让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做。

Tomcat服务器的执行流程

  

第一次执行:

  1. 客户端通过电脑连接服务器,因为是请求是动态的,所以所有的请求交给WEB容器来处理
  2. 在容器中找到需要执行的*.jsp文件
  3. 之后*.jsp文件通过转换变为*.java文件
  4. *.java文件经过编译后,形成*.class文件
  5. 最终服务器要执行形成的*.class文件

第二次执行:

  1. 因为已经存在了*.class文件,所以不在需要转换和编译的过程

修改后执行:

       1.源文件已经被修改过了,所以需要重新转换,重新编译。

JSP基本语法

JSP基本语法主要包括模板元素/表达式/脚本片断/声明/注释五种形式。

1.模板元素:JSP页面中的HTML内容称之为JSP模版元素。 JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观。

2.表达式:

<%=变量或者表达式%>

注意:JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端。JSP脚本表达式中的变量或表达式后面不能有分号(;)

例如:

 <%= new java.util.Date() %>

3.脚本片断:

1 <% 
2         多行java代码 
3 %>
4 
5 //在<% %>中可以定义变量、编写语句,不能定义方法。

注意事项:

  • JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中。
  • JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号(;)结束。
  • 在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。
  • 多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。如:out.println(x);
    单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句

例如:

 1 <%
 2     int x = 10;
 3     
 4 %>
 5 <p>这是JSP页面文本</p>
 6 <%
 7     out.println(x);
 8     int y = 20;
 9     out.println(y);
10 %>

4.声明

1 <%2       //java代码
3 %>

JSP页面中编写的所有代码,默认会翻译到servlet的service方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面。JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 。 
多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。
JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。

例如:

 1 <%!
 2 static { 
 3     System.out.println("loading Servlet!"); 
 4 }
 5 
 6 private int globalVar = 0;
 7 
 8 public void jspInit(){
 9     System.out.println("initializing jsp!");
10 }
11 %>
12 
13 <%!
14 public void jspDestroy(){
15     System.out.println("destroying jsp!");
16 }
17 %>

5.注释:

1  显式注释:直接使用HTML风格的注释:<!- - 注释内容- ->
2 
3  隐式注释:直接使用JAVA的注释://、/*……*/
4 
5 JSP自己的注释:<%- - 注释内容- -%>

注意:HTML的注释在浏览器中查看源文件的时候是可以看得到的,而JAVA注释和JSP注释在浏览器中查看源文件时是看不到注释的内容的,这就是这三种注释的区别。

JSP指令

JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。主要有page指令,include指令,taglib指令,这里着重介绍前两个。

1 //JSP指令的基本语法格式:
2 <%@ 指令 属性名="值" %>//如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。

例如:

<%@ page contentType="text/html;charset=gb2312" import="java.util.Date"%>

1.page指令

page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置。下面是完整语法:

 1 <%@ page 
 2     [ language="java" ] 
 3     [ extends="package.class" ] 
 4     [ import="{package.class | package.*}, ..." ] 
 5     [ session="true | false" ] 
 6     [ buffer="none | 8kb | sizekb" ] 
 7     [ autoFlush="true | false" ] 
 8     [ isThreadSafe="true | false" ] 
 9     [ info="text" ] 
10     [ errorPage="relative_url" ] 
11     [ isErrorPage="true | false" ] 
12     [ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] 
13     [ pageEncoding="characterSet | ISO-8859-1" ] 
14     [ isELIgnored="true | false" ] 
15 %>

page指令的errorPage属性

  • errorPage属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前Web应用程序的根目录(注意不是站点根目录),否则,表示相对于当前页面
  • 可以在web.xml文件中使用<error-page>元素为整个Web应用程序设置错误处理页面。
  • <error-page>元素有3个子元素,<error-code>、<exception-type>、<location>
  • <error-code>子元素指定错误的状态码,例如:<error-code>404</error-code>
  • <exception-type>子元素指定异常类的完全限定名,例如:<exception-type>java.lang.ArithmeticException</exception-type>
  • <location>子元素指定以“/”开头的错误处理页面的路径,例如:<location>/ErrorPage/404Error.jsp</location>
  • 如果设置了某个JSP页面的errorPage属性,那么在web.xml文件中设置的错误处理将不对该页面起作用。

例如:

使用errorPage属性指明出错后跳转的错误页面比如Test.jsp页面有如下的代码:

复制代码
 1 <%@ page language="java" import="java.util.*" errorPage="/ErrorPage/error.jsp" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4     <title>测试page指令的errorPage属性</title>
 5   </head>
 6   <body>
 7     <%
 8       //这行代码肯定会出错,因为除数是0,一运行就会抛出异常
 9         int x = 1/0;
10     %>
11   </body>
12 </html>
复制代码

  在Test.jsp中,page指令的errorPage属性指明了出错后跳转到"/ErrorPage/error.jsp",error.jsp页面代码如下:

复制代码
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <html>
3   <head>
4     <title>错误信息友好提示页面</title>
5   </head>
6   <body>
7            对不起,出错了,请联系管理员解决!
8   </body>
9 </html>
复制代码

运行结果如下:

  

在web.xml中使用<error-page>标签为整个web应用设置错误处理页面

例如:使用<error-page>标签配置针对404错误的处理页面

web.xml的代码下:

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="3.0" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 7   <display-name></display-name>    
 8   <welcome-file-list>
 9     <welcome-file>index.jsp</welcome-file>
10   </welcome-file-list>
11   
12   <!-- 针对404错误的处理页面 -->
13   <error-page>
14       <error-code>404</error-code>
15       <location>/ErrorPage/404Error.jsp</location>
16   </error-page>
17   
18 </web-app>
复制代码

404Error.jsp代码如下:

复制代码
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4     <title>404错误友好提示页面</title>
 5     <!-- 3秒钟后自动跳转回首页 -->
 6     <meta http-equiv="refresh" content="3;url=${pageContext.request.contextPath}/index.jsp">
 7   </head>
 8   <body>
 9     <img alt="对不起,你要访问的页面没有找到,请联系管理员处理!" 
10     src="${pageContext.request.contextPath}/img/404Error.png"/><br/>
11     3秒钟后自动跳转回首页,如果没有跳转,请点击<a href="${pageContext.request.contextPath}/index.jsp">这里</a>
12   </body>
13 </html>
复制代码

当访问一个不存在的web资源时,就会跳转到在web.xml中配置的404错误处理页面404Error.jsp,如下图所示:

  

关于在web.xml中使用<error-page>标签为整个web应用设置错误处理页面在IE下无法跳转的解决办法

  这里需要注意的是,如果错误页面比较小,那么当访问服务器上不存在的web资源或者访问服务器出错时在IE浏览器下是无法跳转到错误页面的,显示的是ie自己的错误页面,而在火狐和google浏览器下(其他浏览器没有测试过)是不存在注意的问题的。

我们可以通过下面的实验来证明

  在web.xml中配置500错误时的错误友好提示页面

1 <!-- 针对500错误的处理页面 -->
2 <error-page>
3       <error-code>500</error-code>
4       <location>/ErrorPage/500Error.jsp</location>
5 </error-page>

500Error.jsp页面的代码如下:

复制代码
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4     <title>500(服务器错误)错误友好提示页面</title>
 5     <!-- 3秒钟后自动跳转回首页 -->
 6     <meta http-equiv="refresh" content="3;url=${pageContext.request.contextPath}/index.jsp">
 7   </head>
 8   <body>
 9     <img alt="对不起,服务器出错!" 
10     src="${pageContext.request.contextPath}/img/500Error.png"/><br/>
11     3秒钟后自动跳转回首页,如果没有跳转,请点击<a href="${pageContext.request.contextPath}/index.jsp">这里</a>
12   </body>
13 </html>
复制代码

500Error.jsp页面的字节大小

 在IE8浏览器下的运行结果:

  在IE下访问Test.jsp出现500错误后,显示的是ie自己的错误页面,而不是我们定制的那个500错误页面,而在google和火狐下却是可以正常跳转到我们自己定制的那个500错误页面的,如下图所示:

很多人遇到这个问题,而解决这个问题的办法有两种:

1、修改IE浏览器的设置(不推荐)

  操作步骤:在IE【工具】->【Internet选项】->【高级】中勾掉【显示友好http错误提示】

  

  经过这样的设置之后,访问服务器出错后就可以直接跳转到我们定制的500错误页面了,如下图所示:

  

  这种做法需要修改客户端浏览器的配置,不推荐这样的方式。

2.不修改IE浏览器的设置下确保定制的错误页面的大小>1024字节

  修改500Error.jsp,多添加一些内容,让页面的字节数大一些,修改后的500Error.jsp的代码如下:

复制代码
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <html>
 3   <head>
 4     <title>500(服务器错误)错误友好提示页面</title>
 5     <!-- 3秒钟后自动跳转回首页 -->
 6     <meta http-equiv="refresh" content="3;url=${pageContext.request.contextPath}/index.jsp">
 7   </head>
 8   <body>
 9     <img alt="对不起,服务器出错了,请联系管理员解决!" 
10     src="${pageContext.request.contextPath}/img/500Error.png"/><br/>
11     3秒钟后自动跳转回首页,如果没有跳转,请点击<a href="${pageContext.request.contextPath}/index.jsp">这里</a>
12   </body>
13 </html>
复制代码

  也就多加了几个中文,让500Error.jsp多了几个字节,500Error.jsp现在的字节数如下:

  

  在IE下访问,当服务器出错时,就可以正常跳转到500Error.jsp这个定制的错误页面了,如下图所示:

  

  经过测试,当定制的错误页面的size=617bytes时,在IE8下已经可以跳转到定制的错误页面了,其他版本的IE浏览器没有经过测试,不过为了保险起见,定制的错误页面的size最好超过1024bytes。

使用page指令的的isErrorPage属性显式声明页面为错误页面

  如果某一个jsp页面是作为系统的错误处理页面,那么建议将page指令的isErrorPage属性(默认为false)设置为"true"来显式声明这个Jsp页面是一个错误处理页面。

例如:将error.jsp页面显式声明为错误处理页面

复制代码
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isErrorPage="true"%>
 2 <html>
 3   <head>
 4     <title>错误信息友好提示页面</title>
 5   </head>
 6   
 7   <body>
 8            对不起,出错了,请联系管理员解决!
 9   </body>
10 </html>
复制代码

  将error.jsp页面显式声明为错误处理页面后,有什么好处呢,好处就是Jsp引擎在将jsp页面翻译成Servlet的时候,在Servlet的 _jspService方法中会声明一个exception对象,然后将运行jsp出错的异常信息存储到exception对象中,如下所示:

  

  由于Servlet的_jspService方法中声明了exception对象,那么就可以在error.jsp页面中使用exception对象,这样就可以在Jsp页面中拿到出错的异常信息了,如下:

  

  如果没有设置isErrorPage="true",那么在jsp页面中是无法使用exception对象的,因为在Servlet的_jspService方法中不会声明一个exception对象,如下所示:

  

  

  Jsp有9大内置对象,而一般情况下exception对象在Jsp页面中是获取不到的,只有设置page指令的isErrorPage属性为"true"来显式声明Jsp页面是一个错误处理页面之后才能够在Jsp页面中使用exception对象。

include指令

语法:

1 @include指令
2 <jsp:include>指令

注意事项:@include可以包含任意的文件,当然,只是把文件的内容包含进来。include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。所以include指令引入通常也称之为静态引入。

语法:<%@ include file="relativeURL"%>,其中的file属性用于指定被引入文件的路径。路径以“/”开头,表示代表当前web应用。

include指令细节注意问题:

  1. 被引入的文件必须遵循JSP语法。
  2. 被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments(片段))作为静态引入文件的扩展名。
  3. 由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)

使用@include可以包含任意的内容,文件的后缀是什么都无所谓。这种把别的文件内容包含到自身页面的@include语句就叫作静态包含,作用只是把别的页面内容包含进来,属于静态包含。

jsp:include指令

  jsp:include指令为动态包含,如果被包含的页面是JSP,则先处理之后再将结果包含,而如果包含的是非*.jsp文件,则只是把文件内容静态包含进来,功能与@include类似。

参考链接

http://www.cnblogs.com/xdp-gacl/p/3764991.html

https://www.cnblogs.com/xdp-gacl/p/3776512.html

https://www.cnblogs.com/xdp-gacl/p/3778993.html

posted on 2019-03-05 09:27  小白coder  阅读(841)  评论(0编辑  收藏  举报