溫馨提示:您的每一次轉載,體現了我寫此文的意義!!!煩請您在轉載時注明出處http://www.aygfsteel.com/sxyx2008/謝謝合作!!!

          雪山飛鵠

          溫馨提示:您的每一次轉載,體現了我寫此文的意義!!!煩請您在轉載時注明出處http://www.aygfsteel.com/sxyx2008/謝謝合作!!!

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            215 Posts :: 1 Stories :: 674 Comments :: 0 Trackbacks

          #

          package com.xmlpull;

          import java.io.File;
          import java.io.FileOutputStream;

          import org.kxml2.io.KXmlSerializer;
          import org.xmlpull.v1.XmlSerializer;


          public class XmlPullCreateXML {
              
              
          public static void main(String[] args) throws Exception{
                  XmlSerializer xmlSerializer
          =new KXmlSerializer();
                  xmlSerializer.setOutput(
          new FileOutputStream(new File("D:\\workspace\\demo\\src\\students.xml")), "utf-8");
                  xmlSerializer.startDocument(
          nulltrue);
                  xmlSerializer.startTag(
          null"data");
                  
          for (int i = 0; i < 10; i++) {
                      xmlSerializer.startTag(
          null"student");
                      xmlSerializer.attribute(
          null"id"""+(i+1));
                      
                      xmlSerializer.startTag(
          null"name");
                      xmlSerializer.text(
          "student"+i);
                      xmlSerializer.endTag(
          null"name");
                      
                      xmlSerializer.startTag(
          null"age");
                      xmlSerializer.text((i
          +10)+"");
                      xmlSerializer.endTag(
          null"age");
                      
                      
                      xmlSerializer.startTag(
          null"sex");
                      
          if(i%2==0){
                          xmlSerializer.text(
          "");
                      }
          else{
                          xmlSerializer.text(
          "");
                      }
                      xmlSerializer.endTag(
          null"sex");
                      
                      
                      xmlSerializer.startTag(
          null"address");
                      xmlSerializer.text(
          "陜西西安");
                      xmlSerializer.endTag(
          null"address");
                      
                      xmlSerializer.endTag(
          null"student");
                  }
                  
                  xmlSerializer.endTag(
          null"data");
                  
                  xmlSerializer.endDocument();
                  
                  xmlSerializer.flush();
                  
              }

          }
          運行后生成的xml文件:
          <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
          <data>
              
          <student id="1">
                  
          <name>student0</name>
                  
          <age>10</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="2">
                  
          <name>student1</name>
                  
          <age>11</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="3">
                  
          <name>student2</name>
                  
          <age>12</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="4">
                  
          <name>student3</name>
                  
          <age>13</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="5">
                  
          <name>student4</name>
                  
          <age>14</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="6">
                  
          <name>student5</name>
                  
          <age>15</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="7">
                  
          <name>student6</name>
                  
          <age>16</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="8">
                  
          <name>student7</name>
                  
          <age>17</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="9">
                  
          <name>student8</name>
                  
          <age>18</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
              
          <student id="10">
                  
          <name>student9</name>
                  
          <age>19</age>
                  
          <sex></sex>
                  
          <address>陜西西安</address>
              
          </student>
          </data>
          代碼叫簡單,不做過多解釋。
          posted @ 2011-08-23 15:46 雪山飛鵠 閱讀(545) | 評論 (0)編輯 收藏

          //調用瀏覽器

          Uri uri 
          = Uri.parse("");
          Intent it 
          = new Intent(Intent.ACTION_VIEW,uri);
          startActivity(it);

          //顯示某個坐標在地圖上

          Uri uri 
          = Uri.parse("geo:38.899533,-77.036476");
          Intent it 
          = new Intent(Intent.Action_VIEW,uri);
          startActivity(it); 

          //顯示路徑

          Uri uri 
          = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");
          Intent it 
          = new Intent(Intent.ACTION_VIEW,URI);
          startActivity(it);

          //撥打電話

          Uri uri 
          = Uri.parse("tel:10086");
          Intent it 
          = new Intent(Intent.ACTION_DIAL, uri); 
          startActivity(it); 

          Uri uri 
          = Uri.parse("tel.10086");
          Intent it 
          =new Intent(Intent.ACTION_CALL,uri);
          需要添加 
          <uses-permission id="android.permission.CALL_PHONE" /> 這個權限到androidmanifest.xml

          //發送短信或彩信

          Intent it 
          = new Intent(Intent.ACTION_VIEW); 
          it.putExtra(
          "sms_body""The SMS text"); 
          it.setType(
          "vnd.android-dir/mms-sms"); 
          startActivity(it); 

          //發送短信

          Uri uri 
          = Uri.parse("smsto:10086"); 
          Intent it 
          = new Intent(Intent.ACTION_SENDTO, uri); 
          it.putExtra(
          "sms_body""cwj"); 
          startActivity(it); 

          //發送彩信

          Uri uri 
          = Uri.parse("content://media/external/images/media/23"); 
          Intent it 
          = new Intent(Intent.ACTION_SEND); 
          it.putExtra(
          "sms_body""some text"); 
          it.putExtra(Intent.EXTRA_STREAM, uri); 
          it.setType(
          "image/png"); 
          startActivity(it); 

          //發送郵件 
          Uri uri = Uri.parse("mailto:android123@163.com");
          Intent it 
          = new Intent(Intent.ACTION_SENDTO, uri);
          startActivity(it);

          Intent it 
          = new Intent(Intent.ACTION_SEND); 
          it.putExtra(Intent.EXTRA_EMAIL, android123@
          163.com); 
          it.putExtra(Intent.EXTRA_TEXT, 
          "The email body text"); 
          it.setType(
          "text/plain"); 
          startActivity(Intent.createChooser(it, 
          "Choose Email Client")); 

          Intent it
          =new Intent(Intent.ACTION_SEND); 
          String[] tos
          ={"me@abc.com"}; 
          String[] ccs
          ={"you@abc.com"}; 
          it.putExtra(Intent.EXTRA_EMAIL, tos); 
          it.putExtra(Intent.EXTRA_CC, ccs); 
          it.putExtra(Intent.EXTRA_TEXT, 
          "The email body text"); 
          it.putExtra(Intent.EXTRA_SUBJECT, 
          "The email subject text"); 
          it.setType(
          "message/rfc822"); 
          startActivity(Intent.createChooser(it, 
          "Choose Email Client")); 

          //播放媒體文件

          Intent it 
          = new Intent(Intent.ACTION_VIEW);
          Uri uri 
          = Uri.parse("file:///sdcard/cwj.mp3");
          it.setDataAndType(uri, 
          "audio/mp3");
          startActivity(it);

          Uri uri 
          = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); 
          Intent it 
          = new Intent(Intent.ACTION_VIEW, uri); 
          startActivity(it); 

          //卸載APK

          Uri uri 
          = Uri.fromParts("package", strPackageName, null); 
          Intent it 
          = new Intent(Intent.ACTION_DELETE, uri); 
          startActivity(it);

          //卸載apk 2
          Uri uninstallUri = Uri.fromParts("package""xxx"null);
          returnIt 
          = new Intent(Intent.ACTION_DELETE, uninstallUri);

          //安裝APK
          Uri installUri = Uri.fromParts("package""xxx"null);
          returnIt 
          = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);

          //播放音樂

          Uri playUri 
          = Uri.parse("file:///sdcard/download/sth.mp3");
          returnIt 
          = new Intent(Intent.ACTION_VIEW, playUri);

          //發送附近

          Intent it 
          = new Intent(Intent.ACTION_SEND); 
          it.putExtra(Intent.EXTRA_SUBJECT, 
          "The email subject text"); 
          it.putExtra(Intent.EXTRA_STREAM, 
          "file:///sdcard/cwj.mp3"); 
          sendIntent.setType(
          "audio/mp3"); 
          startActivity(Intent.createChooser(it, 
          "Choose Email Client"));

          //market上某個應用信,pkg_name就是應用的packageName

          Uri uri 
          = Uri.parse("market://search?q=pname:pkg_name"); 
          Intent it 
          = new Intent(Intent.ACTION_VIEW, uri); 
          startActivity(it); 


          //market上某個應用信息,app_id可以通過www網站看下

          Uri uri 
          = Uri.parse("market://details?id=app_id"); 
          Intent it 
          = new Intent(Intent.ACTION_VIEW, uri); 
          startActivity(it); 

          //調用搜索

          Intent intent 
          = new Intent();
          intent.setAction(Intent.ACTION_WEB_SEARCH);
          intent.putExtra(SearchManager.QUERY,
          "android123")
          startActivity(intent);
          posted @ 2011-08-17 11:10 雪山飛鵠 閱讀(534) | 評論 (0)編輯 收藏

          本人在web ui設計這塊一直很菜。花了一天時間,基于jquery easy ui整了一個后臺管理界面。程序的核心在頁面布局這塊。底層跟數據庫交互,這塊為了簡易起見,使用Apache Commons DbUtils來做了簡單的處理。兼容IE6、IE7、IE8、IE9、firefox4、firefox5、chrom、搜狗瀏覽器等。有心的朋友可以在其他瀏覽器上測試一下。
          登錄頁面

          管理頁面

          下載地址 http://struts2typeconverter.googlecode.com/files/sitemesh.zip
          posted @ 2011-07-23 10:53 雪山飛鵠 閱讀(11511) | 評論 (7)編輯 收藏

          Cron expressions are comprised of 6 required fields and one optional field separated by white space. The fields respectively are described as follows:

          Field Name   Allowed Values   Allowed Special Characters
          Seconds   0-59   , - * /
          Minutes   0-59   , - * /
          Hours   0-23   , - * /
          Day-of-month   1-31   , - * ? / L W
          Month   1-12 or JAN-DEC   , - * /
          Day-of-Week   1-7 or SUN-SAT   , - * ? / L #
          Year (Optional)   empty, 1970-2199   , - * /

          The '*' character is used to specify all values. For example, "*" in the minute field means "every minute".

          The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify 'no specific value'. This is useful when you need to specify something in one of the two fields, but not the other.

          The '-' character is used to specify ranges For example "10-12" in the hour field means "the hours 10, 11 and 12".

          The ',' character is used to specify additional values. For example "MON,WED,FRI" in the day-of-week field means "the days Monday, Wednesday, and Friday".

          The '/' character is used to specify increments. For example "0/15" in the seconds field means "the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means "the seconds 5, 20, 35, and 50". Specifying '*' before the '/' is equivalent to specifying 0 is the value to start with. Essentially, for each field in the expression, there is a set of numbers that can be turned on or off. For seconds and minutes, the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to 31, and for months 1 to 12. The "/" character simply helps you turn on every "nth" value in the given set. Thus "7/6" in the month field only turns on month "7", it does NOT mean every 6th month, please note that subtlety.

          The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last", but it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" - for example "6L" means "the last friday of the month". When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing results.

          The 'W' character is allowed for the day-of-month field. This character is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month". So if the 15th is a Saturday, the trigger will fire on Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you specify "1W" as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not 'jump' over the boundary of a month's days. The 'W' character can only be specified when the day-of-month is a single day, not a range or list of days.

          The 'L' and 'W' characters can also be combined for the day-of-month expression to yield 'LW', which translates to "last weekday of the month".

          The '#' character is allowed for the day-of-week field. This character is used to specify "the nth" XXX day of the month. For example, the value of "6#3" in the day-of-week field means the third Friday of the month (day 6 = Friday and "#3" = the 3rd one in the month). Other examples: "2#1" = the first Monday of the month and "4#5" = the fifth Wednesday of the month. Note that if you specify "#5" and there is not 5 of the given day-of-week in the month, then no firing will occur that month. If the '#' character is used, there can only be one expression in the day-of-week field ("3#1,6#3" is not valid, since there are two expressions).


          Here are some full examples:

          Expression   Meaning
          "0 0 12 * * ?"   Fire at 12pm (noon) every day
          "0 15 10 ? * *"   Fire at 10:15am every day
          "0 15 10 * * ?"   Fire at 10:15am every day
          "0 15 10 * * ? *"   Fire at 10:15am every day
          "0 15 10 * * ? 2005"   Fire at 10:15am every day during the year 2005
          "0 * 14 * * ?"   Fire every minute starting at 2pm and ending at 2:59pm, every day
          "0 0/5 14 * * ?"   Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day
          "0 0/5 14,18 * * ?"   Fire every 5 minutes starting at 2pm and ending at 2:55pm, AND fire every 5 minutes starting at 6pm and ending at 6:55pm, every day
          "0 0-5 14 * * ?"   Fire every minute starting at 2pm and ending at 2:05pm, every day
          "0 10,44 14 ? 3 WED"   Fire at 2:10pm and at 2:44pm every Wednesday in the month of March.
          "0 15 10 ? * MON-FRI"   Fire at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday
          "0 15 10 15 * ?"   Fire at 10:15am on the 15th day of every month
          "0 15 10 L * ?"   Fire at 10:15am on the last day of every month
          "0 15 10 ? * 6L"   Fire at 10:15am on the last Friday of every month
          "0 15 10 ? * 6L"   Fire at 10:15am on the last Friday of every month
          "0 15 10 ? * 6L 2002-2005"   Fire at 10:15am on every last Friday of every month during the years 2002, 2003, 2004 and 2005
          "0 15 10 ? * 6#3"   Fire at 10:15am on the third Friday of every month

           

          Pay attention to the effects of '?' and '*' in the day-of-week and day-of-month fields!

          posted @ 2011-07-18 13:33 雪山飛鵠 閱讀(439) | 評論 (0)編輯 收藏

          Log4j XML Configuration Primer

          Basic example

          Below is a basic xml configuration file for log4j that will get you started:

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
          
          <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
            <appender name="console" class="org.apache.log4j.ConsoleAppender"> 
              <param name="Target" value="System.out"/> 
              <layout class="org.apache.log4j.PatternLayout"> 
                <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/> 
              </layout> 
            </appender> 
          
            <root> 
              <priority value ="debug" /> 
              <appender-ref ref="console" /> 
            </root>
            
          </log4j:configuration>

          This will print all debug or higher messages to the console/screen. Items of note:

          • The appender is defined first, with a name (in this case "console"). A layout is defined for the appender (in this case  PatternLayout ), and a pattern is defined for the layout. What is required for the layout is layout specific, so check the javadoc description for the layout class you choose to use ( PatternLayout  is used most commonly).

          • No loggers are defined in this example, but the configuration for the "root" logger is defined. It is configured to level debug, and the appender named "console" is attached to it. All loggers inherit from root, so in this example, all debug or higher messages from all loggers will be printed to the console appender.

          XML Configuration Format

          In order to better understand the more detailed examples, it is useful to understand the expected format for the xml configuration files. This is defined by the log4j.dtd which is located in the log4j distribution jar in the package org.apache.log4j.xml. The contents of this file will not be listed in its entirety, so please feel free to open/print the file yourself. If you are not familiar with xml dtd file formats, then you should go find a good book on that subject first.

          Near the beginning of the file is the following declaration:

          <!ELEMENT log4j:configuration (renderer*, appender*,(category|logger)*,root?, categoryFactory?)>

          This element defines the expected structure of the xml configuration file: 0 or more renderer elements, followed by 0 or more appender elements, followed by 0 or more logger elements, followed by 0 or 1 root element, followed by 0 or 1 categoryFactory element. If this order is not followed, then errors will be printed by the xml parser at the time the xml file is read in. Also, as a note, the "category" element is the same as the logger element. Prior to log4j version 1.2, loggers were known as category. Much of the documentation still refers to category. Just understand that they are the same thing.

          Further along in the log4j.dtd is the following declaration which defines the allowed attributes:

          <!ATTLIST log4j:configuration
            xmlns:log4j              CDATA #FIXED "http://jakarta.apache.org/log4j/"  
            threshold                (all|debug|info|warn|error|fatal|off|null) "null" 
            debug                    (true|false|null)  "null" 
          >
          • debug - Probably the most important attribute for log4:configuration, setting it to "true" will print out information as the configuration file is read and used to configure the log4j environment. Very useful when trying to fiure out why your configuration file is not doing what you expect.

          • threshold - <yet to be described>

          Understanding the expected structure of the xml configuration file makes it easier to concentrate on the specific elements one needs to configure.

          Appender Configuration

          One can instrument all the code one writes to output useful debug trace messages, but if log4j is not configured to have at least one appender, all will be for naught. None of the useful messages will be displayed anywhere.

          Looking again to the log4j.dtd, appender elements are declared to be:

          <!ELEMENT appender (errorHandler?, param*, layout?, filter*, appender-ref*)>
          <!ATTLIST appender
            name          ID      #REQUIRED
            class         CDATA   #REQUIRED
          >

          An appender element must have name and class attributes. The name is the value used to reference the appender in the rest of the configuration file. The class attribute should be the fully qualified class name of the appender class to use (ie  org.apache.log4j.ConsoleAppender ).

          An appender element can also contain child elements:

          • 0 or 1 errorHandler element - <yet to be described>

          • 0 or more param elements - Each appender can be configured with setting specific to the functioning of the appender. This is implemented by getter and setter methods in the appender class. The param element is used to access the setter methods. The format for param elements is simple; they are atomic elements with a name attribute and a value attribute. The name attribute should be the name of the setter method with the "set" part of the method name omitted (ie method name "setTarget" would be "Target"). The value attribute is the value the setter method should be set with.

          • 0 or 1 layout element - Not all appenders use or require a layout. For appenders that do, the layout element defines what layout class to use. The layout element has one attribute, class, which is the fully qualified class name of the layout class to use. Similar to the appender element, the layout element is allowed to have 0 or more param child elements. Again, the param elements are used to set specific values for the layout class, which varies based on what layout class is used.

          • 0 or more filter elements - See the Filter Configuration section below for more details.

          • 0 or more appender-ref elements - <yet to be described>

          So, from the above, the simple example of the appender named "console" from the basic example starts to make more sense:

            <appender name="console" class="org.apache.log4j.ConsoleAppender">
              <param name="Target" value="System.out"/>
              <layout class="org.apache.log4j.PatternLayout"> 
                <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/> 
              </layout> 
            </appender> 

          The name of of the appender is "console" and this is the name that is used to refer to the appender in the rest of the configuration file. The class to use for the appender is  org.apache.log4j.ConsoleAppender .

          The console appender has one param element defined. Looking at the javadoc for  ConsoleAppender , the  setTarget  method is used to choose which console stream to print messages to, System.out or System.err. The example configures the appender to use System.out.

          The console appender also has a layout element defined which uses  org.apache.log4j.PatternLayout . Looking at the javadoc for  PatternLayout , the setConversionPattern method takes a string describing the layout for messages. The details of this format can also be found in the javadoc.

          The details of the configuration for a specific appender class vary from class to class. Your best bet is to review the javadoc for the appender class you want to use. Pay particular attention to the setter property methods and the values they expect. Each setter method can be accessed using the param element in the xml configuration.

          Currently, the following appender classes exist:

          Logger Configuration

          Now the appenders are configured. But how to configure loggers to output messages at a certain level? How to configure loggers to output to specific appender? Welcome to logger configuration.

          The most important logger you need to configure is the root logger. From the simple example, this was done with the following configuration:

            <root> 
              <priority value ="debug" /> 
              <appender-ref ref="console" /> 
            </root> 

          The root logger is configured to output log message at level "debug" or higher to the appender named "console". All loggers inherit their settings from the root logger, so with no other configuration settings, all loggers will output all of their messages to the "console" appender automatically. This may be fine for simple debugging, but eventually more specific logger configuration is going to be required.

          Looking again to the log4j.dtd, logger elements are declared to be:

          <!ELEMENT logger (level?,appender-ref*)>
          <!ATTLIST logger
            name          ID      #REQUIRED 
            additivity    (true|false) "true"   
          >

          A logger element must have a name attribute. This is the name of the logger used when creating the Logger instance(usually the fully qualified class name). It can also have an optional additivity attribute. More on this later.

          A logger element can also contain child elements:

          • 0 or 1 level element - This defines the level of log messages that will be allowed to be logged for this logger. Normal usage has a value of "debug", "info", "warn", "error", or "fatal". Only that level or above will be reported to the log.

          • 0 or more appender-ref elements - This references a defined appender that log messages from this logger should be directed to. Appender-ref elements are simple elements that have a ref attribute. The value for this attribute should be the name of the appender.

          A typical logger configuration element would look similar to this:

          <logger name="com.mycompany.apackage.MyClass">
            <level value="info"/> 
          </logger>

          Logger Inheritance

          <yet to be described>

          Additivity

          The output of a log statement of logger C will go to all the appenders in C and its ancestors. This is the meaning of the term "appender additivity".

          However, if an ancestor of logger C, say P, has the additivity flag set to false, then C's output will be directed to all the appenders in C and it's ancestors upto and including P but not the appenders in any of the ancestors of P.

          Loggers have their additivity flag set to true by default.

          Example config;

          <logger name="com.eatmutton.muttonsite.torque" additivity="false">
             <level value="info" />
             <appender-ref ref="local-torque" />
          </logger>

          Additivitiy section taken from http://logging.apache.org/log4j/docs/manual.html.

          Converting Configuration Files To XML format

          I have converted the configuration examples from the log4j manual to xml format. Hopefully people can use this to convert their own configuration files.

          Example 1

          # Set root logger level to DEBUG and its only appender to A1.
          log4j.rootLogger=DEBUG, A1
          
          # A1 is set to be a ConsoleAppender.
          log4j.appender.A1=org.apache.log4j.ConsoleAppender
          
          # A1 uses PatternLayout.
          log4j.appender.A1.layout=org.apache.log4j.PatternLayout
          log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
          <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
            <!-- A1 is set to be a ConsoleAppender -->
            <appender name="A1" class="org.apache.log4j.ConsoleAppender">
              <!-- A1 uses PatternLayout -->
              <layout class="org.apache.log4j.PatternLayout"> 
                <param name="ConversionPattern" value="%-4r [%t] %-5p %c %x - %m%n"/> 
              </layout> 
            </appender> 
            <root> 
              <!-- Set root logger level to DEBUG and its only appender to A1 -->
              <priority value ="debug" /> 
              <appender-ref ref="A1" /> 
            </root>
          </log4j:configuration>

          Example 2

          log4j.rootLogger=DEBUG, A1
          log4j.appender.A1=org.apache.log4j.ConsoleAppender
          log4j.appender.A1.layout=org.apache.log4j.PatternLayout
          
          # Print the date in ISO 8601 format
          log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
          
          # Print only messages of level WARN or above in the package com.foo.
          log4j.logger.com.foo=WARN

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
          <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
            <appender name="A1" class="org.apache.log4j.ConsoleAppender"> 
              <layout class="org.apache.log4j.PatternLayout"> 
                <!-- Print the date in ISO 8601 format -->
                <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/> 
              </layout> 
            </appender> 
            <logger name="com.foo">
              <!-- Print only messages of level warn or above in the package com.foo -->
              <level value="warn"/> 
            </logger>
            <root> 
              <priority value ="debug" /> 
              <appender-ref ref="A1" /> 
            </root>
          </log4j:configuration>

          Example 3

          log4j.rootLogger=debug, stdout, R
          
          log4j.appender.stdout=org.apache.log4j.ConsoleAppender
          log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
          
          # Pattern to output the caller's file name and line number.
          log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
          
          log4j.appender.R=org.apache.log4j.RollingFileAppender
          log4j.appender.R.File=example.log
          
          log4j.appender.R.MaxFileSize=100KB
          # Keep one backup file
          log4j.appender.R.MaxBackupIndex=1
          
          log4j.appender.R.layout=org.apache.log4j.PatternLayout
          log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
          <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
            <appender name="stdout" class="org.apache.log4j.ConsoleAppender"> 
              <layout class="org.apache.log4j.PatternLayout"> 
                <!-- Pattern to output the caller's file name and line number -->
                <param name="ConversionPattern" value="%5p [%t] (%F:%L) - %m%n"/> 
              </layout> 
            </appender> 
            <appender name="R" class="org.apache.log4j.RollingFileAppender"> 
              <param name="file" value="example.log"/>
              <param name="MaxFileSize" value="100KB"/>
              <!-- Keep one backup file -->
              <param name="MaxBackupIndex" value="1"/>
              <layout class="org.apache.log4j.PatternLayout"> 
                <param name="ConversionPattern" value="%p %t %c - %m%n"/> 
              </layout> 
            </appender> 
            <root> 
              <priority value ="debug" /> 
              <appender-ref ref="stdout" /> 
              <appender-ref ref="R" /> 
            </root>
          </log4j:configuration>

          Filter Configuration

          Filters can be defined at appender level. For example, to filter only certain levels, the LevelRangeFilter can be used like this:

                  <appender name="TRACE" class="org.apache.log4j.ConsoleAppender">
                          <layout class="org.apache.log4j.PatternLayout">
                                  <param name="ConversionPattern" value="[%t] %-5p %c - %m%n" />
                          </layout>
                          <filter class="org.apache.log4j.varia.LevelRangeFilter">
                                  <param name="levelMin" value="DEBUG" />
                                  <param name="levelMax" value="DEBUG" />
                          </filter>
                  </appender>

          Advanced Topics

          <yet to be described>

          More examples

          (Please feel free to add your own configuration examples here)

          Note that TimeBasedRollingPolicy can only be configured with xml, not log4j.properties

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
          
          <!-- Note that this file is refreshed by the server every 60seconds, as specified in web.xml -->
          
          <log4j:configuration debug="true">
          
                  <appender name="ROLL" class="org.apache.log4j.rolling.RollingFileAppender">
                          <!-- The active file to log to -->
                          <param name="file" value="/applogs/myportal/portal.log" />
                          <param name="append" value="true" />
                          <param name="encoding" value="UTF-8" />
          
                          <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
                                  <!-- The file to roll to, this is a fairly intelligent parameter, if the file
                                  ends in .gz, it gzips it, based on the date stamp it rolls at that time, 
                                  default is yyyy-MM-dd, (rolls at midnight)
                                  See: http://logging.apache.org/log4j/companions/extras/apidocs/org/apache/log4j/rolling/TimeBasedRollingPolicy.html -->
                                  <param name="FileNamePattern" value="/applogs/myportal/portal.%d.log.gz" />
                          </rollingPolicy>
          
                          <layout class="org.apache.log4j.PatternLayout">
                                  <!-- The log message pattern -->
                                  <param name="ConversionPattern" value="%5p %d{ISO8601} [%t][%x] %c - %m%n" />
                          </layout>
                  </appender>
                  
                  <!-- Loggers to filter out various class paths -->
          
                  <logger name="org.hibernate.engine.loading.LoadContexts" additivity="false">
                          <level value="error"/>
                          <appender-ref ref="ROLL" />
                  </logger>
                  
                  <!-- Debugging loggers -->
                  
                  <!-- Uncomment to enable debug on calpoly code only -->
                  <!--
                  <logger name="edu.calpoly">
                          <level value="debug"/>
                          <appender-ref ref="ROLL" />
                  </logger>
                  -->
                  
                  <root>
                          <priority value="info" />
                          <appender-ref ref="ROLL" />
                  </root>
                  
          </log4j:configuration>
          posted @ 2011-07-18 11:24 雪山飛鵠 閱讀(1832) | 評論 (0)編輯 收藏

          自定義標簽庫并不是 JSP 2 才出現的,JSP 1.1 版中已經增加了自定義標簽庫規范,自定義標簽庫是一種非常優秀的表現層組件技術。通過使用自定義標簽庫,可以在簡單的標簽中封裝復雜的功能。

          為什么要使用自定義標簽呢?主要是為了取代丑陋的 JSP 腳本。在 HTML 頁面中插入 JSP 腳本有如下幾個壞處:

          • JSP 腳本非常丑陋,難以閱讀。
          • JSP 腳本和 HTML 代碼混雜,維護成本高。
          • HTML 頁面中嵌入 JSP 腳本,導致美工人員難以參與開發。

          出于以上三點的考慮,我們需要一種可在頁面中使用的標簽,這種標簽具有和 HTML 標簽類似的語法,但由可以完成 JSP 腳本的功能——這種標簽就是 JSP 自定義標簽。

          在 JSP1.1 規范中開發自定義標簽庫比較復雜,JSP 2 規范簡化了標簽庫的開發,在 JSP 2 中開發標簽庫只需如下幾個步驟:

          1. 開發自定義標簽處理類;
          2. 建立一個 *.tld 文件,每個 *.tld 文件對應一個標簽庫,每個標簽庫對應多個標簽;
          3. 在 JSP 文件中使用自定義標簽。

          開發自定義標簽類

          標簽庫和實際開發

          標簽庫是非常重要的技術,通常來說,初學者、普通開發人員自己開發標簽庫的機會很少,但如果希望成為高級程序員,或者希望開發通用框架,就需要大量開發自定義標簽了。所有的 MVC 框架,如 Struts 2、SpringMVC、JSF 等都提供了豐富的自定義標簽。

          當我們在 JSP 頁面使用一個簡單的標簽時,底層實際上由標簽處理類提供支持,從而可以使用簡單的標簽來封裝復雜的功能,從而使團隊更好地協作開發(能讓美工人員更好地參與 JSP 頁面的開發)。

          早期 JSP 自定義標簽類開發過程略微復雜一些,但 JSP 2 已經簡化了這個過程,它只要自定義標簽類都必須繼承一個父類:javax.servlet.jsp.tagext.SimpleTagSupport,除此之外,JSP 自定義標簽類還有如下要求。

          • 如果標簽類包含屬性,每個屬性都有對應的 getter 和 setter 方法。
          • 重寫 doTag() 方法,這個方法負責生成頁面內容。

          下面開發一個最簡單的自定義標簽,該標簽負責在頁面上輸出 HelloWorld。

          // 標簽處理類,繼承 SimpleTagSupport 父類
          public class HelloWorldTag extends SimpleTagSupport 
          { 
              // 重寫 doTag 方法,該方法在標簽結束生成頁面內容
              public void doTag()throws JspException, 
                  IOException 
              { 
                  // 獲取頁面輸出流,并輸出字符串
                  getJspContext().getOut().write("Hello World"); 
              } 
          } 
          

          上面這個標簽處理類非常簡單,它繼承了 SimpleTagSupport 父類,并重寫 doTag() 方法,而 doTag() 方法則負責輸出頁面內容。該標簽沒有屬性,因此無須提供 setter 和 getter 方法。


          建立 TLD 文件

          TLD 是 Tag Library Definition 的縮寫,即標簽庫定義,文件的后綴是 tld,每個 TLD 文件對應一個標簽庫,一個標簽庫中可包含多個標簽,TLD 文件也稱為標簽庫定義文件。

          標簽庫定義文件的根元素是 taglib,它可以包含多個 tag 子元素,每個 tag 子元素都定義一個標簽。通常我們可以到 Web 容器下復制一個標簽庫定義文件,并在此基礎上進行修改即可。例如 Tomcat6.0,在 webapps\examples\WEB-INF\jsp2 路徑下包含了一個 jsp2-example-taglib.tld 文件,這就是示范用的標簽庫定義文件。

          將該文件復制到 Web 應用的 WEB-INF/ 路徑,或 WEB-INF 的任意子路徑下,并對該文件進行簡單修改,修改后的 mytaglib.tld 文件代碼如下:

          <?xml version="1.0" encoding="GBK"?>
          <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 web-jsptaglibrary_2_0.xsd"
              version="2.0">
              <tlib-version>1.0</tlib-version>
              <short-name>mytaglib</short-name>
              <!-- 定義該標簽庫的URI -->
              <uri>http://www.crazyit.org/mytaglib</uri>
              <!-- 定義第一個標簽 -->
              <tag>
                  <!-- 定義標簽名 -->
                  <name>helloWorld</name>
                  <!-- 定義標簽處理類 -->
                  <tag-class>lee.HelloWorldTag</tag-class>
                  <!-- 定義標簽體為空 -->
                  <body-content>empty</body-content>
              </tag>
          </taglib>
          

          上面標簽庫定義文件也是一個標準的 XML 文件,該 XML 文件的根元素是 taglib 元素,因此我們每次編寫標簽庫定義文件都直接添加該元素即可。

          taglib 下有三個子元素:

          • tlib-version:指定該標簽庫實現的版本,這是一個作為標識的內部版本號,對程序沒有太大的作用。
          • short-name:該標簽庫的默認短名,該名稱通常也沒有太大的用處。
          • uri:這個屬性非常重要,它指定該標簽庫的 URI,相當于指定該標簽庫的唯一標識。如上粗體字代碼所示,JSP 頁面中使用標簽庫時就是根據該 URI 屬性來定位標簽庫的。

          除此之外,taglib 元素下可以包含多個 tag 元素,每個 tag 元素定義一個標簽,tag 元素下至少應包含如下三個子元素:

          • name:該標簽庫的名稱,這個屬性很重要,JSP 頁面中就是根據該名稱來使用此標簽的。
          • tag-class:指定標簽的處理類,毋庸置疑,這個屬性非常重要,指定了標簽由哪個 Java 類來處理。
          • body-content:這個屬性也很重要,它指定標簽體內容。該元素的值可以是如下幾個:
            • tagdependent:指定標簽處理類自己負責處理標簽體。
            • empty:指定該標簽只能作用空標簽使用。
            • scriptless:指定該標簽的標簽體可以是靜態 HTML 元素,表達式語言,但不允許出現 JSP 腳本。
            • JSP:指定該標簽的標簽體可以使用 JSP 腳本。

          實際上由于 JSP 2 規范不再推薦使用 JSP 腳本,所以 JSP 2 自定義標簽的標簽體中不能包含 JSP 腳本。所以實際上 body-content 元素的值不可以是 JSP。

          定義了上面的標簽庫定義文件后,將標簽庫文件放在 Web 應用的 WEB-INF 路徑,或任意子路徑下,Java Web 規范會自動加載該文件,則該文件定義的標簽庫也將生效。


          使用標簽庫

          在 JSP 頁面中確定指定標簽需要 2 點:

          • 標簽庫 URI:確定使用哪個標簽庫。
          • 標簽名:確定使用哪個標簽。

          使用標簽庫分成以下兩個步驟:

          1. 導入標簽庫:使用 taglib 編譯指令導入標簽庫,就是將標簽庫和指定前綴關聯起來。
          2. 使用標簽:在 JSP 頁面中使用自定義標簽。

          taglib 的語法格式如下:

          <%@ taglib uri="tagliburi" prefix="tagPrefix" %> 
          

          其中 uri 屬性確定標簽庫的 URI,這個 URI 可以確定一個標簽庫。而 prefix 屬性指定標簽庫前綴,即所有使用該前綴的標簽將由此標簽庫處理。

          使用標簽的語法格式如下:

          <tagPrefix:tagName tagAttribute=”tagValue” … > 
          	<tagBody/> 
          </tagPrefix:tagName> 
          

          如果該標簽沒有標簽體,則可以使用如下語法格式:

          <tagPrefix:tagName tagAttribute=”tagValue” … /> 
          

          上面使用標簽的語法里都包含了設置屬性值,前面我們介紹的 HelloWorldTag 標簽沒有任何屬性,所以使用該標簽只需用 <mytag:helloWorld/> 即可。其中 mytag 是 taglib 指令為標簽庫指定的前綴,而 helloWorld 是標簽名。

          下面是使用 helloWorld 標簽的 JSP 頁面代碼:

          <%@ page contentType="text/html; charset=GBK"%>
          <!-- 導入標簽庫,指定mytag前綴的標簽,
          	由http://www.crazyit.org/mytaglib的標簽庫處理 -->
          <%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%>
          <html>
          <head>
          <title>自定義標簽示范</title>
          </head>
          <body bgcolor="#ffffc0">
          <h2>下面顯示的是自定義標簽中的內容</h2>
          <!-- 使用標簽 ,其中mytag是標簽前綴,根據taglib的編譯指令,
          	mytag前綴將由http://www.crazyit.org/mytaglib的標簽庫處理 -->
          <mytag:helloWorld/><BR>
          </body>
          </html>
          

          上面頁面中第一行粗體字代碼指定了 http://www.crazyit.org/mytaglib 標簽庫的前綴為 mytag,第二行粗體字代碼表明使用 mytag 前綴對應標簽庫里的 helloWorld 標簽。瀏覽該頁面將看到如圖 1 所示效果:


          圖 1. 簡單標簽
          圖 1. 簡單標簽

          帶屬性的標簽

          前面的簡單標簽既沒有屬性,也沒有標簽體,用法、功能都比較簡單。實際上還有如下兩種常用的標簽:

          • 帶屬性的標簽。
          • 帶標簽體的標簽。

          正如前面介紹的,帶屬性標簽必須為每個屬性提供對應的 setter 和 getter 方法。帶屬性標簽的配置方法與簡單標簽也略有差別,下面介紹一個帶屬性標簽的示例:

          public class QueryTag extends SimpleTagSupport
          {
              //標簽的屬性
              private String driver;
              private String url;
              private String user;
              private String pass;
              private String sql;
              //執行數據庫訪問的對象 
              private Connection conn = null;
              private Statement stmt = null;
              private ResultSet rs = null;
              private ResultSetMetaData rsmd = null;
              //標簽屬性driver的setter方法
              public void setDriver(String driver) {
                  this.driver = driver; 
              }
                  //標簽屬性url的setter方法
              public void setUrl(String url) {
                  this.url = url; 
              }
                  //標簽屬性user的setter方法
              public void setUser(String user) {
                  this.user = user; 
              }
                  //標簽屬性pass的setter方法
              public void setPass(String pass) {
                  this.pass = pass; 
              }
                  //標簽屬性driver的getter方法
              public String getDriver() {
                  return (this.driver); 
              }
                  //標簽屬性url的getter方法
              public String getUrl() {
                  return (this.url); 
              }
                  //標簽屬性user的getter方法
              public String getUser() {
                  return (this.user); 
              }
                  //標簽屬性pass的getter方法
              public String getPass() {
                  return (this.pass); 
              }
                  //標簽屬性sql的getter方法
              public String getSql() {
                  return (this.sql); 
              }
                  //標簽屬性sql的setter方法
              public void setSql(String sql) {
                  this.sql = sql; 
              }
              public void doTag()throws JspException,
                  IOException
              {
                     try
                  {
                      //注冊驅動
                      Class.forName(driver);
                      //獲取數據庫連接
                      conn = DriverManager.getConnection(url,user,pass);
                      //創建Statement對象
                      stmt = conn.createStatement();
                      //執行查詢
                      rs = stmt.executeQuery(sql);
                      rsmd = rs.getMetaData();
                      //獲取列數目
                      int columnCount = rsmd.getColumnCount();
                      //獲取頁面輸出流
                      Writer out = getJspContext().getOut();
                      //在頁面輸出表格
                      out.write("<table border='1' bgColor='9999cc' width='400'>");
                      //遍歷結果集
                      while (rs.next())
                      {
                          out.write("<tr>");
                          //逐列輸出查詢到的數據
                          for (int i = 1 ; i <= columnCount ; i++ )
                          {
                              out.write("<td>");
                              out.write(rs.getString(i));
                              out.write("</td>");
                          }
                          out.write("</tr>");
                      }
                  }
                  catch(ClassNotFoundException cnfe)
                  {
                      cnfe.printStackTrace();
                      throw new JspException("自定義標簽錯誤" + cnfe.getMessage());
                  }
                  catch (SQLException ex)
                  {
                      ex.printStackTrace();
                      throw new JspException("自定義標簽錯誤" + ex.getMessage());
                  }
                  finally
                  {
                      //關閉結果集
                      try
                      {
                          if (rs != null)
                              rs.close();
                          if (stmt != null)
                              stmt.close();
                          if (conn != null)
                              conn.close();
                      }
                      catch (SQLException sqle)
                      {
                          sqle.printStackTrace();
                      }
                  }
              }
          }
          

          上面這個標簽稍微復雜一點,它包含了 5 個屬性,如程序中粗體字代碼所示,則程序需要為這 5 個屬性提供 setter 和 getter 方法。

          該標簽輸出的內容依然由 doTag() 方法決定,該方法會根據 SQL 語句查詢數據庫,并將查詢結果顯示在當前頁面中。

          對于有屬性的標簽,需要為 tag 元素增加 attribute 子元素,每個 attribute 子元素定義一個屬性,attribue 子元素通常還需要指定如下幾個子元素:

          • name:設置屬性名,子元素的值是字符串內容。
          • required:設置該屬性是否為不需屬性,該子元素的值是 true 或 false。
          • fragment:設置該屬性是否支持 JSP 腳本、表達式等動態內容,子元素的值是 true 或 false。

          為了配置上面的 QueryTag 標簽,我們需要在 mytaglib.tld 文件中增加如下配置片段:

          <!-- 定義第二個標簽 -->
          <tag>
              <!-- 定義標簽名 -->
              <name>query</name>
              <!-- 定義標簽處理類 -->
              <tag-class>lee.QueryTag</tag-class>
              <!-- 定義標簽體為空 -->
              <body-content>empty</body-content>
              <!-- 配置標簽屬性:driver -->
              <attribute>
                  <name>driver</name> 
                  <required>true</required>
                  <fragment>true</fragment>
              </attribute>
              <!-- 配置標簽屬性:url -->
              <attribute>
                  <name>url</name> 
                  <required>true</required>
                  <fragment>true</fragment>
              </attribute>
              <!-- 配置標簽屬性:user -->
              <attribute>
                  <name>user</name> 
                  <required>true</required>
                  <fragment>true</fragment>
              </attribute>
              <!-- 配置標簽屬性:pass -->
              <attribute>
                  <name>pass</name> 
                  <required>true</required>
                  <fragment>true</fragment>
              </attribute>
              <!-- 配置標簽屬性:sql -->
              <attribute>
                  <name>sql</name> 
                  <required>true</required>
                  <fragment>true</fragment>
              </attribute>
          </tag>
          

          上面 5 行粗體字代碼分別為該標簽配置了 driver、url、user、pass 和 sql 等 5 個屬性,并指定這 5 個屬性都是必填屬性、而且屬性值支持動態內容。

          配置完畢后,就可在頁面中使用標簽,先導入標簽庫,然后使用標簽。使用標簽的 JSP 頁面片段如下:

          <!-- 導入標簽庫,指定mytag前綴的標簽,
              由http://www.crazyit.org/mytaglib的標簽庫處理 -->
          <%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%>
          ...
          <!-- 其他HTML內容 -->
          <!-- 使用標簽 ,其中mytag是標簽前綴,根據taglib的編譯指令,
              mytag前綴將由http://www.crazyit.org/mytaglib的標簽庫處理 -->
          <mytag:query
              driver="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/javaee"
              user="root"
              pass="32147"
              sql="select * from newsinf"/>
          

          在瀏覽器中瀏覽該頁面,效果如圖 2 所示。


          圖 2. 使用帶屬性的標簽執行查詢
          圖 2. 使用帶屬性的標簽執行查詢

          圖 2 中看到從數據庫里查詢到 2 條記錄,當然這也需要底層 javaee 數據庫里包含 newsinf 數據表,且該數據表里包含這兩條記錄才行。

          在 JSP 頁面中只需要使用簡單的標簽,即可完成“復雜”的功能:執行數據庫查詢,并將查詢結果在頁面上以表格形式顯示。這也正是自定義標簽庫的目的——以簡單的標簽,隱藏復雜的邏輯。

          當然,并不推薦在標簽處理類中訪問數據庫,因為標簽庫是表現層組件,它不應該包含任何業務邏輯實現代碼,更不應該執行數據庫訪問,它只應該負責顯示邏輯。


          帶標簽體的標簽

          帶標簽體的標簽,可以在標簽內嵌入其他內容(包括靜態的 HTML 內容和動態的 JSP 內容),通常用于完成一些邏輯運算,例如判斷和循環等。下面以一個迭代器標簽為示例,介紹帶標簽體標簽的開發過程。

          一樣先定義一個標簽處理類,該標簽處理類的代碼如下:

          public class IteratorTag extends SimpleTagSupport
          {
              //標簽屬性,用于指定需要被迭代的集合
              private String collection;
              //標簽屬性,指定迭代集合元素,為集合元素指定的名稱
              private String item;
              //collection屬性的setter和getter方法
              public void setCollection(String collection)
              {
                  this.collection = collection;
              }
              public String getCollection()
              {
                  return this.collection;
              }
              //item屬性的setter和getter方法
              public void setItem(String item)
              {
                  this.item = item;
              }
              public String getItem()
              {
                  return this.item;
              }
              //標簽的處理方法,簡單標簽處理類只需要重寫doTag方法
              public void doTag() throws JspException, IOException
              {
                  //從page scope中獲取屬性名為collection的集合
                  Collection itemList = (Collection)getJspContext().
                      getAttribute(collection);
                  //遍歷集合
                  for (Object s : itemList)
                  {
                      //將集合的元素設置到page 范圍
                      getJspContext().setAttribute(item, s );
                      //輸出標簽體
                      getJspBody().invoke(null);
                  }
              }
          }
          

          上面標簽處理類與前面處理類并沒有太大的不同,該處理類包含 2 個屬性,并為這兩個屬性提供了 setter 和 getter 方法。標簽處理類的 doTag 方法首先從 page 范圍內獲取了指定名稱的 Collection 對象,然后遍歷 Collection 對象的元素,每次遍歷都調用了 getJspBody() 方法,如程序中粗體字代碼所示,該方法返回該標簽所包含的標簽體:JspFragment 對象,執行該對象的 invoke() 方法,即可輸出標簽體內容。該標簽的作用是:遍歷指定集合,每遍歷一個集合元素,即輸出標簽體一次。

          因為該標簽的標簽體不為空,配置該標簽時指定 body-content 為 scriptless,該標簽的配置代碼片段如下代碼所示:

          <!-- 定義第三個標簽 -->
          <tag>
              <!-- 定義標簽名 -->
              <name>iterator</name>
              <!-- 定義標簽處理類 -->
              <tag-class>lee.IteratorTag</tag-class>
              <!-- 定義標簽體支持JSP腳本 -->
              <body-content>scriptless</body-content>
              <!-- 配置標簽屬性:collection -->
              <attribute>
                  <name>collection</name> 
                  <required>true</required>
                  <fragment>true</fragment>
              </attribute>
              <!-- 配置標簽屬性:item -->
              <attribute>
                  <name>item</name> 
                  <required>true</required>
                  <fragment>true</fragment>
              </attribute>
          </tag>
          

          上面配置片段中粗體字代碼指定該標簽的標簽體可以是靜態 HTML 內容,也可以是表達式語言。

          為了測試在 JSP 頁面中使用該標簽的效果,我們首先把一個 List 對象設置成 page 范圍的屬性,然后使用該標簽來迭代輸出 List 集合的全部元素。

          JSP 頁面代碼如下:

          <%@ page import="java.util.*"%>
          <%@ page contentType="text/html; charset=GBK"%>
          <!-- 導入標簽庫,指定mytag前綴的標簽,
              由http://www.crazyit.org/mytaglib的標簽庫處理 -->
          <%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%>
          <html>
              <head>
                  <title>帶標簽體的標簽-迭代器標簽</title>
              </head>
              <body>
                  <h2>帶標簽體的標簽-迭代器標簽</h2>
                  <hr>
                  <%
                  //創建一個List對象
                  List<String> a = new ArrayList<String>();
                  a.add("hello");
                  a.add("world");
                  a.add("java");
                  //將List對象放入page范圍內
                  pageContext.setAttribute("a" , a);
                  %>
                  <table border="1" bgcolor="aaaadd" width="300">
                  <!-- 使用迭代器標簽,對a集合進行迭代 -->
                  <mytag:iterator collection="a" item="item">
                      <tr>
                          <td>${pageScope.item}</td>
                      <tr>
                  </mytag:iterator>
                  </table>
              </body>
          </html>
          

          上面頁面代碼中粗體字代碼即可實現通過 iterator 標簽來遍歷指定集合,瀏覽該頁面即看到如圖 3 所示界面:


          圖 3. 帶標簽體的標簽
          圖 3. 帶標簽體的標簽

          圖 3 顯示了使用 iterator 標簽遍歷集合元素的效果,從 iteratorTag.jsp 頁面的代碼來看,使用 iterator 標簽遍歷集合元素比使用 JSP 腳本遍歷集合元素要優雅得多,這就是自定義標簽的魅力。

          實際上 JSTL 標簽庫提供了一套功能非常強大標簽,例如普通的輸出標簽,像我們剛剛介紹的迭代器標簽,還有用于分支判斷的標簽等等,JSTL(JSP 標準標簽庫)都有非常完善的實現。除此之外,Apache 下還有一套 DisplayTags 的標簽庫實現,做得也非常不錯。
          本文轉自:http://www.ibm.com/developerworks/cn/java/j-lo-jsp2tag/index.html

          posted @ 2011-07-14 16:06 雪山飛鵠 閱讀(411) | 評論 (0)編輯 收藏

          說明一下目錄結構
           
          Spring配置文件
          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
              xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:p
          ="http://www.springframework.org/schema/p"
              xmlns:context
          ="http://www.springframework.org/schema/context"
              xsi:schemaLocation
          ="
              http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/context
              http://www.springframework.org/schema/context/spring-context-3.0.xsd"
          >
              
          <context:component-scan
                  
          base-package="com.spring.action" />
              
          <!--  
                  org.springframework.web.servlet.view.ResourceBundleViewResolver
                  用于多個視圖集成時,ResourceBundleViewResolver是通過解析資源文件來解析請求輸出文件的。
                  <property name="basename" value="views"></property>,即表示在/WEB-INF/classes路徑下有一個
                  views.properties文件,本例中views.properties的內容為
                  welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
                  welcome.url=welcome.vm
                  freemarker.(class)=org.springframework.web.servlet.view.freemarker.FreeMarkerView
                  freemarker.url=freemarker.ftl
              
          -->
              
          <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
                  
          <property name="basename" value="views"></property>
                  
          <!-- 
                      <property name="order" value="0"></property>
                  
          -->
              
          </bean>
              
              
          <!-- jsp視圖解析器 -->
              
          <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                  
          <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
                  
          <property name="prefix" value="/"/>
                  
          <property name="suffix" value=".jsp"/>
              
          </bean>        
              
              
          <!-- velocity視圖解析器 -->
              
          <bean id="velocityViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
                  
          <property name="cache" value="true"/>
                  
          <property name="prefix" value="/"/>
                  
          <property name="suffix" value=".vm"/>
              
          </bean>
              
              
          <!-- velocity環境配置 -->
              
          <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
                  
          <!-- velocity配置文件路徑 -->
                  
          <property name="configLocation" value="/WEB-INF/velocity.properties"/>
                  
          <!-- velocity模板路徑 -->
                  
          <property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
              
          </bean>
              
              
          <!-- FreeMarker環境配置 -->
              
          <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
                  
          <!-- freemarker模板位置 -->
                  
          <property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
              
          </bean>
              
              
          <!-- FreeMarker視圖解析 -->
              
          <bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
                  
          <property name="cache" value="true"/>
                  
          <property name="prefix" value="/"/>
                  
          <property name="suffix" value=".ftl"/>
              
          </bean>
          </beans>
          views.properties
          #welcome為modelAndView.setViewName("welcome");中的welcome   .(class)固定寫法
          welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
          #welcome.url 路徑 welcome.vm模板名稱
          welcome.url
          =welcome.vm

          #freemarker為modelAndView.setViewName(
          "freemarker");中的freemarker   .(class)固定寫法
          freemarker.(class)=org.springframework.web.servlet.view.freemarker.FreeMarkerView
          #freemarker.url 路徑 freemarker.ftl模板名稱
          freemarker.url
          =freemarker.ftl
          點我下載示例代碼
          posted @ 2011-07-13 17:14 雪山飛鵠 閱讀(12839) | 評論 (4)編輯 收藏

          package com.ipmotor.sm.db;

          import java.io.BufferedReader;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.InputStream;
          import java.io.InputStreamReader;
          import java.security.KeyStore;

          import org.apache.http.HttpResponse;
          import org.apache.http.client.HttpClient;
          import org.apache.http.client.methods.HttpGet;
          import org.apache.http.conn.scheme.Scheme;
          import org.apache.http.conn.ssl.SSLSocketFactory;
          import org.apache.http.impl.client.DefaultHttpClient;


          /**
           * 利用HttpClient,模擬https連接
           * 使用4.1版本
           * 
          @since 2011.7.7
           
          */
          public class Test{
              
              
          /**
               * 運行主方法
               * 
          @param args
               * 
          @throws Exception
               
          */
              
          public static void main(String[] args) throws Exception {
                
          //獲得httpclient對象
                HttpClient httpclient = new DefaultHttpClient();
                
          //獲得密匙庫
                KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
                FileInputStream instream 
          = new FileInputStream(new File("D:/zzaa"));
                
          //密匙庫的密碼
                trustStore.load(instream, "123456".toCharArray());
                
          //注冊密匙庫
                SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
                
          //不校驗域名
                socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                Scheme sch 
          = new Scheme("https"800, socketFactory);
                httpclient.getConnectionManager().getSchemeRegistry().register(sch);
                
          //獲得HttpGet對象
                HttpGet httpGet = null;
                httpGet 
          = new HttpGet("https://10.15.32.176:800/cgi-bin/service.cgi?session=caef0c3742c8f8ef4c98772e860c9fd2&rand=128&domain=sun.com&type=domain&cmd=disable");
                
          //發送請求
                HttpResponse response = httpclient.execute(httpGet);
                
          //輸出返回值
                InputStream is = response.getEntity().getContent();
                BufferedReader br 
          = new BufferedReader(new InputStreamReader(is));
                String line 
          = "";
                
          while((line = br.readLine())!=null){
                    System.out.println(line);
                }
              }
          }
          依賴的jar包
          commons-codec-1.4.jar
          commons-logging-1.1.1.jar
          httpclient-4.1.1.jar
          httpclient-cache-4.1.1.jar
          httpcore-4.1.jar
          httpmime-4.1.1.jar
          posted @ 2011-07-08 14:14 雪山飛鵠 閱讀(24677) | 評論 (3)編輯 收藏

          package com.ipmotor.sm.db;

          import java.util.LinkedList;
          import java.util.Queue;
          import java.util.Stack;

          /**
           * 測試jdk中的棧和隊列
           * 
          @author scott
           *
           
          */
          public class TestQueueAndStack {
              
              
          /**
               * 測試隊列
               * <pre>
               * 隊列特點,先進先出,后進后出,火車過山洞例子
               * </pre>
               
          */
              
          static void testQueue(){
                  Queue
          <String> queue=new LinkedList<String>();
                  
          //添加幾個元素
                  queue.offer("a");
                  queue.offer(
          "b");
                  queue.offer(
          "c");
                  queue.offer(
          "d");
                  queue.offer(
          "e");
                  queue.add(
          "1");
                  queue.add(
          "2");
                  queue.add(
          "3");
                  queue.add(
          "4");
                  queue.add(
          "5");
                  System.out.println(
          "隊列中的元素是:"+queue);
                  
          //彈出元素
                  queue.poll();
                  System.out.println(
          "隊列中的元素是:"+queue);
                  
          //查看隊列中首個元素,并不移除
                  String peek=queue.peek();
                  System.out.println(
          "查看隊列中首個元素,并不移除:"+peek);
                  System.out.println(
          "隊列中的元素是:"+queue);
              }
              
              
              
          /**
               * 測試棧
               * <pre>
               * 先進后出,后進先出,水桶倒水
               * </pre>
               
          */
              
          static void testStack(){
                  Stack
          <String> stack=new Stack<String>();
                  
          //添加幾個元素
                  stack.push("a");
                  stack.push(
          "b");
                  stack.push(
          "c");
                  stack.push(
          "d");
                  stack.push(
          "e");
                  stack.add(
          "1");
                  stack.add(
          "2");
                  stack.add(
          "3");
                  stack.add(
          "4");
                  stack.add(
          "5");
                  System.out.println(
          "棧中的元素是:"+stack);
                  
          //彈出元素
                  stack.pop();
                  System.out.println(
          "棧中的元素是:"+stack);
                  
          //查看棧中首個元素,并不移除
                  String peek=stack.peek();
                  System.out.println(
          "查看棧中首個元素,并不移除:"+peek);
                  System.out.println(
          "棧中的元素是:"+stack);
              }
              

              
          /**
               * 
          @param args
               
          */
              
          public static void main(String[] args) {
                  testQueue();
                  System.out.println(
          "-------棧--------");
                  testStack();
              }

          }

          隊列中的元素是:[a, b, c, d, e, 1, 2, 3, 4, 5]
          隊列中的元素是:[b, c, d, e, 1, 2, 3, 4, 5]
          查看隊列中首個元素,并不移除:b
          隊列中的元素是:[b, c, d, e, 1, 2, 3, 4, 5]
          -------棧--------
          棧中的元素是:[a, b, c, d, e, 1, 2, 3, 4, 5]
          棧中的元素是:[a, b, c, d, e, 1, 2, 3, 4]
          查看棧中首個元素,并不移除:4
          棧中的元素是:[a, b, c, d, e, 1, 2, 3, 4]
          posted @ 2011-07-08 13:37 雪山飛鵠 閱讀(957) | 評論 (0)編輯 收藏

          首先在github上申請一個賬戶
          https://github.com/
          接下來創建項目名稱什么的
          然后根據他初始化的信息結合一下博文即可輕松將項目托管到github
          http://artori.us/git-github-usage/
          posted @ 2011-07-01 11:34 雪山飛鵠 閱讀(2392) | 評論 (0)編輯 收藏

          僅列出標題
          共22頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 Last 
          主站蜘蛛池模板: 军事| 泽普县| 革吉县| 河西区| 江门市| 湄潭县| 富蕴县| 塘沽区| 漳州市| 东乌| 色达县| 扶余县| 淮滨县| 开江县| 天祝| 襄城县| 长沙县| 沁阳市| 东至县| 运城市| 吴桥县| 崇州市| 米泉市| 富宁县| 大埔县| 淄博市| 卓资县| 遵义县| 遂川县| 霍城县| 梧州市| 密云县| 曲松县| 抚州市| 东台市| 成都市| 金昌市| 遂平县| 灵山县| 鄂尔多斯市| 万年县|