<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    2010年8月1日

    Java注解使用的幾個小技巧:

      最近經常用到注解,總結了幾個注解使用的小技巧,現整理如下:

     一、使用默認的注解參數:

    使用default關鍵字可以指定注解的默認參數:

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target(ElementType.METHOD)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface SQL {

    String sql() default "";

    }

    如果我們在使用注解@SQL的時候沒有顯式的去指定sql參數,那么就默認采取default關鍵字所指定的值

    二、用value指定默認值

    我們經常看到很多注解是這種形式,例如:@SQL("select email from user")

    這個注解里面的參數為什么沒有帶名稱呢?其實它的注解是這樣定義的:

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target(ElementType.METHOD)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface SQL {

    String value() default "";

    }

    三、在注解中使用數組參數

    如果你用過Struts2的注解來配置Action,那么你會看到如下形式的注解:

    @Results({   

           @Result(name="success",value=xxx

    .jsp",type=org.apache.struts2.dispatcher.ServletRedirectResult.class),   

           @Result(name="input",value="/xxx

    .jsp",type=org.apache.struts2.dispatcher.ServletRedirectResult.class)   

    })   

    怎么來創建這種注解呢?

    其實可以把@Results的參數看作是一個@Result的數組

    定義如下:

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target(ElementType.METHOD)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface Result {

    }

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target(ElementType.METHOD)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface Results {

    Result[] value();   //沒什么特別的,只是接受了一個數組參數而已

    }

    四、讓注解可以去修飾多個Target類型

    我么使用@Target注解來指定某個注解可以修飾的類型,實際上,同上面一樣,@Target接受的是一個數組參數,利用這一特性我們可以讓注解來修飾多個類型。

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    @Target({ElementType.PARAMETER,ElementType.FIELD})

    @Retention(RetentionPolicy.RUNTIME)

    public @interface Param {

    }

    OK!這個注解既可以修飾參數也可以修飾類的屬性

    posted @ 2010-08-02 14:31 遲宏澤 閱讀(3800) | 評論 (0)編輯 收藏
    使用Java來開發JSP標記
        最近復習JSP中。我們知道JSP是Java WEB的一個規范。在這個規范之內我們可以自己去做很多事情。JSP API提供了接口允許我們自己去自定義JSP標簽和EL表達式。自定義JSP標簽的大致思想是這樣的,實現一個包含標簽參數和行為邏輯的類,這個類我們稱它為標記處理器類,它實質上是一個Bean,我們設置標簽的屬性實際上是調用它的setter方法。接下來通過使用標記庫描述文件(TLD)來描述標簽的相關信息,以便在JSP頁面中使用taglib指令時能順利的找到它。下面我們來看看詳細應該怎么去做。
        從JSP2.0開始引入了一個簡單標記處理器接口——javax.servlet.jsp.tagext.SimpleTag接口,這個接口取代了原先JSP1.0提供的3個標記處理器接口,我們只需要使用SimpleTarget接口就可以實現所有類型的JSP標記。之所以稱之為簡單,是因為這樣設計讓開發者在編寫程序上省了不少力氣,但是它可以實現很復雜的功能,并不是說它的功能很簡單。
        該接口包含了如下5個方法:
        void doTag();  //該方法包含了標簽執行的業務邏輯
        JspTag getParent();  //獲取該標簽的父標簽
        setJspBody(JspFragment body); //設置JSP標簽體,關于JspFragment類我們稍后再討論
        setJspContext(JspContext ctx);//設置JSP上下文
        setParent(JspTag parent);  //設置父標簽
    但是多數情況下我們不需要去親自實現這個接口,因為作為開發者,我們關心的是業務邏輯,也就是doTag()方法的內容,這種情況我們只需要繼承javax.servlet.jsp.tagext.SimpleTagSupport類即可,這個類為我們實現了SimpleTag接口,我們只需要去重寫它的doTag()方法。下面我們來實現一個最簡單的標簽:給標簽傳遞一個參數,讓它在頁面上顯示出來.
    首先我們要做的是寫一個標記處理器類:
    package test.jsp.tag.simple;

    import java.io.IOException;

    import javax.servlet.jsp.tagext.SimpleTagSupport;

    public class HelloTag extends SimpleTagSupport{
       
        private String name;
       
        public void setName(String name){
            this.name = name;
        }

        @Override
        public void doTag()throws IOException{
            this.getJspContext().getOut().print("Hello! "+name);
        }
    }

    嗯,這是一個繼承了SimpleTagSupport類的Bean,一樣擁有屬性、setter方法。唯一特別的是重寫了父類的doTag()方法。在這個doTag()中,我們通過獲得一個JSP上下文對象來向頁面輸出一句話:Hello!XXX。

    下面是該介紹JspContext對象的時候了,這是一個抽象類,它唯一的子類是PageContext。這么說剛才所返回的實際對象是PageContext類型的。我們可以對其進行強制轉換:PageContext pageCtx = (PageContext)this.getJspContext();

    通過PageContext對象我們就可以訪問到Request和Response對象了,如:

    HttpServletRequest request = (HttpServletRequest)pageCtx.getRequest();
    HttpServletResponse response = (HttpServletResponse)pageCtx.getResponse();

    通過這種方式我們就可以在標簽處理器中操作WEB應用各個作用域的數據了。

    我們都知道在使用JSP標簽時要在JSP頁面開頭使用taglib指令進行聲明,如:
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    taglib指令通過URL來對標簽進行定位。但是它是如何做到的呢?這就要靠TLD了,TLD就是標記庫描述文件(Tag Library Descriptor,TLD),我們看JSTL的JAR包中,META-INF文件夾下每個庫都有一個對應的部署描述文件。TLD實際上是一個XML文件,里面描述了標記庫和其中標記的信息。一個完整的TLD文件結構如下所示:


    <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">
       
      <tlib-version>1.1</tlib-version>
      <short-name>test</short-name>
      <uri>http://test</uri>
     
      <tag>
        <name>hello</name>
        <tag-class>test.jsp.tag.simple.HelloTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
          <name>name</name>
          <required>true</required>
        </attribute>
      </tag>
     
      <tag>
        <name>if</name>
        <tag-class>test.jsp.tag.simple.IfTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
          <name>test</name>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
      </tag>
      <tag>
        <name>foreach</name>
        <tag-class>test.jsp.tag.simple.ForeachTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
          <name>items</name>
          <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
          <name>var</name>
        </attribute>
      </tag>

      <function>
       <description>
          Just for test
       </description>
       <name>add</name>
       <function-class>test.jsp.el.AddEl</function-class>
       <function-signature>int add(int,int)</function-signature>
      </function>
    </taglib>

    起始標簽是taglib,<tlib-version>定義了taglib的版本號,<short-name>定義了標簽庫的簡稱,<uri>定義了URI標識,taglib就是通過此URI來找到相關的標記庫的。
    接下來的<tag>標簽便是定義JSP標簽的屬性了:
    以下是必須的屬性
    <name>標簽名稱
    <tag-class>標記器類
    <body-content>動作體類型,JSP2.0支持如下動作體:
    empty 空標記
    jsp:可以包含標簽、EL和Scriptlet
    scriptless:不允許Java腳本內容
    tagdependent:對體不進行處理
    <attribute>標簽定義了標簽參數。
    其中:
    <name>標簽指定了參數的名稱。
    <required>指定了參數是否是必要的。true是必要,false是不必要
    <rtexprvalue>指定了是否允許使用表達式(包括EL表達式和Java表達式),true為允許,false為不允許

    <funtion>標簽定義了EL表達式,我們稍后再做介紹。


    如何執行動作體?
    我們在編寫JSP頁面時經常會用到<c:if>和<c:forEach>之類的標簽
    <c:if test="true">
      <p>條件是真的,執行!</p>
    </c:if>
    只要滿足條件,就會去執行動作體,那么我們怎么在自定義JSP標記中去執行動作體呢?
    首先我們先要來研究一個叫做JspFragment的類。JspFragment代表了JSP標簽的動作體,我們通過它的invoke方法就可以執行動作體,下面我們來實現一個類似于<c:if>的標簽:
    package test.jsp.tag.simple;

    import java.io.IOException;

    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;

    public class IfTag extends SimpleTagSupport{

        private boolean test;
       
        public void setTest(boolean test){
            this.test = test;
        }
       
            @Override
        public void doTag()throws IOException,JspException{
            JspFragment body = getJspBody();
            //如果成立則執行相應邏輯
            if(test){
                body.invoke(null);
            }
        }
    }
    只要滿足了條件,標簽動作體就會執行。
    invoke方法接受一個java.io.Writer對象,使用這個對象將內容輸出到頁面,如果不輸出則可以給它傳遞一個null參數。

    JSP中引入了EL表達式給我們的開發帶來了很大的方便,同自定義標簽一樣,允許開發者去自定義EL表達式函數,定義EL表達式函數要比定義標簽簡單多了,我們甚至不需要去實現任何接口,假設我們要實現一個簡單的EL表達式函數來計算兩個數的和,就可以這樣:

    package test.jsp.tag.simple;

    public class Calculator {

        public static int add(int a,int b){
            return a+b;
        }
       
        public static int minus(int a,int b){
            return a-b;
        }
       
        public static int multiply(int a,int b){
            return a*b;
        }
       
        public static int divide(int a,int b){
            return a/b;
        }
    }

    這個類中全部是static方法,這是一個工具類。
    然后我們只需要在TLD聲明即可:

    <function>
       <description>
          Just for test
       </description>
       <name>add</name>
       <function-class>test.jsp.el.AddEl</function-class>
       <function-signature>int add(int,int)</function-signature>
    </function>

    function-signature類似于C語言中的函數聲明,通過這個找到到底調用類中哪個工具方法。
    使用的時候只需要這樣就可以了:${test:add(1,2)}運行時輸出結果為3


    posted @ 2010-08-01 15:10 遲宏澤 閱讀(3014) | 評論 (1)編輯 收藏

    導航

    <2010年8月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    統計

    常用鏈接

    留言簿

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 好久久免费视频高清| 你懂的免费在线观看| 最近中文字幕电影大全免费版 | 久久精品国产亚洲AV忘忧草18| a国产成人免费视频| 亚洲av永久无码精品网站| 国产在线播放线91免费| 亚洲va久久久噜噜噜久久男同 | 免费无码又爽又刺激一高潮| 国产亚洲婷婷香蕉久久精品| 日本视频在线观看永久免费| 久久久久亚洲精品日久生情| 精品福利一区二区三区免费视频| 91亚洲自偷在线观看国产馆| 午夜毛片不卡高清免费| 午夜亚洲国产精品福利| 中文字幕第13亚洲另类| 91大神在线免费观看| 亚洲乱码一二三四区乱码| 四虎国产精品免费视| 久久精品无码专区免费| 1区1区3区4区产品亚洲| 最近中文字幕免费mv视频7| 激情小说亚洲色图| 亚洲成AV人在线播放无码| 国产成人免费午夜在线观看| 亚洲av无码专区首页| 亚洲欧洲精品无码AV| 中文字幕免费高清视频| 亚洲AV无码一区二区三区网址| 国产精品亚洲产品一区二区三区 | 亚洲综合免费视频| 亚洲妇女无套内射精| 亚洲精品无码久久千人斩| 2021国内精品久久久久精免费| 午夜亚洲国产理论片二级港台二级| 久久精品国产亚洲一区二区三区| 91禁漫免费进入| 视频一区二区三区免费观看| 日韩精品一区二区亚洲AV观看| 免费成人av电影|