jsp常见的指令总结
一、三个编译指令
1、page指令:
首先,我们要明确一点就是page指令是一个全局指令,针对当前页面,其次我们再来深挖他的功能,它到底有哪些功能那,在我们程序中起到什么作用???
a、语法结构:<%page %>
b、<%@page language="java"%>:这个属性用于设定jsp的编程语言,目前java是唯一有效的编程语言。
c、<%@page extends=""%>:我们知道jsp的底层其实是Servlet,这里的这个属性就是指我们的这个jsp是继承那个Servlet的。这个我们一般不做修改,默认继承的是HttpJspBase.
d、<%@page erropage=""%>:这个标签的属性指的是当我们的这个jsp页面发生变化的时候,会跳转到我们这个页面。
e、<%@page isErrotpage=""%>:这个属性其实是和errorpage的属性配合使用的,如果我们把它设置成true,则该页面就可以做为错误页面。
f、<%@page contentType="text/html" charset="gb123"%>:这个属性是我们最常用的,用于设置文件格式和编码格式。
g、<%@page session="true"%>:指的是该页面是否可以用到Session对象,说白了就是设置该页面有没有资格参与http会话。
h、<%@page import=""%>:这个属性用来引入我们需要用到的jar包。
i、 <%@page buffer=""%>:指定到客户输出流的缓冲模式。如果为none,则不缓冲;如果指定数值,那么输出就用不小于这个值的缓冲区进行缓冲。与autoFlash一起使用。默认不小于8KB,根据不同的服务器可设置。例如,buffer="64kb"。
j、<%@page autoFlash=""%>:如果为true缓冲区满时,到客户端输出被刷新;如果为false缓冲区满时,出现运行异常,表示缓冲区溢出。默认为true,例如autoFlash="true"。
k、<%@page info=""%>:关于JSP页面的信息,定义一个字符串,可以使用servlet.getServletInfo()获得。 默认省略。例如,info="测试页面"。
l、<%@page isThreadSafe=""%>:用来设置JSP文件是否能多线程使用。如果设置为true,那么一个JSP能够同时处理多个用户的请求;相反,如果设置为false,一个JSP只能一次处理一个请求。例如,isThreadSafe="true"。
m、<%@page pageEncoding=""%>:JSP页面的字符编码 ,默认值为pageEncoding="iso-8859-1",例如pageEncoding="gb2312"。
2、include指令
首先,我们明确这个指令是干啥的??顾名思义,就是包含一个文件的,说白了该指令可以把外部的一个jsp页面加载到当前的jsp页面中,但有一点我们要注意,jsp页面只能解析静态的外部jsp页面。
a、语法结构:<%include file=" "%>:file中添加我们要引入文件的url。
b、一个比较好的Include指令例子就是使用多页面来包含一个通用的头模块和尾模块的内容。
就像这样:
header.jsp
<%! int pageCount = 0; void addCount() { pageCount++; } %> <% addCount(); %> <html> <head> <title>The include Directive Example</title> </head> <body> <center> <h2>The include Directive Example</h2> <p>This site has been visited <%= pageCount %> times.</p> </center> <br/><br/>
footer.jsp
<br/><br/> <center> <p>Copyright © 2010</p> </center> </body> </html>
main.jsp:
<%@ include file="header.jsp" %> <center> <p>Thanks for visiting my page.</p> </center> <%@ include file="footer.jsp" %>
3、taglib指令
a、这个指令是干什么的那???这个指令是引入标签库或者自定义标签库的一个指令。
b、语法结构:<%@taglib uri="" prefix="">
c、自定义taglib标签:
第一步:开发自定义标签类
原理:底层是由标签处理类提供支持,从而实现简单的标签来封装复杂的功能,从而使团队更好的协作开发。
自定义标签类都必须继承一个父类:javax.servlet.jsp.tagext.SimpleTagSupport,或者TagSupport除此之外,JSP自定义标签类还有如下要求。
1)、如果标签类包含属性,每个属性都有对应的getter和setter方法。
2)、重写doTag()或者doStartTag()或doEndTag()方法方法,这个方法负责生成页面内容。
不带属性的标签代码:
public class HelloWorldTag extends TagSupport { private static final long serialVersionUID = -3382691015235241708L; @Override public int doEndTag() throws JspException { try { pageContext.getOut().write("Hello World !"); return super.doEndTag(); } catch (JspException e) { e.printStackTrace(); return 0; } catch (IOException e) { e.printStackTrace(); return 0; } } @Override public int doStartTag() { try { pageContext.getOut().write("Hello World"); return super.doStartTag(); } catch (JspException e) { e.printStackTrace(); return 0; } catch (IOException e) { e.printStackTrace(); return 0; } } }
问题1:tagsupport中的dostartTag和doEndTag这两个方法有什么区别???
doStartTag是在扫描到起始标签时调用,doEndTag是在扫描到结束标签是调用。
例如:<helloWorld> helloWorld</helloWorld>
则jsp引擎分析到<helloWorld> 时调用doStratTag, 分析到</helloWorld>时调用doEndTag
第二步:建立TLD文件
TLD是Tag Library Definition的缩写,即标签库定义,文件的后缀是tld,每个TLD文件对应一个标签库,一个标签库中可包含多个标签,TLD文件也称为标签库定义文件。
标签库定义文件的根元素是taglib,它可以包含多个tag子元素,每个tag子元素都定义一个标签。通常我们可以到Web容器下复制一个标签库定义文件,并在此基础上进行修改即可。例如Tomcat6.0,在webapps\examples\WEB-INF\jsp2路径下包含了一个jsp2-example-taglib.tld文件,这就是示范用的标签库定义文件。
将该文件复制到Web应用的WEB-INF/路径,或WEB-INF的任意子路径下,并对该文件进行简单修改,修改后的helloworld.tld文件代码如下:
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>myhelloworld</short-name> <!-- 定义该标签库的URI 必须添加但可以空--> <uri></uri> <!-- 定义第一个标签 --> <tag> <!-- 定义标签名 --> <name>helloWorld</name> <!-- 定义标签处理类 --> <tag-class>org.lxh.taglib.HelloWorldTag</tag-class> <!-- 定义标签体为空 --> <body-content>empty</body-content> </tag> </taglib>
二、七个动作指令
jsp:forward: 执行页面转向,将请求的处理转发到下一个页面。
jsp:param: 用于传递参数,必须与其他支持参数标签一起使用。
jsp:include: 用于动态引入一个 JSP 页面。
jsp:plugin: 用于下载 JavaBean 或 Applet 到客户端执行。
jsp:useBean: 使用 JavaBean。
jsp:setProperty: 修改 JavaBean 实例的属性值。
jsp:getProperty: 获取 JavaBean 实例的属性值。
1、forward指令
forward指令用于将页面响应转发给另外的页面。既可以转发给静态的HTML页面,也可以转发到动态的JSP页面,或者转发到容器中的Servlet。
JSP的forward指令的格式如下。
对于JSP 1.0,使用如下语法:
<jsp:forward page="{relativeURL|<%=expression%>}"/>
对于JSP 1.1以上,可使用如下语法:
<jsp:forward page="{relativeURL|<%=expression%>}">
{<jsp:param.../>}
</jsp:forward>
第二种语法用于在转发时增加额外的请求参数。增加的请求参数的值可以通过HttpServletRequest类的getParameter()方法获取。
下面示例页面使用了forward动作指令来转发用户请求。
<jsp:forward page="forward-result.jsp">
<jsp:param name="age" value="29"/>
</jsp:forward>
将客户端请求转发到forward-result.jsp页面,转发请求时增加了一个请求参数:参数名为age,参数值为29。
在forward-result.jsp页面中,使用request内置对象(request内置对象是HttpServletRequest的实例)来获取增加的请求参数值。
<!-- 使用request内置对象获取age参数的值 -->
<%=request.getParameter("age")%>
执行forward指令转发请求时,客户端的请求参数不会丢失。
执行forward指令转发请求时,用户请求的地址没有发生变化,但页面内容完全变为被forward目标页的内容。
2、include指令
include指令是一个动态include指令,也用于导入某个页面,它不会导入被include页面的编译指令,仅仅将被导入页面的body内容插入本页面。
下面是include动作指令的语法格式:
<jsp:include page="{relativeURL│<%=expression%>}" flush="true"/>
或者
<jsp:include page="{relativeURL│<%=expression%>}" flush="true">
<jsp:param name="parameterName" value="patameterValue"/>
</jsp:include>
flush属性用于指定输出缓存是否转移到被导入文件中。如果指定为true,则包含在被导入文件中;如果指定为false,则包含在原文件中。对于JSP 1.1旧版本,只能设置为false。
对于第二种语法格式,则可在被导入页面中加入额外的请求参数。
下面页面使用了动态导入语法来导入指定JSP页面。
<!-- 使用动态include指令导入页面 -->
<jsp:include page="scriptlet.jsp" />
上面页面中粗体字代码使用了动态导入语法来导入了scriptlet.jsp。表面上看,该页面的执行效果与使用静态include导入的页面并没有什么不同。但查看jsp-include.jsp页面生成Servlet的源代码,可以看到如下片段:
//使用页面输出流,生成HTML标签内容
out.write("<!DOCTYPE HTML PUBLIC /"-//W3C//DTD HTML 4.0 Transitional//EN/ ">/r/n");
out.write("<HTML>/r/n");
out.write("<HEAD>/r/n");
out.write("<TITLE>jsp-include测试</TITLE>/r/n");
out.write("</HEAD>/r/n");
out.write("<BODY>/r/n");
//动态导入,直接引入scriptlet.jsp页面
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response,
"scriptlet.jsp", out);
out.write("/r/n");
out.write("</BODY>/r/n");
out.write("</HTML>/r/n");
out.write("/r/n");
上面代码片段中粗体字代码显示了动态导入的关键:动态导入只是使用一个include方法来插入目标页面的内容,而不是将目标页面完全融入本页面中。
归纳起来,静态导入和动态导入有如下两点区别:
静态导入是将被导入页面的代码完全融入,两个页面融合成一个整体Servlet;而动态导入则在Servlet中使用include方法来引入被导入页面的内容。
静态导入时被导入页面的编译指令会起作用;而动态导入时被导入页面的编译指令则失去作用,只是插入被导入页面的body内容。
除此之外,执行include动态指令时,还可增加额外的请求参数。
在上面的JSP页面中的粗体字代码同样使用jsp:include指令导入页面,而且在jsp:include指令中还使用param指令传入参数,该参数可以在forward-result.jsp页面中使用request对象获取。
3、UseBean指令
<jsp:useBean>标签表示用来在JSP页面中创建一个BEAN实例并指定它的名字以及作用范围。
语法:
<jsp:useBean id="name" scope="page | request | session | application" typeSpec />
其中typeSpec有以下几种可能的情况:
class="className" | class="className" type="typeName" | beanName="beanName" type="typeName" | type="typeName" |
注:
你必须使用class或type,而不能同时使用class和beanName。beanName表示Bean的名字,其形式为“a.b.c”。
4、GetProperty指令
<jsp:getProperty>标签表示获取BEAN的属性的值并将之转化为一个字符串,然后将其插入到输出的页面中。
语法:
<jsp:getProperty name="name" property="propertyName" />
注:
1、在使用<jsp:getProperty>之前,必须用<jsp:useBean>来创建它。
2、不能使用<jsp:getProperty>来检索一个已经被索引了的属性。
3、能够和JavaBeans组件一起使用<jsp:getProperty>,但是不能与Enterprise Java Bean一起使用。
5、SetProperty指令
<jsp:setProperty>标签表示用来设置Bean中的属性值。
语法:
<jsp:setProperty name="beanName" prop_expr />
其中prop_expr有以下几种可能的情形:
property="*" | property="propertyName" | property="propertyName" param="parameterName" | property="propertyName" value="propertyValue"
6、Plugin指令
<jsp:plugin>标签表示执行一个applet或Bean,有可能的话还要下载一个Java插件用于执行它。
语法:
<jsp:plugin
type="bean | applet"
code="classFileName"
codebase="classFileDirectoryName"
[ name="instanceName" ]
[ archive="URIToArchive, ..." ]
[ align="bottom | top | middle | left | right" ]
[ height="displayPixels" ]
[ width="displayPixels" ]
[ hspace="leftRightPixels" ]
[ vspace="topBottomPixels" ]
[ jreversion="JREVersionNumber | 1.1" ]
[ nspluginurl="URLToPlugin" ]
[ iepluginurl="URLToPlugin" ] >
[ <jsp:params>
[ <jsp:param name="parameterName" value="{parameterValue | <%= expression %>}" /> ]+
</jsp:params> ]
[ <jsp:fallback> text message for user </jsp:fallback> ]
</jsp:plugin>
注:
<jsp:plugin>元素用于在浏览器中播放或显示一个对象(典型的就是applet和Bean),而这种显示需要在浏览器的java插件。
当Jsp文件被编译,送往浏览器时,<jsp:plugin>元素将会根据浏览器的版本替换成<object>或者<embed>元素。注意,<object>用于HTML 4.0 ,<embed>用于HTML 3.2。
一般来说,<jsp:plugin>元素会指定对象是Applet还是Bean,同样也会指定class的名字,还有位置,另外还会指定将从哪里下载这个Java插件。
7、param指令
param指令用于设置参数值,这个指令本身不能单独使用,单独的param没有实际意义,param指令可与一下三个指令结合使用:
jsp:include
jsp:forward
jsp:plugin
param指令的语法格式如下:
<jsp:param name="paramName" value="paramValue">
三、jsp中其他要注意的问题
1、JSP的声明(statement)
用来定义在产生的类文件中的类的属性和方法(成员变量)。可声明类(即是内部类)。
由于servlet是工作在多线程环境下,所以尽量不要在service方法体外声明成员变量。
<%!.....%> //声明时要加"!",属于类成员,最先加载,可写于任何位置;不加则是脚本的局部变量,必须调用前写。
如: <%!String hello="Hello, World!";%> //变量的声明
<%=hello%> //变量的调用
<%! private int counter=0; public int count(){ return ++counter;} %> //函数的声明
<h1><%=count()%></h1> //函数的调用
声明规则:
1) JSP中声明的变量和方法对应于Servlet中的实例方法和实例变量。这些将被同时请求该页面的所有用户所共享;
2) 在使用变量或方法前须先定义(不是说声明变量的位置在页面中要处于使用变量的前面,而是指变量不声明不能使用);
3) 声明的变量或方法的作用域为当前页面或包含的页面;
4) 语句间以分号分隔。
2、JSP代码段(Scriptlet)
<% java代码 %>
是一段可以在处理请求时间执行的Java代码。可以产生输出,也可以是一些流程控制语句。
在代码段中定义的变量为service方法中的局部变量。
1._jspService()中的局部代码:
<% System.out.println("Hi,I like JSP."); %> //在控制台打印出,网页上没显示
<% out.println("Hi,I like JSP."); %> //打印在网页上
<% Connection conn=DriverManager.getConnection(); Statement st=conn.createStatement();
String sql="select * from users"; ResultSet rs=st.executeQuery(sql);
//……
%>
问:能否在JSP脚本里定义方法?
答:不能! //脚本相当于方法,不能在方法里定义方法
<%!public void helloworld(){}%> //可以声明方法
<% public void helloworld(){}%> //编译出错;脚本不能定义方法
2.比较:
<%! int i=100;%> //成员变量
<% int i=101;%> //_jspService()方法中的局部变量
<%=i%> //同一文件里,局部变量优先
3.脚本小程序规则:
1) 你使用的脚本语言决定了脚本小程序的规则;
2) 语句间以分号分隔;
3) 可以使用默认的对象、import进的类、declaration声明的方法和对象以及useBean tag中声明的对象。
3、JSP表达式(expression)
<%=……%> // "="号
在JSP请求处理阶段计算他的值,表达式生成的代码是Service方法中的一个代码片断。
JSP对于声明的处理:1、计算表达式的值
2、将值转换成String
3、用out.println发送标签;把数据输出至页面的当前位置
<%="Hello,JSP world!"%> //out.println("Hello,JSP world");
<%=name%> //<%!String name="GiGi";%> out.println(name);
<%=new java.util.Date()%> //out.println(new java.util.Date());
表达式规则:
1) 你使用的脚本语言决定了脚本小程序的规则;
2) 执行的顺序为从左到右;
3) 分号不能用于表达式。
4、JSP中的注释
1.java格式注释
编译器会忽略掉此类注释中的内容(客户端的源码看不见)
<%-- JSP注释;可多行 --%>
<%// java 单行注释 %>
<%/* java multi lines comments */%>
<%/**java 特有的注释*/%>
2.html风格注释
编译器会执行此类注释中的代码(客户端的源码看得见)
<!-- html风格注释 --> 等价于out.println("<!-- html风格注释 -->")
这种注释方式不好的地方就是当页面注释信息太多的时候会增大服务器的负荷。
还有注释信息需要在网络上传输,从而降低效率;内部程序员的测试数据一般不能写在这种注释中,以免泄露。
5、JSP中的异常处理
一、try/catch/finally/throws/throw
// 在局部代码里处理异常。
二、errorPage, isErrorPage
// 在整个页面处理异常。
1.errorPage
形如: <%@page errorPage="error.jsp"%>
表示:需要错误处理的页面
2.isErrorPage
形如: <%@page isErrorPage="true"%>
指示:错误页面。其中,有一个隐式对象exception可用: <%=exception%>
产生(隐含)内建对象exception,可通过它获得异常信息
<%=exception.getMessage() %> //把异常信息打印出来
三、声明的方式处理异常
// 在整个应用处理异常。(范围比前两种更大)
1.配置: 在web.xml进行配置异常处理
…… <error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/MathError.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page> ……
2.复习:Java中的异常——有2种
受查异常(Checked Exception)
非受查异常(Unchecked Exception) Java中的RuntimeException及其子类是不需要处理的(try/catch)
因为所有的RuntimeException总是可以通过优化代码来避免,因此,这种异常被称为"Unchecked Exception"。
3.思考:
三种异常处理方式同时启动用,那个优先级高? 作用域越小,优先级越高。
注意:要使得页面自动跳转到错误页面,必须关闭浏览器的"显示友好HTTP错误信息"选项。
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException { /*只处理这两种兼容的异常*/ …… }
安全的系统(企业级应用):
1.身份认证(合法用户) --登录
2.授权(静态) --定义权限
3.访问控制(动态) --比较
4.安全审计(日志) --修复bug (只有敏感的部门需要)
JAAS实现安全
JAAS——Java Authentication and Authorization Service
(Java认证(Authentication)与授权(Authorization)服务)
是Java EE规范之一,实现Java EE应用程序安全性的一个重要途径
(要求:会使用,不必深入理解)