捕風之巢

          統計

          留言簿(3)

          java友情鏈接

          閱讀排行榜

          評論排行榜

          j2ee小應用

          附加功能 (目錄)
          實現圖片上傳 (目錄)
            用戶必須能夠上傳圖片,因此需要文件上傳的功能。比較常見的文件上傳組件有Commons FileUpload(http://jakarta.apache.org/commons/fileupload/a>)和COS FileUpload(http://www.servlets.com/cos),Spring已經完全集成了這兩種組件,這里我們選擇Commons FileUpload。
            由于Post一個包含文件上傳的Form會以multipart/form-data請求發送給服務器,必須明確告訴 DispatcherServlet如何處理MultipartRequest。首先在dispatcher-servlet.xml中聲明一個 MultipartResolver:

          <bean?id="multipartResolver"
          ???????class
          ="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          ????????
          <!--?設置上傳文件的最大尺寸為1MB?-->
          ????????
          <property?name="maxUploadSize">
          ????????
          <value>1048576</value>
          ????
          </property>
          </bean>


            這樣一旦某個Request是一個MultipartRequest,它就會首先被MultipartResolver處理,然后再轉發相應的Controller。
            在UploadImageController中,將HttpServletRequest轉型為MultipartHttpServletRequest,就能非常方便地得到文件名和文件內容:

          public?ModelAndView?handleRequest(HttpServletRequest?request,?HttpServletResponse?response)?throws?Exception?{
          ????
          //?轉型為MultipartHttpRequest:
          ????MultipartHttpServletRequest?multipartRequest?=?(MultipartHttpServletRequest)?request;
          ????
          //?獲得文件:
          ????MultipartFile?file?=?multipartRequest.getFile("file");
          ????
          //?獲得文件名:
          ????String?filename?=?file.getOriginalFilename();
          ????
          //?獲得輸入流:
          ????InputStream?input?=?file.getInputStream();
          ????
          //?寫入文件
          }


          生成縮略圖 (目錄)
            當用戶上傳了圖片后,必須生成縮略圖以便用戶能快速瀏覽。我們不需借助第三方軟件,JDK標準庫就包含了圖像處理的API。我們把一張圖片按比例縮放到120X120大小,以下是關鍵代碼:

          public?static?void?createPreviewImage(String?srcFile,?String?destFile)?{
          ????
          try?{
          ????????File?fi?
          =?new?File(srcFile);?//?src
          ????????File?fo?=?new?File(destFile);?//?dest
          ????????BufferedImage?bis?=?ImageIO.read(fi);

          ????????
          int?w?=?bis.getWidth();
          ????????
          int?h?=?bis.getHeight();
          ????????
          double?scale?=?(double)w/h;
          ????????
          int?nw?=?IMAGE_SIZE;?//?final?int?IMAGE_SIZE?=?120;
          ????????int?nh?=?(nw?*?h)?/?w;
          ????????
          if(?nh>IMAGE_SIZE?)?{
          ????????????nh?
          =?IMAGE_SIZE;
          ????????????nw?
          =?(nh?*?w)?/?h;
          ????????}

          ????????
          double?sx?=?(double)nw?/?w;
          ????????
          double?sy?=?(double)nh?/?h;

          ????????transform.setToScale(sx,sy);
          ????????AffineTransformOp?ato?
          =?new?AffineTransformOp(transform,?null);
          ????????BufferedImage?bid?
          =?new?BufferedImage(nw,?nh,?BufferedImage.TYPE_3BYTE_BGR);
          ????????ato.filter(bis,bid);
          ????????ImageIO.write(bid,?
          "jpeg",?fo);
          ????}
          ?catch(Exception?e)?{
          ????????e.printStackTrace();
          ????????
          throw?new?RuntimeException("Failed?in?create?preview?image.?Error:?"?+?e.getMessage());
          ????}

          }

          實現RSS (目錄)
            RSS是一個標準的XML文件,Rss閱讀器可以讀取這個XML文件獲得文章的信息,使用戶可以通過Rss閱讀器而非瀏覽器閱讀Blog,我們只要動態生成這個XML文件便可以了。RSSLibJ是一個專門讀取和生成RSS的小巧實用的Java庫,大小僅25k,可以從http://sourceforge.net/projects/rsslibj/下載rsslibj-1_0RC2.jar和它需要的EXMLjar兩個文件,然后復制到web/WEB-INF/lib/下。
            使用RSSLibJ異常簡單,我們先設置好HttpServletResponse的Header,然后通過RSSLibJ輸出XML即可:

          Channel?channel?=?new?Channel();
          channel.setDescription(account.getDescription());
          baseUrl?
          =?baseUrl.substring(0,?n);
          channel.setLink(
          "http://server-name/home.c?accountId="?+?accountId);
          channel.setTitle(account.getTitle());
          List?articles?
          =?facade.getArticles(accountId,?account.getMaxPerPage(),?1);
          Iterator?it?
          =?articles.iterator();
          while(it.hasNext())?{
          ????Article?article?
          =?(Article)it.next();
          ????channel.addItem(
          "http://server-name/article.c?articleId="?+?article.getArticleId(),
          ????????article.getSummary(),?article.getTitle()
          ????);
          }

          //?輸出xml:
          response.setContentType("text/xml");
          PrintWriter?pw?
          =?response.getWriter();
          pw.print(channel.getFeed(
          "rss"));
          pw.close();

          實現全文搜索 (目錄)
            全文搜索能大大方便用戶快速找到他們希望的文章,為blog增加一個全文搜索功能是非常必要的。然而,全文搜索不等于SQL的LIKE語句,因為關系數據庫的設計并不是為全文搜索設計的,數據庫索引對全文搜索無效,在一個幾百萬條記錄中檢索LIKE '%A%'可能會耗時幾分鐘,這是不可接受的。幸運的是,我們能使用免費并且開源的純Java實現的Lucene全文搜索引擎,Lucene可以非常容易地集成到我們的blog中。
            Lucene不提供直接對文件,數據庫的索引,只提供一個高性能的引擎,但接口卻出人意料地簡單。我們只需要關心以下幾個簡單的接口:
            Document:代表Lucene數據庫的一條記錄,也代表搜索的一條結果。
            Field:一個Document包含一個或多個Field,類似關系數據庫的字段。
            IndexWriter:用于創建新的索引,也就是向數據庫添加新的可搜索的大段字符串。
            Analyzer:將字符串拆分成單詞(Token),不同的文本對應不同的Analyzer,如HtmlAnalyzer,PDFAnalyzer。
            Query:封裝一個查詢,用于解析用戶輸入。例如,將“bea blog”解析為“同時包含bea和blog的文章”。
            Searcher:搜索一個Query,結果將以Hits返回。
            Hits:封裝一個搜索結果,包含Document集合,能非常容易地輸出結果。
            下一步,我們需要為Article表的content字段建立全文索引。首先為Lucene新建一個數據庫,請注意這個數據庫是Lucene專用的,我們不能也不必知道它的內部結構。Lucene的每個數據庫對應一個目錄,只需要指定目錄即可:

          String?indexDir?=?"C:/search/blog";
          IndexWriter?indexWriter?
          =?new?IndexWriter(indexDir,?new?StandardAnalyzer(),?true);
          indexWriter.close();

            然后添加文章,讓Lucene對其索引:

          String?title?
          =?"文章標題"?//?從數據庫讀取
          String?content?=?"文章內容"?//?從數據庫讀取
          //?打開索引:
          IndexWriter?indexWriter?=?new?IndexWriter(indexDir,?new?StandardAnalyzer(),?false);
          //?添加一個新記錄:
          Document?doc?=?new?Document();
          doc.add(Field.Keyword(
          "title",?title));
          doc.add(Field.Text(
          "content",?content));
          //?建立索引:
          indexWriter.addDocument(doc);
          //?關閉:
          indexWriter.close();

           要搜索文章非常簡單:
           然后添加文章,讓對其索引:

          String?title?=?"文章標題"?//?從數據庫讀取
          String?content?=?"文章內容"?//?從數據庫讀取
          //?打開索引:
          IndexWriter?indexWriter?=?new?IndexWriter(indexDir,?new?StandardAnalyzer(),?false);
          //?添加一個新記錄:
          Document?doc?=?new?Document();
          doc.add(Field.Keyword(
          "title",?title));
          doc.add(Field.Text(
          "content",?content));
          //?建立索引:
          indexWriter.addDocument(doc);
          //?關閉:
          indexWriter.close();

            要搜索文章非常簡單:

          Searcher?searcher?=?new?IndexSearcher(dir);
          Query?query?
          =?QueryParser.parse(keyword,?"content",?new?StandardAnalyzer());
          Hits?hits?
          =?searcher.search(query);
          if(hits?!=?null){
          ????
          for(int?i?=?0;i?<?hits.length();?i++){
          ????????Document?doc?
          =?hits.doc(i);
          ????????System.out.println(
          "found?in?"?+?doc.get("title"));
          ????????System.out.println(doc.get(
          "content"));
          ????}

          }

          searcher.close();
            我們設計一個LuceneSearcher類封裝全文搜索功能,由于必須鎖定數據庫所在目錄,我們把數據庫設定在/WEB-INF/search/下,確保用戶不能訪問,并且在配置文件中初始化目錄:

          <bean?id="luceneSearcher"?class="org.crystalblog.search.LuceneSearcher">
          ????
          <property?name="directory">
          ???????
          <value>/WEB-INF/search/</value>
          ????
          </property>
          </bean>

          效果如下:


          (圖4:search)

          發送Email (目錄)
            Blog用戶可以讓系統將來訪用戶的留言發送到注冊的Email地址,為了避免使用SMTP發信服務器,我們自己手動編寫一個SendMail組件,直接通過SMTP協議將Email發送到用戶信箱。
            SendMail組件只需配置好DNS服務器的IP地址,即可向指定的Email信箱發送郵件。并且,SendMail使用緩沖隊列和多線程在后臺發送Email,不會中斷正常的Web服務。具體代碼請看SendMail.java。

          測試 (目錄)
            服務器配置為:P4 1.4G,512M DDR,100M Ethernet,Windows XP Professional SP2。
            測試服務器分別為WebLogic Server 8.1,Tomcat 4.1/5.0,Resin 2.1.1。
            測試數據庫為MS SQL Server 2000 SP3。如果你使用Oracle或者DB2,MySQL等其他數據庫并測試成功,請將SQL初始化腳本和詳細配置過程發一份給我,謝謝。
            由于時間有限,沒有作進一步的調優。WebLogic Server和iBatis有很多優化選項,詳細配置可以參考相關文檔。

          中文支持 (目錄)
            測試發現,中文不能在頁面中正常顯示,為了支持中文,首先在web.xml加入Filter,用于將輸入編碼設置為gb2312:
          <filter>
          ????
          <filter-name>encodingFilter</filter-name>
          ????
          <filter-class>org.crystalblog.web.filter.EncodingFilter</filter-class>
          ????
          <init-param>
          ????????
          <param-name>encoding</param-name>
          ????????
          <param-value>gb2312</param-value>
          ????
          </init-param>
          </filter>
          <filter-mapping>
          ????
          <filter-name>encodingFilter</filter-name>
          ????
          <url-pattern>/*</url-pattern>
          </filter-mapping>

            然后用文本工具搜索所有的.htm,.html,.properties文件,將“iso-8859-1”替換為“gb2312”,現在頁面中文已經能正常顯示,但是Lucene仍不能正常解析中文,原因是標準的StandardA?nalyzer只能解析英文,可以從網上下載一個支持中文的 Analyzer。

          posted on 2006-10-13 10:08 捕風 閱讀(265) 評論(1)  編輯  收藏 所屬分類: java高級

          評論

          # re: j2ee小應用 2008-01-19 08:41 touchsky88

          Dealing with Chinese, unicode I suppose is a pain on the neck.

          Add the following part solve the unicode problem.
          <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <!-- 設置上傳文件的最大尺寸為1MB -->
          <property name="maxUploadSize">
          <value>1048576</value>
          </property>
          <property name="defaultEncoding">
          <value>UTF-8</value>
          </property>
          </bean>  回復  更多評論   

          主站蜘蛛池模板: 鸡东县| 敦化市| 会昌县| 拉孜县| 玉溪市| 海晏县| 兰西县| 定襄县| 吐鲁番市| 荥经县| 明溪县| 顺平县| 安新县| 陇南市| 河南省| 哈密市| 朝阳市| 伽师县| 乌兰察布市| 隆昌县| 彩票| 深圳市| 新源县| 渑池县| 儋州市| 洱源县| 肃宁县| 五原县| 都兰县| 龙陵县| 河北省| 山阴县| 卢湾区| 达拉特旗| 海阳市| 福安市| 翁牛特旗| 台北市| 府谷县| 赤水市| 龙南县|