标签:
jsp基础知识详解
不管是JSP还是Servlet,虽然都可以用于开发动态web资源。但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。
其原因为,程序的数据通常要美化后再输出:
让jsp既用Java代码产生动态数据,又做美化会导致页面难以维护。
让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护。
因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做。
目标:
Web服务器是如何调用并执行一个jsp页面的?
Jsp页面中的html排版标签是如何被发送到客户端的?
Jsp页面中的java代码服务器是如何执行的?
Web服务器在调用jsp时,会给jsp提供一些什么java对象?
思考:JSP为什么可以像servlet一样,也可以叫做动态web资源的开发技术?
其实Jsp就是一个Servlet,所以我们要先介绍Servlet的相关技术,当我们第一次访问Jsp的时候,Jsp引擎都会将这个Jsp翻译成一个Servlet,这个文件存放在Tomcat中的work目录中,这里,我们新建一个MyJsp.jsp页面,然后访问以下,我们看一下翻译后的源码:
以下是MyJsp.jsp页面的内容:
1、JSP文件必须在JSP服务器内运行
2、JSP文件必须生成Servlet才能执行
3、每个JSP页面的第一个访问者速度很慢,因为必须等待JSP编译成Servlet
4、JSP页面的访问者无须安装任何客户端,甚至不需要可以运行Java的运行环境,因为JSP页面输送到客户端的是标准HTML页面
1、HTML注释<!-- -->
2、JSP注释<%-- --%>
HTML的注释可以通过源代码查看到,但JSP的注释是无法通过源代码查看到的。这表明JSP注释不会被发送到客户端。
在JSP声明中声明方法看起来很特别,似乎没有类,只有方法的定义,方法似乎可以脱离类独立存在。实际上,JSP声明将会转换成Servlet的成员变量或成员方法,因此JSP声明依然符合Java语法。由于JSP声明语法定义的变量和方法对应于Servlet的成员变量和方法,所以JSP声明部分定义的变量和方法可以使用private、public等访问修饰符修饰,也可使用static修饰,将其变成类属性和类方法。但不能使用abstract修饰声明部分的方法,因为抽象方法将导致JSP对应Servlet变成抽象类,从而导致无法实例化。
JSP脚本将转换成Servlet里_jspService方法的可执行性代码。这意味着在JSP小脚本部
分也可以声明变量,但在JSP脚本部分声明的变量是局部变量,将不能使用private等访问控制符修饰,也不能使用static修饰。
实际上不仅JSP小脚本部分会转换成_jspService方法里的可执行性代码,JSP页面里的所有静态内容都将由_jspService方法里输出语句来输出,这就是JSP脚本可以控制JSP页面中静态内容的原因,由于JSP脚本将转换成_jspService方法里的可执行性代码,而Java语法不允许在方法里定义方法,所以JSP脚本里不能定义方法。
a) Page:该指令是针对当前页面的指令
b) Include:用于指定包含另一个页面
c) Taglib:用于定义和访问自定义标签
静态包含意义:包含页面在编译时将完全包含了被包含页面的代码。
1、jsp:forward指令
a) 执行forward指令时,用户请求的地址依然没有发生改变,但页面内容却完全变为被forward目标页的内容
b) 执行forward指令转发请求时,客户端请求参数不会丢失
2、include指令
a) Include指令是一个动态include指令,也用于导入某个页面,它不会导入被include页面的编译指令,仅仅将被导入页面的body内容插入到本页里。
静态导入和动态导入有如下两点区别:
a) 静态导入是将被导入页面的代码完全融入,两个页面融合成一人整体Servlet;而动态导入则在Servlet中使用Include方法来引入被导入页面的内容。
b) 静态导入时被导入页面的编译指令会起作用;而动态导入时被导入页面的编译指令则失去作用,只是插入被导入页面的body内容。
c) 除此之外,执行include动态指令时,还可增加额外的请求参数,如:
<jsp:include page="forward-result.jsp">
<jsp:param name="age" value="32"/>
</jsp:forward>
3、useBean、setProperty、getProperty指令
a) 这3个指令都是与JavaBean相关的指令,其中useBean指令用于在JSP页面中初始化一个Java实例;setProperty指令用于为JavaBean实例的属性设置值;getProperty指令用于输出JavaBean实例属性。
b) 如果多个页面中需要重复使用某段代码,我们可以把这段代码定义成Java类的方法,然后让多个JSP页面调用该方法即可,这样可以达到较好的代码复用。
c) <jsp:useBean id="name" class="classname" scope="page | request | application | session" />
d) 将Java源文件放在Web应用的WEB-INF/src路径下,实际上Java源文件对Web应用不起作用,所以我们会使用Ant来编译它,并将编译得到的二进制文件放入WEB-INF/classes路径下。而且,当我们为Web应用提供了新的class文件后,必须重启该Web应用,让它可以重新加载这些新的class文件。
4、plugin指令
a) Plugin指令主要用于下载服务器端的javabean或Applet到客户端执行。
Jsp-plugin.jsp
<jsp:plugin type="applet" code="Hello.class">
<!--为Applet传入参数 -->
<jsp:params>
<jsp:param name="helo" value="Java世界"/>
</jsp:params>
<!-- 不能显示Applet时的提示信息 -->
<jsp:fallback>
<p>不能下载jre插件</p>
</jsp:fallback>
</jsp:plugin>
Hello.java
Public class Hello extends Applet
{
Public void paint(Graphics g)
{
g.drawString(getParameter("hello"),20,30);
g.setColor(new Color(255,200,200));
g.fillRect(50,60,200,150);
}
}
5、param指令
a) 用于设置参数值,这个指令本身不能单独使用,可以和以下三个指令结合使用
i. jsp:include
ii. jsp:forward
iii. jsp:plugin
b) param指令格式:<jsp:param name="paramNmae" value="paramValue" />
6、jsp:useBean指令:创建一个JavaBean实例
7、jsp:setProperty:设置JavaBean实例的属性值
8、jsp:getProperty:输出JavaBean实例的属性值
几大内置对象的实质:它们要么是_jspService()方法的形参,要么是-_jspService()方法的局部变量,所以我们直接调用这些对象,无须创建它们。
当我们编写jsp页面时,一定不要停留在页面本身来看问题,这样可能导致许多误解,导致我们无法理解JSP的运行方式。因为上面8个内置对象要么是_jspService()方法的形参,要么是-_jspService()方法的局部变量,所以Jsp页面中只有JSP脚本才可以直接访问它们,JSP声明部分不能直接使用内置对象。(jsp脚本也将转换成Servlet里面_jspService方法的可执行性代码,而jsp声明将转换成Servlet里面的成员变量或成员方法,成员方法不能访问局部变量或局部方法!)
1、application对象
a) Application对象代表Web应用本身,因此使用application来操作Web应用相关数据。Application对象通常有如下两个应用:
i. 在整个Web应用的多个JSP、Servlet之间共享数据
ii. 访问Web应用的配置参数
b) application不仅可以用于两个JSP页面之间共享数据,还可以用于Servlet和JSP之间共享数据。我们可以把Application理解成一个Map对象,任何JSP、Servlet都可以把某个变量放入Application中保存,并为之指定一下属性名;而该应用里的其他JSP、Servlet就可以根据该属性名来得到这个变量。
3、config对象
4、Out对象
5、PageContext对象
a) 这个对象代表页面上下文,该对象主要用于访问JSP之间的共享数据。使用pageContext可以访问page、request、session、application范围的变量
6、request对象
a) 获取请求参数
i. String getParameter(String paramName);
ii. Map getParameterMap();
iii. Enumeration getParameterNames();
iv. String[] getParameterValues(String name);
b) 操作request范围的属性
setAttribution(String attName,Object attValue)
Object getAttribution(String attName)
c) 执行forward或include
HttpServletRequest类提供了一个getRequestDispatcher(String path)方法,其中path就是希望forward或者include的目标路径,该方法返回RequestDispatcher,该对象提供了如下两个方法:
getRequestDispatcher("/a.jsp").include(request,response);
getRequestDispatcher("/a.jsp").forward(request,response);
7、Response对象
a) Response代表服务器对客户端的响应。大部分时候,程序无须使用Response来响应客户端请求,因为有个更简单的响应对象——out,它代表页面输出流,直接使用Out生成响应更简单。但Out是JspWriter的实例,JspWriter是Writer的子类,Writer是字符流,无法输出非字符内容。此时必须使用Response作为响应输出。
i. Response响应生成图片
ii. 重定向response.sendRedirect("redirect-result.jsp");
Forward和redirect对比
执行forward后依然是上一次请求,执行redirect后生成第二次请求
Forward的目标页面可以访问原请求的请求参数,因为依然是同一次请求;redirect的目标页面不能访问原请求的请求参数,因为是第二次请求了。
Forward地址栏里请求的URL不会改变;redirect地址栏改为重定向的目标URL。相当于浏览器地址栏里输入新的URL后按回车键。
b) 增加Cookie
获取请求参数:String name = request.getParameter("name"):
创建Cookie实例:Cookie c = new Cookie ( "username" , name);
设置Cookie对象的生命期限:c.setMaxAge(24 * 3600);
向客户端增加Cookie对象:response.addCookie(c);
8、Session对象
a) Session对象是HttpSession的实例,HttpSession有如下几个常用方法
i. setAttribution(Stirng attName , Object attValue);
ii. getAttribution(String attName);
b) Session机制通常用于保存客户端的状态信息,这些状态信息需要保存到Web服务器的硬盘上,所以要求Session里的属性值必须是可序列化的,否则将会引发不可序列化的异常。
1、Servlet的开发
a) Servlet,通常称为服务器端小程序,是运行在服务器端的程序,用于处理及响应客户端的请求。Servlet是个特殊的Java类,这个Java类必须继承HttpServlet。
b) Servlet和JSP的区别在于:
i. Servlet中没有内置对象,原来JSP中的内置对象都必须由程序显示创建。
ii. 对于静态的HTML标签,Servlet都必须使用页面输出流逐行输出。
c) 普通Servlet类里的Service()方法的作用,完全等同于JSP生成Servlet类里的_jspService()方法。因此原JSP页面里的JSP脚本,静态HTML内容,在普通Servlet里都应该转换成service()方法的代码或输出语句;原JSP声明中的内容,对应为在Servlet中定义的成员变量或成员方法。
2、Servlet配置
a) 配置Servlet需要配置两个部分:
i. 配置Servlet的名字:对应web.xml文件中的<servlet/>元素
ii. 配置Servlet的URL:对应web.xml文件中的<servlet-mapping/>元素
<servlet>
<servlet-name>firstServlet</servlet-name>
<servlet-class>lee.FirstServlet</servlet-class>
//<load-on-startup>1</load-on-startup>
</sevlet>
<servlet-mapping>
<servlet-name>firstServlet</servlet-name>
<url-pattern>/firstServlet</url-pattern>
</servlet-mapping>
3、Servlet的生命周期
a) 创建Servlet实例有两个时机:
i. 客户端第一次请求某个Servlet时,系统创建该Servlet的实例:大部分的Servlet都是这种Servlet。
ii. Web应用启动时立即创建Servlet实例,即load-on-startup Servlet。
b) 实际上JSP和Servlet完全统一,所以JSP和Servlet有相同的生命周期。
4、访问Servlet的配置参数
a) java.lang.String.getInitParameter(java.lang.String name):用于获取初始化参数。
b) 例如:TestServlet.java: String driver=config.getInitParameter("driver");
Web.xml: <init-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</para-value>
</init-param>
1、在JSP中开发标签库只需如下几个步骤:
a) 开发自定义标签处理类
b) 建立一个*.tld文件对应一个标签库,每个标签库对应多个标签
c) 在JSP文件中使用自定义标签
参考:
http://blog.csdn.net/jiangwei0910410003/article/details/23687279
http://blog.163.com/edison_mail/blog/static/17059721720108845456350/
标签:
原文地址:http://blog.csdn.net/u010098331/article/details/51728666