1、Java EE WEB 工程项目文件结构

组成:静态HTML页、Servlet、JSP和其他相关的class;

每个组件在WEB应用中都有固定的存放目录。

WEB应用的配置信息存放在web.xml文件中。

每发布一个组件都必须在web.xml文件中添加相应的配置信息Java Web 应用程序必须使用规范的目录结构。

应用程序根目录,可以取任意的名字,所有的HTML、JSP文件都放在这个目录下
    1.1 WEB-) 存放第三方类库文件,即打包后的JAR文件
        1.1.4 TLD文件: 标签库描述文件 
    1.2 其他静态文件:
        1.2.1 HTML
        1.2.2 CSS
        1.2.3 JavaScript
        1.2.4 图片等
    1.3 *.jsp: 存放任意多个JSP页面

2、web.xml文件

位于每个WEB应用的的WEB-INF路径下的web.xml文件被称为配置描述符,这个web.xml文件对于Java Web应用十分重要,总体来说,web.xml主要负责以下内容:

1. JSP环境参数初始化
2. 配置和管理Servlet
3. 配置和管理Listener

4. 配置和管理Filter
5. 配置和管理JNDI
6. Session配置
7. MIME TYPE配置
8. 错误处理
9. 配置标签库
10. 配置JSP属性
11. 配置和管理JAAS授权认证
12. 配置和管理资源引用
13. WEB应用默认首页(welcome文件)的设置

web文件及注释

<?xml version="1.0" encoding="GBK"?>

/*
<?xml version="1.0" encoding="GBK"?>是一个基本的XML文件的框架,不管是什么配置文件,只要是基于XML的,它的基本结构都是这样
*/
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

/*
web.xml文件的根元素是<web-app.../>元素,整个web.xml只有这个根元素,每个web.xml必须以这个<web-app>根元素作为开头,在Servlet 3.0规范中,该元素新增了
metadata-complete属性,当该属性值为true时,该web应用"不会"加载Annotation配置的WEB组件(如Servlet、Filter、Listener等),反之则加载
*/

<small-icon>/路径/smallicon.gif</small-icon>
    <large-icon>/路径/largeicon-jpg</large-icon>

/*
    1. icon信息: 用来指定web站点中小图标和大图标的路径
        1) small-icon: 大小为16 X 16 pixel,但是图象文件必须为GIF或JPEG格式,扩展名必须为:.gif或
.jpg.
        2) large-icon: 大小为32 X 32 pixel,但是图象文件必须为GIF或JPEG的格式,扩展名必须为; gif
或jpg.
    */

<display-name>站点名称</display-name>
    <description>站点描述</discription>

/*
    2. 描述信息
    display-name: 定义站点的名称
    description: 对站点的描述
    */

<distributable/>
    /*
    3. distributable
    distributable元素为空标签,它的存在与否可以指定站台是否可分布式处理.如果web.xml中出现这个元素,则代表站台在开发时已经被设计为能在多个JSP Container之间分散执行
    */

<context-param>
       <param-name>param_name</param-name>
       <param-value>param_value</param-value>
    </context-param>
   /*
    4. JSP环境参数: context-param
    context-param元素用来设定web站台的环境参数(context),它包含两个子元素:
        1) param-name: 参数名称
        2) param-value: 值
    此所设定的参数,在JSP网页中可以使用下列方法来取得:
    ${initParam.param_name}
    若在Servlet可以使用下列方法来获得:
    String param_name=getServletContext().getInitParamter("param_name");
    */

<filter>
        <small-icon>/路径/smallicon.gif</small-icon>
        <large-icon>/路径/largeicon-jpg</large-icon>
        <filter-name>encodingfilter</filter-name>
        <display-name>站点名称</display-name>
        <description>站点描述</discription>
        <filter-class>com.my.app.EncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingfilter</filter-name>
        <url-pattern>

/*
    5. filter过滤器、filter-mapping
    用于指定WEB容器的过滤器,在请求和响应对象在Servlet处理之前和之后,可以通过此过滤器对这两个对象进行处理 
    filter-class 中指定的过滤器类须继承 javax.servlet.Filter具有须有以下三种方法
    init(FilterConfig filterConfig):初始化;一般情况下时读取配置文件中的init-param参数值 如 filterConfig.getInitParameter("encoding")
    doFilter(...):用于对request,response进行处理,并能过chain.doFilter(...) 交过下一个控制器
    destroy():资源销毁
    filter-mapping则指示需要进行过滤器处理的URL访问模式,可以理解为当我们的URL匹配到指定的模式后,则对这个请求执行指定的"过滤处理流程"(可以把它理解为一种路由机制)
    */

/*</url-pattern>
    </filter-mapping> 
       <servlet>
        <small-icon>/路径/smallicon.gif</small-icon>
        <large-icon>/路径/largeicon-jpg</large-icon>
        <servlet-name>MyServletName</servlet-name>
        <display-name>站点名称</display-name>
        <description>站点描述</discription>

/*
    6. servlet、servlet-mapping
    和filter过滤器类似,servlet也是用来配置映射处理机制的
    和filter-mapping的作用类似,servlet-mapping用来定义servlet所对应URL.
    */

<servlet-class>com.Little.MyServlet</servlet-class>
        <jsp-file>/path/index.jsp</jsp-file>
        <init-param>
            <param-name>name1</param-name>
            <param-value>value1</param-value>
        </init-param>

/*
        servlet-class、jsp-file有且只能出现一个
        */
 
        /*
        指定当Web应用启动时,装载Servlet的次序
        1) 当值为正数或零时: 容器在应用启动时就加载这个servlet,Servlet容器先加载数值小的servlet,再依次加载其他数值大的servlet
        2) 当值为负或未定义: 容器在该servlet被选择时才加载,即Servlet容器将在Web客户首次访问这个servlet时加载它
        */
        <load-on-startup></load-on-startup>
        /*
        设定运行时角色,可以使当前Servlet以一个特定的角色运行,有利于安全权限控制
        */
        <run-as>   
            <description>Security role for anonymous access</description>   
            <role-name>tomcat</role-name>   
        </run-as> 
               <security-role-ref>
            <role-name>boss</role-name> <!-- New alias -->
            <role-link>manager</role-link> <!-- Real name -->
        </security-role-ref>

/*
        security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如,假如编写了一个调用 request.isUserInRole("boss")的servlet,
但后来该servlet被用在了一个其口令文件调用角色manager而不 是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个
        */
  
    </servlet>
   
    <servlet-mapping>
        <servlet-name>LoginChecker</servlet-name>
        <url-pattern>/LoginChecker</url-pattern>
        <servlet-name>MyServletName</<servlet-name>
    </servlet-mapping>

/*
    7. security-role(虚拟安全用户)
    给出安全角色的一个列表,这些角色将出现在servlet元素内的security-role-ref元素的role-name元素中。分别声明角色可使高级IDE处理安全信息更为容易。
    */
    <security-role>
        <description>安全账户描述</discription>
        <role-name>admin</role-name>
    </security-role>

/*
    8. listener
    监听器也叫Listener,是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,Servlet本身在一些特定的关键处理流程节点上增加Hook
回调机制,使得我们可以在这些节点位置配置监听器
    常见的监听器如下:
    Listener接口
    1) ServletContextListener: ServletContextEvent
    2) ServletContextAttributeListener: ServletContextAttributeEvent
    3) HttpSessionListener: HttpSessionEvent
    4) HttpSessionActivationListener: HttpSessionAttributeListener
    5) HttpSessionBindingEvent: HttpSessionBindingListener
    6) ServletRequestListener: ServletRequestEvent
    7) ServletRequestAttributeListener: ServletRequestAttributeEvent
    */
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

/*
    9. session配置
    session-config包含一个子元素session-timeout.定义web站台中的session参数,定义这个web站台所有session的有效期限.单位为分钟
    */
    <session-config>
        <session-timeout>20</session-timeout>
    </session-config>

/*
    10. mime-mapping
    mime-mapping包含两个子元素extension和mime-type.定义某一个扩展名和某一MIME Type做对映,和apache中的文件扩展处理器原理类似,对指定的扩展名指定相应的处理程序
    */
    <mime-mapping>
        <extension>doc</extension>
        <mime-type>application/vnd.ms-word</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>xls</extension>
        <mime-type>application/vnd.ms-excel</mime-type>
    </mime-mapping>

/*
    11. welcome-file-list
    welcome-file-list包含一个子元素welcome-file.用来定义首页列单,即当客户端的请求没有指定具体的页面时,服务区器默认指定的首页脚本
    */
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>

/*
    12. error-page
    错误处理机制,error-page元素包含三个子元素error-code,exception-type和location.将错误代码(Error Code)或异常(Exception)的种类对应到web站点资源路径。
简单来说就是返回特定HTTP状态代码或者特定类型的异常被抛出时,制定响应将要显示的页面。
    */
    <error-page>
        <error-code>404</error-code>
        <exception-type>java.lang.Exception</exception-type>
        <location>/error404.jsp</location>
    </error-page>
    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <exception-type>java.lang.NullException</exception-type>
        <location>/except.jsp</location>
    </error-page>

/*
    13. jsp-config
    JSP相关配置
    */
    <jsp-config>
        <taglib>
            /*
            taglib-uri定义TLD文件的URI,JSP网页的taglib指令可以经由这个URI存取到TLD文件
            */
            <taglib-uri>Taglib</taglib-uri>
            /*
            taglib-location定义TLD文件对应Web站台的存放位置
            */
            <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
        </taglib>
        <jsp-property-group>
            <description>
                Special property group for JSP Configuration JSP example.
            </description>
            <display-name>JSPConfiguration</display-name>
            /*
            设定值所影响的范围,如:/CH2 或者/*.jsp
            */
            <uri-pattern>/*</uri-pattern>
            /*
            若为true,表示不支持EL语法
            */
            <el-ignored>true</el-ignored>
            /*
            设定JSP网页的编码
            */
            <page-encoding>GB2312</page-encoding>
            /*
            若为true表示不支持<%scription%>语法.
            */
            <scripting-inivalid>true</scripting-inivalid>
            /*
            设置JSP网页的结尾,扩展名为.jspf
            */
            <include-coda>.jspf</include-coda>
            /*
            设置JSP网页的抬头,扩展名为.jspf
            */
            <include-prelude>.jspf</include-prelude>
        </jsp-property-group>
    </jsp-config>

/*
    14. resource-ref、resource-env-ref
    resource-ref声明资源工厂使用的外部资源
    resource-env-ref声明与资源相关的管理对象
    */
    <resource-ref>
        <description>JNDI JDBC DataSource of JSPBook</description> <!-- 资源说明 -->
        <res-ref-name>jdbc/sample_db</res-ref-name> <!-- 资源名称 -->
        <res-type>javax.sql.DataSoruce</res-type> <!-- 资源种类 -->
        <res-auth>Container</res-auth> <!-- 资源由Application或Container来许可 -->
        <res-sharing-scope>Shareable|Unshareable</res-sharing-scope> <!-- 资源是否可以共享.默认值为 Shareable -->
    </resource-ref>

<resource-env-ref>   
        <resource-env-ref-name>jms/StockQueue</resource-env-ref-name>   
    </resource-env-ref>

/*
    15. EJB配置
    ejb-ref用于声明一个EJB的主目录的引用
    用于声明一个EJB的本地主目录的应用。
    */
    <ejb-ref>   
        <description>Example EJB reference</decription>   
        <ejb-ref-name>ejb/Account</ejb-ref-name>   
        <ejb-ref-type>Entity</ejb-ref-type>   
        <home>com.mycompany.mypackage.AccountHome</home>   
        <remote>com.mycompany.mypackage.Account</remote>   
    </ejb-ref>

<ejb-local-ref>   
        <description>Example Loacal EJB reference</decription>   
        <ejb-ref-name>ejb/ProcessOrder</ejb-ref-name>   
        <ejb-ref-type>Session</ejb-ref-type>   
        <local-home>com.mycompany.mypackage.ProcessOrderHome</local-home>   
        <local>com.mycompany.mypackage.ProcessOrder</local>   
    </ejb-local-ref>

/*
    16. WEB应用环境参数配置
    */
    <env-entry> 
        <description>环境参数说明</description>
        <env-entry-name>minExemptions</env-entry-name>   
        <env-entry-value>1</env-entry-value>   
        <env-entry-type>java.lang.Integer</env-entry-type>   
    </env-entry>
   
    /*
    17. 安全配置、资源限制访问配置
    在Web应用程序的web.xml中创建security-constraint、login-config和security-role元素
    */
    /*
    配置对指定资源、指定角色的访问权限
    */
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>HelloServlet</web-resource-name>
            <url-pattern>/HelloServlet</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <description>This applies only to the "tomcat" security role</description>
            <role-name>admin</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
     
    /*
    auth-method的方法有:
        1) BASIC
        BASIC是一种常见的Web认证方式,浏览器给用户提示一个对话框,要求输入用户名和密码,随后Tomcat将给出的用户名和密码与tomcat-users.xml中的用户名和密码进行比较,
然后使用前面的security-constraint配置来确定用户是否可访问受保护的servlet
        2) FORM
        3) CLIENT-CERT
        4) DIGEST
    */
    <login-config>
        <realm-name>在HTTP验证返回包中的显示名称</<realm-name>
        <auth-method>BASIC</auth-method>
        <form-login-config>如果auth-method采用FORM,则这里填写form-login-config名称</form-login-config>

</login-config>
    /*
    关于security-role,在前面的servlet已经说明过,这里要强调一下:
    web.xml中的HTTP认证方法实际上有两个步骤:
        1) 检查提供的用户名和密码是否正确。
        2) 判断用户是否映射到特定的安全角色。例如,用户可能提供了正确的用户名和密码,但没有映射到特定的安全角色,也将被禁止访问特定的Web资源。
    */
    <security-role>
        <role-name>admin</role-name>
    </security-role> 
</web-app>

web.xml中有一些环境参数的加载配置,它们之间存在优先级的关系

  1. web.xml 的加载顺序是:context-param -> listener -> filter -> servlet ,而相同类型节点之间的程序调用的顺序是根据对应的mapping的顺序进行调用的3JSP文件

JSP的本质是Servlet,当用户向指定Servlet发送请求时,Servlet利用输出流动态生成HTML页面,包括每一个静态的HTML标签和所有在HTML页面中出现的内容
JSP页面由如下两部分组成:

  1. 1. 静态部分: 标准的HTML标签、静态的页面内容,也就是普通的HTML代码
  2. 2. 动态部分: java程序控制的内容,这些内容由Java程序来动态生成

JSP文件样式:

/*
1. JSP的编译指令
*/
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>learn j2ee</title>
    /*
    2. JSP注释
    */
</head>
/*
3. JSP声明
*/
<body>
/*
4. JSP表达式
*/
/*
5. JSP脚本
*/
/*
6. JSP的动作指令
*/
/*
7. JSP脚本中的内置对象
*/
</body>
</html>

编译指令:

  1. JSP的编译指令是通过JSP引擎的消息,它不直接生成输出。编译指令都有默认值,我们并不需要为每个指令设置值。它的格式如下
  2. <%@ 编译指令名 属性名="属性值"...%>(不同属性名之间用空格分开)
  3. 1) page: Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令
  4. 1.1) buffer: 指定缓冲区的大小。缓冲区是JSP内部对象"out",它用于缓存JSP页面对客户端浏览器的输出,默认值为8KB,可以设置为none,也可以设置为其他的值,单位为Kb
  5. 1.2) autoFlush: 当缓冲区即将满而溢出时,是否需要强制输出缓冲区的内容:
  6. 1.2.1) 如果设置为true则正常输出
  7. 1.2.2) 如果设置为false,则会在buffer溢出时产生一个异常
  8. 1.3) contentType: 用于设定生成网页的文件格式(MIME类型)、和编码字符集(页面字符集类型)(text/html;charSet=ISO-8859-1)
  9. 1.3.1) 默认的MIME类型是text/html
  10. 1.3.2) 默认的字符集类型为ISO-8859-1
  11. 1.4) errorPage: 指定错误处理页面,如果本页面产生了异常或错误,而该JSP页面没有对应的错误处理代码(没有用trycatch机制捕捉异常),则会自动调用该属性所指定的JSP页面。值得注意的是,为页面指定错误发生时的错误提示页面是一种安全的做法,能够在一定程度上组织error-based-sql-injection的攻击
  12. 1.5) isErrorPage: 指定当前页面是否可以作为另一个JSP页面的错误处理页面
  13. 1.6) extends: JSP程序编译时所产生的Java类,需要继承的父类,或者需要实现的接口的全限定类名(即包含包名在内的完整路径)
  14. 1.7) import: 用来导入包。默认自动导入的包(参数之间用逗号分隔)(java.lang.*,javax.servlet.*)
  15. 1.7.1) java.lang.*
  16. 1.7.2) javax.servlet.*
  17. 1.7.3) javax.servlet.jsp.*
  18. 1.7.4) javax.servlet.http.*
  19. 1.8) info: 定义JSP页面的描述信息
  20. 1.9) isThreadSafe: 指定对JSP页面的访问是否为线程安全
  21. 1.10) language: 定义JSP页面所用的脚本语言,默认是Java
  22. 1.11) session: 指定JSP页面是否使用session
  23. 1.12) isELIgnored: 指定是否执行EL表达式
  24. 1.13) isScriptingEnabled: 确定脚本元素能否被使用
  25. 2) include: 用于指定包含另一个页面
  26. <%@include file="file.jsp"%>
  27. 可以将外部文件嵌入到当前JSP文件中,同时解析这个页面中的JSP语句(如果有的话),也就是说,它既可以包含静态的文本,也可以包含动态的JSP页面。包含页面在编译时将完全包含了被包含页面的代码,融合成一个页面。作用和PHP中的inlcuderequire类似。
  28. 需要注意的是,要指出的是,静态包含还会将被包含页面的编译指令也包含进来,如果两个页面的编译指令冲突,那么页面就会出错(即被包含的页面中不能重复定义pageincludetaglib)
  29. 3) taglib: 用于定义和访问自定义标签
  30. 自定义标签库是一种非常优秀的表现层组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的功能,在JSP2中使用自定义标签需要以下步骤
  31. 1) 开发自定义标签处理类
  32. JSP页面使用一个标签时,底层实际上由标签处理类提供支持,从而可以通过简单的标签来封装复杂的功能,从而使团队更好地协作开发。自定义标签类应该继承一个父类: javax.servlet.jsp.tagext.SimpleTagSupport,除此之外,JSP自定义标签类还有如下要求(通过接口来强制性保证):
  33. 1) 如果标签包含属性,每个属性都有对应的gettersetter方法
  34. 2) 重写doTag()方法,这个方法负责生成页面内容
  35. example1: 无属性、无标签体的最简单的标签处理类
  36. package lee;
  37. import javax.servlet.jsp.tagext.*;
  38. import javax.servlet.jsp.*;
  39. import java.io.*;
  40.  
  41. public class HelloWorldTag extends SimpleTagSupport
  42. {
  43. //重写doTag方法,该方法在标签结束生成页面内容
  44. public void doTag()throws JspException, IOException
  45. {
  46. //获取页面输出流,并输出字符串
  47. getJspContext().getOut().write("Hello World " + new java.util.Date());
  48. }
  49. }
  50. 这个标签处理类继承了SimpleTagSupport父类,并重写了doTag()方法,doTag()负责输出页面内容(即标签代表的内容)
  51.  
  52. example2: 带属性的标签处理类
  53. package lee;
  54. import javax.servlet.jsp.tagext.*;
  55. import javax.servlet.jsp.*;
  56. import java.io.*;
  57. import java.sql.*;
  58.  
  59. public class QueryTag extends SimpleTagSupport
  60. {
  61. //标签的属性
  62. private String driver;
  63. private String url;
  64. private String user;
  65. private String pass;
  66. private String sql;
  67.  
  68. //driver属性的setter和getter方法
  69. public void setDriver(String driver)
  70. {
  71. this.driver = driver;
  72. }
  73. public String getDriver()
  74. {
  75. return this.driver;
  76. }
  77.  
  78. //url属性的setter和getter方法
  79. public void setUrl(String url)
  80. {
  81. this.url = url;
  82. }
  83. public String getUrl()
  84. {
  85. return this.url;
  86. }
  87.  
  88. //user属性的setter和getter方法
  89. public void setUser(String user)
  90. {
  91. this.user = user;
  92. }
  93. public String getUser()
  94. {
  95. return this.user;
  96. }
  97.  
  98. //pass属性的setter和getter方法
  99. public void setPass(String pass)
  100. {
  101. this.pass = pass;
  102. }
  103. public String getPass()
  104. {
  105. return this.pass;
  106. }
  107.  
  108. //sql属性的setter和getter方法
  109. public void setSql(String sql)
  110. {
  111. this.sql = sql;
  112. }
  113. public String getSql()
  114. {
  115. return this.sql;
  116. }
  117.  
  118. //conn属性的setter和getter方法
  119. public void setConn(Connection conn)
  120. {
  121. this.conn = conn;
  122. }
  123. public Connection getConn()
  124. {
  125. return this.conn;
  126. }
  127.  
  128. //stmt属性的setter和getter方法
  129. public void setStmt(Statement stmt)
  130. {
  131. this.stmt = stmt;
  132. }
  133. public Statement getStmt()
  134. {
  135. return this.stmt;
  136. }
  137.  
  138. //rs属性的setter和getter方法
  139. public void setRs(ResultSet rs)
  140. {
  141. this.rs = rs;
  142. }
  143. public ResultSet getRs()
  144. {
  145. return this.rs;
  146. }
  147.  
  148. //rsmd属性的setter和getter方法
  149. public void setRsmd(ResultSetMetaData rsmd)
  150. {
  151. this.rsmd = rsmd;
  152. }
  153. public ResultSetMetaData getRsmd()
  154. {
  155. return this.rsmd;
  156. }
  157. //执行数据库访问的对象
  158. private Connection conn = null;
  159. private Statement stmt = null;
  160. private ResultSet rs = null;
  161. private ResultSetMetaData rsmd = null;
  162. public void doTag()throws JspException,
  163. IOException
  164. {
  165. try
  166. {
  167. //注册驱动
  168. Class.forName(driver);
  169. //获取数据库连接
  170. conn = DriverManager.getConnection(url,user,pass);
  171. //创建Statement对象
  172. stmt = conn.createStatement();
  173. //执行查询
  174. rs = stmt.executeQuery(sql);
  175. rsmd = rs.getMetaData();
  176. //获取列数目
  177. int columnCount = rsmd.getColumnCount();
  178. //获取页面输出流
  179. Writer out = getJspContext().getOut();
  180. //在页面输出表格
  181. out.write("<table border='1' bgColor='#9999cc' width='400'>");
  182. //遍历结果集
  183. while (rs.next())
  184. {
  185. out.write("<tr>");
  186. //逐列输出查询到的数据
  187. for (int i = 1 ; i <= columnCount ; i++ )
  188. {
  189. out.write("<td>");
  190. out.write(rs.getString(i));
  191. out.write("</td>");
  192. }
  193. out.write("</tr>");
  194. }
  195. }
  196. catch(ClassNotFoundException cnfe)
  197. {
  198. cnfe.printStackTrace();
  199. throw new JspException("自定义标签错误" + cnfe.getMessage());
  200. }
  201. catch (SQLException ex)
  202. {
  203. ex.printStackTrace();
  204. throw new JspException("自定义标签错误" + ex.getMessage());
  205. }
  206. finally
  207. {
  208. //关闭结果集
  209. try
  210. {
  211. if (rs != null)
  212. rs.close();
  213. if (stmt != null)
  214. stmt.close();
  215. if (conn != null)
  216. conn.close();
  217. }
  218. catch (SQLException sqle)
  219. {
  220. sqle.printStackTrace();
  221. }
  222. }
  223. }
  224. }
  225.  
  226. example3: 带标签体的标签处理类
  227. 带标签体的标签可以在标签内嵌入其他内容(包括静态HTML、动态JSP内容),通常用于完成一些逻辑运算
  228. package lee;
  229. import javax.servlet.jsp.tagext.*;
  230. import javax.servlet.jsp.*;
  231. import java.io.*;
  232. import java.sql.*;
  233. import java.util.*;
  234.  
  235. public class IteratorTag extends SimpleTagSupport
  236. {
  237. //标签属性,用于指定需要被迭代的集合
  238. private String collection;
  239. //标签属性,指定迭代集合元素,为集合元素指定的名称
  240. private String item;
  241.  
  242. //collection属性的setter和getter方法
  243. public void setCollection(String collection)
  244. {
  245. this.collection = collection;
  246. }
  247. public String getCollection()
  248. {
  249. return this.collection;
  250. }
  251. //item属性的setter和getter方法
  252. public void setItem(String item)
  253. {
  254. this.item = item;
  255. }
  256. public String getItem()
  257. {
  258. return this.item;
  259. }
  260. //标签的处理方法,简单标签处理类只需要重写doTag方法
  261. public void doTag() throws JspException, IOException
  262. {
  263. //从page scope中获取属性名为collection的集合
  264. Collection itemList = (Collection)getJspContext().getAttribute(collection);
  265. //遍历集合
  266. for (Object s : itemList)
  267. {
  268. //将集合的元素设置到page 范围
  269. getJspContext().setAttribute(item, s);
  270. //输出标签体
  271. getJspBody().invoke(null);
  272. }
  273. }
  274. }
  275.  
  276. example4: "页面片段"作为属性的标签处理类
  277. package lee;
  278. import javax.servlet.jsp.tagext.*;
  279. import javax.servlet.jsp.*;
  280. import java.io.*;
  281.  
  282. public class FragmentTag extends SimpleTagSupport
  283. {
  284. private JspFragment fragment;
  285.  
  286. //fragment属性的setter和getter方法
  287. public void setFragment(JspFragment fragment)
  288. {
  289. this.fragment = fragment;
  290. }
  291. public JspFragment getFragment()
  292. {
  293. return this.fragment;
  294. }
  295. @Override
  296. public void doTag() throws JspException, IOException
  297. {
  298. JspWriter out = getJspContext().getOut();
  299. out.println("<div style='padding:10px;border:1px solid black'>");
  300. out.println("<h3>下面是动态传入的JSP片段</h3>");
  301. //调用、输出“页面片段”
  302. fragment.invoke( null );
  303. out.println("</div");
  304. }
  305. }
  306. 上面的程序定义了JspFragment类型的fragment属性,该属性代表了使用该标签时的"页面片段"
  307.  
  308. example5: 动态属性的标签处理类
  309. 在某些特殊情况下,我们需要传入自定义标签的属性个数是不确定的、属性名也是不确定的,这就需要使用到动态属性的标签
  310. package lee;
  311. import javax.servlet.jsp.tagext.*;
  312. import javax.servlet.jsp.*;
  313. import java.io.*;
  314. import java.util.*;
  315.  
  316. public class DynaAttributesTag extends SimpleTagSupport implements DynamicAttributes
  317. {
  318. //保存每个属性名的集合
  319. private ArrayList<String> keys = new ArrayList<String>();
  320. //保存每个属性值的集合
  321. private ArrayList<Object> values = new ArrayList<Object>();
  322.  
  323. @Override
  324. public void doTag() throws JspException, IOException
  325. {
  326. JspWriter out = getJspContext().getOut();
  327. //此处只是简单地输出每个属性
  328. out.println("<ol>");
  329. for( int i = 0; i < keys.size(); i++ )
  330. {
  331. String key = keys.get( i );
  332. Object value = values.get( i );
  333. out.println( "<li>" + key + " = " + value + "</li>" );
  334. }
  335. out.println("</ol>");
  336. }
  337.  
  338. /*
  339. 实现DynamicAttributes接口必须实现setDynamicAttribute,该方法用于为该标签处理类动态添加属性名、属性值
  340. */
  341. @Override
  342. public void setDynamicAttribute( String uri, String localName, Object value) throws JspException
  343. {
  344. //添加属性名
  345. keys.add( localName );
  346. //添加属性值
  347. values.add( value );
  348. }
  349. }
  350.  
  351. 2) 建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库可包含多个标签
  352. TLD(Tag Library Definition 标签库定义)的根元素是taglib,它可以包含多个tag子元素,每个tag元素都定义一个标签
  353. taglib结构如下
  354. 1) tlib-version: 指定该标签库实现的内部版本号
  355. 2) short-name: 该标签库的默认短名
  356. 3) uri: 指定该标签库的唯一标识URIJSP页面中使用标签库就是根据该URI属性来定位标签库的
  357. 4) tag: 每个tag元素定义一个标签
  358. 4.1) name: 该标签的名字
  359. 4.2) tag-class: 该标签的处理类
  360. 4.3) body-content: 指定标签体内容
  361. 4.3.1) tagdependent: 标签处理类自己负责处理标签体
  362. 4.3.2) empty: 该标签只能作为空标签使用
  363. 4.3.3) scriptless: 该标签可以是静态HTML元素、表达式语言,但不允许JSP脚本
  364. 4.3.4) JSP: 该标签可以使用JSP脚本
  365. 4.3.5) dynamic-attributes: 该标签是否支持动态属性
  366. JSP2规范的自定义标签还允许直接将一段"页面代码"作为属性,这种方式给自定义标签提供了更大的灵活性,它和普通标签的区别并不大,对于以"页面代码"作为属性的自定义标签来说,需要注意的是:
  367. 1) 标签处理类中定义类型为JspFragment的属性,该属性代表了"页面片段"
  368. 2) 使用标签库时,通过<jsp:attribute../>动作指令为标签库属性指定值
  369. 除此之外,还可以动态属性的标签
  370. <?xml version="1.0" encoding="GBK"?>
  371. <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
  372. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  373. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
  374. version="2.0">
  375. <tlib-version>1.0</tlib-version>
  376. <short-name>mytaglib</short-name>
  377. <!-- 定义该标签库的URI -->
  378. <uri>http://littlehann.cnblogs.com/mytaglib</uri>
  379.  
  380. <!-- 定义第一个标签 -->
  381. <tag>
  382. <!-- 定义标签名 -->
  383. <name>helloWorld</name>
  384. <!-- 定义标签处理类 -->
  385. <tag-class>lee.HelloWorldTag</tag-class>
  386. <!-- 定义标签体为空 -->
  387. <body-content>empty</body-content>
  388. </tag>
  389.  
  390. /*
  391. 定义第二个标签,对于有属性的标签,需要为<tag../>元素增加<attribute../>子元素,每个attribute子元素定义一个标签元素。<attribute../>子元素通常还需要指定如下子元素
  392. 1) name: 属性名,子元素的值是字符串内容
  393. 2) required: 该属性是否为必须属性,true or false
  394. 3) fragment: 该属性是否支持JSP脚本、表达式等动态内容,true or false
  395. */
  396. <tag>
  397. <!-- 定义标签名 -->
  398. <name>query</name>
  399. <!-- 定义标签处理类 -->
  400. <tag-class>lee.QueryTag</tag-class>
  401. <!-- 定义标签体为空 -->
  402. <body-content>empty</body-content>
  403. <!-- 配置标签属性:driver -->
  404. <attribute>
  405. <name>driver</name>
  406. <required>true</required>
  407. <fragment>true</fragment>
  408. </attribute>
  409. <!-- 配置标签属性:url -->
  410. <attribute>
  411. <name>url</name>
  412. <required>true</required>
  413. <fragment>true</fragment>
  414. </attribute>
  415. <!-- 配置标签属性:user -->
  416. <attribute>
  417. <name>user</name>
  418. <required>true</required>
  419. <fragment>true</fragment>
  420. </attribute>
  421. <!-- 配置标签属性:pass -->
  422. <attribute>
  423. <name>pass</name>
  424. <required>true</required>
  425. <fragment>true</fragment>
  426. </attribute>
  427. <!-- 配置标签属性:sql -->
  428. <attribute>
  429. <name>sql</name>
  430. <required>true</required>
  431. <fragment>true</fragment>
  432. </attribute>
  433. </tag>
  434.  
  435. <!-- 定义第三个带标签体的标签 -->
  436. <tag>
  437. <!-- 定义标签名 -->
  438. <name>iterator</name>
  439. <!-- 定义标签处理类 -->
  440. <tag-class>lee.IteratorTag</tag-class>
  441. <!-- 定义标签体不允许出现JSP脚本 -->
  442. <body-content>scriptless</body-content>
  443. <!-- 配置标签属性:collection -->
  444. <attribute>
  445. <name>collection</name>
  446. <required>true</required>
  447. <fragment>true</fragment>
  448. </attribute>
  449. <!-- 配置标签属性:item -->
  450. <attribute>
  451. <name>item</name>
  452. <required>true</required>
  453. <fragment>true</fragment>
  454. </attribute>
  455. </tag>
  456. <tag>
  457. <!-- 定义以"页面片段"作为属性的标签名 -->
  458. <name>fragment</name>
  459. <!-- 定义标签处理类 -->
  460. <tag-class>lee.FragmentTag</tag-class>
  461. <!-- 指定该标签不支持标签体 -->
  462. <body-content>empty</body-content>
  463. <!-- 定义标签属性:fragment -->
  464. <attribute>
  465. <name>fragment</name>
  466. <required>true</required>
  467. <fragment>true</fragment>
  468. </attribute>
  469. </tag>
  470. <!-- 定义接受动态属性的标签 -->
  471. <tag>
  472. <name>dynaAttr</name>
  473. <tag-class>lee.DynaAttributesTag</tag-class>
  474. <body-content>empty</body-content>
  475. <!-- 指定支持动态属性 -->
  476. <dynamic-attributes>true</dynamic-attributes>
  477. </tag>
  478. </taglib>
  479. 定义了上面的标签库定义文件之后,将标签库文件放在WEB应用的WEB-INF路径下,WEB容器会自动加载该文件,则该文件定义的标签库也将生效
  480.  
  481. 3) JSP文件中使用自定义标签
  482. JSP页面中使用标签库步骤
  483. 1) 导入标签库: 使用taglib编译指令导入标签库,由URI唯一标识指定标签库,并将标签库和指定前缀关联起来(即所有使用该前缀的标签将由此标签库处理)
  484. <%@ taglib uri="tagliburi" prefix="tagPrefix" %>
  485. 2) 使用标签: JSP页面中使用自定义标签
  486. <tagPrefix:tagName tagAttribute="tagValue" ..>
  487. <tagBody/>
  488. </tagPrefix:tagName>
  489. example1: helloWorld标签使用
  490. <%@ taglib uri="http://littlehann.cnblogs.com/mytaglib" prefix="mytag"%>
  491. <mytag:helloWorld></mytag:helloWorld>
  492.  
  493. example2: QueryTag标签使用
  494. <%@ taglib uri="http://littlehann.cnblogs.com/mytaglib" prefix="mytag"%>
  495. <mytag:query
  496. driver="com.mysql.jdbc.Driver"
  497. url="jdbc:mysql://localhost:3306/javaee"
  498. user="root"
  499. pass="32147"
  500. sql="select * from news_inf"/>
  501. 可以看出自定义标签库的作用,以简单的标签,隐藏复杂的逻辑
  502.  
  503. example3: IteratorTag标签使用
  504. <%@ taglib uri="http://littlehann.cnblogs.com/mytaglib" prefix="mytag"%>
  505. <%
  506. //创建一个List对象
  507. List<String> a = new ArrayList<String>();
  508. a.add("疯狂Java");
  509. a.add("www.crazyit.org");
  510. a.add("java");
  511. //将List对象放入page范围内
  512. pageContext.setAttribute("a" , a);
  513. %>
  514. <table border="1" bgcolor="#aaaadd" width="300">
  515. <!-- 使用迭代器标签,对a集合进行迭代 -->
  516. <mytag:iterator collection="a" item="item">
  517. <tr>
  518. <td>${pageScope.item}</td>
  519. <tr>
  520. </mytag:iterator>
  521. </table>
  522. 可以看到,使用iterator标签遍历集合元素比使用JSP脚本遍历集合元素要优雅,这也是自定义标签的优势
  523.  
  524. example4: fragment标签使用
  525. <%@ taglib uri="http://littlehann.cnblogs.com/mytaglib" prefix="mytag"%>
  526. <mytag:fragment>
  527. <!-- 使用jsp:attribute标签传入fragment参数 -->
  528. <jsp:attribute name="fragment">
  529. <!-- 下面是动态的JSP页面片段 -->
  530. <mytag:helloWorld/>
  531. </jsp:attribute>
  532. </mytag:fragment>
  533. <mytag:fragment>
  534. <jsp:attribute name="fragment"> <!-- 下面是动态的JSP页面片段 -->
  535. ${pageContext.request.remoteAddr}
  536. </jsp:attribute>
  537. </mytag:fragment>
  538.  
  539. example5: dynaAttr标签使用
  540. <%@ taglib uri="http://littlehann.cnblogs.com/mytaglib" prefix="mytag"%>
  541. <mytag:dynaAttr name="crazyit" url="crazyit.org"/>
  542. <mytag:dynaAttr 书名="疯狂Java讲义" 价格="99.0" 出版时间="2008年" 描述="Java图书"/>
  543. 可以看到,不管传入多少属性,这个标签都可以处理
  544.  
  545. JSTLSun提供的一套标签库,DisplayTagApache组织下的一套开源标签库,主要用于生成页面并显示效果

Java EE 学习总结的更多相关文章

  1. Java EE学习——Quartz的Cron表达式

    经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比 ...

  2. Java EE 学习(9):IDEA + maven + spring 搭建 web(5)- 博客文章管理

    转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) . 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Jav ...

  3. Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理

    转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) ava E ...

  4. Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

    参考: https://my.oschina.net/gaussik/blog/513444 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 ...

  5. Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring

    参考:https://my.oschina.net/gaussik/blog/513353 注:此文承接上一文:Java EE 学习(5):IDEA + maven + spring 搭建 web(1 ...

  6. Java EE 学习(5):IDEA + maven + spring 搭建 web(1)

    参考:http://www.cnblogs.com/lonelyxmas/p/5397422.html http://www.ctolib.com/docs-IntelliJ-IDEA-c--1590 ...

  7. Java EE 学习(4):IDEA + maven 搭建 web(2)

    参考:http://www.bubuko.com/infodetail-1855067.html 现使用 Maven 创建项目:本节接Java EE 学习(3):IDEA + maven 搭建 web ...

  8. 【Java EE 学习 80 上】【WebService】

    一.WebService概述 什么是WebService,顾名思义,就是基于Web的服务,它使用Http方式接收和响应外部系统的某种请求,从而实现远程调用.WebService实际上就是依据某些标准, ...

  9. 【Java EE 学习 74 上】【数据采集系统第六天】【使用Jfreechart的统计图实现】【Jfreechart的基本使用方法】

    之前已经实现了数据的采集,现在已经有了基本的数据,下一步就需要使用这些数据实现统计图的绘制了.这里使用Jfreechart实现这些统计图的绘制.首先看一下Jfreechart的基本用法,只有知道了它的 ...

  10. 【Java EE 学习 69 中】【数据采集系统第一天】【SSH框架搭建】

    经过23天的艰苦斗争,终于搞定了数据采集系统~徐培成老师很厉害啊,明明只是用了10天就搞定的项目我却做了23天,还是模仿的...呵呵,算了,总之最后总算是完成了,现在该好好整理该项目了. 第一天的内容 ...

随机推荐

  1. Spring XML配置文件示例(一)——<Servlet name>-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  2. HR外包系统 - 工资计算-几种常见账单计算规则

    01-正常工资计税 (包括同一月多地计税方式) 02-年终奖计税 (包括可分批发放,但计税总额不变)  按工资 除以月份,看落在那个计税区间,获取税率和扣除数,再用总额*税率-扣除数,要考虑当月工资如 ...

  3. apk 打包方式

    1 项目-->Android tools -->Export Signed  Application Package 2 在项目 manifest.xml文件下 单击“use the Ex ...

  4. Sizeof与Strlen的区别与联系(转)

    Sizeof与Strlen的区别与联系 一.sizeof     sizeof(...)是运算符,在头文件中typedef为unsigned int,其值在编译时即计算好了,参数可以是数组.指针.类型 ...

  5. 函数fgets和fputs、fread和fwrite、fscanf和fprintf用法小结 (转)

    函数fgets和fputs.fread和fwrite.fscanf和fprintf用法小结 字符串读写函数fgets和fputs 一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符 ...

  6. 软引用SoftReference异步加载图片

    HashMap<String, SoftReference<Drawable>> imageCache 关于SoftReference这个类多少知道些机制,会用就ok了. 机制 ...

  7. SSH框架应用解析

    一.什么是SSH SSH 不仅仅只是一个框架,而是由多个框架集成而来,是 struts+spring+hibernate的一个集成框架,是目前较流行的一种Web应用程序开源框架,结构清晰.可复用性好. ...

  8. HDU 2222 Keywords Search (AC自动机)

    题意:给你一些模式串,再给你一串匹配串,问你在匹配串中出现了多少种模式串,模式串可以相同 AC自动机:trie树上进行KMP.首先模式串建立trie树,再求得失配指针(类似next数组),其作用就是在 ...

  9. Tomcat不输入项目名进入自己项目(根目录指向自己的项目)

    <Host name="localhost" appBase="webapps" unpackWARs="true" autoDepl ...

  10. MVVM模式下实现拖拽

    在文章开始之前先看一看效果图 我们可以拖拽一个"游戏"给ListBox,并且ListBox也能接受拖拽过来的数据, 但是我们不能拖拽一个"游戏类型"给它. 所以 ...