乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      SpringSide開發(fā)實戰(zhàn)(五):兵馬未動,糧草先行...

       nbtymm 2007-01-15
      做過項目的人都知道,在構(gòu)思完一個項目的功能之后,緊接著的事情就是考慮這些構(gòu)思的功能如何實現(xiàn),對于自己不熟悉的領(lǐng)域,要進(jìn)行技術(shù)穿刺。我的穿刺方法為先查找有無比較好的開源組件可用,如果沒有,就查找相關(guān)的文檔,自己編寫和測試代碼。

      在這一篇,我主要解決三個問題。
      1、解決字符串加密的問題,在前面一篇中,我們設(shè)計用戶模塊的時候,準(zhǔn)備將用戶的密碼字段以MD5加密的方式保存,因此,這里需要寫一個對字符串加密生成MD5字符串的方法;
      2、解決生成圖像縮略圖和生成驗證碼的問題;
      3、解決url重寫的問題,之所以要用到url重寫,主要是為了讓用戶在訪問自己的主頁時,可以使用http://www./username或者h(yuǎn)ttp://username.這樣的形式,而不是像http://www./index.jsp?username=xxx這樣難看的形式。

      需要說明的是,要解決上面的三個問題,不是沒有開源的東西可用,而是我覺得每次都要整合不同的組件是在是太麻煩,而我們需要的功能也不是很復(fù)雜,我們不需要太通用的東西,只要能夠解決這里特定的問題就行了,因此不如自己動手實現(xiàn),同時還可以獲得技術(shù)上的提高。

      首先來看看MD5加密的問題,JDK中本來提供有數(shù)據(jù)加密的支持,其中java.security.MessageDigest類就可以實現(xiàn)MD5的加密,但是,加密后生成的數(shù)據(jù)是byte[]類型的,這里只需要寫一個方法將它轉(zhuǎn)換為字符串就行,代碼如下:

      package  com.xkland.util;

      import  java.security.MessageDigest;
      import  java.lang.NullPointerException;
      import  java.security.NoSuchAlgorithmException;

      public   class  StringUtil  {
       
      public   static   char [] num_chars  =   new   char [] { 0 ,
        
      1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
        
      9 , A , B , C , D , E , F }
      ;
       
       
      public   static  String toMD5String(String input) 
       
      throws  NullPointerException,NoSuchAlgorithmException {
        
      if (input  ==   null throw   new  NullPointerException();
        
      char [] output  =   new   char [ 32 ];
        MessageDigest md 
      =  MessageDigest.getInstance( " MD5 " );
        
      byte [] by  =  md.digest(input.getBytes());
        
      for ( int  i = 0 ;i < by.length;i ++ ) {
         output[
      2 * i]  =  num_chars[ (by[i]  &   0xf0 >>   4  ];
         output[
      2 * i + 1 =  num_chars[ by[i]  &   0xf  ];
        }

        
      return   new  String(output);
       }

      }


      下面是它的測試用例:

      package  com.xkland.util;

      import  junit.framework.TestCase;

      public   class  StringUtilTest  extends  TestCase  {

       
      public   void  testToMD5String()  {
        
      try {
         System.out.println(StringUtil.toMD5String(
      " abc " ));
        }
      catch (Exception e) {
         
        }

       }


      }



      運(yùn)行測試用例,輸出結(jié)果為:

      900150983CD24FB0D6963F7D28E17F72


      再來說說關(guān)于圖像縮略圖生成的問題,我準(zhǔn)備將它設(shè)置為一個可以讓Spring管理的類,簡單的說,可以利用Spring的配置文件來設(shè)置該類的一些屬性,比如原圖像保存的目錄和目標(biāo)圖像保存的目錄,生成的縮略圖的大小,生成縮略圖的方式。這里特別需要說明的就是這個生成縮略圖的方式,我們即可以指定它只簡單的執(zhí)行縮放,也可以指定它進(jìn)行剪裁以后再縮放。為什么要這么設(shè)計,請大家看看如下的效果圖,對于下面這兩張美女圖:
      32.jpg

      33.jpg


      如果我們只通過簡單的縮放來生成縮略圖,那么在網(wǎng)頁上的布局效果為:
      38.JPG

      如果我們通過先剪切后縮放的效果來生成縮略圖,那么在網(wǎng)頁上布局的效果為:
      39.JPG

      可以看到通過第二種方式生成的縮略圖布局要漂亮一些,但是會損失圖片的信息。因此,兩種方式各有優(yōu)劣。所以在設(shè)計的時候就設(shè)計為能夠讓用戶靈活配置。

      對于有些網(wǎng)友反映的gif動畫經(jīng)過縮放以后就不能動了,這個問題的主要原因是因為Java SDK 1.4和1.5版本的ImageIO類只能讀gif格式的文件,而不能寫gif格式的文件,因此,對于gif格式的文件,生成的縮略圖只能用png格式代替,在我的設(shè)計中,我準(zhǔn)備讓bmp格式的文件也讓png格式代替,因為png格式生成的文件更小,而且也不損失圖片質(zhì)量。至于Java SDK 1.4和1.5版不支持寫gif格式的文件,可以查看Java文檔,下面是截圖:
      30.JPG

      最新推出的Java SDK 6是可以寫gif格式的文件的,因此如果要解決這個問題,可以使用最新的JDK,下面是文檔截圖:
      31.JPG

      下面是我寫的生成縮略圖和生成驗證碼的ImageUtil類的源代碼:

      package  com.xkland.util;

      import  javax.imageio.ImageIO;

      import  java.awt.image.BufferedImage;
      import  java.io.File;
      import  java.awt.Image;
      import  java.awt.Graphics2D;
      import  java.util.Random;
      import  java.awt.Font;

      public   class  ImageUtil  {
          
      private  String sourceDir; // 圖片的存放路徑
           private  String destinationDir; // 縮略圖的存放路徑
           private  String mode; // 生成縮略圖的模式,可選ScaleOnly或ClipAndScale
           private  String width; // 縮略圖的寬度
           private  String height; // 縮略圖的高度
           private  String characterStorage; // 用來生成驗證碼的字符倉庫
          
          
      // 以下代碼段是為了使用Spring注入屬性
           public   void  setCharacterStorage(String characterStorage)  {
              
      this .characterStorage  =  characterStorage;
          }

          
      public   void  setDestinationDir(String destinationDir)  {
              
      this .destinationDir  =  destinationDir;
          }

          
      public   void  setHeight(String height)  {
              
      this .height  =  height;
          }

          
      public   void  setMode(String mode)  {
              
      this .mode  =  mode;
          }

          
      public   void  setSourceDir(String sourceDir)  {
              
      this .sourceDir  =  sourceDir;
          }

          
      public   void  setWidth(String width)  {
              
      this .width  =  width;
          }

          
          
      // 生成縮略圖的方法,默認(rèn)縮略圖的文件名和原圖相同,存放路徑不同
           public   void  createMicroImage(String fileName)
          
      throws  Exception {
              
      // 判斷sourceDir的格式是否為以"\"結(jié)尾,并生成完整的路徑
              String sourceFileName;
              String destinationFileName;
              
      if (sourceDir.lastIndexOf( \\ !=  (sourceDir.length() - 1 )) {
                  sourceFileName 
      =  sourceDir  +   " \\ "   +  fileName;
                  destinationFileName 
      =  destinationDir  +   " \\ "   +  fileName;
              }
      else {
                  sourceFileName 
      =  sourceDir  +  fileName;
                  destinationFileName 
      =  destinationDir  +  fileName;
              }

              
              
      // 創(chuàng)建文件,并判斷原文件是否存在
              File sourceFile  =   new  File(sourceFileName);
              
      if ( ! sourceFile.exists()) {
                  
      throw   new  Exception();
              }

              
      // 根據(jù)擴(kuò)展名判斷原文件的格式
              String extension  =  fileName.substring(fileName.lastIndexOf( . ) + 1 );
              
      if ( ! extension.equalsIgnoreCase( " jpg " &&   ! extension.equalsIgnoreCase( " bmp " )
                      
      &&   ! extension.equalsIgnoreCase( " gif " &&   ! extension.equalsIgnoreCase( " png " )) {
                  
      throw   new  Exception();
              }

              
              
      // 判斷縮略圖的寬度和高度是否正確,如果不能正確解析則拋出異常
               int  destinationWidth  =  Integer.parseInt(width);
              
      int  destinationHeight  =  Integer.parseInt(height);
              
              
      // 判斷縮放模式是否正確,如果配置錯誤,則拋出異常
               if ( ! mode.equalsIgnoreCase( " ScaleOnly " )
                      
      &&   ! mode.equalsIgnoreCase( " ClipAndScale " )) {
                  
      throw   new  Exception();
              }

              
              
      // 讀取圖像文件,并創(chuàng)建BufferedImage對象,如果不能讀取,則拋出異常
              BufferedImage image  =   null ;
              image 
      =  ImageIO.read(sourceFile);
              
      if (image == null ) {
                  
      throw   new  Exception();
              }

              
              
      // 獲取原圖像文件的高度和寬度
               int  sourceWidth  =  image.getWidth();
              
      int  sourceHeight  =  image.getHeight();
              
      // 生成縮略圖
               if (mode.equalsIgnoreCase( " ScaleOnly " )) {
                  BufferedImage destinationImage;
                  
      if (( float )sourceWidth / destinationWidth  >  ( float )sourceHeight / destinationHeight) {
                      Image tempImage 
      =  image.getScaledInstance(destinationWidth, ( int )(destinationWidth * (( float )sourceHeight / sourceWidth)), Image.SCALE_DEFAULT);
                      destinationImage 
      =   new  BufferedImage(destinationWidth, ( int )(destinationWidth * (( float )sourceHeight / sourceWidth)),BufferedImage.TYPE_INT_RGB);
                      Graphics2D graphics 
      =  destinationImage.createGraphics();
                      graphics.drawImage(tempImage,
      0 , 0 , null );
                      
                  }
      else {
                      Image tempImage 
      =  image.getScaledInstance(( int )(destinationHeight * (( float )sourceWidth / sourceHeight)), destinationHeight, Image.SCALE_DEFAULT);
                      destinationImage 
      =   new  BufferedImage(( int )(destinationHeight * (( float )sourceWidth / sourceHeight)), destinationHeight,BufferedImage.TYPE_INT_RGB);
                      Graphics2D graphics 
      =  destinationImage.createGraphics();
                      graphics.drawImage(tempImage,
      0 , 0 , null );
                  }
          
                  
      //  如果是bmp或者gif,則縮略圖為png格式
                   if (extension.equalsIgnoreCase( " bmp " ) || extension.equalsIgnoreCase( " gif " )) {
                      extension 
      =   " png " ;
                      destinationFileName 
      =  destinationFileName.substring( 0 , destinationFileName.lastIndexOf( . ))  +   " . "   +  extension;
                  }

                  File destinationFile 
      =   new  File(destinationFileName);
                  ImageIO.write(destinationImage, extension, destinationFile);
              }
      else {
                  BufferedImage destinationImage;
                  
      if (( float )sourceWidth / destinationWidth  >  ( float )sourceHeight / destinationHeight) {
                      
      // 先裁減
                       int  x  =  sourceWidth  -  ( int )(sourceHeight * (( float )destinationWidth / destinationHeight));
                      Image clipedImage 
      =  image.getSubimage(( int )( 0.5 * x),  0 , ( int )(sourceHeight * (( float )destinationWidth / destinationHeight)), sourceHeight);
                      
      // 后縮放
                      Image scaledImage  =  clipedImage.getScaledInstance(destinationWidth, destinationHeight, Image.SCALE_DEFAULT);
                      destinationImage 
      =   new  BufferedImage(destinationWidth, destinationHeight,BufferedImage.TYPE_INT_RGB);
                      Graphics2D graphics 
      =  destinationImage.createGraphics();
                      graphics.drawImage(scaledImage,
      0 , 0 , null );
                      
                  }
      else {
      //                 先裁減
                       int  y  =  sourceHeight  -  ( int )(sourceWidth * (( float )destinationHeight / destinationWidth));
                      Image clipedImage 
      =  image.getSubimage( 0 , ( int )( 0.5 * y), sourceWidth, ( int )(sourceWidth * (( float )destinationHeight / destinationWidth)));
                      
      // 后縮放
                      Image scaledImage  =  clipedImage.getScaledInstance(destinationWidth, destinationHeight, Image.SCALE_DEFAULT);
                      destinationImage 
      =   new  BufferedImage(destinationWidth, destinationHeight,BufferedImage.TYPE_INT_RGB);
                      Graphics2D graphics 
      =  destinationImage.createGraphics();
                      graphics.drawImage(scaledImage,
      0 , 0 , null );
                  }
          
                  
      //  如果是bmp或者gif,則縮略圖為png格式
                   if (extension.equalsIgnoreCase( " bmp " ) || extension.equalsIgnoreCase( " gif " )) {
                      extension 
      =   " png " ;
                      destinationFileName 
      =  destinationFileName.substring( 0 , destinationFileName.lastIndexOf( . ))  +   " . "   +  extension;
                  }

                  File destinationFile 
      =   new  File(destinationFileName);
                  ImageIO.write(destinationImage, extension, destinationFile);
              }

          }


          
      // 生成驗證碼的方法
           public  BufferedImage createValidateImage() {
              BufferedImage validateImage 
      =   new  BufferedImage( 80 , 20 ,BufferedImage.TYPE_INT_RGB);
              Graphics2D graphics 
      =  validateImage.createGraphics();
              
              
      // 從characterStorage中隨機(jī)抽取四個字符生成驗證碼
               int  length  =  characterStorage.length();
              
      char [] chars  =   new   char [ 4 ];
              Random rand 
      =   new  Random();
              
      for ( int  i = 0 ; i < 4 ; i ++ ) {
                  
      int  index  =  rand.nextInt(length);
                  chars[i] 
      =  characterStorage.charAt(index);
              }

              String str 
      =   new  String(chars);
              graphics.setFont(
      new  Font( " 宋體 " ,Font.BOLD, 18 ));
              System.out.println(graphics.getFont());
              graphics.drawString(str, 
      2 16 );
              
      // 隨機(jī)畫干擾直線
               for ( int  i = 0 ; i < 5 ; i ++ ) {
                  
      int  x1  =  rand.nextInt( 80 );
                  
      int  y1  =  rand.nextInt( 20 );
                  
      int  x2  =  rand.nextInt( 80 );
                  
      int  y2  =  rand.nextInt( 20 );
                  graphics.drawLine(x1, y1, x2, y2);
              }

              
              
      return  validateImage;
          }

      }


      寫得比較倉促,沒有進(jìn)行重構(gòu),所以比較難看一點(diǎn)。下面是測試用例的代碼:

      package  com.xkland.util;

      import  junit.framework.TestCase;
      import  javax.imageio.ImageIO;
      import  java.awt.image.BufferedImage;
      import  java.io.File;

      public   class  ImageUtilTest  extends  TestCase  {

          
      public   void  testCreateMicroImage()  throws  Exception  {
              ImageUtil util 
      =   new  ImageUtil();
              util.setSourceDir(
      " E:\\ " );
              util.setDestinationDir(
      " F:\\ " );
              util.setWidth(
      " 100 " );
              util.setHeight(
      " 100 " );
              
              
      // 以僅縮放的形式生成縮略圖
              util.setMode( " ScaleOnly " );
              
      // 橫圖像
              util.createMicroImage( " 001.bmp " );
              
      // 豎圖像
              util.createMicroImage( " 002.jpg " );
              
              
      // 以先裁減后縮放的形式生成縮略圖
              util.setDestinationDir( " G:\\ " );
              util.setMode(
      " ClipAndScale " );
              
      // 橫圖像
              util.createMicroImage( " 001.bmp " );
              
      // 豎圖像
              util.createMicroImage( " 002.jpg " );
          }

          
          
      public   void  testCreateValidateImage()  throws  Exception {
              ImageUtil util 
      =   new  ImageUtil();
              util.setCharacterStorage(
      " ABCDEFGHIJKLMNOPQRSTUVWXYZ北冥有魚其名為鯤鯤之大不知其幾千里也化而為鳥其名為鵬鵬之背不知其幾千里也怒而飛其翼若垂天之云是鳥也海運(yùn)則將徙于南冥南冥者天池也 " );
              BufferedImage image 
      =  util.createValidateImage();
              ImageIO.write(image, 
      " jpg " new  File( " F:\\validateImage.jpg " ));
          }


      }


      運(yùn)行該測試用例,可以成功的生成縮略圖,并且可以生成驗證碼,生成的驗證碼如下圖:
      40.jpg
      把以上代碼再修改再完善,就可以創(chuàng)建更漂亮一點(diǎn)的圖形了。

      為了把上面這個ImageUtil類讓SpringSide管理起來,并進(jìn)行靈活的配置,可以在src\main\resources\spring目錄下建立beans.xml文件,并如下配置:

      <? xml version="1.0" encoding="UTF-8" ?>
      <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www./dtd/spring-beans-2.0.dtd" >
      < beans >
          
      < bean  id ="imageUtil"  class ="com.xkland.util.ImageUtil" >
              
      < property  name ="sourceDir" >
                  
      < value > E:\ </ value >
              
      </ property >
              
      < property  name ="destinationDir" >
                  
      < value > F:\ </ value >
              
      </ property >
              
      < property  name ="width" >
                  
      < value > 100 </ value >
              
      </ property >
              
      < property  name ="height" >
                  
      < value > 100 </ value >
              
      </ property >
              
      < property  name ="mode" >
                  
      < value > ScaleOnly </ value >
              
      </ property >
              
      < property  name ="characterStorage" >
                  
      < value > ABCDEFGHIJKLMNOPQRSTUVWXYZ北冥有魚其名為鯤鯤之大不知其幾千里也化而為鳥其名為鵬鵬之背不知其幾千里也怒而飛其翼若垂天之云是鳥也海運(yùn)則將徙于南冥南冥者天池也 </ value >
              
      </ property >
          
      </ bean >
      </ beans >


      最后,我們再來看看url重寫的問題。俗話說得好:“會者不難,難者不會”,剛開始我為了實現(xiàn)文章開頭所說的url重寫功能,嘗試采用的是配置Servlet映射的方法,但是怎么都不成功,后來才想到使用Filter來實現(xiàn)。有時候開源的東西會直接影響人的思路,比如Struts 1.x采用的就是配置Servlet映射的方法,而到了2.0,也改成Filter了。

      在Filter中實現(xiàn)url重寫比較簡單,無非就是分析字符串和替換字符串,這里我就不列代碼了。只有想不到,沒有做不到,想辦法實現(xiàn)我們設(shè)計的功能,這便是技術(shù)穿刺的作用。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約