关于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下。