JSP:一种动态网页技术,在html中内嵌java代码,本质是Servlet。
JSP的特点
- 跨平台
- 预编译。用户第一次访问JSP页面时,服务器会对JSP页面进行编译,会保存编译结果。以后再次访问此JSP页面时,直接执行编译好的代码,不再重新编译。
JSP运行原理
- JSP本质是Servlet,JSP容器就是Servlet容器,比如Tomcat。
- 创建Servlet实例后,会调用jspInit()来初始化这个Servelt,在JSP容器中的实际是Servlet,创建Servlet实例后,这个Servlet会常驻内存。
- 浏览器每次访问此JSP时,JSP容器都会调用jspServer()来处理请求。JSP容器会为每一个jsp请求创建一条新的线程来处理。处理完成后以html的形式返回给浏览器(JSP是在服务器上解析的)。
- 从JSP容器中移出JSP对应的Servlet时,会调用jspDestroy()。
JSP语法
<%! int a=1,b=2; public int add(int a,int b){ return a+b; } %> <% int sum= add(a,b); out.print(sum); %>
在<%! %>声明|定义变量、方法。
一个jsp对应一个Servlet,Servlet是一个特殊的Java类。在<%! %>中声明|定义的变量是Servlet的成员变量,声明|定义的方法是Servlet的成员方法。
<%! %>中的代码有限制,比如不能使用jsp的内置对象,不方便。
<% %>中可以写所有的Java 代码,可以把声明写在<% %>中,一样的。
JSP注释
在<% %>、<%! %>中,依旧使用java本身的注释。
在<% %>、<%! %>外,可以使用<%-- -->、<!-- -->。
<%-- -->是jsp的注释,<!-- -->是html注释,区别是jsp注释在编译成servlet时会被扔掉,浏览器查看源代码时看不到jsp注释。html注释会被保留,查看源代码时仍然看得到html注释。
JSP输出表达式
<%= 常量|变量|表达式 %>
直接写在html中,会输出等号后面部分的执行结果,相当于out.println()。
<%=1 %> <%=a+1 %> <%=sum(2,3) %>
表达式后面不能写分号。
JSP常用的编译指令
编译指令用法: <%@ 编译指令名 属性名1="属性值1" 属性名2="属性值2" %> ,有多个属性时,空格分隔。
1、page指令
page指令通常位于jsp页面的顶部,给当前jsp页面设置页面属性。一个jsp页面可以有多个page指令。
常用属性:
- language="java"
- contentType="text.html" //文档类型。比如text/plain 纯文本,image/jpeg jpg图像,image/gif gif图像。
- pageEncoding="utf-8" //编码字符集
- import="" //导入包、类
- session="true" //是否使用内置的session对象,默认为true
- isErrorPage="false" //当前页面是否是错误处理页面,默认为false。为true时,本页面有内置的exception对象。
- errorPage="/error.html" //指定错误处理页面,如果当前页面发生异常|错误,且本页面中未处理该异常,则会自动跳转到指定的错误处理页面
- buffer="" //指定输出缓冲区的大小,默认为8KB。输出内容到浏览器时,会先放到服务器的缓冲区中,缓冲区满了才会刷到浏览器。
2、include指令
include用于包含一个文本,可以是静态的html,也可以是动态的jsp。
常用属性:file="/test.jsp" //指定要包含的文件。
include编译指令是一种静态包含,要包含的文件是确定的。编译时先用要包含的文件中的文本替换掉这句代码,再作为一个整体编译成一个Servlet。
被包含的文本可以是一小段代码,不必是一个完整页面。
JSP中常用的动作指令|动作元素
1、<jsp:include page="relativeUrl|<%=expression %>" />
包含一个文本,page指定要包含的文本,可以使用相对路径,也可以使用java输出表达式。
包含的文件是可变的,属于动态包含。
是把被包含页面的执行结果|效果包含进来。编译时各自编译。
2、<jsp:forward page="relativeUrl|<%=expression %> />
请求转发。将请求转发给另一个页面处理,由另一个页面响应。
服务器内部行为,浏览器总的只发送一次HTTP请求。
说明:以上2个动作元素均可写成双标签,带子元素<jsp:param />,用于向目标页面传递额外参数。
<jsp:param name="" value="" />
可使用多个<jsp:param />。
传递的参数相当于表单参数,在目标页面中使用request.getparameter(String name)取出。
3、<jsp:useBean id="" class="" scope="" />
调用空参构造器创建一个JavaBean实例。该JavaBean要有空参的构造器。
id指定创建的实例的name,相当于变量名,class指定JavaBean的类名,scope指定把这个实例放到哪个域中。
JSP|Servlet有4个域:
- page 只在当前页面中有效
- session 只在本次session中有效
- request 只在本次请求中有效
- application 在整个web项目中一直有效
4、<jsp:setProperty name="" property="" value="" />
3只是调用空参的构造器创建JavaBean的实例,并没有初始化这个实例。
<jsp:property />是给一个JavaBean的实例设置一个属性值。
name指定JavaBean的实例,property指定属性名(成员变量),value指定属性值。
property,单数,只能设置一个属性,要设置多个需使用多个<jsp:property />。
实质是调用JavaBean的setter()方法来设置属性值,所有目标JavaBean需要提供gtesetter()方法。
5、<jsp:getProperty name="" property="" />
获取JavaBean实例的属性值。会直接在该位置输出这个属性值。
name指定JavaBean的实例,property指定属性名。
说明:输出表达式<%= %>、编译指令、动作指令均相当于html元素,位置和html元素的位置一样,不是放在<% %>、<%! %>中的。
JSP中的内置对象|隐式对象
Servlet中没有内置对象,对象需要通过代码显示创建。
JSP中有9个内置对象,可直接使用:
- out //JspWriter类型,JSP的字符输出流。有时write()输出效果不对,需要使用print()。
- request
- response
- session
- config //ServletConfig类型,当前Servlet|JSP的配置
- application //ServletContext类型,整个Web应用的共享数据。
- exception
- page //Object类型,当前JSP转换为Servlet后,Servlet的实例
- pageContext //PageContext类型,jsp的页面容器
request、response、session、config、application,这几个对象的使用方式和在Sevlet中的使用方式完全相同。
config是当前JSP|Servlet的配置,JSP一般不用配置,这个对象不常用。
pageContext的常用方法
- getXxx() //获取另外8个内置对象
- void setAttribute(String name, Object value, int scope) //将一个属性放到某个域中
- Object getAttribute(Stirng name, int scope) //从某个域中取出属性值
- void removeAttitude(Stirng name, int scope) //从某个域中移出指定属性
- void removeAttribute(String name) //从所有域中都移出该属性
- Object findAttribute(String name) //在所有域中查找该属性的值
域可使用4个常量:
- pageContext.PAGE_SCOPE
- pageContext.REQUEST_SCOPE
- pageContext.SESSION_SCOPE
- pageContext.APPLICATION_SCOPE
这四个常量可以使用pageContext这个内置对象来引用,也可以使用PageContext这个类来引用,比如 PageContext.PAGE_SCOPE 。
Servlet、JSP中都有这4个域,Servlet、JSP之间传递数据一般是通过这4个域来传递的。
这4个域相当于4个不同Map,可以在不同的域中存储相同的属性。比如可以在page、session中都存储name属性。
pageContext.getAttribute(String name, int scope)是在指定的域中查找属性值。
pageContext.findAttribute(String name)是依次在page、request、session、application中查找属性值,找到一个就返回,不再继续往下找。
BeanUtils
各种Java工具、框架层出不穷,并不能保证总能正确调用JavaBean的setter()、getter()方法。
BeanUtils是Apache的开源项目,提供了一套简单、易用的API,可以动态调用JavaBean的setter()、getter()方法。
下载BeanUtils,把commons-beanutils.jar添加到项目中。
此外还需要添加commons-logging.jar包。
BeanUtils的核心类是BeanUtils类,BeanUtils类常用的方法:
- static void setProperty(Object bean, String name, Object value) //设置属性值。bean指定JavaBean的实例,name指定属性(成员变量),value指定属性值。
- static void populate(Object bean, Map<String, ? extends Object> properties) //批量设置属性值。Map中的key是属性名,value是属性值。
- static String getProperty(Object bean, String name) //获取属性值,注意返回值是String。
这三个方法均是BeanUtils的静态方法。