关于Servlet与JSP

一.Servlet是什么

Servlet是sun公司制订的一种用来扩展web服务器功能的组件规范。

1、扩展web服务器功能

早期的web服务器(比如apache web server,微软的 iis)只能够处理静态资源(即需要事先将html文件写好),不能够处理动态资源的请求(即需要依据请求参数然后进行计算,生成相应的页面)。

为了让这些web服务器能够处理动态资源的请求,需要扩展它们的功能。早期使用的是cgi技术(common gateway interface),可以使用很多语言,比如perl,c等来开发cgi程序。

但是cgi程序有几个问题,比如开发比较复杂(因为需要程序员自己去分析请求参数)、性能不佳(因为当web服务器收到请求之后,会启动一个cgi进程来处理请求),还有cgi程序依赖平台,可移植性不好。

现在,可以使用servlet来扩展。当浏览器将请求发送给web服务器(比如,apache web server),web服务器会向servlet容器发送请求,servlet容器负责解析请求数据包,

当然,也包括网络通讯相关的一些处理,然后,将解析之后的数据交给servlet来处理(servlet只需要关注具体的业务处理,不用关心网络通讯相关的问题)。

2、组件规范

(1)组件: 符合一定规范,并且实现部分功能的软件模块。组件必须要部署到容器里面才能运行。

(2)容器: 符合一定规范,并且提供组件的运行环境的程序。

3、安装tomcat(是一个servlet容器)

servlet容器其实也可以作为一个简单的web服务器来使用。

(1)将tomcat压缩文件解压到/home/soft01/opt/apache-tomcat5.5.23.tar.gz;

(2)配置环境变量 ;

(3)启动tomcat;

cd /home/soft01/apache-tomcat/bin
sh startup.sh或者sh catalina.sh run

接下来,可以打开浏览器,输入http://localhost:8080

如果要关闭tomcat,可以使用:

cd /home/soft01/apache-tomcat/bin
sh shutdown.sh

4.如何写一个servlet

(1)先写一个java类,实现Servlet接口或者继承HttpServlet抽象类。

(2)编译;

(3)打包;

即创建一个具有如下结构的文件夹

appname(应用名)
WEB-INF
classes(.class文件)
lib(.jar文件, lib文件夹可选)
web.xml(部署描述文件 url-pattern)

(4)部署

将(3)创建的文件夹拷贝到servlet容器特定的文件夹下面。注意:也可以将(3)创建的文件夹使用jar命令进行压缩,生成.war为后缀的文件,然后拷贝。

(5)启动servlet容器,访问servlet。http://ip:port/appname/url-pattern

比如,在浏览器地址栏输入: http://localhost:8080/firstweb/sayHello

二.Servlet原理

1、Servlet运行原理

比如,在浏览器地址栏输入:http://ip:port/web01/hello

(1)浏览器依据ip,port建立与servlet容器之间的连接。

(2)浏览器将请求数据打包(即按照http协议的要求,将相关数据封装成一个数据包,一般称之为请求数据包)并发送给servlet容器。

(3)servlet容器解析请求数据包,并将解析之后得到的数据放到request对象上。同时,容器还要创建一个response对象。

(4)servlet容器依据请求资源路径(即/web06/hello)找到servlet的配置,然后创建servlet对象。

(5)容器接下来调用servlet对象的service方法,并且会将事先创建好的request对象和response对象作为service方法的参数传递给servlet对象。

(6)servlet可以通过request对象获得请求参数,进行相应的处理,然后将处理结果写到response对象上。

(7)容器读取response对象上的数据,然后将处理结果打包(响应数据包)并发送给浏览器。

(8)浏览器解析响应数据包,将返回的数据展现给用户。

2、Servlet容器处理请求资源路径

比如,在浏览器地址栏输入:http://ip:port/appname/abc.html,浏览器会将"/appname/abc.html"作为请求资源路径发送给servlet容器。

(1)servlet容器会先假设访问的是一个servlet,会依据应用名(appname)找到应用所在的文件夹,然后找到web.xml文件。

(2)匹配<url-pattern>:

a.精确匹配(完全匹配):

b.通配符匹配: 使用"*"来匹配任意长度的字符串。

比如:

<url-pattern>/*</url-pattern>

<url-pattern>/abc/*</url-pattern>

c.后缀匹配: 使用"*."开头,后接任意的字符串,

比如:<url-pattern>*.do</url-pattern>以上,表示匹配所以.do结尾的请求。

(3)如果都不匹配,则容器认为访问的是一个静态资源文件(比如 html文件),然后容器会查找该文件,如果找到则返回,否则会返回404。

(4)一个servlet处理多种请求

使用后缀匹配模式,比如<url-pattern>*.do</url-pattern>

分析请求资源路径,然后依据分析的结果分别进行不同的处理。String request.getRequestURI();//获得请求资源路径

3、Servlet的生命周期

servlet的生命周期的含义?

servlet容器如何去创建servlet对象,如何给servlet对象分配资源,如何调用servlet对象的方法来处理请求,以及如何去销毁servlet对象的整个过程。

servlet生命周期的四个阶段:

(1)实例化

a.实例化,指的是容器调用servlet的构造器,创建servlet对象。

b.什么时候实例化?

情况1:容器收到请求之后才创建servlet对象。在默认情况下,容器只会为servlet创建唯一的一个实例。

情况2: 容器事先(容器启动时)将某些servlet(需要配置load-on-startup参数)对象创建好。load-on-startup参数值必须是 >=0的整数,越小,优先级(即先被实例化)越高。

(2)初始化

a.初始化,指的是容器在创建好servlet对象之后,会立即调用servlet对象的init方法。

b.init方法:

b1.init方法只会执行一次。

b2.GenericServlet已经实现了init方法,该方法会将容器创建好的ServletConfig对象作为参数传给init方法。

b3.ServletConfig对象提供了一个getInitParameter方法来访问servlet的初始化参数。

step1:在web.xml文件里面,使用<init-param>来配置初始化参数

step2:String getInitParameter(String paraName);

b4.如果GenericServlet的init方法提供的初始化操作不满足需要,可以override init()方法。

(3)就绪

a.就绪指的是servlet对象可以接受调用了,容器收到请求之后,会调用servlet对象的service方法来处理。

b.HttpServlet已经实现了service方法,该方法会依据请求类型(get/post)分别调用doGet,doPost方法。

所以在写一个servlet时,有两种选择:

选择1:override HttpServlet的doGet,doPost方法。

选择2:override HttpServlet的service方法。

(4)销毁

a.销毁指的是servlet容器在销毁servlet对象之前,会调用destroy方法。

b.destroy方法只会执行一次。

4、Servlet生命周期相关的几个接口与类

(1)Servlet接口

a.init(ServletConfig config)

b.service(ServletRequest req,ServletResponse res)

c.destroy()

(2)GenericServlet抽象类:实现了Servlet接口中的init,destroy方法。

(3)HttpServlet抽象类:继承了GenericServlet抽象类,实现了service方法。

(4)ServletConfig接口:String getInitParameter(String paraName)。

(5)ServletRequest接口是HttpServletRequest的父接口,ServletResponse接口是HttpServletResponse的父接口。

5、转发

(1)什么是转发

一个web组件(servlet/jsp)将未完成的处理通过容器转交给另外一个web组件继续完成。常见的情况是: 一个servlet将数据处理完毕之后,转交给一个jsp去展现。

(2)如何转发。

step1:绑订数据到request:request.setAttribute(String name,Object obj);//name:绑订名, obj:绑订值

step2:获得一个转发器:RequestDispatcher rd = request.getRequestDispatcher(String url);//url:要转发给哪一个web组件

step3:转发:rd.forward(request,response);

step4:在转发的目的地,可以使用request.getAttribute方法获得绑订的数据,然后进行处理。Object request.getAttribute(String name);//如果name对应的值不存在,会返回null。

(3)编程需要注意的两个问题。

a.转发之前,先清空response对象中缓存的数据。

b.转发之前,不能够调用out.close()。

(4)转发的特点

a.转发的目的地只能够是同一个应用内部的某个组件的地址。

b.转发之后,浏览器地址栏的地址不变。

(5)转发与重定向的区别

a、转发的目的地只能是同一个应用内部某个组件的地址,而重定向的目的地是任意的。

b、转发之后,浏览器地址栏的地址不变,而重定向会变。

c、转发所涉及的各个web组件可以共享request对象,而重定向不可以。

d、转发是一件事情未做完,而重定向是一件事情已经做完。

6、让容器来处理系统异常

(1)将异常抛给容器throw new ServletException(e);

(2)编写一个错误处理页面,比如system_error.jsp

(3)配置错误处理页面(让容器知道,当捕获到了相应的异常后,应该调用哪一个页面)。

<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/system_error.jsp</location>
</error-page>

7、路径问题

即链接地址、表单提交地址、重定向、转发这四种情况下,

如何写正确的路径(地址)。

<a href="list.do"></>
<form action="add.do">
response.sendRedirect("list.do");
request.getRequestDispatcher("emplist.jsp");

(1)什么是相对路径?不以"/"开头的路径;

(2)什么是绝对路径?以"/"开头的路径;

(3)如何写绝对路径?链接地址,表单提交地址,重定向的绝对路径应该从应用名开始写,而转发应该从应用名之后开始写。

//获得实际部署时的应用名String request.getContextPath();

8、状态管理

(1)什么是状态管理?将浏览器与web服务器之间多次交互当做一个整体来看待,并且将多次交互所涉及的数据保存下来。

(2)如何进行状态管理?

第一大类:客户端状态管理技术:即将状态(也就是多次交互所涉及的数据)保存在客户端(浏览器)。

第二大类:服务器端状态管理技术:即将状态保存在web服务器端。

9、cookie

(1)什么是cookie?

a.是一种客户端的状态管理技术。

b.当浏览器访问服务器的时候,服务器可以将少量的数据以set-cookie消息头的方式发送给浏览器,浏览器会将这些数据保存下来;

当浏览器再次访问服务器时,会将之前保存的这些数据以cookie消息头的方式发送给服务器。

(2)如何创建一个cookie?

Cookie c = new Cookie(String name,String value);//name:cookie的名称, value:cookie的值。

response.addCookie(c);

(3)查询cookie

Cookie[] request.getCookies();//如果没有任何的cookie,返回null。

String cookie.getName();//返回cookie的名称;

String cookie.getValue();//返回cookie的值;

(4)编码问题

cookie的值或者名称只允许出现合法的ascii字符串。

如果是中文,需要将中文转换成ascii字符串。

String URLEncoder.encode(String str,String code);

String URLDecoder.decode(String str,String code);

(5)cookie的生存时间

默认情况下,浏览器会将cookie保存在内存里,只要浏览器不关闭,cookie会一直存在。

cookie.setMaxAge(int seconds);

注意:

a.单位是秒。

b.当seconds > 0时,浏览器会将cookie保存在硬盘上,

当cookie保存的时间超过了seconds,则cookie会被浏览器删除。

当seconds < 0时,缺省值(浏览器会将cookie保存在内存里)。

当seconds = 0时,删除cookie。

比如,要删除名称为userId的cookie:

Cookie c = new Cookie("userId","");

c.setMaxAge(0);

response.addCookie(c);

10、session (会话)。

(1)session是什么

a.session是服务器端的状态管理技术。

b.当浏览器访问服务器时,服务器会创建一个session对象(该对象有一个唯一的id号,称之为sessionId),

接下来,服务器在默认情况下,会使用set-cookie消息头将这个sessionId发送给浏览器,浏览器会将这个sessionId保存下来(内存);

当浏览器再次访问服务器时,会将sessionId使用cookie消息头发送给服务器,服务器依据这个sessionId就可以找到之前创建的session对象。

(2)如何获得一个session对象

方式一:

HttpSession s = request.getSession(boolean flag);//HttpSession是一个接口

当flag = true时:服务器会先检查请求当中是否有sessionId,如果没有,则创建一个session对象。

如果有sessionId,则服务器会依据sessionId查找对应的session对象,如果找到了,则返回。找不到,服务器会创建一个新的session对象。

当flag = false时:服务器会先检查请求当中是否有sessionId,如果没有,则返回null。

如果有sessionId,则服务器会依据sessionId查找对应的session对象,如果找到了,则返回,找不到,返回null。

方式二:HttpSession s = request.getSession();等价于request.getSession(true)。

(3)HttpSession接口中提供的常用方法

String getId();//获得sessionId

setAttribute(String name,Object obj);//绑订一个对象到session对象上。

Object getAttribute(String name);//获得绑订对象,如果不存在,返回null。

removeAttribute(String name);//解除绑订

(4)session的超时

服务器会将空闲时间过长的session对象删除掉。服务器默认的session超时限制一般是30分钟,可以修改这个默认的超时限制,比如,可以修改tomcat的web.xml文件。

<session-config>
<session-timeout>30</session-timeout>
</session-config>

修改之后需要重新启动tomcat服务器。也可以修改某个应用的web.xml。也可以通过编程的方式来修改超时的限制setMaxInactiveInterval(int seconds);

(5)立即删除session:invalidate()。

11、session案例

(1)session验证

sessino验证经常用于保护一些需要登录之后才能访问的资源。

比如,只有登录成功以后,才能访问main.jsp。

step1:登录成功以后,绑订一些数据到session对象上。

比如:session.setAttribute("user",user);

step2:对于需要保护的资源,添加session验证的代码。

比如:

Object obj = session.getAttribute("user");
if(obj == null){
response.sendRedirect("login.jsp");//没有登录成功,或者因为session超时,服务器已经删除了之前的session对象。
}

(2)验证码:生成一个验证码,要求长度为5,并且随机从"A~Z,0~9"选取。

(3)用户禁止cookie以后,如果继续使用session。

(1)如果用户禁止cookie,服务器仍然会将sessionId以cookie的方式发送给浏览器,但是,浏览器不再保存这个cookie(即sessionId)了。

(2)如果想继续使用session,需要采取其它方式来实现。

sessionId的跟踪。可以使用url重写来实现sessionId的跟踪。

(4)url重写

1).什么是url重写。

浏览器在访问服务器上的某个地址时,不能够直接写这个组件的地址,而应该使用服务器生成的这个组件的

地址。

比如,

<a href="some">someServlet</a> 错误!

应该

<a href="<%=response.encodeURL("some")%>">

someServlet</a>encodeURL方法会在"some"后面添加sessionId。

(5)如何进行url重写。

a.response.encodeURL(String url); //encodeURL方法用于链接地址、表单提交地址。

比如:<form action="<%=response.encodeURL("some")%>">

b.response.encodeRedirectURL(String url);//encodeRedirectURL方法用于重定向地址。

比如:

response.sendRedirect(

response.encodeRedirectURL("list.do"));

(6)session优点与缺点

优点:
a.session比较安全(相对于cookie)

b.session能够保存的数据类型更加丰富(cookie只能保存字符串)

c.session能够保存的数据大小更大(cookie只能保存大约4k左右的数据)

d.cookie可以被用户禁止,而session没有这个问题。

缺点:

a.session会将数据放在服务器端,所以,对服务器的资源的占用比较大。而cookie会将数据保存在浏览器端,对服务器资源的占用没有。

b.session默认情况下,会将sessionId以cookie的方式发送给浏览器,浏览器会将session保存到内存里面,

如果浏览器关闭,浏览器发请求时就没有sessionId,服务器端的session对象就找不到了。

12、过滤器

(1)什么是过滤器

servlet规范当中定义的一种特殊的组件,可以拦截servlet容器的调用过程并进行相应的处理。

(2)如何写一个过滤器

step1:写一个java类,实现Filter接口。

step2:在doFilter方法里面,编写处理业务逻辑。

step3:配置过滤器。

(3)过滤器的优先级

如果有多个过滤器都满足过滤的条件,则容器会依据<filter-mapping>的先后顺序来调用过滤器。

(4)初始化参数

step1:使用<init-param>配置初始化参数

step2:调用 String FilterConfig.getInitParameter(String paramname);

(5)优点

a.可以实现代码的“可插拔性”(增加或者减少某个模块,不会影响程序的正常运行)。

b.可以将多个组件相同的处理逻辑集中写在过滤器里面,方便代码的维护。

13、监听器

(1)什么是监听器

servlet规范当中定义的一种特殊的组件,用来监听容器产生的事件并进行处理。容器会产生两大类事件:

a.生命周期相关的事件:容器在创建或者销毁request,session,servletContext(servlet上下文)时产生的事件。

b.绑订相关的事件:容器调用了request,session,servletContext的setAttribute,removeAttribute时产生的事件。

(2)如何写一个监听器

step1:写一个java类,实现监听器接口(依据监听的事件类型来选择对应的接口)。

step2:在监听器接口定义的方法里面,编写处理业务逻辑。

step3:配置统计在线人数。

(3)ServletContext

a.容器在启动的时候,会为每一个应用创建唯一的一个符合ServletContext接口要求的对象(Servlet上下文),该对象会一直存在,除非容器关闭。

b.如何获得Servlet上下文

b1.GenericServlet.getServletContext();

b2.HttpSession.getServletContext();

b3.ServletConfig.getServletContext();

b4.FilterConfig.getServletContext();

c.作用:

c1.绑订数据

setAttribute,removeAttribute,getAttribute

request,session,servletContext都提供了绑订数据相关的三个方法。如果都满足使用的条件,应该优先使用生命周期短的(request的生存时间<session<servletContext)。

request对象上绑订的数据只有同一个请求所涉及的各个web组件可以共享,比如:

一个servlet将数据绑订到request,然后转发到一个jsp。请求先交给过滤器来处理,然后调用servlet。

session对象上绑订的数据是同一个会话所涉及的各个web组件可以共享。servletContext绑订的数据是公开的,谁都可以访问,而且随时可访问。

c2.访问全局的初始化参数

即使用<context-param>配置的初始化参数,可以被同一个应用中的所有的servlet,filter共享。

String getInitparameter(String paraName);

c3.依据逻辑路径(path)获得实际部署时的物理路径。

String getRealPath(String path);

14、上传文件

step1:给表单设置enctype="multipart/form-data"。(http协议要求),并且,表单只能使用post方式来提交。

step2:在服务器端,不能够使用request.getParameter方法。此时,需要调用request.getInputStream获得一个InputStream,

然后,分析这个流来获得数据。一般,使用一些工具来分析这个流(比如,apache提供的file-upload.jar)。

15、servlet线程安全问题

(1)为什么说servlet会有线程安全问题。

当容器收到一个请求之后,会启动一个线程来处理该请求,如果有多个请求到达容器,并且这多个请求要访问的是同一个servlet,则会发生多个线程调用同一个servlet的情况,

此时,就需要考虑线程安全问题了,比如,这多个线程都要修改servlet的属性值。

(2)如何处理线程安全问题

a.加锁:使用synchronized对方法或者代码块加锁。加锁会影响一些性能。

b.让一个servlet实现SingleThreadModel接口。容器会为这样的servlet(实现了SingleThreadModel接口)

创建多个实例(一个线程一个实例)。因为有可能会产生过多的servlet实例,所以,在比较大型的应用当中,尽量少用。

三.JSP是什么

jsp (java server page)java服务器端动态页面,是sun公司制订的一种服务器端的动态页面生成技术规范。

1、Jsp九大内置对象对应servlet中的java对象

(1)page——this

(2)pageContext——PageContext

(3)request——HttpServletRequest

(4)response——HttpServletResponse

(5)config——ServletConfig

(6)exception——Throwable

(7)out——JspWriter

(8)session——HttpSession

(9)application——ServletContext

2、为什么要使用jsp

因为直接使用servlet,虽然也可以生成动态页面,但是编写繁琐(需要使用out.println来输出),并且维护困难(如果页面发生了改变,需要修改java代码),所以sun制订了jsp规范。

jsp其实是一个以.jsp为后缀的文件,容器会自动将.jsp文件转换成一个.java文件(其实就是一个servlet),然后调用该servlet。所以,从本质上讲,jsp其实就是一个servlet。

3、如何写一个jsp文件

(1)创建一个以".jsp"为后缀的文件。

(2)在该文件里面,可以添加如下的内容:

1)html (css,js):直接写即可。

2)java代码:

a.java代码片断:<% java代码 %>

b.jsp表达式:<%= java表达式 %>

3)隐含对象:

所谓隐含对象,指的是在.jsp文件里面直接可以使用的对象,比如out,request,response。之所以能直接使用这些对象,是因为容器会自动添加创建这些对象的代码。

什么是pageContext?容器会为每一个jsp实例(jsp所对应的那个servlet对象)创建唯一的一个符合PageContext接口的对象,称之为page上下文。该对象会一直存在,除非jsp实例被销毁。

作用:

绑订数据:setAttribute,removeAttribute,getAttributepageContext上面绑订的数据只有对应的jsp实例能访问。

找到其它八个隐含对象(jsp标签时再说)

config: ServletConfig实例 (a5.jsp),可以使用该对象来访问jsp的初始化参数。

page: jsp实例本身。

4)指令:

指令是什么?通知容器,在将.jsp文件转换成.java文件时,做一些额外的处理,比如导包。

指令的语法<%@指令名称 属性名=属性值 %>

c.page指令c1,import属性:导包比如: <%@page import="java.util.*"%><%@page import="java.util.*,java.text.*"%>

c2.contentType属性:设置response.setContentType的内容, 比如:<%@page contentType="text/html;charset=utf-8"%>

c3.pageEncoding属性:告诉容器.jsp文件的编码格式,这样,容器在读取jsp文件的内容时(即解码)时,不会出现乱码。

page指令

import属性:导包

pageEncoding属性:告诉容器,jsp文件的编码。

contentType属性:设置response.setContentType的内容。

session属性:true(缺省值)/false,如果值为false,则容器不会添加获得session的语句。 (a2.jsp)

isELIgnored属性:true(缺省值)/false,如果值为false,告诉容器不要忽略el表达式。

isErrorPage属性:true/false(缺省值),如果值为true,表示这是一个错误处理页面(即专门用来处理其它jsp产生的异常,只有当isErrorPage=true时,才能使用exception隐含对象)。(a3.jsp,a4.jsp)

errorPage属性:设置一个错误处理页面。

d.include指令file属性:将某个文件的内容(由file属性指定)插入到该指令所在的位置。

1.include指令。

告诉容器,在将.jsp文件转换成.java文件时,在指令所在的位置插入相应的文件的内容。

比如: <%@include file="head.jsp"%>

e.taglib指令:导入jsp标签。

5)注释 (a6.jsp)

<!-- 注释的内容 --> : 允许注释的内容是java代码,如果是java代码,会被容器执行。但是,执行发的结果会被浏览器忽略(不会显示出来)

<%-- 注释的内容 --%> : 注释的内容不能是java代码,如果是java代码,会被容器忽略。

4、jsp是如何运行的

(1)容器依据.jsp文件生成.java文件(就是一个servlet)。

a.html (css,js) ----> service方法里,使用out.write输出。

b.<% %> -----> service方法里,照搬。

(2)容器接下来就会调用servlet来处理请求了(会将之前生成的.java文件进行编译、然后实例化、初始化、调用相应的方法处理请求)。

c.<%= %> ------> service方法里,使用out.print输出。

5、jsp标签和el表达式

(1)jsp标签是什么?

sun公司制订的一种技术规范,利用jsp标签(类似于html标签)来代替jsp中的java代码。这样做的好处是,jsp页面会更简洁,并且更好维护。

(2)jstl是什么?

java standard taglib(java标准标签库,apache开发了一套标签,捐献给了sun,sun将其命名为jstl)。

step1,将jstl标签对应的jar文件拷贝到WEB-INF\lib下。C:\Program Files\MyEclipse 5.5.1 GA\myeclipse\eclipse\plugins\com.genuitec.eclipse.j2eedt.core_5.5.1\data\libraryset\JSTL1.1\libstandard.jar jstl.jar

step2,使用taglib指令引入jsp标签。

(3)el表达式是什么?

是一套简单的计算规则,用于给jsp标签的属性赋值,也可以直接输出。

(4)el表达式的使用

访问bean的属性

第一种方式:a3.jsp

比如: ${user.name}

容器会依次从pageContext,request,session,application中查找(getAttribute)

绑订名为"user"的对象,接下来,会调用该对象的"getName"方法,最后输出执行结果。

依次:先从pageContext中查找,如果找不到,再查找request,如果找到了,则不再向下查找。

相比于直接写java代码,有两个优点:

第1个优点:会将null转换成""输出。

第2个优点:如果绑订名称对应的值不存在,不会报null指针异常,会输出""。

如果要指定查找范围,可以使用pageScope,requestScope,sessionScope,applicationScope来指定查找的范围。

第二种方式: a4.jsp

比如: ${user["name"]},这种方式的优点有两个:

第1:[]里面允许出现变量

第2:[]里面允许出现从0开始的下标,用来访问数组中的某个元素。

2).进行一些简单的计算,计算的结果可以用来给jsp

标签的属性赋值,也可以直接输出。 (a5.jsp)

a.算术运算: "+","-","*","/","%",注意,"+"号操作不能够连接字符串。

b.关系运算: ">",">=","<","<=","!=","=="

c.逻辑运算: "&&","||","!"

d.empty运算: 判断是否是一个空字符串,或者是一个空的集合,如果是,返回true。

以下四种情况都是true:

d1.空字符串

d2.空的集合

d3.null

d4.找不到值

3)获取请求参数值(a6.jsp)

${param.username} 等价于request.getParameter("username");

${paramValues.city} 等价于request.getParameterValues("city");

(5)jstl中的几个核心标签

1)if(a7.jsp)

<c:if test="" var="" scope="">

标签体

</c:if>

当test属性值为true,执行标签体的内容,test属性可以使用el表达式。

var属性用来指定绑订名称。

scope属性指定绑订的范围,可以是"page","request",

"session","application"。

2)choose(a8.jsp)

<c:choose>

<c:when test="">

</c:when>
...
<c:otherwise>

</c:otherwise>

</c:choose>

when和otherwise必须要放到choose标签里面才能使用。when可以出现1次或者多次,otherwise可以出现0次或者1次。

3)forEach(a9.jsp)

<c:forEach var="" items="" varStatus="">

</c:forEach>

用来遍历集合,其中,items属性用来指定要遍历的集合,可以使用el表达式。var属性指定绑订名,绑订范围是

pageContext,绑订值是集合中的某个元素。

varStatus属性指定绑订名,绑订范围是pageContext,绑订值是一个由容器创建的一个对象,该对象封装了当前迭代的状态。比如,该对象提供了getIndex,getCount

方法,其中,getIndex会返回当前迭代的元素的下标(从0开始),getCount会返回当前迭代的次数(从1开始)。

6、jsp标签是如何运行的

容器依据命名空间找到标签的描述文件(.tld文件),接下来,依据标签的名称找到标签类的类名,然后将该标签类实例化,最后,调用标签实例的相应的方法。

注意:容器会从WEB-INF下查找,如果找不到,还会查找 WEB-INF\lib下的jar文件。

(1)自定义标签

step1:写一个java类,继承SimpleTagSupport类。

step2:在doTag方法里面,编写相应的处理逻辑。

step3:在.tld文件当中,描述该标签。.tld文件可以放在WEB-INF下,也可以放到META-INF下。可以参考c.tld文件来写。

<body-content>的作用是告诉容器,标签有没有标签体,如果有标签体,标签体里面可以出现哪些内容。

可以有三个值,分别是:

a.empty :没有标签体。

b.scriptless:可以有标签体,但是,标签体里面不能够出现java代码(<% %> <%= %> <%! %>)

c.JSP:有标签体,并且标签体的内容可以是java代码。只有复杂标签技术支持JSP,简单标签技术只支持empty和scriptless。

(2)javaee5.0当中,如何使用el表达式和jstl。

tomcat5.5---> servlet2.4 ---> j2ee 1.4

tomcat6.0---> servlet2.5 ---> javaee5.0

在javaee5.0以上版本当中,已经将jstl标签库对应的jar文件包含进来了,不用再去将这些jar文件拷贝到WEB-INF\lib下。

相关推荐