一、jsp简介
jsp是一种特殊的servlet,是一种动态的网页技术标准,它可以在传统的html页面中插入Java程序,在服务器端执行,但是最终返回的是HTML页面。jsp最终在程序中生成一个.java文件,这个Java中可以看出jsp继承于JspServlet,而JSPServlet则是继承于HttpServlet的。
Jsp页面的目的就是是的前端展示和后端逻辑servlet分离,所以一般不推荐在jsp中写Java代码。jsp在整个执行的过程中,用户通过浏览器请求到达服务器,服务器调用jsp引擎(一个Java程序),jsp引擎会将jsp翻译为一个servet,所以第一次访问这个jsp的时候会略微慢一些,之后如果jsp引擎发现这个jsp没有发生变化就会直接调用之前生成的servlet。
二、jsp中Java脚本的书写方式
1、Java小脚本
<%
Java语句
%>
在这里面的语句,翻译成servlet之后会直接放入,servlet中service方法中,并且在这里面是不能定义方法的。注意小脚本中可以使不完整的,只要保证多个小脚本连一起是完整的就行。
2、声明元素
<%!
声明
%>
声明中可以定义一些变量、方法,这里面的内容是放在service方法之外的。
3、表达式
<%=EL %>
表达式中是不能以”;”结尾的。表达式是一个简化的了的out.println语句。
三、jsp指令
jsp指令是为了JSP引擎设计的,不会直接产出任何输出,但是可以用来告诉jsp引擎一些jsp页面其他的处理过程。
JSP2.0中指令一共有三种:page、include、taglib,其语法格式一般为<%@ %>
1、page指令
其作用主要是用于指定页面的各种实行,常用的实行如下:
<%@page
[language="java" ] 语言
[extends="package.class" ]
[import="{package.class | package.*}, ..." ] 导包
[session="true | false" ]
[buffer="none | 8kb | sizekb" ]
[autoFlush="true | false" ]
[isThreadSafe="true | false" ]
[info="text" ]
[errorPage="relative_url" ]
[isErrorPage="true | false" ]
[contentType="mimeType [ ;charset=characterSet ]" |"text/html ; charset=ISO-8859-1" ]
[pageEncoding="characterSet | ISO-8859-1" ] //指定编码集
[isELIgnored="true | false" ]
%>
可以在一条page指令的import属性中引入多个类或包,其中的每个包或类之间使用逗号(,)分隔。例如:
<%@ page import="java.util.Date,java.io.*,java.sql.*"%>
page设置错误页面,当然也可以在web.xml中指定全局的错误页面。errorPage属性的设置值必须使用相对路径,如果以"/"开头代表的是当前应用程序的根目录,而不是站点的根目录。
在web.xml文件中使用<error-page>设置整个web应用的错误页面,<error-page>下面有三个子元素。
<error-code>指定错误的状态码
<exception-type>指定异常类的完全限定名
<location>指定以"/"为开头的错误的处理页面的路径
问题:我在设置了404、500状态码页面和error页面,404错误是跳转到了404页面,但是500状态码跳转到了error页面,并没有跳转到500页面中,好奇怪啊!!以后在研究研究
<!--
使用page指令的isErrorPage属性显式声明页面为错误页面
好处:
将error.jsp页面显式声明为错误处理页面后,有什么好处呢,好处就是Jsp引擎在将jsp页面翻译成Servlet的时候,
在Servlet的_jspService方法中会声明一个exception对象,然后将运行jsp出错的异常信息存储到exception对象中
于Servlet的_jspService方法中声明了exception对象,那么就可以在error.jsp页面中使用exception对象,
这样就可以在Jsp页面中拿到出错的异常信息了
-->
对不起,出错了,请联系系统的管理员!!<br>
异常信息如下:<%=exception.getMessage() %><!-- 如果不指定isErrorPage的话就会编译错误!-->
2、include指令
include指令用于包含其他页面,一共有两种方式,一种是静态包含一种是动态包含。
静态包含:<%@includefile=”header.jsp”%>,这种方式中被引入的文件是必须遵从jsp规范的,不论是什么扩展名,jsp引擎都会按照jsp的规范处理它的内容,被include涉及的jsp页面最终只会被翻译为一个servlet,所以这两个页面的指令不能冲突(pageEncoding和导包除外)。
动态包含:<jsp:includepage=”/user/test”flush=”true”/>,如果被包含的是jsp页面,则会先处理在进行包含,如果不是jsp页面,只会静态的包含,于@include类似。
静态包含和动态包含有什么区别?
静态包含是在编译期包含,虽然有两个jsp页面文件,但是生成的servlet却只有一个,而动态包含在运行期进行,每个jsp都会产生一个servlet,效率上面还是静态包含要好!
3、taglib指令用于在JSP页面中导入标签库,如JSTLjava标准标签库和自定义的标签。
四、JSP九大隐式对象
SP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。
-
NO
内置对象
类型
1
pageContext
javax.servlet.jsp.PageContext
2
request
Javax.servlet.http.HttpServletRequest
3
response
javax.servlet.http.HttpServletResponse
4
session
Javax.servlet.http.HttpSession
5
application
Javax.servlet.ServletContext
6
config
Javax.servlet.ServletConfig
7
out
Javax.servlet.jsp.JspWriter
8
page
Java.lang.Object
9
exception
Java.lang.Throwable
page隐式对象说明
page对象代表的是这个页面本身,就是将页面看做为一个对象,基本不咋用。
out隐式对象
out对象用于想浏览器发送文本信息,out对象同调用pageContext的getOut方法得到和response的getPrintWriter方法返回的PrintWriter对象非常类似,out对象是JspWriter类型,相当于带了缓存功能的printWriter,实际上即便向out中写入了内容,只有满足如下之一才能将该内容写入到Servlet引擎的缓存区中:
设置page的buffer属性关闭out的缓存功能,
out的缓冲区已经满了
刷新缓冲区
整个jsp页面结束
<%
out.write("hahahahaha<br/>");
response.getWriter().write("wowowowowowo<br/>");
%>
从效果上面已经可以看出来,JSPWriter对象中带有的缓存效果了。
注意:记住不要同时使用out和response.getWriter()输出数据,原因上面已经说的很清楚了,最好是只使用out对象来输出数据。
pageContext隐式对象
pageContent对象是九大隐式对象中最重要的一个对象了,代表了JSP页面的运行环境,这个对象不仅封装了其他8大隐式对象的引用,自身也是一个域对象,可用于存放数据,它的生命周期就是这个jsp页面的生命周期,执行的时候上来就会创建pageContext对象,但是jsp执行完了就会死亡。这个对象还封装了web开发中经常涉及的一些常用操作,例如引入跳转其它资源,检索其它对象的属性。
通过pageContext获取其它隐式对象
getException方法返回exception隐式对象。
getPage方法返回page隐式对象。
getRequest方法返回request隐式对象。
getResponse方法返回response隐式对象。
getServletConfig方法返回config隐式对象。
getServletContext方法返回application隐式对象。
getSession方法返回session隐式对象。
getOut方法返回out隐式对象。
pageContext封装其它8大内置对象的意义。
思考:如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将具有什么功能?
答:如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将可以获取8大隐式对象,此时这个java对象就可以和浏览器交互了,此时这个java对象就成为了一个动态web资源了,这就是pageContext封装其它8大内置对象的意义。把pageContext传递给谁,谁就能成为一个动态web资源。
思考:那么什么情况下需要把pageContext传递给另外一个java类呢,什么情况下需要使用这种技术呢
答:在比较正规的开发中,jsp页面是不允许出现java代码的(jsp页面里面是不能出现一行java代码的,在软件开发里面,你要想你这个jsp是一个合格、良好的jsp的话,jsp页面里面是不准出现一行java代码的),如果jsp页面出现了java代码,那么就应该想办法把java代码移除掉。我们可以开发一个自定义标签来移除jsp页面上的java代码,首先围绕自定义标签写一个java类,jsp引擎在执行自定义标签的时候就会调用围绕自定义标签写的那个java类,在调用java类的时候就会把pageContext对象传递给这个java类,由于pageContext对象封装了对其它8大隐式对象的引用,因此在这个java类中就可以使用jsp页面中的8大隐式对象(request,response,config,application,exception,Session,page,out)了,pageContext对象在jsp自定义标签开发中特别重要。
pageContext作为域对象
常用的方法
void setAttribute(String name , Object value)
ObjectgetAttribute(String name)
voidremoveAttribute(String name)
findAttribute(Stringname)---查找各个域中的属性
findAttribute方法按照查找顺序”page→request→session→application”在这四个对象中去查找,只要找到了就返回属性值,如果四个对象都没有找到要查找的属性,则返回一个null。
EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回””(注意,不是null,而是空字符串)
五、JSP标签说明
JSP标签也称之为JspAction(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。
jsp的常用标签有以下三个:
<jsp:include>标签
<jsp:forward>标签
<jsp:param>标签
<jsp:include>
标签
用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。其语法为:
page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
<jsp:forward>
标签
用于把请求转发给另外一个资源。其语法为:<jsp:forwardpage="relativeURL | <%=expression%>" />
在实际开发中,我们要为网站设置首页,访问首页时,我们要将数据交给Servlet进行处理,但我们又不能在项目的web.xml文件中配置一个servlet
解决方案是:在项目的web.xml中配置网站的首页,如下:
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
然后在index.jsp在使用jsp:forward标签跳转到Servlet,如下:
<!-- <jsp:forward>
标签的应用场景
-->
<jsp:forward page="/IndexServlet"></jsp:forward>
<jsp:param>
标签
当使用<jsp:include>
和<jsp:forward>
标签引入或将请求转发给其它资源时,可以使用<jsp:param>
标签向这个资源传递参数。
语法
1
<jsp:include page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
语法
2
<jsp:forward page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
比如在
1.
jsp
中导入
<jsp:include page="/
2
.jsp">
<jsp:param value="hello" name="parm1"/>
<jsp:param value="world" name="parm2"/>
</jsp:include>
那么
<h1>
接收从
IncludeTagTest2.jsp
页面中传递过来的参数:
</h1>
<h2><%=request.getParameter("parm1") %></h2>
<h2><%=request.getParameter("parm2") %></h2>
就可以接收到
1.jsp
中传递过来的参数了
六、JSP中的四大作用域
JSP的四大作用域:page、request、session、application
这四大作用域,其实就是其九大内置对象中的四个,为什么说他们也是JSP的四大作用域呢?因为这四个对象都能存储数据,比如request.setAttribute()注意和request.setParameter()区分开来,一个是存储在域中的、一个是请求参数,session.setAttribute()、application其实就是SerlvetContext,自然也有setAttribute()方法。而page作用域的操作就需要依靠pageContext对象来进行了。在上面我们也有提到JSP的四大作用域,
page作用域:代表变量只能在当前页面上生效
request:代表变量能在一次请求中生效,一次请求可能包含一个页面,也可能包含多个页面,比如页面A请求转发到页面B
session:代表变量能在一次会话中生效,基本上就是能在web项目下都有效,session的使用也跟cookie有很大的关系。一般来说,只要浏览器不关闭,cookie就会一直生效,cookie生效,session的使用就不会受到影响。
application:代表变量能一个应用下(多个会话),在服务器下的多个项目之间都能够使用。比如baidu、wenku等共享帐号。
七、jsp标签(标准标签)
EL表达式
1、访问相关的属性(bean)
访问属性的顺序是:pageContext、request、session、application。只要找到蓝就会返回,没有找到的话就会返回””---空字符串。
${user.name}或者${user["name"]}、${user.interest[0]},可以访问数组下标,要有get方法。
2、运算
算术运算+、-、×、/
关系运算:>、<、>=、<= 、==
逻辑运算:&&|| !
empty运算:用来判断集合是否为空,或者是否是一个空字符串
JSRL核心标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
if
<c:iftest="${user.gender == 'm'}" var="flag"scope="request">男</c:if> 等价于request.setAttribute("flag",运行结果true/false) ,scope可以写page,session,application
choose相当于if{}else{}else{}
when可以出现1次或者多次。当test属性为true时,会执行该分支。
otherwise可以出现0次或者1次。表示例外。
<c:choose>
<c:whentest="${user.gender == 'm'}">男
</c:when>
<c:whentest="${user.gender == 'f'}">女
</c:when>
<c:otherwise>保密
</c:otherwise>
</c:choose>
3)、forEach标签,用来遍历集合或者数组。每次从集合或者数组中取一个元素,然后将其绑定到pageContext上,绑定名由var属性来指定。
<c:forEachitems="${userlist}" var="u" varStatus="s">
<trclass="row${s.index%2+1}"> //css写个row1row2的class,表格行颜色互换
<td>${u.name}</td>
<td>${u.gender}</td>
<td>${u.age}</td>
<td>${s.index}</td>
<td>${s.count}</td>
</tr>
</c:forEach>
自定义标签
八、总结
1、什么是JSP?
JSP本质上就是一个servlet,因为servlet输出html太麻烦了,所以就有了JSP,JSP就是专门用来书写html的,当然其中也能写java代码。
2、JSP的内容包括什么?
模版数据和元素。其中元素有包括脚本(java代码)、指令(页面属性)、和行为(标签,为了JSP中不嵌入那么多java代码衍生的)
3、JSP中九大内置对象是哪九个?
九大内置对象, page、config、appliction、request、response、session、out、exception、pageContext
4、九大内置对象和servlet中对象的关系
page就是jsp转换为servletservlet对象本身,也就是this
config-- Servlet中的servletConfig
application-- Servlet中的ServletContext
request --Servlet中的request
response --Servlet中的response
session --Servlet中的session
out -- JspWriter
exception --异常对象
pageContext --表示 jsp页面上下文(jsp管理者)类型:PageContext,
其中pageContext对象最牛逼,有了他就拥有了天下,哈哈~
5、JSP中的四大作用域。
page、request、session、application
其中操作page域中属性需要借助pageContext对象。
6、JSP中还有其他两大块内容
一个是EL表达式,很重要,
另一个是jstl标签库的使用