JSP运行过程 JSP脚本 静态动态包含 jsp指令 jsp内置对象jsp四大作用域 jsp动作元素 EL表达式 JSTL 设计模式 JSP开发模式 EL内置对象
Posted 阿善9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSP运行过程 JSP脚本 静态动态包含 jsp指令 jsp内置对象jsp四大作用域 jsp动作元素 EL表达式 JSTL 设计模式 JSP开发模式 EL内置对象相关的知识,希望对你有一定的参考价值。
Day38 JSP
JSP的运行过程具体如下:
(1)客户端发出请求,请求访问JSP文件。
(2)JSP容器先将JSP文件转换成一个Java源文件(Java Servlet源程序),在转换过程中,如果发现JSP文件中存在任何语法错误,则中断转换过程,并向服务端和客户端返回出错信息。
(3)如果转换成功,则JSP容器将生成的Java源文件编译成相应的字节码文件*.class。该class文件就是一个Servlet,Servlet容器会像处理其他Servlet一样来处理它。
为了使同学们更容易理解JSP的运行原理,接下来简单介绍分析一下JSP所生成的Servlet代码。
以HelloWorld.jsp为例,当用户第一次访问HelloWorld.jsp页面时,该页面会先被JSP容器转换为一个名称为HelloWorld_jsp.java的源文件,然后将源文件编译为一个名称为HelloWorld_jsp.class字节码文件。如果项目发布在Tomcat的webapps目录中,源文件和.class文件可以在“Tomcat安装目录/work/Catalina/localhost/项目名/org/apache/jsp”下找到,如图1-7所示。
JSP的工作模式是请求/响应模式,客户端首先发出HTTP请求,JSP程序收到请求后进行处理并返回处理结果。在一个JSP文件第一次被请求时,JSP引擎(容器)把该JSP文件转换成为一个Servlet,而这个引擎本身也是一个Servlet。JSP的运行过程如图1-6所示。
图1-1 JSP的运行原理
JSP的运行过程具体如下:
(1)客户端发出请求,请求访问JSP文件。
(2)JSP容器先将JSP文件转换成一个Java源文件(Java Servlet源程序),在转换过程中,如果发现JSP文件中存在任何语法错误,则中断转换过程,并向服务端和客户端返回出错信息。
(3)如果转换成功,则JSP容器将生成的Java源文件编译成相应的字节码文件*.class。该class文件就是一个Servlet,Servlet容器会像处理其他Servlet一样来处理它。
l 跨平台:由于JSP是基于Java语言的,它可以使用Java API,所以它也是跨平台的,可以应用于不同的系统中,如Windows、Linux等。当从一个平台移植到另一个平台时,JSP和JavaBean的代码并不需要重新编译,这是因为Java的字节码是与平台无关的,这也应验了Java语言“一次编译,到处运行”的特点。
l 业务代码相分离:在使用JSP技术开发Web应用时,可以将界面的开发与应用程序的开发分离开。开发人员使用html来设计界面,使用JSP标签和脚本来动态生成页面上的内容。在服务器端,JSP引擎(或容器,本书中指Tomcat)负责解析JSP标签和脚本程序,生成所请求的内容,并将执行结果以HTML页面的形式返回到浏览器。
l 组件重用:JSP中可以使用JavaBean编写业务组件,也就是使用一个JavaBean类封装业务处理代码或者作为一个数据存储模型,在JSP页面中,甚至在整个项目中,都可以重复使用这个JavaBean,同时,JavaBean也可以应用到其他Java应用程序中。
l 预编译:预编译就是在用户第一次通过浏览器访问JSP页面时,服务器将对JSP页面代码进行编译,并且仅执行一次编译。编译好的代码将被保存,在用户下一次访问时,会直接执行编译好的代码。这样不仅节约了服务器的CPU资源,还大大的提升了客户端的访问速度。
1.1.1.1
1.1.1.2 JSP脚本元素(掌握)
如何在jsp中编写java代码
l Jsp Scriptlets代码段
n 格式: <% ..java代码..%>
n 此处声明的变量都是局部变量,最后编译到servlet的_jspService()方法中
l Jsp声明语句
n 格式:<%! ..java代码..%>
n 此处声明的java代码会编译到_jspService()方法外,定义的都是成员方法、成员变量等
l Jsp表达式
n 格式:<%=..java代码…%>
n 主要用于代码数据的输出.
方式1:设置错误状态码 (常见)
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
方式2:设置异常信息
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/error.jsp</location>
</error-page>
其他
language 解析当前JSP页面使用的语言
import: jsp导入其他包
import="java.util.List"
session : 控制jsp页面 session内置对象是否可以使用
1.1.1.3 include指令—静态包含
在实际开发时,有时需要在JSP页面静态包含一个文件,例如HTML文件,文本文件等,这时,可以通过include指令来实现,include指令的具体语法格式如下所示:
<%@ include file="被包含的文件地址"%> 路径不需要加项目名
1.1.1.4 taglib指令
用于页面中引入标签库的,这个指令会在后面介绍JSTL的时候讲解
1.1.1 jsp九大内置对象(重点)
在JSP页面中,有一些对象需要频繁使用,如果每次都重新创建这些对象则会非常麻烦。为了简化Web应用程序的开发,JSP2.0规范中提供了9个隐式(内置)对象,它们是JSP默认创建的,可以直接在JSP页面中使用。
Jsp内置对象中使用固定字符串来表示Servlet中对应的类
request javax.servlet.http. HttpServletRequest 获得用户请求
session javax.servlet.http. HttpSession 服务器端保存用户信息
config javax.servlet. HttpServletConfig 当前servlet的配置对象
application javax.servlet. ServletContext 上下文对象,所有用户共享数据
response javax.servlet.http. HttpServletResponse 返回动态响应信息
out java.io. PrintWriter(javax.servlet.jsp.JspWrite) 用于页面输出
pageContext javax.servlet.jsp.PageContext当前JSP对象
page java.lang.Object jsp编译以后的Servlet对象
exception java.lang.Throwable 表示当前jsp页面所发生的异常,在错误页面才其作用
1.1.2 四大作用域(掌握)
l page:表示当前页,通常没用。jsp标签底层使用。
l request:表示一次请求。通常一次请求就一个页面,但如果使用请求转发,可以涉及多个页面。
l session:表示一次会话。可以在多次请求之间共享数据。
l application:表示 一个web应用(项目)。可以整个web项目共享,多次会话共享数据。
实际开发中,遵循能小不大的原则
1.1.3 JSP动作元素(了解)
1.1.3.1 <jsp:include>动作元素
在JSP页面中,为了把其他资源的输出内容插入到当前JSP页面的输出内容中,JSP技术提供了<jsp:include>动作元素,<jsp:include>动作元素的具体语法格式如下所示:
<jsp:include>包含页面时 先编译展示 jsp页面 再展示包含页面 如果jsp标签中添加flush属性 设置为true 择
1.1.3.2 静态包含和动态包含的区别
1.1.3.3 什么是EL表达式?
主要用于操作域中的数据
,让Jsp的代码更加简化
替代JSP表达式 <%= %>,用来向浏览器输出内容
l .和[]的区别.
1)[]用于有下标的数据(数组,list集合) .用于有属性的数据(map,对象)
2)如果属性名中包含有特殊的字符.必须使用[]
1.1.3.4 JSTL安装和测试
n 导入jar包
n 引入标签库taglib
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
uri部分是固定
prefix表示给核心库起别名,名称任意定义,建议使用 prefix="c"
n 使用
<c:out value="你好"></c:out>
l JSTL核心库—if标签(掌握)
JSTL标签库支持EL表达式 c:if test="EL表达式"
<h3>List集合--String</h3>
<%
List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
pageContext.setAttribute("list", list);
%>
<c:forEach items="${list}" var="str">
${str}<br>
</c:forEach>
<h3>List集合--JavaBean</h3>
<%
List<User> uses = new ArrayList<User>();
uses.add(new User("p001", "zhangsan", 18));
uses.add(new User("p002", "李四", 18));
uses.add(new User("p003", "王武", 18));
pageContext.setAttribute("uses", uses);
%>
<c:forEach items="${uses}" var="user">
${user.uname}<br>
</c:forEach>
1.1 MVC设计模式(重点)
l Model-View-controller的缩写
理念:数据处理和数据显示相分离
1.2 JSP开发模式
Servlet+JSP+javaBean
<%out 和response同时输出内容response输出的内容在前面%> 因为 out和response都存在缓冲区 out输出前是将内容放到response缓冲区 所以response比out先输出
<body>
<%
//使用 JSP 的输出流
out.print("first");
//使用 Servlet 的输出流
response.getWriter().print("second");
%>
</body>
1.2.0.1 EL的使用:内置对象
分类 |
内置对象名称 |
描述 |
作用域 |
pageScope |
page作用域 |
requestScope |
request作用域 |
|
sessionScope |
session作用域 |
|
applicationScope |
application作用域 |
|
请求参数 |
param |
获得一个参数 |
paramValues |
获得一组参数 |
|
请求头 |
header |
获得一个请求头 |
headerValues |
获得一组请求头 |
|
JSP上下文对象 |
pageContext |
|
全局初始化参数 |
initParam |
|
cookie |
cookie |
|
l 获得指定作用域的数据
<%--初始化数据--%>
<%
pageContext.setAttribute("name", "pValue");
request.setAttribute("name", "rValue");
session.setAttribute("name", "sValue");
application.setAttribute("name", "aValue");
%>
<%--使用JSP脚本获得--%>
<%=pageContext.getAttribute("name") %> <!-- 如果没找到 返回null -->
<%=request.getAttribute("name") %>
<%=session.getAttribute("name") %>
<%=application.getAttribute("name") %>
<%--获得指定作用域的数据--%>
${ pageScope.name } <!-- 返回的是"" -->
${ requestScope.name }
${ sessionScope.name }
${ applicationScope.name }
<%--依次获得数据--%>
${ name } <%-- 底层使用 pageContext.findAttribute("name") ,依次从page、request、session、application获得数据,如果都没有返回null --%>
l 请求参数
//请求路径:/day18/a_el.jsp?username=jack&hobby=xxx&hobby=yyy
<%--
param.xxx 对应 request.getParameter("xxx");
paramValue.xxx 对应 request.getParameterValues("xxx");
--%>
${param.username} <br/>
${param.hobby}<br/> <%--获得第一个参数--%>
${paramValues.hobby} <br/> <%--获得一组数据,使用数组 --%>
${paramValues.hobby[1]} <br/> <%--如果是数组,可以使用下标获得 --%>
l 请求头
<%--
header.xxx 对应 request.getHeader("xxx");
headerValues.xxx 对应 request.getHeaders("xxx");
--%>
${header.accept} <br/>
\\${header.accept-Encoding} <br/> <%--非法的,有异常,“-”被解析成减号。使用"/"进行单个el表达式转义 --%>
${header[\'accept-Encoding\']} <br/>
${headerValues[\'accept-Encoding\'][0]} <br/>
l pageContext
<%--
pageContext 对应 pageContext对象
--%>
jsp: <%= ((HttpServletRequest)pageContext.getRequest()).getContextPath() %> <br/>
el : ${pageContext.request.contextPath} <br/>
可以看到<c:if>标签有三个属性,接下来将针对这三个属性进行讲解,具体如下:
l test属性用于设置逻辑表达式;
l var属性用于指定逻辑表达式中变量的名字;
l scope属性用于指定var变量的作用范围,默认值为page。如果属性test的计算结果为true,那么标签体将被执行,否则标签体不会被执行。
语法1:迭代包含多个对象的集合
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
语法2:迭代指定范围内的集合
<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin"
end="end" [step="step"]>
body content
</c:forEach>
在上述语法格式中,可以看到<c:forEach>标签有多个属性。接下来针对这些属性进行讲解,具体如下:
l var属性用于指将当前迭代到的元素保存到page域中的名称;
l items属性用于指定将要迭代的集合对象;
l varStatus用于指定当前迭代状态信息的对象保存到page域中的名称;
l begin属性用于指定从集合中第几个元素开始进行迭代,begin的索引值从0开始,如果没有指定items属性,就从begin指定的值开始迭代,直到迭代结束为止;
l step属性用于指定迭代的步长,即迭代因子的增量。
<c:forEach>标签在程序开发中经常会被用到,因此熟练掌握<c:forEach>标签是很有必要的,接下来,通过几个具体的案例来学习<c:forEach>标签的使用
- JSP脚本元素是指嵌套在<%和%>之中的一条或多条Java程序代码。通过JSP脚本元素可以将Java代码嵌入HTML页面中,所有可执行的Java代码,都可以通过JSP脚本来执行。
4.如果JSP表单元素的值为空,如何避免null出现在页面上?
答:可以写一个简单的函数对空值进行处理,判断值是否为空,如果为空就返回空字符串。实例代码如下:
<%!
String blanknull(String e)
{
return (e==null)?"":s;
} %>
<%
<input type="text" name="username" value="<%=blanknull(username)%>"
%>
、如何避免JSP页面自动生成session对象?为什么要这么做?
答:在默认情况下,在对一个JSP页面发出请求时,如果session还没有建立,那么JSP页面会自动为请求创建一个session对象,但是session是比较消耗资源的,如果没有必要保持和使用session,就不应该创建session,例如一些只用来宣传产品的网页,往往没必要使用session来保存信息,可以在JSP中使用page指令进行设置,避免JSP页面为每个请求都自动创建session。实例代码如下:
<%@page session="false"%>
38、在JSP页面中如何删除一个cookie?
答:
<%
Cookie cookie=new Cookie("cookie名","cookie值");
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);%>
删除session session.removeattribute() session.attribute(null)
4、JSTL的功能,为什么要用JSTL?(JavaServer Pages Standard Tag Library)
答:
功能:主要用于基本输入输出、流程控制、循环、XML文件剖析、数据库查询及国际化和文字格式标准化的应用等。
原因:在jsp页面做条件判断或者循环操作并输出时,比较费力。
<%
//放置空对象
List list1=null;
request.setAttribute("l1", list1);
//放置空集合
List list2=new ArrayList();
//list2.add("1");
request.setAttribute("l2", list2);
//放置空字符串
request.setAttribute("kong", "");
request.setAttribute("i", 5);
%>
${empty l1 }<br> true
${empty l2 }<br> true
${empty kong }<br> true
${i>6?"i>6":"i<6" }
</body>
User p1=new User();
User p2=null;
request.setAttribute("p1", p1);
request.setAttribute("p2", p2);
%>
${empty p1 } false
${empty p1 } true
注意:list集合和对象 空参构造 结果不同
1、forward和redirect的区别
1.从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
2.从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.
3从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.
4.从效率来说
forward:高.
redirect:低.
5.forward不需要加项目名 因为是在项目中跳转
Redirect 需要加项目名
3.jsp中的@page指令 中有errorpage属性设置错误页面的. session 设置成false关闭jsp自动生成session 节约服务器资源
以上是关于JSP运行过程 JSP脚本 静态动态包含 jsp指令 jsp内置对象jsp四大作用域 jsp动作元素 EL表达式 JSTL 设计模式 JSP开发模式 EL内置对象的主要内容,如果未能解决你的问题,请参考以下文章