zoukankan      html  css  js  c++  java
  • 关于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-INFlib下。C:Program FilesMyEclipse 5.5.1 GAmyeclipseeclipsepluginscom.genuitec.eclipse.j2eedt.core_5.5.1datalibrarysetJSTL1.1libstandard.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-INFlib下的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-INFlib下。

  • 相关阅读:
    hdu1542线段树+离散化+扫描线
    Codeforces Round #373 (Div. 2)
    Codeforces Round #381 (Div. 2)
    Codeforces Round #352 (Div. 2)
    CodeForces
    poj3311 状压dp+floyd
    CodeForces 385 D.Bear and Floodlight 状压DP
    Codeforces Round #299 (Div. 2)D. Tavas and Malekas
    Tavas and Karafs 二分+结论
    ThikPHP3.1 常用方法(one)
  • 原文地址:https://www.cnblogs.com/ZJOE80/p/13064650.html
Copyright © 2011-2022 走看看