布置形貌符文件就像一切XML文件一样,必须以一个XML头最先。这个头声明可以运用的XML版本并给出文件的字符编码。
DOCYTPE声明必须马上涌如今此头今后。这个声明关照服务器实用的servlet范例的版本(如2.2或2.3)并指定治理此文件其他部份内容的语法的DTD(Document Type Definition,文档范例定义)。
一切布置形貌符文件的顶层(根)元素为web-app。请注重,XML元素不像HTML,他们是大小写敏感的。因而,web-App和WEB-APP都是不正当的,web-app必须用小写。
2 布置形貌符文件内的元素序次
XML 元素不仅是大小写敏感的,而且它们还对涌如今其他元素中的序次敏感。比方,XML头必须是文件中的第一项,DOCTYPE声明必须是第二项,而web- app元素必须是第三项。在web-app元素内,元素的序次也很重要。服务器不肯定强迫要求这类序次,但它们许可(现实上有些服务器就是如许做的)完全拒绝实行含有序次不准确的元素的Web运用。这示意运用非规范元素序次的web.xml文件是不可移植的。
下面的列表给出了一切可直接涌如今web-app元素内的正当元素所必须的序次。比方,此列表申明servlet元素必须涌如今一切servlet-mapping元素之前。请注重,一切这些元素都是可选的。因而,可以省略掉某一元素,但不能把它放于不准确的位置。
l icon icon元素指出IDE和GUI东西用来示意Web运用的一个和两个图象文件的位置。
l display-name display-name元素供应GUI东西能够会用来标记这个特定的Web运用的一个称号。
l description description元素给出与此有关的申明性文本。
l context-param context-param元素声明运用范围内的初始化参数。
l filter 过滤器元素将一个名字与一个完成javax.servlet.Filter接口的类相干联。
l filter-mapping 一旦命名了一个过滤器,就要应用filter-mapping元素把它与一个或多个servlet或JSP页面相干联。
l listener servlet API的版本2.3增加了对事宜监听顺序的支撑,事宜监听顺序在竖立、修正和删除会话或servlet环境时取得关照。Listener元素指出事宜监听顺序类。
l servlet 在向servlet或JSP页面制订初始化参数或定制URL时,必须起首命名servlet或JSP页面。Servlet元素就是用来完成此项使命的。
l servlet-mapping 服务器平常为servlet供应一个缺省的URL:http://host/webAppPrefix/servlet/ServletName。然则,常常会变动这个URL,以便servlet可以接见初始化参数或更轻易地处置惩罚相对URL。在变动缺省URL时,运用servlet-mapping元素。
l session-config 如果某个会话在肯定时刻内未被接见,服务器可以扬弃它以勤俭内存。可经由历程运用HttpSession的setMaxInactiveInterval要领明白设置单个会话对象的超时价,也许可应用session-config元素制订缺省超时价。
l mime-mapping 如果Web运用具有想到特别的文件,愿望能保证给他们分派特定的MIME范例,则mime-mapping元素供应这类保证。
l welcom-file-list welcome-file-list元素指导服务器在收到援用一个目次名而不是文件名的URL时,运用哪一个文件。
l error-page error-page元素使得在返回特定HTTP状况代码时,也许特定范例的非常被抛出时,可以制订将要显现的页面。
l taglib taglib元素对标记库形貌符文件(Tag Libraryu Descriptor file)指定别号。此功能使你可以变动TLD文件的位置,而不必编辑运用这些文件的JSP页面。
l resource-env-ref resource-env-ref元素声明与资本相干的一个治理对象。
l resource-ref resource-ref元素声明一个资本工场运用的外部资本。
l security-constraint security-constraint元素制订应当庇护的URL。它与login-config元素团结运用
l login-config 用login-config元夙来指定服务器应当怎样给试图接见受庇护页面的用户受权。它与sercurity-constraint元素团结运用。
l security-role security-role元素给出平安角色的一个列表,这些角色将涌如今servlet元素内的security-role-ref元素的role-name子元素中。离别地声明角色可以使高等IDE处置惩罚平安信息更加轻易。
l env-entry env-entry元素声明Web运用的环境项。
l ejb-ref ejb-ref元素声明一个EJB的主目次的援用。
l ejb-local-ref ejb-local-ref元素声明一个EJB的当地主目次的运用。
3 分派称号和定制的UL
在web.xml中完成的一个最罕见的使命是对servlet或JSP页面给出称号和定制的URL。用servlet元素分派称号,运用servlet-mapping元素将定制的URL与刚分派的称号相干联。
3.1 分派称号
为了供应初始化参数,对servlet或JSP页面定义一个定制URL或分派一个平安角色,必须起首给servlet或JSP页面一个称号。可经由历程 servlet元素分派一个称号。最罕见的花样包括servlet-name和servlet-class子元素(在web-app元素内),以下所示:
Xml代码
<servlet> <servlet-name>Test</servlet-name> <servlet-class>moreservlets.TestServlet</servlet-class> </servlet> <servlet><servlet-name>Test</servlet-name><servlet-class>moreservlets.TestServlet</servlet-class></servlet>
这示意位于WEB-INF/classes/moreservlets/TestServlet的servlet已取得了注册名Test。给 servlet一个称号具有两个重要的寄义。起首,初始化参数、定制的URL情势以及其他定制经由历程此注册名而不是类名援用此servlet。其次,可在 URL而不是类名中运用此称号。因而,应用适才给出的定义,URL http://host/webAppPrefix/servlet/Test 可用于 http://host/webAppPrefix/servlet/moreservlets.TestServlet 的场合。
请记着:XML元素不仅是大小写敏感的,而且定义它们的序次也很重要。比方,web-app元素内一切servlet元素必须位于一切servlet- mapping元素(下一小节引见)之前,而且还要位于5.6节和5.11节议论的与过滤器或文档相干的元素(如果有的话)之前。相似地,servlet 的servlet-name子元素也必须涌如今servlet-class之前。5.2节"布置形貌符文件内的元素序次"将仔细引见这类必须的序次。
比方,顺序清单5-1给出了一个名为TestServlet的简朴servlet,它驻留在moreservlets顺序包中。由于此servlet是扎根在一个名为deployDemo的目次中的Web运用的构成部份,所以TestServlet.class放在deployDemo/WEB- INF/classes/moreservlets中。顺序清单5-2给出将安排在deployDemo/WEB-INF/内的web.xml文件的一部份。此web.xml文件运用servlet-name和servlet-class元素将称号Test与TestServlet.class相干联。图 5-1和图5-2离别显现应用缺省URL和注册名挪用TestServlet时的效果。
顺序清单5-1 TestServlet.java
Java代码
package moreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String uri = request.getRequestURI(); out.println(ServletUtilities.headWithTitle("Test Servlet") +"<BODY BGCOLOR=\"#FDF5E6\">\n" +"<H2>URI: " + uri "</H2>\n" +"</BODY></HTML>"); } } package moreservlets;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class TestServlet extends HttpServlet {public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();String uri = request.getRequestURI();out.println(ServletUtilities.headWithTitle("Test Servlet") +"<BODY BGCOLOR=\"#FDF5E6\">\n" +"<H2>URI: " + uri "</H2>\n" +"</BODY></HTML>");}}
顺序清单5-2 web.xml(申明servlet称号的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- … --> <servlet> <servlet-name>Test</servlet-name> <servlet-class>moreservlets.TestServlet</servlet-class> </servlet> <!-- … --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- … --><servlet><servlet-name>Test</servlet-name><servlet-class>moreservlets.TestServlet</servlet-class></servlet><!-- … --></web-app>
3.2 定义定制的URL
大多半服务器具有一个缺省的serlvet URL:
host/webAppPrefix/servlet/packageName.ServletName。虽然在开辟中运用这个URL很轻易,然则我们常常会愿望另一个URL用于布置。比方,能够会须要一个涌如今Web运用顶层的URL(如,host/webAppPrefix/Anyname),而且在此URL中没有servlet项。位于顶层的URL简化了相对URL的运用。另外,对很多开辟人员来讲,顶层URL看上去比更长更贫苦的缺省URL更简短。
事实上,有时须要运用定制的URL。比方,你能够想关闭缺省URL映照,以便更好地强迫实行平安限制或防备用户意外埠接见无初始化参数的servlet。如果你制止了缺省的URL,那末你怎样接见servlet呢?这时刻只需运用定制的URL了。
为了分派一个定制的URL,可运用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素供应了一个恣意称号,可应用此称号援用相应的servlet;url-pattern形貌了相关于Web运用的根目次的URL。url- pattern元素的值必须以斜杠(/)肇端。
下面给出一个简朴的web.xml摘录,它许可运用URL host/webAppPrefix/UrlTest而不是host/webAppPrefix/servlet/Test或
host/webAppPrefix/servlet/moreservlets.TestServlet。请注重,依然须要XML头、 DOCTYPE声明以及web-app关闭元素。另外,可回忆一下,XML元素涌现地序次不是随便的。特别是,须要把一切servlet元素放在一切 servlet-mapping元素之前。
Xml代码
<servlet> <servlet-name>Test</servlet-name> <servlet-class>moreservlets.TestServlet</servlet-class> </servlet> <!-- ... --> <servlet-mapping> <servlet-name>Test</servlet-name> <url-pattern>/UrlTest</url-pattern> </servlet-mapping> <servlet><servlet-name>Test</servlet-name><servlet-class>moreservlets.TestServlet</servlet-class></servlet><!-- ... --><servlet-mapping><servlet-name>Test</servlet-name><url-pattern>/UrlTest</url-pattern></servlet-mapping>
URL情势还可以包括通配符。比方,下面的小顺序指导服务器发送一切以Web运用的URL前缀最先,以..asp完毕的要求到名为BashMS的servlet。
Xml代码
<servlet> <servlet-name>BashMS</servlet-name> <servlet-class>msUtils.ASPTranslator</servlet-class> </servlet> <!-- ... --> <servlet-mapping> <servlet-name>BashMS</servlet-name> <url-pattern>/*.asp</url-pattern> </servlet-mapping> <servlet><servlet-name>BashMS</servlet-name><servlet-class>msUtils.ASPTranslator</servlet-class></servlet><!-- ... --><servlet-mapping><servlet-name>BashMS</servlet-name><url-pattern>/*.asp</url-pattern></servlet-mapping>
3.3 命名JSP页面
由于JSP页面要转换成sevlet,天然愿望就像命名servlet一样命名JSP页面。毕竟,JSP页面能够会从初始化参数、平安设置或定制的URL中受益,正如一般的serlvet那样。虽然JSP页面的背景现实上是servlet这句话是准确的,但存在一个症结的怀疑:即,你不知道JSP页面的现实类名(由于体系本身遴选这个名字)。因而,为了命名JSP页面,可将jsp-file元素替换为servlet-calss元素,以下所示:
Xml代码
<servlet> <servlet-name>Test</servlet-name> <jsp-file>/TestPage.jsp</jsp-file> </servlet> <servlet><servlet-name>Test</servlet-name><jsp-file>/TestPage.jsp</jsp-file></servlet>
命名JSP页面的缘由与命名servlet的缘由完全雷同:即为了供应一个与定制设置(如,初始化参数和平安设置)一同运用的称号,而且,以便能变动激活 JSP页面的URL(比方说,以便多个URL经由历程雷同页面得以处置惩罚,也许从URL中去掉.jsp扩展名)。然则,在设置初始化参数时,应当注重,JSP页面是应用jspInit要领,而不是init要领读取初始化参数的。
比方,顺序清单5-3给出一个名为TestPage.jsp的简朴JSP页面,它的事变只是打印出用来激活它的URL的当地部份。TestPage.jsp安排在deployDemo运用的顶层。顺序清单5-4给出了用来分派一个注册名PageName,然后将此注册名与http://host/webAppPrefix/UrlTest2/anything 情势的URL相干联的web.xml文件(即,deployDemo/WEB-INF/web.xml)的一部份。
顺序清单5-3 TestPage.jsp
Html代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>JSP Test Page</TITLE> </HEAD> <BODY BGCOLOR="#FDF5E6"> <H2>URI: <%= request.getRequestURI() %></H2> </BODY> </HTML> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>JSP Test Page</TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><H2>URI: <%= request.getRequestURI() %></H2></BODY></HTML>
顺序清单5-4 web.xml(申明JSP页命名的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <servlet> <servlet-name>PageName</servlet-name> <jsp-file>/TestPage.jsp</jsp-file> </servlet> <!-- ... --> <servlet-mapping> <servlet-name> PageName </servlet-name> <url-pattern>/UrlTest2/*</url-pattern> </servlet-mapping> <!-- ... --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- ... --><servlet><servlet-name>PageName</servlet-name><jsp-file>/TestPage.jsp</jsp-file></servlet><!-- ... --><servlet-mapping><servlet-name> PageName </servlet-name><url-pattern>/UrlTest2/*</url-pattern></servlet-mapping><!-- ... --></web-app>
4 制止激活器servlet
对servlet或JSP页面竖立定制URL的一个缘由是,如许做可以注册从 init(servlet)或jspInit(JSP页面)要领中读取得初始化参数。然则,初始化参数只在是应用定制URL情势或注册名接见 servlet或JSP页面时可以运用,用缺省URL http://host/webAppPrefix/servlet/ServletName 接见时不能运用。因而,你能够会愿望关闭缺省URL,如许就不会有人意外埠挪用初始化servlet了。这个历程有时称为制止激活器servlet,由于多半服务器具有一个用缺省的servlet URL注册的规范servlet,并激活缺省的URL运用的现实servlet。
有两种制止此缺省URL的重要要领:
l 在每一个Web运用中从新映照/servlet/情势。
l 全局关闭激活器servlet。
重要的是应当注重到,虽然从新映照每一个Web运用中的/servlet/情势比完全制止激活servlet所做的事变更多,但从新映照可以用一种完全可移植的体式格局来完成。相反,全局制止激活器servlet完全是针对详细机械的,事实上有的服务器(如ServletExec)没有如许的挑选。下面的议论对每一个Web运用从新映照/servlet/ URL情势的战略。背面供应在Tomcat中全局制止激活器servlet的仔细内容。
4.1 从新映照/servlet/URL情势
在一个特定的Web运用中制止以http://host/webAppPrefix/servlet/ 最先的URL的处置惩罚非常简朴。所需做的事变就是竖立一个毛病音讯servlet,并运用前一节议论的url-pattern元素将一切婚配要求转向该 servlet。只需简朴地运用:
Xml代码
<url-pattern>/servlet/*</url-pattern> <url-pattern>/servlet/*</url-pattern>
作为servlet-mapping元素中的情势即可。
比方,顺序清单5-5给出了将SorryServlet servlet(顺序清单5-6)与一切以http://host/webAppPrefix/servlet/ 开首的URL相干联的布置形貌符文件的一部份。
顺序清单5-5 web.xml(申明JSP页命名的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <servlet> <servlet-name>Sorry</servlet-name> <servlet-class>moreservlets.SorryServlet</servlet-class> </servlet> <!-- ... --> <servlet-mapping> <servlet-name> Sorry </servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> <!-- ... --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- ... --><servlet><servlet-name>Sorry</servlet-name><servlet-class>moreservlets.SorryServlet</servlet-class></servlet><!-- ... --><servlet-mapping><servlet-name> Sorry </servlet-name><url-pattern>/servlet/*</url-pattern></servlet-mapping><!-- ... --></web-app>
顺序清单5-6 SorryServlet.java
Java代码
package moreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SorryServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Invoker Servlet Disabled."; out.println(ServletUtilities.headWithTitle(title) +"<BODY BGCOLOR=\"#FDF5E6\">\n" +"<H2>" + title + "</H2>\n" + "Sorry, access to servlets by means of\n" +"URLs that begin with\n" +"http://host/webAppPrefix/servlet//n" +"has been disabled.\n" + "</BODY></HTML>"); } public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException { doGet(request, response); } } package moreservlets;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class SorryServlet extends HttpServlet {public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();String title = "Invoker Servlet Disabled.";out.println(ServletUtilities.headWithTitle(title) +"<BODY BGCOLOR=\"#FDF5E6\">\n" +"<H2>" + title + "</H2>\n" +"Sorry, access to servlets by means of\n" +"URLs that begin with\n" +"http://host/webAppPrefix/servlet//n" +"has been disabled.\n" + "</BODY></HTML>");}public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
4.2 全局制止激活器:Tomcat
Tomcat 4中用来关闭缺省URL的要领与Tomcat 3中所用的很不雷同。下面引见这两种要领:
1.制止激活器: Tomcat 4
Tomcat 4用与前面雷同的要领关闭激活器servlet,即应用web.xml中的url-mapping元素举行关闭。不同之处在于Tomcat运用了放在 install_dir/conf中的一个服务器专用的全局web.xml文件,而前面运用的是寄存在每一个Web运用的WEB-INF目次中的规范 web.xml文件。
因而,为了在Tomcat 4中关闭激活器servlet,只需在install_dir/conf/web.xml中简朴地注释出/servlet/* URL映照项即可,以下所示:
Xml代码
<servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> <servlet-mapping><servlet-name>invoker</servlet-name><url-pattern>/servlet/*</url-pattern></servlet-mapping>
再次提示,应当注重这个项是位于寄存在install_dir/conf的Tomcat专用的web.xml文件中的,此文件不是寄存在每一个Web运用的WEB-INF目次中的规范web.xml。
2.制止激活器:Tomcat3
在Apache Tomcat的版本3中,经由历程在install_dir/conf/server.xml中注释出InvokerInterceptor项全局制止缺省 servlet URL。比方,下面是制止运用缺省servlet URL的server.xml文件的一部份。
Xml代码
<!-- <RequsetInterceptor className="org.apache.tomcat.request.InvokerInterceptor" debug="0" prefix="/servlet/" /> --> <!--<RequsetInterceptor className="org.apache.tomcat.request.InvokerInterceptor" debug="0" prefix="/servlet/" />-->
5 初始化和预装载servlet与JSP页面
这里议论掌握servlet和JSP页面的启动行动的要领。特别是,申清楚明了怎样分派初始化参数以及怎样变动服务器生存期中装载servlet和JSP页面的时刻。
5.1 分派servlet初始化参数
应用init-param元素向servlet供应初始化参数,init-param元素具有param-name和param-value子元素。比方,鄙人面的例子中,如果initServlet servlet是应用它的注册名(InitTest)接见的,它将可以从其要领中挪用getServletConfig(). getInitParameter("param1")取得"Value 1",挪用getServletConfig().getInitParameter("param2")取得"2"。
Xml代码
<servlet> <servlet-name>InitTest</servlet-name> <servlet-class>moreservlets.InitServlet</servlet-class> <init-param> <param-name>param1</param-name> <param-value>value1</param-value> </init-param> <init-param> <param-name>param2</param-name> <param-value>2</param-value> </init-param> </servlet> <servlet><servlet-name>InitTest</servlet-name><servlet-class>moreservlets.InitServlet</servlet-class><init-param><param-name>param1</param-name><param-value>value1</param-value></init-param><init-param><param-name>param2</param-name><param-value>2</param-value></init-param></servlet>
在触及初始化参数时,有几点须要注重:
l 返回值。GetInitParameter的返回值老是一个String。因而,在前一个例子中,可对param2运用Integer.parseInt取得一个int。
l JSP中的初始化。JSP页面运用jspInit而不是init。JSP页面还须要运用jsp-file元素替代servlet-class。
l 缺省URL。初始化参数只在经由历程它们的注册名或与它们注册名相干的定制URL情势接见Servlet时可以运用。因而,在这个例子中,param1和 param2初始化参数将可以在运用URL http://host/webAppPrefix/servlet/InitTest 时可用,但在运用URL http://host/webAppPrefix/servlet/myPackage.InitServlet 时不能运用。
比方,顺序清单5-7给出一个名为InitServlet的简朴servlet,它运用init要领设置firstName和emailAddress字段。顺序清单5-8给出分派称号InitTest给servlet的web.xml文件。
顺序清单5-7 InitServlet.java
Java代码
package moreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class InitServlet extends HttpServlet { private String firstName, emailAddress; public void init() { ServletConfig config = getServletConfig(); firstName = config.getInitParameter("firstName"); emailAddress = config.getInitParameter("emailAddress"); } public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String uri = request.getRequestURI(); out.println(ServletUtilities.headWithTitle("Init Servlet") +"<BODY BGCOLOR=\"#FDF5E6\">\n" +"<H2>Init Parameters:</H2>\n" +"<UL>\n" +"<LI>First name: " + firstName + "\n" +"<LI>Email address: " + emailAddress + "\n" +"</UL>\n" + "</BODY></HTML>"); } } package moreservlets;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class InitServlet extends HttpServlet {private String firstName, emailAddress;public void init() {ServletConfig config = getServletConfig();firstName = config.getInitParameter("firstName");emailAddress = config.getInitParameter("emailAddress");}public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();String uri = request.getRequestURI();out.println(ServletUtilities.headWithTitle("Init Servlet") +"<BODY BGCOLOR=\"#FDF5E6\">\n" +"<H2>Init Parameters:</H2>\n" +"<UL>\n" +"<LI>First name: " + firstName + "\n" +"<LI>Email address: " + emailAddress + "\n" +"</UL>\n" + "</BODY></HTML>");}}
顺序清单5-8 web.xml(申明初始化参数的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <servlet> <servlet-name>InitTest</servlet-name> <servlet-class>moreservlets.InitServlet</servlet-class> <init-param> <param-name>firstName</param-name> <param-value>Larry</param-value> </init-param> <init-param> <param-name>emailAddress</param-name> <param-value>Ellison@Microsoft.com</param-value> </init-param> </servlet> <!-- ... --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- ... --><servlet><servlet-name>InitTest</servlet-name><servlet-class>moreservlets.InitServlet</servlet-class><init-param><param-name>firstName</param-name><param-value>Larry</param-value></init-param><init-param><param-name>emailAddress</param-name><param-value>Ellison@Microsoft.com</param-value></init-param></servlet><!-- ... --></web-app>
5.2 分派JSP初始化参数
给JSP页面供应初始化参数在三个方面不同于给servlet供应初始化参数。
1)运用jsp-file而不是servlet-class。因而,WEB-INF/web.xml文件的servlet元素以下所示:
Xml代码
<servlet> <servlet-name>PageName</servlet-name> <jsp-file>/RealPage.jsp</jsp-file> <init-param> <param-name>...</param-name> <param-value>...</param-value> </init-param> ... </servlet> <servlet><servlet-name>PageName</servlet-name><jsp-file>/RealPage.jsp</jsp-file><init-param><param-name>...</param-name><param-value>...</param-value></init-param>...</servlet>
2) 险些老是分派一个明白的URL情势。对servlet,平常相应地运用以http://host/webAppPrefix/servlet/ 最先的缺省URL。只需记着,运用注册名而不是原称号即可。这关于JSP页面在技术上也是正当的。比方,在上面给出的例子中,可用URL http://host/webAppPrefix/servlet/PageName 接见RealPage.jsp的对初始化参数具有接见权的版本。但在用于JSP页面时,很多用户好像不喜欢运用通例的servlet的URL。另外,如果 JSP页面位于服务器为其供应了目次清单的目次中(如,一个既没有index.html也没有index.jsp文件的目次),则用户能够会衔接到此 JSP页面,单击它,从而意外埠激活未初始化的页面。因而,好的方法是运用url-pattern(5.3节)将JSP页面的原URL与注册的 servlet名相干联。如许,客户机可运用JSP页面的一般称号,但依然激活定制的版本。比方,给定来自项目1的servlet定义,可运用下面的 servlet-mapping定义:
Xml代码
<servlet-mapping> <servlet-name>PageName</servlet-name> <url-pattern>/RealPage.jsp</url-pattern> </servlet-mapping> <servlet-mapping><servlet-name>PageName</servlet-name><url-pattern>/RealPage.jsp</url-pattern></servlet-mapping>
3)JSP页运用jspInit而不是init。自动从JSP页面竖立的servlet也许已运用了inti要领。因而,运用JSP声明供应一个init要领是不正当的,必须制订jspInit要领。
为了申明初始化JSP页面的历程,顺序清单5-9给出了一个名为InitPage.jsp的JSP页面,它包括一个jspInit要领且安排于 deployDemo Web运用条理构造的顶层。平常,http://host/deployDemo/InitPage.jsp 情势的URL将激活此页面的不具有初始化参数接见权的版本,从而将对firstName和emailAddress变量显现null。然则, web.xml文件(顺序清单5-10)分派了一个注册名,然后将该注册名与URL情势/InitPage.jsp相干联。
顺序清单5-9 InitPage.jsp
Html代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD><TITLE>JSP Init Test</TITLE></HEAD> <BODY BGCOLOR="#FDF5E6"> <H2>Init Parameters:</H2> <UL> <LI>First name: <%= firstName %> <LI>Email address: <%= emailAddress %> </UL> </BODY></HTML> <%! private String firstName, emailAddress; public void jspInit() { ServletConfig config = getServletConfig(); firstName = config.getInitParameter("firstName"); emailAddress = config.getInitParameter("emailAddress"); } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>JSP Init Test</TITLE></HEAD><BODY BGCOLOR="#FDF5E6"><H2>Init Parameters:</H2><UL><LI>First name: <%= firstName %><LI>Email address: <%= emailAddress %></UL></BODY></HTML><%!private String firstName, emailAddress;public void jspInit() {ServletConfig config = getServletConfig();firstName = config.getInitParameter("firstName");emailAddress = config.getInitParameter("emailAddress");}%>
顺序清单5-10 web.xml(申明JSP页面的init参数的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <servlet> <servlet-name>InitPage</servlet-name> <jsp-file>/InitPage.jsp</jsp-file> <init-param> <param-name>firstName</param-name> <param-value>Bill</param-value> </init-param> <init-param> <param-name>emailAddress</param-name> <param-value>gates@oracle.com</param-value> </init-param> </servlet> <!-- ... --> <servlet-mapping> <servlet-name> InitPage</servlet-name> <url-pattern>/InitPage.jsp</url-pattern> </servlet-mapping> <!-- ... --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- ... --><servlet><servlet-name>InitPage</servlet-name><jsp-file>/InitPage.jsp</jsp-file><init-param><param-name>firstName</param-name><param-value>Bill</param-value></init-param><init-param><param-name>emailAddress</param-name><param-value>gates@oracle.com</param-value></init-param></servlet><!-- ... --><servlet-mapping><servlet-name> InitPage</servlet-name><url-pattern>/InitPage.jsp</url-pattern></servlet-mapping><!-- ... --></web-app>
5.3 供应运用范围内的初始化参数
平常,对单个地servlet或JSP页面分派初始化参数。指定的servlet或JSP页面应用ServletConfig的getInitParameter要领读取这些参数。然则,在某些状况下,愿望供应可由恣意servlet或JSP页面借助ServletContext的getInitParameter要领读取的体系范围内的初始化参数。
可应用context-param元素声明这些体系范围内的初始化值。context-param元素应当包括param-name、param-value以及可选的description子元素,以下所示:
Xml代码
<context-param> <param-name>support-email</param-name> <param-value>blackhole@mycompany.com</param-value> </context-param> <context-param><param-name>support-email</param-name><param-value>blackhole@mycompany.com</param-value></context-param>
可回忆一下,为了保证可移植性,web.xml内的元素必须以准确的序次声明。但这里应当注重,context-param元素必须涌现恣意与文档有关的元素(icon、display-name或description)今后及filter、filter-mapping、listener或 servlet元素之前。
5.4 在服务器启动时装载servlet
如果servlet或JSP页面有一个要花很长时刻实行的init (servlet)或jspInit(JSP)要领。比方,如果init或jspInit要领从某个数据库或ResourceBundle查找产量。这类状况下,在第一个客户机要求时装载servlet的缺省行动将对第一个客户机发作较长时刻的耽误。因而,可应用servlet的load-on- startup元素划定服务器在第一次启动时装载servlet。下面是一个例子。
Xml代码
<servlet> <servlet-name> … </servlet-name> <servlet-class> … </servlet-class> <!-- Or jsp-file --> <load-on-startup/> </servlet> <servlet><servlet-name> … </servlet-name><servlet-class> … </servlet-class> <!-- Or jsp-file --><load-on-startup/></servlet>
可以为此元素体供应一个整数而不是运用一个空的load-on-startup。主意是服务器应当在装载较大数量的servlet或JSP页面之前装载较少数量的servlet或JSP页面。比方,下面的servlet项(安排在Web运用的WEB-INF目次下的web.xml文件中的web-app元素内)将指导服务器起首装载和初始化SearchServlet,然后装载和初始化由位于Web运用的result目次中的index.jsp文件发作的 servlet。
Xml代码
<servlet> <servlet-name>Search</servlet-name> <servlet-class>myPackage.SearchServlet</servlet-class> <!-- Or jsp-file --> <load-on-startup>1</load-on-startup> /servlet> <servlet> <servlet-name>Results</servlet-name> <servlet-class>/results/index.jsp</servlet-class> <!-- Or jsp-file --> <load-on-startup>2</load-on-startup> </servlet> <servlet><servlet-name>Search</servlet-name><servlet-class>myPackage.SearchServlet</servlet-class> <!-- Or jsp-file --><load-on-startup>1</load-on-startup>/servlet><servlet><servlet-name>Results</servlet-name><servlet-class>/results/index.jsp</servlet-class> <!-- Or jsp-file --><load-on-startup>2</load-on-startup></servlet>
6 声明过滤器
servlet版本2.3引入了过滤器的观点。虽然一切支撑servlet API版本2.3的服务器都支撑过滤器,但为了运用与过滤器有关的元素,必须在web.xml中运用版本2.3的DTD。
过滤器可截取和修正进入一个servlet或JSP页面的要求或从一个servlet或JSP页面发出的相应。在实行一个servlet或JSP页面之前,必须实行第一个相干的过滤器的doFilter要领。在该过滤器对其FilterChain对象挪用doFilter时,实行链中的下一个过滤器。如果没有其他过滤器,servlet或JSP页面被实行。过滤器具有对到来的ServletRequest对象的悉数接见权,因而,它们可以检察客户机名、查找到来的cookie等。为了接见servlet或JSP页面的输出,过滤器可将相应对象包裹在一个替身对象(stand-in object)中,比方说把输出累加到一个缓冲区。在挪用FilterChain对象的doFilter要领今后,过滤器可搜检缓冲区,若有必要,就对它举行修正,然后传送到客户机。
比方,顺序清单5-11帝国难以了一个简朴的过滤器,只需接见相干的servlet或JSP页面,它就截取要求并在规范输出上打印一个报告(开辟历程当中在桌面体系上运转时,大多半服务器都可以运用这个过滤器)。
顺序清单5-11 ReportFilter.java
Java代码
package moreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class ReportFilter implements Filter { public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws ServletException, IOException { HttpServletRequest req = (HttpServletRequest)request; System.out.println(req.getRemoteHost() +" tried to access " +req.getRequestURL() +" on " + new Date() + "."); chain.doFilter(request,response); } public void init(FilterConfig config)throws ServletException {} public void destroy() {} } package moreservlets;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;import java.util.*;public class ReportFilter implements Filter {public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws ServletException, IOException {HttpServletRequest req = (HttpServletRequest)request;System.out.println(req.getRemoteHost() +" tried to access " +req.getRequestURL() +" on " + new Date() + ".");chain.doFilter(request,response);}public void init(FilterConfig config)throws ServletException {}public void destroy() {}}
一旦竖立了一个过滤器,可以在web.xml中应用filter元素以及filter-name(恣意称号)、file-class(完全限制的类名)和(可选的)init-params子元素声明它。请注重,元素在web.xml的web-app元素中涌现的序次不是恣意的;许可服务器(但不是必须的)强迫所需的序次,而且现实中有些服务器也是如许做的。但这里要注重,一切filter元素必须涌如今恣意filter-mapping元素之前, filter-mapping元素又必须涌如今一切servlet或servlet-mapping元素之前。
比方,给定上述的ReportFilter类,可在web.xml中作出下面的filter声明。它把称号Reporter与现实的类ReportFilter(位于moreservlets顺序包中)相干联。
Xml代码
<filter> <filter-name>Reporter</filter-name> <filter-class>moresevlets.ReportFilter</filter-class> </filter> <filter><filter-name>Reporter</filter-name><filter-class>moresevlets.ReportFilter</filter-class></filter>
一旦命名了一个过滤器,可应用filter-mapping元素把它与一个或多个servlet或JSP页面相干联。关于此项事变有两种挑选。
起首,可运用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名(此servlet名必须稍后在雷同的 web.xml文件中运用servlet元素声明)关联。比方,下面的顺序片断指导体系只需应用一个定制的URL接见名为SomeServletName 的servlet或JSP页面,就运转名为Reporter的过滤器。
Xml代码
<filter-mapping> <filter-name>Reporter</filter-name> <servlet-name>SomeServletName</servlet-name> </filter-mapping> <filter-mapping><filter-name>Reporter</filter-name><servlet-name>SomeServletName</servlet-name></filter-mapping>
其次,可应用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相干联。比方,相面的顺序片断指导体系只需接见Web运用中的恣意URL,就运转名为Reporter的过滤器。
Xml代码
<filter-mapping> <filter-name>Reporter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping><filter-name>Reporter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
比方,顺序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相干联的web.xml文件的一部份。名字 PageName顺次又与一个名为TestPage.jsp的JSP页面以及以情势http: //host/webAppPrefix/UrlTest2/ 开首的URL相干联。TestPage.jsp的源代码已JSP页面命名的议论在前面的3节"分派称号和定制的URL"中给出。事实上,顺序清单5- 12中的servlet和servlet-name项从该节一成不变地拿过来的。给定这些web.xml项,可看到下面的规范输出情势的调试报告(换行是为了轻易浏览)。
顺序清单5-12 Web.xml(申明filter用法的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <filter> <filter-name>Reporter</filter-name> <filter-class>moresevlets.ReportFilter</filter-class> </filter> <!-- ... --> <filter-mapping> <filter-name>Reporter</filter-name> <servlet-name>PageName</servlet-name> </filter-mapping> <!-- ... --> <servlet> <servlet-name>PageName</servlet-name> <jsp-file>/RealPage.jsp</jsp-file> </servlet> <!-- ... --> <servlet-mapping> <servlet-name> PageName </servlet-name> <url-pattern>/UrlTest2/*</url-pattern> </servlet-mapping> <!-- ... --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><filter><filter-name>Reporter</filter-name><filter-class>moresevlets.ReportFilter</filter-class></filter><!-- ... --><filter-mapping><filter-name>Reporter</filter-name><servlet-name>PageName</servlet-name></filter-mapping><!-- ... --><servlet><servlet-name>PageName</servlet-name><jsp-file>/RealPage.jsp</jsp-file></servlet><!-- ... --><servlet-mapping><servlet-name> PageName </servlet-name><url-pattern>/UrlTest2/*</url-pattern></servlet-mapping><!-- ... --></web-app>
7 指定迎接页
如果用户供应了一个像http: //host/webAppPrefix/directoryName/ 如许的包括一个目次名但没有包括文件名的URL,会发作什么事变呢?用户能取得一个目次表?一个毛病?照样规范文件的内容?如果取得规范文件内容,是 index.html、index.jsp、default.html、default.htm或别的什么东西呢?
Welcome-file-list 元素及其辅佐的welcome-file元素处理了这个隐约的题目。比方,下面的web.xml项指出,如果一个URL给出一个目次名但未给出文件名,服务器应当起首试用index.jsp,然后再试用index.html。如果二者都没有找到,则效果有赖于所用的服务器(如一个目次列表)。
Xml代码
<welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list> <welcome-file-list><welcome-file>index.jsp</welcome-file><welcome-file>index.html</welcome-file></welcome-file-list>
虽然很多服务器缺省遵照这类行动,但不肯定必须如许。因而,明白地运用welcom-file-list保证可移植性是一种优越的习气。
8 指定处置惩罚毛病的页面
如今我相识到,你在开辟servlet和JSP页面时从不会犯毛病,而且你的一切页面是那样的清楚,平常的顺序员都不会被它们的搞糊涂。然则,是人总会犯毛病的,用户能够会供应不合划定的参数,运用不准确的URL也许不能供应必须的表单字段值。除此之外,别的开辟人员能够不那末仔细,他们应当有些东西来战胜本身的不足。
error-page元素就是用来战胜这些题目的。它有两个能够的子元素,离别是:error-code和exception- type。第一个子元素error-code指出在给定的HTTP毛病代码涌现时运用的URL。第二个子元素excpetion-type指出在涌现某个给定的Java非常但未捕获到时运用的URL。error-code和exception-type都应用location元素指出相应的URL。此 URL必须以/最先。location所指出的位置处的页面可经由历程查找HttpServletRequest对象的两个特地的属性来接见关于毛病的信息,这两个属性离别是:javax.servlet.error.status_code和javax.servlet.error.message。
可回忆一下,在web.xml内以准确的序次声明web-app的子元素很重要。这里只需记着,error-page涌如今web.xml文件的末端四周,servlet、servlet-name和welcome-file-list今后即可。
8.1 error-code元素
为了更好地相识error-code元素的值,可考虑一下如果不准确地输入文件名,大多半站点会作出什么反应。如许做平常会涌现一个404毛病信息,它示意不能找到该文件,但险些没供应更多有效的信息。另一方面,可以试一下在http://www.microsoft.com/、http://www.ibm.com/ 处也许特别是在http://www.bea.com/ 处输出未知的文件名。这是会得出有效的音讯,这些音讯供应可挑选的位置,以便查找感兴趣的页面。供应如许有效的毛病页面关于Web运用来讲是很有价值得。事实上rm-error-page子元素)。由form-login-page给出的HTML表单必须具有一个j_security_check的 ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。
比方,顺序清单5-19指导服务器运用基于表单的考证。Web运用的顶层目次中的一个名为login.jsp的页面将网络用户名和口令,而且失利的上岸将由雷同目次中名为login-error.jsp的页面报告。
顺序清单5-19 web.xml(申明login-config的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <security-constraint> ... </security-constraint> <login-config> <auth-method> FORM </auth-method> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/login-error.jsp</form-error-page> </form-login-config> </login-config> <!-- ... --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- ... --><security-constraint> ... </security-constraint><login-config><auth-method> FORM </auth-method><form-login-config><form-login-page>/login.jsp</form-login-page><form-error-page>/login-error.jsp</form-error-page></form-login-config></login-config><!-- ... --></web-app>
9.2 限制对Web资本的接见
如今,可以指导服务器运用何种考证要领了。"了不得,"你说道,"除非我能指定一个来收到庇护的 URL,不然没有多大用处。"没错。指出这些URL并申明他们应当取得何种庇护恰是security-constriaint元素的用处。此元素在 web.xml中应当涌如今login-config的紧前面。它包括是个能够的子元素,离别是:web-resource-collection、 auth-constraint、user-data-constraint和display-name。下面各小节对它们举行引见。
l web-resource-collection
此元素肯定应当庇护的资本。一切security-constraint元素都必须包括最少一个web-resource-collection项。此元素由一个给出恣意标识称号的web-resource-name元素、一个肯定应当庇护的URL的url-pattern元素、一个指出此庇护所实用的 HTTP敕令(GET、POST等,缺省为一切要领)的http-method元素和一个供应材料的可选description元素构成。比方,下面的 Web-resource-collection项(在security-constratint元素内)指出Web运用的proprietary目次中一切文档应当遭到庇护。
Xml代码
<security-constraint> <web-resource-coolection> <web-resource-name>Proprietary</web-resource-name> <url-pattern>/propritary/*</url-pattern> </web-resource-coolection> <!-- ... --> </security-constraint> <security-constraint><web-resource-coolection><web-resource-name>Proprietary</web-resource-name><url-pattern>/propritary/*</url-pattern></web-resource-coolection><!-- ... --></security-constraint>
重要的是应当注重到,url-pattern仅实用于直接接见这些资本的客户机。特别是,它不适合于经由历程MVC体系构造应用 RequestDispatcher来接见的页面,也许不适合于应用相似jsp:forward的手腕来接见的页面。这类不均匀如果应用妥当的话很有优点。比方,servlet可应用MVC体系构造查找数据,把它放到bean中,发送要求到从bean中提取数据的JSP页面并显现它。我们愿望保证决不直接接见受庇护的JSP页面,而只是经由历程竖立该页面将运用的bean的servlet来接见它。url-pattern和auth-contraint元素可经由历程声明不许可任何用户直接接见JSP页面来供应这类保证。然则,这类不均匀的行动能够让开辟人员放松小心,使他们有时对应受庇护的资本供应不受限制的接见。
l auth-constraint
只管web-resource-collention元素养出了哪些URL应当遭到庇护,然则auth-constraint元素却指出哪些用户应当具有受庇护资本的接见权。此元素应当包括一个或多个标识具有接见权限的用户种别role- name元素,以及包括(可选)一个形貌角色的description元素。比方,下面web.xml中的security-constraint元素部门划定只需指定为Administrator或Big Kahuna(或二者)的用户具有指定资本的接见权。
Xml代码
<security-constraint> <web-resource-coolection> ... </web-resource-coolection> <auth-constraint> <role-name>administrator</role-name> <role-name>kahuna</role-name> </auth-constraint> </security-constraint> <security-constraint><web-resource-coolection> ... </web-resource-coolection><auth-constraint><role-name>administrator</role-name><role-name>kahuna</role-name></auth-constraint></security-constraint>
重要的是认识到,到此为止,这个历程的可移植部份完毕了。服务器怎样肯定哪些用户处于任何角色以及它怎样寄存用户的口令,完全有赖于详细的体系。
比方,Tomcat运用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相干联,正以下面例子中所示,它指出用户joe(口令bigshot)和jane(口令enaj)属于administrator和kahuna角色。
Xml代码
<tomcat-users> <user name="joe" password="bigshot" roles="administrator,kahuna" /> <user name="jane" password="enaj" roles="kahuna" /> </tomcat-users> <tomcat-users><user name="joe" password="bigshot" roles="administrator,kahuna" /><user name="jane" password="enaj" roles="kahuna" /></tomcat-users>
l user-data-constraint
这个可选的元素指出在接见相干资本时运用任何传输层庇护。它必须包括一个transport-guarantee子元素(正当值为NONE、 INTEGRAL或CONFIDENTIAL),而且可选地包括一个description元素。transport-guarantee为NONE值将对所用的通信协定不加限制。INTEGRAL值示意数据必须以一种防备截取它的人浏览它的体式格局传送。虽然原理上(而且在将来的HTTP版本中),在 INTEGRAL和CONFIDENTIAL之间能够会有差异,但在当前实践中,他们都只是简朴地要求用SSL。比方,下面指导服务器只许可对相干资本做 HTTPS衔接:
Xml代码
<security-constraint> <!-- ... --> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <security-constraint><!-- ... --><user-data-constraint><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint></security-constraint>
l display-name
security-constraint的这个很少运用的子元素赋予能够由GUI东西运用的平安束缚项一个称号。
9.3 分派角色名
迄今为止,议论已集合到完全由容器(服务器)处置惩罚的平安题目之上了。但servlet以及JSP页面也可以处置惩罚它们本身的平安题目。
比方,容器能够许可用户从bigwig或bigcheese角色接见一个显现主管人员分外紧贴的页面,但只许可bigwig用户修正此页面的参数。完成这类更仔细的掌握的一种罕见要领是挪用HttpServletRequset的isUserInRole要领,并据此修正接见。
Servlet的 security-role-ref子元素供应涌如今服务器专用口令文件中的平安角色名的一一般号。比方,如果编写了一个挪用 request.isUserInRole("boss")的servlet,但厥后该servlet被用在了一个其口令文件挪用角色manager而不是boss的服务器中。下面的顺序段使该servlet可以运用这两个称号中的任何一个。
Xml代码
<servlet> <!-- ... --> <security-role-ref> <role-name>boss</role-name> <!-- New alias --> <role-link>manager</role-link> <!-- Real name --> </security-role-ref> </servlet> <servlet><!-- ... --><security-role-ref><role-name>boss</role-name> <!-- New alias --><role-link>manager</role-link> <!-- Real name --></security-role-ref></servlet>
也可以在web-app内应用security-role元素供应将涌如今role-name元素中的一切平安角色的一个全局列表。离别地生命角色使高等IDE轻易处置惩罚平安信息。
10 掌握会话超时
如果某个会话在肯定的时刻内未被接见,服务器可把它抛弃以勤俭内存。可应用HttpSession的setMaxInactiveInterval要领直接设置一般会话对象的超时价。如果不采纳这类要领,则缺省的超时价由详细的服务器决议。但可应用session-config和session- timeout元夙来给出一个实用于一切服务器的明白的超时价。超时价的单元为分钟,因而,下面的例子设置缺省会话超时价为三个小时(180分钟)。
Xml代码
<session-config> <session-timeout>180</session-timeout> </session-config> <session-config><session-timeout>180</session-timeout></session-config>
11 Web运用的文档化
越来越多的开辟环境最先供应servlet和JSP的直接支撑。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio(写此文时,已被Macromedia收买)以及IBM VisuaAge for Java等。
大批的web.xml元素不仅是为服务器设想的,而且照样为可视开辟环境设想的。它们包括icon、display-name和discription等。
可回忆一下,在web.xml内以适当地序次声明web-app子元素很重要。不过,这里只需记着icon、display-name和description是web.xml的web-app元素内的前三个正当元素即可。
l icon
icon元素指出GUI东西可用来代表Web运用的一个和两个图象文件。可应用small-icon元素指定一幅16 x 16的GIF或JPEG图象,用large-icon元素指定一幅32 x 32的图象。下面举一个例子:
Xml代码
<icon> <small-icon>/images/small-book.gif</small-icon> <large-icon>/images/tome.jpg</large-icon> </icon> <icon><small-icon>/images/small-book.gif</small-icon><large-icon>/images/tome.jpg</large-icon></icon>
l display-name
display-name元素供应GUI东西能够会用来标记此Web运用的一个称号。下面是个例子。
<display-name>Rare Books</display-name>
l description
description元素供应解释性文本,以下所示:
Xml代码
<description> This Web application represents the store developed for rare-books.com, an online bookstore specializing in rare and limited-edition books. </description> <description>This Web application represents the store developed for rare-books.com, an online bookstore specializing in rare and limited-edition books.</description>
12 关联文件与MIME范例
服务器平常都具有一种让Web站点治理员将文件扩展名与媒体相干联的要领。比方,将会自动赋予名为mom.jpg的文件一个image/jpeg的MIME 范例。然则,如果你的Web运用具有几个不寻常的文件,你愿望保证它们在发送到客户机时分派为某种MIME范例。mime-mapping元素(具有 extension和mime-type子元素)可供应这类保证。比方,下面的代码指导服务器将application/x-fubar的MIME范例分派给一切以.foo末端的文件。
Xml代码
<mime-mapping> <extension>foo</extension> <mime-type>application/x-fubar</mime-type> </mime-mapping> <mime-mapping><extension>foo</extension><mime-type>application/x-fubar</mime-type></mime-mapping>
也许,你的Web运用愿望重载(override)规范的映照。比方,下面的代码将关照服务器在发送到客户机时指定.ps文件作为纯文本(text/plain)而不是作为PostScript(application/postscript)。
Xml代码
<mime-mapping> <extension>ps</extension> <mime-type>application/postscript</mime-type> </mime-mapping> <mime-mapping><extension>ps</extension><mime-type>application/postscript</mime-type></mime-mapping>
13 定位TLD
JSP taglib元素具有一个必要的uri属性,它给出一个TLD(Tag Library Descriptor)文件相关于Web运用的根的位置。TLD文件的现实称号在宣布新的标签库版本时能够会转变,但我们愿望防止变动一切现有JSP页面。另外,能够还愿望运用坚持taglib元素的精练性的一个简短的uri。这就是布置形貌符文件的taglib元素派用处的地点了。Taglib包括两个子元素:taglib-uri和taglib-location。taglib-uri元素应当与用于JSP taglib元素的uri属性的东西相婚配。Taglib-location元素给出TLD文件的现实位置。比方,如果你将文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。如今,如果web.xml在web-app元素内包括以下内容。
Xml代码
<taglib> <taglib-uri>/charts.tld</taglib-uri> <taglib-location>/WEB-INF/tlds/chart-tags-1.3beta.tld</taglib-location> </taglib> <taglib><taglib-uri>/charts.tld</taglib-uri><taglib-location>/WEB-INF/tlds/chart-tags-1.3beta.tld</taglib-location></taglib>
给出这个申明后,JSP页面可经由历程下面的简化情势运用标签库。
<%@ taglib uri="/charts.tld" prefix="somePrefix" %>
14 指定运用事宜监听顺序
运用事宜监听器顺序是竖立或修正servlet环境或会话对象时关照的类。它们是servlet范例的版本2.3中的新内容。这里只简朴地申明用来向Web运用注册一个监听顺序的web.xml的用法。
注册一个监听顺序触及在web.xml的web-app元素内安排一个listener元素。在listener元素内,listener-class元素列出监听顺序的完全的限制类名,以下所示:
Xml代码
<listener> <listener-class>package.ListenerClass</listener-class> </listener> <listener><listener-class>package.ListenerClass</listener-class></listener>
虽然listener元素的构造很简朴,但请不要遗忘,必须准确地给出web-app元素内的子元素的序次。listener元素位于一切的servlet 元素之前以及一切filter-mapping元素今后。另外,由于运用生存期监听顺序是serlvet范例的2.3版本中的新内容,所以必须运用 web.xml DTD的2.3版本,而不是2.2版本。
比方,顺序清单5-20给出一个名为ContextReporter的简朴的监听顺序,只需Web运用的Servlet-Context竖立(如装载Web运用)或消弭(如服务器关闭)时,它就在规范输出上显现一条音讯。顺序清单5-21给出此监听顺序注册所须要的web.xml文件的一部份。
顺序清单5-20 ContextReporterjava
Java代码
package moreservlets; import javax.servlet.*; import java.util.*; public class ContextReporter implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { System.out.println("Context created on " + new Date() + "."); } public void contextDestroyed(ServletContextEvent event) { System.out.println("Context destroyed on " + new Date() + "."); } } package moreservlets;import javax.servlet.*;import java.util.*;public class ContextReporter implements ServletContextListener {public void contextInitialized(ServletContextEvent event) {System.out.println("Context created on " + new Date() + ".");}public void contextDestroyed(ServletContextEvent event) {System.out.println("Context destroyed on " + new Date() + ".");}}
顺序清单5-21 web.xml(声明一个监听顺序的摘录)
Xml代码
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- ... --> <filter-mapping> … </filter-mapping> <listener> <listener-class>package.ListenerClass</listener-class> </listener> <servlet> ... </servlet> <!-- ... --> </web-app> <?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- ... --><filter-mapping> … </filter-mapping><listener><listener-class>package.ListenerClass</listener-class></listener><servlet> ... </servlet><!-- ... --></web-app>
15 J2EE元素
本节形貌用作J2EE环境构成部份的Web运用的web.xml元素。这里将供应一个简明的引见,仔细内容可以参阅http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3范例的第5章。
l distributable
distributable 元素指出,Web运用是以如许的体式格局编程的:即,支撑集群的服务器可平安地在多个服务器上散布Web运用。比方,一个可散布的运用必须只运用 Serializable对象作为其HttpSession对象的属性,而且必须防止用实例变量(字段)来完成持续性。distributable元素直接涌如今discription元素今后,而且不包括子元素或数据,它只是一个以下的标志。
<distributable />
l resource-env-ref
resource -env-ref元素声明一个与某个资本有关的治理对象。此元素由一个可选的description元素、一个resource-env-ref- name元素(一个相关于java:comp/env环境的JNDI名)以及一个resource-env-type元素(指定资本范例的完全限制的类),以下所示:
Xml代码
<resource-env-ref> <resource-env-ref-name>jms/StockQueue</resource-env-ref-name> <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type> </resource-env-ref> <resource-env-ref><resource-env-ref-name>jms/StockQueue</resource-env-ref-name><resource-env-ref-type>javax.jms.Queue</resource-env-ref-type></resource-env-ref>
l env-entry
env -entry元素声明Web运用的环境项。它由一个可选的description元素、一个env-entry-name元素(一个相关于java: comp/env环境JNDI名)、一个env-entry-value元素(项值)以及一个env-entry-type元素(java.lang顺序包中一个范例的完全限制类名,java.lang.Boolean、java.lang.String等)构成。下面是一个例子:
Xml代码
<env-entry> <env-entry-name>minAmout</env-entry-name> <env-entry-value>100.00</env-entry-value> <env-entry-type>minAmout</env-entry-type> </env-entry> <env-entry><env-entry-name>minAmout</env-entry-name><env-entry-value>100.00</env-entry-value><env-entry-type>minAmout</env-entry-type></env-entry>
l ejb-ref
ejb -ref元素声明对一个EJB的主目次的运用。它由一个可选的description元素、一个ejb-ref-name元素(相关于java: comp/env的EJB运用)、一个ejb-ref-type元素(bean的范例,Entity或Session)、一个home元素(bean的主目次接口的完全限制名)、一个remote元素(bean的长途接口的完全限制名)以及一个可选的ejb-link元素(当前bean链接的另一个 bean的称号)构成。
l ejb-local-ref
ejb-local-ref元素声明一个EJB的当地主目次的援用。除了用local-home替代home外,此元素具有与ejb-ref元素雷同的属性并以雷同的体式格局运用。
给你的session加个监听器
本日一个门生问我怎样完成在网页里显如今线用户的称号——他已运用了session,然则没法处置惩罚用户脱离的状况,然后致使在线用户列表的无穷增大。跟他说了本身在application中举行超时搜检,更新application的时刻就比较当前一切列表中的session是不是凌驾本身指定的时刻距离。厥后想了想,又给他提了运用给session加监听器的要领。然则提的时刻本身也没有做过,所以只是说这类体式格局很庞杂,发起他照样本身举行超时搜检。适才又看了看材料,发明现实上给session加监听器的体式格局很简朴,不禁以为本身有点误人子弟了,如今将要领写在这,借以申饬本身今后要严谨。
起首写一个SessionBinder类,它完成了HttpSessionBindingListener接口的valueBound要领和valueUnbound要领,示例代码以下:
Java代码
public class SessionBinder implements HttpSessionBindingListener { public void valueBound(HttpSessionBindingEvent event){ //you can do anything you want!this method will be called when this binder is bind with any session. } public void valueUnbound(HttpSessionBindingEvent event) { //you can do something while this session is invalidate } } public class SessionBinder implements HttpSessionBindingListener {public void valueBound(HttpSessionBindingEvent event){//you can do anything you want!this method will be called when this binder is bind with any session.}public void valueUnbound(HttpSessionBindingEvent event) {//you can do something while this session is invalidate}}
如今写好了SessionBinder,我们如今挑选在一个servlet中向session中到场这个监听器——在jsp中的代码誊写与此雷同
//省略前面的代码,此操纵能够发作在servlet的doGet要领中,也多是doPost要领中
Java代码
HttpSession session = req.getSession(true);//起首取得须要到场监听器的session对象,req是HttpRequest对象 SessionBinder sb = new SessionBinder();//竖立一个监听器对象 session.putValue("BinderObject",sb);//将监听器到场此session中,从此时最先实行sb的valueBound要领 HttpSession session = req.getSession(true);//起首取得须要到场监听器的session对象,req是HttpRequest对象SessionBinder sb = new SessionBinder();//竖立一个监听器对象session.putValue("BinderObject",sb);//将监听器到场此session中,从此时最先实行sb的valueBound要领
//省略背面的代码
随后,如果全部session超时也许被用户中断今后,sb的valueUnbound自动实行
以上就是实例详解怎样设置Web.xml的仔细内容,更多请关注ki4网别的相干文章!