<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>阿杰的Blog</title>
    <description>　　天天挑战，天天奋斗，疯狂的８０后。</description>
    <link>http://jackzhangyunjie.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>电子地图－－MapABC研究（三）为地图上添加点并得到中心坐标</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/233770" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/233770</a>&nbsp;
          发表时间: 2008年08月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          出于项目的需要，还要继续对MapABC进行研究，昨天看了下地图上加点，结合项目实际写了个例子，用Struts2结合MapABC实现。<br />　　<span style="color: red">有一点请注意：使用Mapabc的话，页面编码必须是utf-8。</span><br />　　下面是具体的实现页面enInfor.jsp:<br /><pre name="code" class="java">
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&lt;%@ page language="java" pageEncoding="utf-8"%>
&lt;%@ taglib prefix="s" uri="/struts-tags"%>
&lt;%
String path = request.getContextPath();
%>

&lt;html>
&lt;head>
&lt;title>企业用户基本信息&lt;/title>
&lt;script type="text/javascript" src="http://api.mapabc.com/fmp/v1.0/js/fmp.js?key=a12d3fe7926bb4d1e88a902e53a13c4e0cd06cdf83c3e5925aed194ee24cca1ee1168fc5032b616a">&lt;/script>
&lt;script type="text/javascript" src="http://api.mapabc.com/fmp/v1.0/js/mapcomponent.js?key=a12d3fe7926bb4d1e88a902e53a13c4e0cd06cdf83c3e5925aed194ee24cca1ee1168fc5032b616a">&lt;/script>
&lt;link href="&lt;%=path %>/common/style.css" rel="stylesheet" type="text/css" />
&lt;/head>
&lt;body>
&lt;div id="inforContent">
  &lt;div id="inforMsg">
    &lt;s:form action="/user/enRegister.action">
      &lt;table align="center">
        &lt;tr>
          &lt;th colspan="2" align="center">企业用户信息填写&lt;/th>
        &lt;/tr>
        &lt;tr>
          &lt;td>企业名称：&lt;/td>
          &lt;td>&lt;input type="text" name="enterprise">&lt;/td>
        &lt;/tr>
        &lt;tr>
          &lt;td>企业电话：&lt;/td>
          &lt;td>&lt;input type="text" name="tel">&lt;/td>
        &lt;/tr>
        &lt;tr>
          &lt;td>企业地址：&lt;/td>
          &lt;td>&lt;input type="text" name="address">&lt;/td>
        &lt;/tr>
        &lt;tr>
          &lt;td>企业描述：&lt;/td>
          &lt;td>&lt;textarea rows="5" cols="15" name="description">&lt;/textarea>&lt;/td>
        &lt;/tr>
        &lt;tr>
          &lt;td>经营范围：&lt;/td>
          &lt;td>&lt;input name="dealInArea" type="checkbox" value="餐饮">餐饮
            &lt;input name="dealInArea" type="checkbox" value="娱乐">娱乐
          &lt;input name="dealInArea" type="checkbox" value="休闲">休闲          &lt;/td>
        &lt;/tr>
        &lt;tr>
        	&lt;td>纬度坐标：&lt;/td>
        	&lt;td>
        		&lt;input type="text" id="enLat" name="enLat" disabled="disabled">
        	&lt;/td>
        &lt;/tr>
        &lt;tr>
        	&lt;td>经度坐标：&lt;/td>
        	&lt;td>
        		&lt;input type="text" id="enLng" name="enLng" disabled="disabled">
        	&lt;/td>
        &lt;/tr>
        &lt;tr>
        	&lt;td colspan="2" align="center">
            	&lt;input type="submit" value="提交">
                &lt;input type="reset" value="重写">
            &lt;/td>
        &lt;/tr>
      &lt;/table>
    &lt;/s:form>
  &lt;/div>
  &lt;div id="mapControl">
  	&lt;div id="mapMsg"> 地图显示区域 &lt;/div>
  	&lt;div id="control">
  		&lt;input type="button" value="标注所在地" onclick="beginDrawPointOnMap();">
  	&lt;/div>
  &lt;/div>
  &lt;!--注意加载位置，一定要在DIV声明之后-->
  &lt;script type="text/javascript" src="&lt;%=path%>/common/map.js">&lt;/script>
&lt;/div>
&lt;/body>
&lt;/html>
</pre><br />style.css是样式文件，很简单的：<br /><pre name="code" class="java">
@charset "utf-8";
/* CSS Document */

#inforContent{
	background:#999999;
    width:90%;
}
#inforMsg{
   width:40%;
   float:left;
}
#mapControl{
	width:60%;
	height:400px;
	float:left;
}
#mapMsg{
   width:100%;
   height:350px;
   float:left;
}
#control{
	width:100%;
	height:50px;
	float:left;
}
</pre><br />具体的地图操作位于map.js文件中：<br /><pre name="code" class="java">
//创建一个MmapOptions对象
var mapOptions = new MMapOptions();

//设置地图组件的Id
mapOptions.mapId = "fmptest";

//设置地图的初始Zoom值
mapOptions.zoomLevel = 15;

//创建地图对象
var mapObj = new MMap("mapMsg", mapOptions);

//使用组件API
var mapComponent = new MapComponent(mapObj);

//设置城市中心点
mapComponent.setMapCityCenter("0371");

//企业用户标注自己位置事件
mapObj.addEventListener(MMap.EVENT_POINT_DRAWN,getCenterLatLng);

//得到标点的经纬度坐标
function getCenterLatLng(event){
	var center = mapObj.getCenterByLatLng();
         //对enLat文本进行赋值
	document.getElementById("enLat").value=center.lat;
　　　　　//对enLng文本进行赋值
	document.getElementById("enLng").value=center.lng;
         //画点结束后，结束画点操作
	mapObj.quitMouseDraw();
}

//对进入编辑模式下的tip进行填充内容
function fillPointContent() {
	var defaultPointStyle = new MStyle();
	defaultPointStyle.canBeTop = false;
	return defaultPointStyle;
}
//开始在地图上画点
function beginDrawPointOnMap()
{
	var pointStyle = fillPointContent();
	pointStyle.textContent = "鼠标画点";
	mapObj.beginDrawPointOnMap(pointStyle);
}

</pre><br />以上就是全部的代码，后面会把这些坐标存储至数据库中，下次用户看的时候就可以直接显示信息啦。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/233770#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 28 Aug 2008 10:56:59 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/233770</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/233770</guid>
      </item>
      <item>
        <title>电子地图－－MapABC研究（二）地图编辑</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/232837" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/232837</a>&nbsp;
          发表时间: 2008年08月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　这是电子地图研究的第二部分。<br />　　普通用户使用地图无非就是查询出行路线、公交线路查询、日常生活查询，但对于商家而言就要多一种功能，那就是对自己位置的标注，以及内容的描述。<br />　　本次要研究的就是对商家有用的地图的编辑功能。<br />　　下面是个具体的例子：<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><br />&lt;html><br />&lt;head><br />&lt;script type="text/javascript" src="http://api.mapabc.com/fmp/v1.0/js/fmp.js?key=f6c97a7f64063cfee7c2dc2157847204d4dbf09385481afc98c532e3a8066ae5f1a785336235b092">&lt;/script><br />&lt;script type="text/javascript" src="http://api.mapabc.com/fmp/v1.0/js/mapcomponent.js?key=f6c97a7f64063cfee7c2dc2157847204d4dbf09385481afc98c532e3a8066ae5f1a785336235b092">&lt;/script><br />&lt;/head><br />&lt;body><br />&lt;div id="mapObj" style="width: 700px; height: 500px">&lt;/div><br />&lt;script type="text/javascript"><br /><br />//创建一个MmapOptions对象<br />var mapOptions = new MMapOptions();<br /><br />//设置地图组件的Id<br />mapOptions.mapId = "fmptest";<br /><br />//设置地图的初始Zoom值<br />mapOptions.zoomLevel = 15;<br /><br />//设置地图的中心点<br />//mapOptions.center = new MLatLng("LQGXRMMVKHDLL", "JIOMSTNTPOLHLH");<br /><br />//创建地图对象<br />var mapObj = new MMap("mapObj", mapOptions);<br /><br />//使用组件API<br />var mapComponent = new MapComponent(mapObj);<br /><br />//设置城市中心点<br />mapComponent.setMapCityCenter("0371");<br /><br />//注册导出地图数据事件 后执行 onexportMapData 方法<br />mapObj.addEventListener(MMap.EVENT_EXPORT_MAP_DATA, onexportMapData);<br /><br /><br />function editMode(){<br />//设置地图为编辑模式<br />mapObj.setMapMode(MMapMode.EDIT);<br />}<br /><br />//编辑模式下 添加点<br />function createPoint(){<br />//MStyle是一个图样式类<br />var defaultPointStyle = new MStyle();<br />defaultPointStyle.canBeTop = true;<br />mapObj.addGeometry(MGeometry.TYPE_POINT, defaultPointStyle);<br />}<br /><br />//导出地图数据事件处理函数<br />function onexportMapData(event){<br />alert(event.args);<br />/**<br />event.type=”onExportMapData”<br />event.args=mapId,jsonString<br />args 的值是一个以“,”分隔的字符串，其中：<br />mapId：地图的Id<br />jsonString：整个地图的几何对象的JSON 字符串。<br />**/<br />}<br />　<br />//导出点的数据方法<br />function exportMapData(){<br />	mapObj.exportMapData();<br />}<br /><br />//导出地图数据事件处理函数<br />function onexportMapData(event){<br />	alert(event.args);<br />/**<br />event.type=”onExportMapData”<br />event.args=mapId,jsonString<br />args 的值是一个以“,”分隔的字符串，其中：<br />mapId：地图的Id<br />jsonString：整个地图的几何对象的JSON 字符串。<br />**/<br />}<br /><br />&lt;/script><br />操作方法: 先在 地图上左键标点 并填入标题 内容点击确定. 然后点击导出数据&lt;br />&lt;br /><br /><br /><br />&lt;input type="button" onClick="javascript:editMode();" value="进入编辑模式" /> <br />&lt;input type="button" onClick="javascript:createPoint();" value="添加点" /> <br />&lt;input type="button" onClick="javascript:exportMapData();" value="导出数据" /> <br /><br />&lt;/body><br />&lt;/html><br />如果结合数据库存储的话，就可以把商家描述的信息保存对数据库中，以备下次使用。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/232837#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 26 Aug 2008 14:09:50 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/232837</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/232837</guid>
      </item>
      <item>
        <title>电子地图－－MapABC研究（一）</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/232642" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/232642</a>&nbsp;
          发表时间: 2008年08月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　回头想想做J2EE也有一年多啦，这一年中一经历了很多很多，不过还是觉得很幸福的，做自己喜欢的事情没有什么不开心的，不过总觉得做J2EE的命中注定要不断的去研究新的技术，这一年多的时间里学会了Dwr、Spring、Struts2、Hibernate、EJB、FreeMarker、JFreeChat，现在又根据项目的需要去研究MapABC，不过还是觉得很开心。<br />　　别的不说，咱还是书归正传说说咱的MapABC吧！<img src="/images/smiles/icon_biggrin.gif"/><br />　　MapABC是由北京图盟科技有限公司提供的，为实现互联网和移动终端互动地图服务提供了最为有效的解决方案，Mapabc基于此系统构建的基础地图服务运营平台，可不间断地、快速地应对大并发访问请求，完全满足电信运营商和搜索引擎的苛刻性能指标。<br />　　Mapabc已经成为中国市场占有率最高、平台响应速率最快、地图数据最丰富的基础地图服务提供商。<br />　　要使用MapABC　API就必须要有MapABC的帐号，并申请MapABC的Key，申请页面要求输入您的网址，这个网址即可以是真实的网址，也可以是自己本地的，比如说可以是http://localhost这样的（刚开始的时候也以为一定要是域名才可以使用的，这样在开发的时候就很方便）。<br />　　申请完成后，得到Key就可以在本地使用啦。<br />　　下面是一个简单的例子：<br /><pre name="code" class="java">
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&lt;html>
&lt;head>
&lt;!--必须导入的,后面的Key值即是你申请得到的Key-->
&lt;script type="text/javascript" src="http://api.mapabc.com/fmp/v1.0/js/fmp.js?key=f6c97a7f64063cfee7c2dc2157847204d4dbf09385481afc98c532e3a8066ae5f1a785336235b092">&lt;/script>
&lt;!--使用组件API要导入-->
&lt;script type="text/javascript" src="http://api.mapabc.com/fmp/v1.0/js/mapcomponent.js?key=f6c97a7f64063cfee7c2dc2157847204d4dbf09385481afc98c532e3a8066ae5f1a785336235b092">&lt;/script>
&lt;/head>
&lt;body>
&lt;div id="mapObj" style="width: 500px; height: 400px">&lt;/div>
&lt;script type="text/javascript">
//创建一个MmapOptions对象
var mapOptions = new MMapOptions();

//设置地图组件的Id
mapOptions.mapId = "fmptest";

//设置地图的初始Zoom值
mapOptions.zoomLevel = 15;
//设置地图的中心点，参数第一个代表纬度、第二个代表经度，已经太经过加密
//mapOptions.center = new MLatLng("LQGXRMMVKHDLL", "JIOMSTNTPOLHLH");

//创建地图对象
var mapObj = new MMap("mapObj", mapOptions);

//设置是否使用鹰眼
//mapObj.showNavigator(false);

//设置是否显示全屏按钮
mapObj.showFullScreenButton(true);

//创建组件API对象
var mapComponent = new MapComponent(mapObj);

//设置城市中心为郑州，建议使用此形式，可以不用记大量的坐标
mapComponent.setMapCityCenter("0371");
&lt;/script>

&lt;/body>
&lt;/html>
</pre><br />感兴趣的朋友也可以去MapABC的官网上去看他的进阶教程。<br />哦，对啦，还有一个关于城市坐标的文件，我已经放在附件里啦，大家可以下下来看看，是城市名、城市的经纬度和城市代码，朋友们可以自己进行修改城市的区域代码，也可以通过城市坐标得到城市中心。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/232642#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 26 Aug 2008 08:48:56 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/232642</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/232642</guid>
      </item>
      <item>
        <title>互联网高性能系统构建思路</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/232264" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/232264</a>&nbsp;
          发表时间: 2008年08月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　　　　　　　　　　　　　<div style="text-align: center"><strong>互联网高性能系统构建思路</strong> </div> <br /><br />　　　　　　　　　　　　<div style="text-align: center"><span style="color: red">2008-3-11 海纳咨询 王怀志</span></div><br /><br />    高性能系统与传统的系统集成系统，从感官功能上来说好像差不多，一般都有一个web，都有数据库存储，查询功能等等。但是高性能系统与其他系统集成类系统最大的区别就是它的设计思路一定要效率优先，把性能排在了首位。<br /><br /><br />    有人说，系统集成类项目也注重性能，压力测试呀！没错，但是互联网高性能系统可以容忍数据的非实时性。设计拥有很弱的事务，是高性能系统设计的要点之一。<br /><br /><br />1。事务的淡化<br /><br />    比如，一个网民更改了自己的信息，但是别人在一段时间内发现他的信息还是过时的，这就是互联网系统可以容忍的。有时候，互联网系统后台的分布式系统会根据压力情况主动丢包，造成一些数据的丢失，这个网民更改了自己的信息后，这个报文在后台系统里丢失了。<br /><br />2。数据存储的个性化<br /><br />    高性能数据最好不要放在数据库中，这一点上一定要有个性化的设计。一个博客系统，每天都有大量的人在不断更新着，比如有这样的需求，每个人都想知道目前的博客排行榜。这样的数据一定不能放在数据库，应该放在内存中的一个数据结构中，这个结构里的数据不是经常改动的，很显然，网民不会苛求你的系统必须很准确的算出排行榜，一天更新一次其实足够。有人说，放在数据库中怎么了，为什么不行，我用存储过程不就行了吗，我也不会每天计算一次，然后放在一个专有表中吗，供网民直接提取吗？但是我更倾向直接把这些数据放在服务器的最上层，不要为这些数据再向下层的数据库要数据，而浪费你的cpu了。<br /><br /><br />3。系统的简单化<br /><br />    系统当中的每个系统都要尽量占资源，很多人都说尽量要把数据放在数据库中，别忘了，凡是能称得上数据库的对机器来说都是大象，都会占用无谓的资源。蚂蚁能解决的问题，为什么要请一个大象，最后才发现“请神容易，送神难”。如果不是很复杂能自己开发系统，最好自己开发，因为对自己的系统的性能瓶颈最容易分析。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/232264#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Aug 2008 10:30:02 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/232264</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/232264</guid>
      </item>
      <item>
        <title>程序员修炼之七杀秘技</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/232233" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/232233</a>&nbsp;
          发表时间: 2008年08月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="color: red">程序员修炼之七杀秘技</span><br />作者：周恒　来源：IT博客 　 酷勤网收集　2007-08-21<br /><br />摘要<br />   学好一门计算机编程语言真的不值得过分骄傲，可悲的是，我们往往一门编程语言也没有学习好就在简历上写着精通XX编程。 想想一个旧社会的老太太，即使一天学都没有上过，说起话，讲起故事来也能出口成章。 一小孩，从出生开始短短三年就能把复杂如汉语的语言说得很流利 <br />   学好一门计算机编程语言真的不值得过分骄傲，可悲的是，我们往往一门编程语言也没有学习好就在简历上写着精通XX编程。 <br />想想一个旧社会的老太太，即使一天学都没有上过，说起话，讲起故事来也能出口成章。 <br />想想一个小孩，从出生开始短短三年就能把复杂如汉语的语言说得很流利了。 <br /><br />   为什么有的程序员，工作十年了还不开窍，仍然写不出高质量的程序，以至于哀叹程序员是吃青春饭，过了三十岁就不知道何去何从。 <br /><br />   为什么有的程序员，勤勤恳恳，却事倍功半，写出来的程序仍然七疮八孔，bug众多？ <br /><br />   计算机至今无法像人类这样好的理解自然语言，编程语言其实比自然语言简单的多，但是为什么我们学起编程语言来还不如三岁小孩学自然语言？ <br />小孩学语言和成长的过程对我们学习编程语言是不是有所启迪呢？ <br /><br />   笔者曾多次与公司新员工座谈，新员工多爱问程序员有何速成之法，谈起应该菜鸟如何修炼七步杀一人之绝技，具体的方法总结了一下，是为七多，现分享如下，各位看家指正： <br /><br /><strong>多想：</strong>思考是写好程序的源泉，从今天起开始思考吧； <br /><strong>多写：</strong>努力与实践是成功的不二法门； <br /><strong>多读：</strong>读高手写的程序，召唤内心深处的渴望，压抑不住写程序的冲动，是一件心旷神怡的事情； <br /><strong>多讲：</strong>头几次讲课的人绝对比听课的人能收获更多，我们公司运用此法取得了很好的培训效果； <br /><strong>多审：</strong>怀疑自己和他人的程序，并不是怀疑自己的智商，要想成为一个优秀的程序员，拿自己开审吧； <br /><strong>多画：</strong>许多学数学的人往往后发先至，超越计算机可伴选手成为程序高手，因为他们画竹之前先成竹于胸； <br /><strong>多构：</strong>“妈呀，我以前写的那一段程序真烂，惨不忍睹”，大有往事不堪回首之意。为什么不重构呢？ <br />如能真正贯彻此七多，并做到如切如磋，如琢如磨，恭喜你，因为你也一定能成为个中高手了
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/232233#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Aug 2008 10:02:52 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/232233</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/232233</guid>
      </item>
      <item>
        <title>Dwr2+Struts2+Spring2.5+Hibernate3完美整合－－用户登录注册系统</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/231797" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/231797</a>&nbsp;
          发表时间: 2008年08月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　用户注册和登录是每个系统的必须存在的一部分，基于Dwr+Struts2+Spring+Hibernate写了一个用户登录注册系统。<br />　　其中用Dwr去进行用户注册的用户是否存在的验证。<br />　　全部业务控制交由Spring去进行处理。事务处理也交由Spring去管理。<br />　　压缩文件中不包含Jar文件(由于全部的Jar将近12M，不能全部上传)，所用到的Jar目录为,工程中再也不会出现由于MyEclipse自动整合而出现的大量Jar文件<img src="/images/smiles/icon_biggrin.gif"/>：<br /><pre name="code" class="java">

//如果不用，启动时不会出错，但使用Dwr时，会抛出异常：java.lang.NoClassDefFoundError: antlr/ANTLRException
antlr-2.7.2.jar　

//如果不用此包，在启动时会抛出： nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
asm.jar

//如果不用此包，在启动时抛出：nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
aspectjweaver.jar

//如果不用此包，在启动时抛出：nested exception is java.lang.NoClassDefFoundError: net/sf/cglib/proxy/CallbackFilter
cglib-2.1.3.jar

//如果不用此包，在启动时抛出：nested exception is java.lang.NoClassDefFoundError: org/apache/commons/collections/SequencedHashMap
commons-collections-3.1.jar

//这个似乎可以不用的
commons-fileupload-1.2.1.jar

//这个就不用说啦，几乎所有框架都要使用的
commons-logging-1.0.4.jar 

//如果不用此包会抛出：java.lang.NoClassDefFoundError: org/dom4j/DocumentException
dom4j-1.6.1.jar

//dwr必须
dwr.jar 


//不用此包，在启动时招聘：java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
jta.jar

//Mysql　JDBC驱动
mysql-connector.jar

//Hibernate必须使用，注意此包是包含全部的。
hibernate3.jar

//Spring整体包
spring.jar            

//struts2必须               
freemarker-2.3.8.jar   
//struts2必须
ognl-2.6.11.jar       
//struts2核心包
struts2-core-2.0.11.2.jar
//struts2整合Spring插件  
struts2-spring-plugin-2.0.11.2.jar 
//struts2必须
xwork-2.0.5.jar 
</pre><br /><br />　　数据库设计(使用MySql数据库)：<br /><pre name="code" class="java">
create table user
(
  id varchar(32) not null,
  userName varchar(20),
  password varchar(20),
  primary key(id)
);
create table user_infor
(
  id varchar(32) not null,
  user_id varchar(32),
  name varchar(20),
  email varchar(30),  
  sex char,
  age int,
  address varchar(300),
  primary key(id)
);
ALTER TABLE user_infor
    ADD FOREIGN KEY(user_id) 
    REFERENCES user(id)
    ON DELETE CASCADE;
</pre><br />由于没有包含全部的Jar文件，所以朋友需要把上面所述的Jar加载。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/231797#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 23 Aug 2008 09:51:03 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/231797</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/231797</guid>
      </item>
      <item>
        <title>Struts2得到Request和Session</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/231205" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/231205</a>&nbsp;
          发表时间: 2008年08月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在Struts1.*中，要想访问request、response以及session等Servlet对象是很方便的，因为它们一直是作为形参在各个方法之间进行传递的，而在Struts2中我们就很难看到它们的芳踪了，因为我们获得表单中的值都是通过预先设置好了的get方法来得到的，那么如果有些参数我们必须通过request.getParametre或者session.getAttribute来得到，那么应该怎么做呢？按照Max的教程上的说法，<strong>可以分为两种：IoC方式和非IoC方式</strong>，如何理解这两种方式的区别呢？IoC是Spring里面的特征之一，字面意思是反转控制，说白了就是依赖注入，比方说类A依赖类B，那么就主动的给A注入一个类B的对象，下面看一下这两种方法的具体实现。<br /><strong><span style="color: red">1．非Ioc方式</span></strong><br />这种方式主要是利用了com.opensymphony.xwork2.ActionContext类以及org.apache.struts2.ServletActionContext类，具体的方法如下所示。<br /><strong>获得request对象：</strong><br /><pre name="code" class="java">HttpServletRequest request = ServletActionContext.getRequest ();
ActionContext ct= ActionContext.getContext()
   HttpServletRequest request=
(HttpServletRequest)ct.get(ServletActionContext.HTTP_REQUEST);</pre><strong>获得session对象：</strong><br />在Struts2中底层的session都被封装成了Map类型，我们称之为SessionMap，而平常我们所说的session则是指HttpSession对象，具体的获得方法如下所示。<br /><pre name="code" class="java">
Map session=ActionContext.getSession();
Map session=(Map)ActionContext.getContext().getActionContext.SESSION);</pre><br />得到这个SessionMap之后我们就可以对session进行读写了，如果我们想得到原始的HttpSession可以首先得到HttpServletRequest对象，然后通过request.getSession()来取得原始的HttpSession对象。一般情况下SessionMap已经可以完成所有的工作，我们不必再去碰底层的session了。<br /><strong><span style="color: red">2．IoC方式</span></strong><br />这种方式相对来说变化就比较少了，具体流程如下所示。<br /><strong>获得request对象：</strong><br /><span style="color: red">第一步：</span>让action实现ServletRequestAware接口<br /><span style="color: red">第二步：</span>在action中声明一个HttpServletRequest类型的实例变量<br /><span style="color: red">第三步：</span>在action中实现ServletRequestAware接口的setServletRequest方法，实现方式很简单，如下所示。<br />         private HttpServletRequest request;<br />        public void setServletRequest(HttpServletRequest request) {<br />            this.request = request;<br />    }<br /><strong>获得Session对象</strong>(注意，此时的session是SessionMap类型)：<br /><span style="color: red">第一步：</span>让action实现SessionAware接口<br /><span style="color: red">第二步：</span>在action中声明一个HttpServletRequest类型的实例变量<br /><span style="color: red">第三步：</span>在action中实现SessionAware接口的setSession方法，实现方式很简单，如下所示。<br />         private Map session;<br />publicvoid setSession(Map session) {<br />            this. session = session;<br />    }<br /> Trackback: <a href="http://tb.blog.csdn.net/TrackBack.aspx?PostId=1721226" target="_blank">http://tb.blog.csdn.net/TrackBack.aspx?PostId=1721226</a><br />以下是另一篇关于得到Request和Session的文章：<br /><pre name="code" class="java">
在Struts2里，如果需要在Action中使用session，可以通过下面两种方式得到
1.通过ActionContext class中的方法getSession得到
2.Action实现org.apache.struts2.interceptor.SessionAware接口的方式来对session进行操作
 
下面先看一个采用第一种方式，在action中得到session的例子
package s2.ex.action; 


import java.util.Map; 


import com.opensymphony.xwork2.ActionContext; 

import com.opensymphony.xwork2.ActionSupport; 


public class SessionTestAction extends ActionSupport { 


    public String execute() { 

     ActionContext actionContext = ActionContext.getContext(); 

       Map session = actionContext.getSession(); 

       session.put("USER_NAME", "Test User"); 

       return SUCCESS; 

    } 

}
在这个例子中，通过ActionContext得到session，并往session里放置一个key为USER_NAME，值为Test User的内容。
 
下面是一个实现org.apache.struts2.interceptor.SessionAware接口来对session操作的例子
package s2.ex.action; 


import java.util.Map; 


import org.apache.struts2.interceptor.SessionAware; 


import com.opensymphony.xwork2.ActionSupport; 


public class SessionTest1Action extends ActionSupport implements SessionAware { 

    private Map session; 

    public void setSession(Map session) { 

       this.session = session; 


    } 

    public String execute() { 

       this.session.put("USER_NAME", "Test User 1"); 

       return SUCCESS; 

    } 

}
 
在这个例子中实现了接口SessionAware中的setSession方法。
 
上面两种方式都可以得到session，能实现的功能都是一样的。
这里推荐通过第二种方式来使用session，原因是便于做单体测试，用第二种方式，只需要构造一个Map就可以对action class进行单体测试了。

    在一个项目中可能会有很多action都需要用到session，如果每个action都来实现org.apache.struts2.interceptor.SessionAware这个接口，可能会显得比较麻烦，所以建议作一个抽象的BaseAction类来实现org.apache.struts2.interceptor.SessionAware接口，以后所有的action只要继承这个BaseAction就可以了。
 
下面是一个如何在JSP中使用session的例子。
&lt;%@ page contentType="text/html; charset=UTF-8" %> 

&lt;%@page pageEncoding="utf-8" %> 

&lt;%@taglib prefix="s" uri="/struts-tags" %> 

&lt;html> 

&lt;head> 

    &lt;title>Session Test&lt;/title> 

&lt;/head> 


&lt;body> 

&lt;h1>&lt;s:property value="#session.USER_NAME"/>&lt;/h1> 

&lt;h1>&lt;/h1> 

&lt;/body> 

&lt;/html>

   一般在项目中往往会往session里放置一个Object，必如说user，user里有个boolean admin和String userName，如果user里存在isAdmin的方法，在jsp中可以通过&lt;s:if test="#session.user.admin">来判断用户有没有管理权限，通过&lt;s:property value="#session.user.userName">或者来取得用户名。
 
 </pre>
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/231205#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 21 Aug 2008 15:39:26 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/231205</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/231205</guid>
      </item>
      <item>
        <title>hibernate集合映射inverse和cascade详解 （转载）</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/230319" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/230319</a>&nbsp;
          发表时间: 2008年08月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          ﻿4. hibernate如何根据pojo来更新数据库<br /><br />4.0 在<strong>commit/flush</strong>之前，hibernate不会对pojo对象作神秘的处理。<br />4.0.1 在select查询出pojo时，hibernate根据“字段--属性”的对应关系，用字段的值填充pojo的属性；<br />然后根据“关系标记”生成sql语句从relationTable中查询出满足条件的relation Pojo，并把这些relation Pojo放到“关系属性”中。<em>这个过程是机械的。</em><br /><br />4.0.2 在pojo对象被查出来后，到commit(或flush)之前，它将是一个普通的java对象，hibernate不会做额外的手脚。<br />比如，不会限制你设置一个属性的值为null或其它任何值<br />在集合类Set的add(object)操作时， 不会改变object的值，不会检查参数object是否是一个pojo对象<br />设置mainPojo的一个“桥属性”的值，不会自动设置relationPojo的对应的“桥属性”的值。<br />执行session.delete(pojo)时，pojo本身没有变化，他的属性值也没有变化。<br />执行session.save(pojo)时，如果pojo的id不是hibernate或数据库生成,则它的值没有变化。<br />如果pojo的id是hibernate或数据库生成，则hibernate会把id给pojo设上去。<br /><br />extend: 对lazy=true的set，hibernate在进行set的操作(调用java.util.Set中声明的方法)时<br />会先inialize这个set，仅此而已。而inialize仅仅是从数据库中捞出set的数据。 <br />如果一个set已经被inialize了，那么对它进行的操作就是java.util.Set接口中定义的语义。<br /><br />另外，如果id由hibernate来生成，那么在save(pojo)时，hibernate会改变该pojo，会设置它的id，这可能改变该pojo的hashCode。<br /><br />mapping文件中标记的某些属性及pojo对象的操作会对数据库操作产生影响，这些影响都是在commit时才会起作用。<br />而在commit前pojo的状态不受它们的影响。<br /><br />不过，待commit之时，将由hibernate完全掌控，它好像知道pojo对象从创建到commit这中间的所有变化。<br /><br /><br /><strong>4.01. 关联更新</strong><br />"关系标记"对应的属性是一个pojo或一个pojo的集合，修改“关系属性”的值能会导致更新mainTable表，也可能会更新relationTable表。<br /><br />这种更新暂叫“关联更新”。<br /><br /><br /><strong>4.1.inverse属性的作用（假定没有设置cascade属性） </strong><br />4.1.1 “只有集合标记（set/map/list/array/bag）才有inverse属性”。<br />————不妨以标记set为例，具体为“一个地区（Address表）的学校（School表）” -- address.schoolSet。<br /><br />4.1.2 “set的inverse属性决定是否把对set的改动反映到数据库中去。<br />inverse=false————反映；inverse=true————不反映”<br />inverse属性默认为false<br /><br />对&lt;one-to-many>和&lt;many-to-many>子标记，这两条都适用。<br />不管是对set做什么操作，4.1.2都适用。<br /><br />4.1.3当inverse=false时，hibernate如何将对set的改动反映到数据库中：<br /><br />对set的操作主要有：（1）新增元素 address.getSchoolSet().add(oneSchool);<br />（2）删除元素 address.getSchoolSet().remove(oneSchool);<br />（3）删除set address.setSchoolSet(null);<br />（4）设新set address.setSchoolSet( newSchoolSet);<br />（5）转移set otherSchoolSet = otherAddress.getSchoolSet();<br />otherAddress.setSchoolSet(null);<br />address.setSchoolSet(otherSchoolSet);<br />（6）改变set中元素的属性的值 如果是改变key属性，这会导致异常<br />如果改变的是普通的属性，则hibernate认为set没有变化（在后面可以看出缘由）。<br />所以这种情形不予考虑。<br /><br />改变set后，hibernate对数据库的操作根据是&lt;one-to-many>关系还是&lt;many-to-many>关系而有不同。<br /><br />对one-to-many，对school set的改动，会改变表SCHOOL中的数据:<br />#SCHOOL_ID是school表的主键，SCHOOL_ADDRESS是school表中的地址栏位<br />#表School的外键为SCHOOL_ADDRESS，它对应表Address的主键ADDRESS_ID<br />（11）insert oneSchool———— sqlInsertRowString: <br />update SCHOOL set SCHOOL_ADDRESS=? where SCHOOL_ID=? <br />(仅仅update foreign-key的值。)<br />（22）delete oneSchool———— sqlDeleteRowString: <br />update SCHOOL set SCHOOL_ADDRESS=null where SCHOOL_ID=?<br />（很奇怪，把foreign-key设置为null不知道有什么实际意义？）<br />（33）delete 属于某一address的所有school ————sqlDeleteString：<br />update SCHOOL set SCHOOL_ADDRESS=null where SCHOOL_ADDRESS=?<br />（44）update ————sqlUpdateRowString：""， no need<br /><br />对many-to-many，对school set的改动，会改变关系表ADDRESS_SCHOOL中的数据:<br />#“地区————学校”的关系为多对多的关系有点牵强，只是为了方便与上面的one-to-many作比较<br />#假设有一个关系表ADDRESS_SCHOOL，有两个字段ADDRESS_ID, SCHOOL_ID，<br />#这两个字段分别对应ADDRESS和SCHOOL两表的key<br />（11）insert的SQL语句为： insert into ADDRESS_SCHOOL(ADDRESS_ID, SCHOOL_ID) <br />values(?,?)<br />（22）delete的SQL语句为： delete from ADDRESS_SCHOOL <br />where ADDRESS_ID=? AND SCHOOL_ID=?<br />（33）delete all的SQL语句为： delete from ADDRESS_SCHOOL<br />where ADDRESS_ID=?<br />（44）update的sql语句为 ————sqlUpdateRowString：<br />update ADDRESS_SCHOOL set ADDRESS_ID=?<br />where ADDRESS_ID=? AND SCHOOL_ID=?<br /><br />对set的操作(1),hibernate会执行(11)sqlInsertRowString<br />对set的操作(2),hibernate会执行(22)sqlDeleteRowString<br />对set的操作(3),hibernate会执行(33)sqlDeleteString<br />对set的操作(4),老的schoolSet因为没有所属的address,所以被全部delete掉，即先执行(33)sqlDeleteString<br />然后新增新的schoolSet,即再执行sqlInsertRowString<br />对set的操作(5)，实际上就是将set从一个pojo转移到另一pojo：<br />首先，执行sqlDeleteString，删除掉otherAddress所属的school<br />然后，执行sqlDeleteString，删除掉address原先的school<br />最后，执行sqlInsertRowString，将otherSchoolSet新增给address<br /><br />总结：（1）对one-to-many而言，改变set，会让hibernate执行一系列的update语句， 不会delete/insert数据<br />（2）对many-to-many而言，改变set,只修改关系表的数据，不会影响many-to-many的另一方。<br />（3）虽然one-to-many和many-to-many的数据库操作不一样，但目的都是一个：维护数据的一致性。执行的sql都<br />只涉及到“桥字段”，不会考虑或改变其他的字段，所以对set的操作(6)是没有效果地。<br />extend:对list,可能还会维护index字段。<br /><br />4.1.4 “inverse与cascade没有什么关系，互无牵扯。”<br />commit后，这两个属性发挥作用的时机不同，hibernate会根据对pojo对象的改动，及cascade属性的设置，<br />生成一系列的Action，比如UpdateAction,DeleteAction,InsertAction等，每个Action都有execute方法以执行对应的sql语句。<br />待所有这些Action都生成好了后，hibernate再一起执行它们，在执行sql前，inverse属性起作用，<br />当inverse=true时，不执行sql；当inverse=false时，执行sql。<br /><br />4.1.5 inverse的默认值为false，所以inverse属性默认会进行“关联更新”。<br /><br />4.1.6 建议：只对set + many-to-many设置inverse=false，其他的标记不考虑inverse属性。<br />  糟糕的是，不设置inverse属性时，inverse默认为false。<br /><br />4.2. 级联（cascade）属性的作用： <br />4.2.1 只有“关系标记”才有cascade属性：many-to-one，one-to-one ，any, <br />set(map, bag, idbag, list, array) + one-to-many(many-to-many)<br /><br />4.2.2 级联指的是当主控方执行操作时，关联对象（被动方）是否同步执行同一操作。<br />pojo和它的关系属性的关系就是“主控方 -- 被动方”的关系，如果关系属性是一个set，那么被动方就是set中的一个一个元素，。<br />比如：学校（School）有三个属性：地区(Address),校长（TheMaster）和学生(Set， 元素为Student)<br />执行session.delete(school)时，级联决定是否执行session.delete(Address),session.delete(theMaster)，<br />是否对每个aStudent执行session.delete(aStudent)。<br /><br />extend:这点和inverse属性是有区别的。见4.3.<br /><br />4.2.3 一个操作因级联cascade可能触发多个关联操作。前一个操作叫“主控操作”，后一个操作叫“关联操作”。<br />cascade属性的可选值：<br />all : 所有情况下均进行关联操作。<br />none：所有情况下均不进行关联操作。这是默认值。<br />save-update:在执行save/update/saveOrUpdate时进行关联操作。<br />delete：在执行delete时进行关联操作。 <br /><br />具体执行什么“关联操作”是根据“主控操作”来的：<br />“主控操作”       “关联操作”<br />session.saveOrUpdate --> session.saveOrUpdate (执行saveOrUpdate实际上会执行save或者update)<br />session.save ----> session.saveOrUpdate<br />session.udpate --> session.saveOrUpdate<br />session.delete --> session.delete<br /><br />4.2.4 主控操作和关联操作的先后顺序是“先保存one，再保存many；先删除many，再删除one；先update主控方，再update被动方”<br />对于one-to-one，当其属性constrained="false"（默认值）时，它可看作one-to-many关系；<br />  当其属性constrained="true"时，它可看作many-to-one关系；<br />对many-to-many，它可看作one-to-many。<br /><br />比如：学校（School）有三个属性：地区(Address),校长（TheMaster，其constrained="false"）和学生(Set， 元素为Student) <br />当执行session.save(school)时，<br />实际的执行顺序为：session.save(Address);<br />session.save(school);<br />session.save(theMaster);<br />for( 对每一个student ){<br />session.save(aStudent);<br />}<br /><br />当执行session.delete(school)时，<br />实际的执行顺序为：session.delete(theMaster);<br />for( 对每一个student ){<br />session.delete(aStudent);<br />}<br />session.delete(school);<br />session.delete(Address);<br /><br />当执行session.update(school)时，<br />实际的执行顺序为：session.update(school);<br />session.saveOrUpdate(Address);<br />session.saveOrUpdate(theMaster);<br />for( 对每一个student ){<br />session.saveOrUpdate(aStudent);<br />}<br />注意：update操作因级联引发的关联操作为saveOrUpdate操作，而不是update操作。<br />saveOrUpdate与update的区别是：前者根据操作对象是保存了还是没有保存，而决定执行update还是save<br /><br />extends: 实际中，删除学校不会删除地区，即地区的cascade一般设为false<br />另外，many-to-many关系很少设置cascade=true，而是设置inverse=false。这个反映了cascade和inverse的区别。见4.3<br /><br />4.2.6 cascade的默认值为false，所以inverse属性默认会进行“关联更新”。<br /><br />4.2.7 总结：级联（cascade）就是操作一个对象时，对它的属性（其cascade=true）也进行这个操作。<br /><br /><br />4.3 inverse和cascade的比较<br />这两个属性本身互不影响，但起的作用有些类似，都能引发对关系表的更新。<br /><br />4.3.1 inverse只对set+one-to-many(或many-to-many)有效，对many-to-one, one-to-one无效。<br />cascade对关系标记都有效。<br /><br />4.3.2 inverse对集合对象整体起作用，cascade对集合对象中的一个一个元素起作用，如果集合为空，那么cascade不会引发关联操作。<br />比如将集合对象置为null， school.setStudentSet(null)<br />inverse导致hibernate执行:udpate STUDENT set SCHOOL_ID=null where SCHOOL_ID=?<br />cascade则不会执行对STUDENT表的关联更新， 因为集合中没有元素。<br /><br />再比新增一个school, session.save(school)<br />inverse导致hibernate执行：<br />for( 对(school的每一个student ){<br />udpate STUDENT set SCHOOL_ID=? where STUDENT_ID=? //将学生的school_id改为新的school的id<br />}<br />cascade导致hibernate执行：<br />for( 对school的每一个student ){<br />session.save(aStudent); //对学生执行save操作<br />}<br /><br />extends:如果改变集合中的部分元素（比如新增一个元素），<br />inverse: hibernate先判断哪些元素改变了，对改变的元素执行相应的sql<br />cascade: 它总是对集合中的每个元素执行关联操作。<br />（在关联操作中，hibernate会判断操作的对象是否改变）<br /><br />4.3.2 两个起作用的时机不同：<br />cascade：在对主控方操作时，级联发生。<br />inverse: 在flush时（commit会自动执行flush)，对session中的所有set，hibernate判断每个set是否有变化，<br />对有变化的set执行相应的sql，执行之前，会有个判断：if( inverse == true ) return;<br /><br />可以看出cascade在先，inverse在后。<br /><br />4.3.3 inverse 对set + one-to-many 和 set + many-to-many 起的作用不同。hibernate生成的sql不同。<br />对one-to-many，hibernate对many方的数据库表执行update语句。<br />对many-to-many, hibernate对关系表执行insert/update/delte语句，注意不是对many方的数据库表而是关系表。<br /><br />cascase 对set都是一致的，不管one-to-many还是many-to-many。都简单地把操作传递到set中的每个元素。所以它总是更新many<br />方的数据库表。<br /><br />4.3.4 建议：只对set + many-to-many设置inverse=false，其他的标记不考虑inverse属性，都设为inverse=true。<br />  <br />  对cascade，一般对many-to-one，many-to-many，constrained=true的one-to-one 不设置级联删除。<br /><br />引自：<a href="http://bbs.tech.ccidnet.com/simple/index.php?t144447.html" target="_blank">http://bbs.tech.ccidnet.com/simple/index.php?t144447.html</a>
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/230319#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 20 Aug 2008 09:29:31 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/230319</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/230319</guid>
      </item>
      <item>
        <title>Dwr－EditTable完整版</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/227132" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/227132</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　Dwr是Java领域一个著名的服务器端Ajax框架，借助Dwr的帮助，我们可以直接在客户端页面通过Javascript调用远程Java的方法。<br />　　看Dwr的示例中有一个EditTable的示例，觉得在实际使用中会非常的有用，就把此示例进行了扩展，实现与数据库的交互，在页面上可以直接添加用户、修改用户和删除用户操作。<br />　　数据库设计：<br />　　<pre name="code" class="java">
create table jackdemo1
(
  id int primary key auto_increment,
  name varchar(50),
  age int,
  address varchar(200)
);
    </pre><br />　　使用Dwr，首先要配置Web.xml文件：<br /><pre name="code" class="java">
&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	&lt;servlet>
		&lt;servlet-name>dwr-invoker&lt;/servlet-name>
		&lt;servlet-class>
			org.directwebremoting.servlet.DwrServlet
		&lt;/servlet-class>
	&lt;/servlet>
	&lt;servlet-mapping>
		&lt;servlet-name>dwr-invoker&lt;/servlet-name>
		&lt;url-pattern>/dwr/*&lt;/url-pattern>
	&lt;/servlet-mapping>
&lt;/web-app>
</pre><br />然后要在web.xml文件同一级目录下建立一个dwr.xml文件，具体的配置如下：<br /><pre name="code" class="java">
&lt;!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"
    "http://getahead.org/dwr/dwr20.dtd">
&lt;dwr>
	&lt;allow>
		&lt;create javascript="People" creator="new">
			&lt;param name="class" value="com.jack.dwr.simple.People">&lt;/param>
		&lt;/create>
		&lt;convert match="com.jack.dwr.simple.Person" converter="bean" javascript="Person">&lt;/convert>
	&lt;/allow>
&lt;/dwr>
</pre><br />其实Javascript="People"是要在客户端使用的对象名称，&lt;param>是对象的Java类名，因为People类中对应的方法中使用了Person类，所在在这里要使用&lt;convert>进行转换。<br />Person类是一个POJO类：<br /><pre name="code" class="java">
package com.jack.dwr.simple;


public class Person {
	private int id;
	private String name;
	private int age;
	private String address;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

}
</pre><br />上面的各个属性对应数据库中的字段信息。<br />People类是对数据进行操作类也是就是具体的业务类：<br /><pre name="code" class="java">
package com.jack.dwr.simple;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * A container for a set of people
 * 
 * @author jackzhangyunjie
 */
public class People {
	private Connection conn;

	/**
	 * 构造函数，同时初始化建立与数据库的连接
	 */
	public People() {
		try {
			conn = DBConnection.getConnectionMySqlDB("3306", "jackdemo",
					"root", "jack");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 删除一个用户
	 * 
	 * @param person
	 *            要删除的用户
	 * 
	 */
	public void deletePerson(Person person) throws Exception {
		String sql = "delete from jackdemo1 where id=?";
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setInt(1, person.getId());
		//更新数据库操作
		pstmt.executeUpdate();
		//关闭预编译和数据库连接
		pstmt.close();
		conn.close();
	}

	/**
	 * 更新用户信息
	 * @param person　要进行更新的用户对象
	 * @throws Exception
	 */
	public void updatePerson(Person person) throws Exception {
		String sql = "update jackdemo1 set name=?,age=?,address=? where id=?";
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, person.getName());
		pstmt.setInt(2, person.getAge());
		pstmt.setString(3, person.getAddress());
		pstmt.setInt(4, person.getId());
		//更新数据库操作
		pstmt.executeUpdate();
		//关闭预编译和数据库连接
		pstmt.close();
		conn.close();
	}

	/**
	 * 得到全部的人员信息
	 * 
	 * @return 返回一个包含人员的List
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public List getAllPerson() throws SQLException {
		List list = new ArrayList();
		String sql = "select * from jackdemo1";
		Statement st = conn.createStatement();
		//查询数据库，得到所有人员信息
		ResultSet rs = st.executeQuery(sql);
		while (rs.next()) {
			Person person = new Person();
			person.setId(rs.getInt("id"));
			person.setName(rs.getString("name"));
			person.setAge(rs.getInt("age"));
			person.setAddress(rs.getString("address"));
			list.add(person);
		}
		return list;
	}

	/**
	 * 添加人员
	 * 
	 * @param person
	 *            要添加的人员的信息
	 */
	public void addPerson(Person person) throws Exception {
		String sql = "insert into jackdemo1(name,age,address) values(?,?,?)";
		PreparedStatement pstmt = conn.prepareStatement(sql);
		//设置人员信息
		pstmt.setString(1, person.getName());
		pstmt.setInt(2, person.getAge());
		pstmt.setString(3, person.getAddress());
		//更新数据库操作
		pstmt.executeUpdate();
		//关闭预编译和数据库连接
		pstmt.close();
		conn.close();
	}
}
</pre><br />以上就是具体的业务操作信息，其中<br />DBConnection.getConnectionMySqlDB("3306", "jackdemo","root", "jack")方法用于建立与数据库的连接。<br />DBConnection是一个数据库连接类：<br /><pre name="code" class="java">
package com.jack.dwr.simple;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBConnection {
	public static Connection getConnectionMySqlDB(String post, String dbName,String userName,String password)
			throws Exception {
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:" + post + "/" + dbName;
		String user = userName;
		String pwd = password;
		Class.forName(driver);
		return DriverManager.getConnection(url, user, pwd);
	}
}
</pre><br />当然你也可以自己扩展别的数据库连接方法。<br />具体的JSP页面：<br /><pre name="code" class="java">
&lt;%@ page language="java" pageEncoding="GBK"%>
&lt;%
	String path = request.getContextPath();
%>

&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
&lt;html>
	&lt;head>

		&lt;title>EditTable的完整扩展&lt;/title>
		&lt;script type="text/javascript" src="&lt;%=path%>/dwr/util.js">&lt;/script>
		&lt;script type="text/javascript" src="&lt;%=path%>/dwr/engine.js">&lt;/script>
		&lt;script type="text/javascript"
			src="&lt;%=path%>/dwr/interface/People.js">&lt;/script>
		&lt;script type="text/javascript" src="people.js">&lt;/script>
	&lt;/head>

	&lt;body onload="init();">
		&lt;div id="tabContents">
			&lt;div id="demoDiv">
				&lt;h3>
					All People
				&lt;/h3>
				&lt;table border="1">
					&lt;thead>
						&lt;tr>
							&lt;th>
								IDCode
							&lt;/th>
							&lt;th>
								Person
							&lt;/th>
							&lt;th>
								AGE
							&lt;/th>
							&lt;th>
								ADDRESS
							&lt;/th>
							&lt;th>
								Actions
							&lt;/th>
						&lt;/tr>
					&lt;/thead>
					&lt;tbody id="peoplebody">
						&lt;tr id="pattern" style="display: none;">
							&lt;td>
								&lt;span id="tableId">Id&lt;/span>
							&lt;/td>

							&lt;td>
								&lt;span id="tableName">Name&lt;/span>
							&lt;/td>
							&lt;td>
								&lt;span id="tableAge">Age&lt;/span>
							&lt;/td>
							&lt;td>
								&lt;span id="tableAddress">Address&lt;/span>
							&lt;/td>
							&lt;td>
								&lt;input id="edit" type="button" value="Edit" onclick="editClicked(this.id)" />
								&lt;input id="delete" type="button" value="Delete"	onclick="deleteClicked(this.id)" />
							&lt;/td>
						&lt;/tr>
					&lt;/tbody>
				&lt;/table>
				&lt;h3>
					&lt;input id="add" type="button" value="添加人员" onclick="addPerson();" />
				&lt;/h3>
				&lt;div id="operation" style="display:none;">
					&lt;h3>
					&lt;span id="operationType">&lt;/span>
				&lt;/h3>
				&lt;table class="plain">
					&lt;tr>
						&lt;td>
							Name:
						&lt;/td>
						&lt;td>
							&lt;input id="name" type="text" size="30" />
						&lt;/td>
					&lt;/tr>
					&lt;tr>
						&lt;td>
							Age:
						&lt;/td>
						&lt;td>
							&lt;input id="age" type="text" size="20" />
						&lt;/td>
					&lt;/tr>
					&lt;tr>
						&lt;td>
							Address:
						&lt;/td>
						&lt;td>
							&lt;input type="text" id="address" size="40" />
						&lt;/td>
					&lt;/tr>
					&lt;tr>
						&lt;td colspan="2" align="right">
							&lt;small>(ID=&lt;span id="id">-1&lt;/span>)&lt;/small>
							&lt;input type="button" value="Save" onclick="writePerson()" />
							&lt;input type="button" value="Clear" onclick="clearPerson()" />
						&lt;/td>
					&lt;/tr>
				&lt;/table>
				&lt;/div>
			&lt;/div>
	&lt;/body>
&lt;/html>
</pre><br />上面是具体的页面信息，people.js信息如下:<br /><pre name="code" class="java">

var peopleCache = {};
var viewed = -1;
var type;
function init() {
	fillTable();
}
function fillTable() {
	People.getAllPerson(function (people) {
		// Delete all the rows except for the "pattern" row
		dwr.util.removeAllRows("peoplebody", {filter:function (tr) {
			return (tr.id != "pattern");
		}});
		// Create a new set cloned from the pattern row
		var person, id;
		people.sort(function (p1, p2) {
			return p1.name.localeCompare(p2.name);
		});
		for (var i = 0; i &lt; people.length; i++) {
			person = people[i];
			id = person.id;
			dwr.util.cloneNode("pattern", {idSuffix:id});
			dwr.util.setValue("tableId" + id, person.id);
			dwr.util.setValue("tableName" + id, person.name);
			dwr.util.setValue("tableAge" + id, person.age);
			dwr.util.setValue("tableAddress" + id, person.address);
			$("pattern" + id).style.display = ""; // officially we should use table-row, but IE prefers "" for some reason
			peopleCache[id] = person;
		}
	});
}
function editClicked(eleid) {
alert(eleid);
	document.getElementById("operation").style.display = "block";
	document.getElementById("operationType").innerHTML = "\u7f16\u8f91\u6570\u636e";
	var person = peopleCache[eleid.substring(4)];
	dwr.util.setValues(person);
	type = "edit";
}
function addPerson() {
	document.getElementById("operation").style.display = "block";
	document.getElementById("operationType").innerHTML = "\u6dfb\u52a0\u6570\u636e";
	dwr.util.setValue("name", "");
	dwr.util.setValue("age", "");
	dwr.util.setValue("address", "");
	dwr.util.setValue("id", "?");
	type = "add";
}
//insert or update Person into database
function writePerson() {
	var person; 
	if (type == "add") {
		person = {name:null, age:null, address:null};
		dwr.util.getValues(person);
		dwr.engine.beginBatch();
		People.addPerson(person);
	}else if(type=="edit"){
		person = {id:null,name:null,age:null,address:null};
		dwr.util.getValues(person);
		dwr.engine.beginBatch();
		People.updatePerson(person);
	}
	fillTable();
	dwr.engine.endBatch();
	document.getElementById("operation").style.display = "none";
	dwr.util.setValue("name", "");
	dwr.util.setValue("age", "");
	dwr.util.setValue("address", "");
	dwr.util.setValue("id", "?");
}
//delete person from database
function deleteClicked(eleid) {
	var person = peopleCache[eleid.substring(6)];
	dwr.engine.beginBatch();
	People.deletePerson(person);
	fillTable();
	dwr.engine.endBatch();
}
</pre><br /><br />以上就是全部的扩展内容。也可以通过附件下载运行看看效果。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/227132#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 18:24:34 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/227132</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/227132</guid>
      </item>
      <item>
        <title>报表－－JFreeChart</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/227097" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/227097</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　对于一个企业级的应用而言，常常需要生成大量的统计图表，例如饼图，柱状图等。生成这些统计图通常有两种做法：一种是直接使用Applet作为容器来显示这些统计图，或者临时生成统计图的图片，并在HTML页面中显示这些图片。<br /><br />　　对于第一种直接使用Applet来装载统计图的形式，需要客户机上安装Java虚拟机，这可能并不是每个浏览者都愿意面对的事情。<br /><br />　　JFreeChart让开发者无需自己来处理底层的图形处理细节，借助JFreeChart的帮助，开发者可以非常便捷地开发出各种各样的图表，包括：饼图、柱状图、线图、区域图、分布图、混合图、甘特图及一些仪表盘等。<br /><br />　　JFreeChart是一个开源项目，但其文档是付费的。<br /><br />　　使用JFreeChart必须使用包有jfreechart-x.jar和jcommon-x.jar。其实x代表版本。<br /><br />　　使用JFreeChart开发统计图只要实现下面四个步骤：<br /><br />　　　　1.提供一个Dataset实例，该实例里包含了创建统计图表的数据。<br /><br />　　　　2.使用ChartFactory的多个工厂方法createXXXChart来创建统计图表，统计图表就是一个JFreeChart对象。<br /><br />　　　　3.得到JFreeChart对象后，可以调用setTitle来修改统计图表的标题；或者调用getLegend方法来获得指定索引的图表图例，取得图例对象后即可修改图表的图例。<br /><br />　　　　4.通过JFreeChart对象的getPlot方法，即可获得图表的Plot对象，该对象对应于统计图表的实际图表部分，可以调用Plot对象的方法来修改图表中的各种显示内容。<br /><br />　　　但在实际开发过程中完成可以只实现前两个步骤，步骤三和步骤四分别是对统计图图例的操作和对统计图显示信息的修改。<br /><br />　　　现在只使用步骤一和步骤二生成一个简单的统计图示例，具体代码如下：<br /><br /><pre name="code" class="java">
package com.jack.jfreechart.piechart;

import java.awt.Font;
import java.io.File;
import java.io.FileOutputStream;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.general.DefaultPieDataset;

public class PieChartDemo {
 public PieChartDemo() throws Exception{
  //得到数据
  DefaultPieDataset data = this.getDataSet();

　//生成一个饼图图表对象，参数分别为：饼图标题、数据、是否显示图例、是否显示工具提示、是否生成URL
  JFreeChart chart = ChartFactory.createPieChart("图书销量统计图", data, true, false, false);

　//创建一个writebook.jpg的文件
  FileOutputStream fos = new FileOutputStream("writebook.jpg");

  //创建一个名为savebook.jpg的文件
  File file = new File("savebook.jpg");

  //对savebook.jpg进行数据的写入及保存
  ChartUtilities.saveChartAsJPEG(file, chart, 600, 600);

　//将数据写入到writebook.jpg文件中
//  ChartUtilities.writeChartAsJPEG(fos, chart, 600, 600);
 }


　//设置要进行统计的数据
 public DefaultPieDataset getDataSet(){
  DefaultPieDataset dataset = new DefaultPieDataset();
  dataset.setValue("Spring2.0宝典", 47000);
  dataset.setValue("轻量级J2EE企业实战", 38000);
  dataset.setValue("基于J2EE的Ajax宝典", 31000);
  dataset.setValue("Javascript权威指南", 29000);
  dataset.setValue("Ajax in Action", 25000);
  return dataset;
 }


 public static void main(String[] args){
  try {
   PieChartDemo demo = new PieChartDemo();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

</pre><br /><br />如果想更深入的理解JFreeChart，请认真研究ChartFactory对象和ChartUtilities对象，这两个对象决定要生成的统计图类型和生成具体的统计图信息。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/227097#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 17:03:26 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/227097</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/227097</guid>
      </item>
      <item>
        <title>Dwr初探——HelloDwr</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/226474" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/226474</a>&nbsp;
          发表时间: 2008年08月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Dwr用了也有一段时间啦，不过觉得用的东西都很肤浅，这段时间不太忙，觉得有必要对Dwr进行深入的了解。<br />　　下面就是Dwr最简单的一个例子。Hello Dwr<br />　　使用Dwr时，要确保您的Lib下已经存在Dwr的Jar文件。然后配置Web.xml文件，具体配置如下：<br />&lt;web-app version="2.5" xmlns="<a href="http://java.sun.com/xml/ns/javaee">http://java.sun.com/xml/ns/javaee</a>"<br />&nbsp;xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br />&nbsp;xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/javaee">http://java.sun.com/xml/ns/javaee</a> <br />&nbsp;<a href="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd</a>"&gt;<br />&nbsp;&lt;servlet&gt;<br />&nbsp;&nbsp;&lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;<br />&nbsp;&nbsp;&lt;servlet-class&gt;<br />&nbsp;&nbsp;&nbsp;org.directwebremoting.servlet.DwrServlet<br />&nbsp;&nbsp;&lt;/servlet-class&gt;<br />&nbsp;&lt;/servlet&gt;<br />&nbsp;&lt;servlet-mapping&gt;<br />&nbsp;&nbsp;&lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;<br />&nbsp;&nbsp;&lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt;<br />&nbsp;&lt;/servlet-mapping&gt;<br />&lt;/web-app&gt;<br />其中Dwr对应的Servlet类只用记得类所在的包名，就可以在dwr.jar文件中打到具体的类名。<br />　　然后建立Dwr的配置文件(dwr.xml),路径与您的web.xml在同一目录下。具体的dwr.xml文件的配置如下：<br />&lt;!DOCTYPE dwr PUBLIC<br />&nbsp;&nbsp;&nbsp; "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN"<br />&nbsp;&nbsp;&nbsp; "<a href="http://getahead.org/dwr/dwr20.dtd">http://getahead.org/dwr/dwr20.dtd</a>"&gt;<br />&lt;dwr&gt;<br />&nbsp;&lt;allow&gt;<br />&nbsp;&nbsp;&lt;create javascript="hello" creator="new"&gt;<br />&nbsp;&nbsp;&nbsp;&lt;param name="class" value="com.jack.dwr.simple.HelloDwr"&gt;&lt;/param&gt;<br />&nbsp;&nbsp;&lt;/create&gt;<br />&nbsp;&lt;/allow&gt;<br />&lt;/dwr&gt;<br />　　其中javascript="hello"是在页面中要使用的具体的名字，&lt;param&gt;是要对应到的类名。<br />　　要页面中使用Dwr即可以是HTML页面也可以JSP页面，下面是在JSP页面中如何使用Dwr框架：<br />&lt;%@ page language="java" pageEncoding="GBK"%&gt;<br />&lt;%<br />&nbsp;String path = request.getContextPath();<br />&nbsp;String basePath = request.getScheme() + "://"<br />&nbsp;&nbsp;&nbsp;+ request.getServerName() + ":" + request.getServerPort()<br />&nbsp;&nbsp;&nbsp;+ path + "/";<br />%&gt;</p>
<p>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />&lt;html&gt;<br />　&lt;head&gt;<br />　　&lt;base href="&lt;%=basePath%&gt;"&gt;<br />　　　　&lt;title&gt;Hello dwr&lt;/title&gt;<br />　　　　&lt;script type="text/javascript" src="&lt;%=path%&gt;/dwr/engine.js"&gt;&lt;/script&gt;<br />　　　　&lt;script type="text/javascript" src="&lt;%=path%&gt;/dwr/util.js"&gt;&lt;/script&gt;<br />　　　　&lt;script type="text/javascript" src="&lt;%=path%&gt;/dwr/interface/hello.js"&gt;&lt;/script&gt;<br />　　　　&lt;script type="text/javascript"&gt;<br />&nbsp;function sayHello(){<br />&nbsp;　person = document.getElementById("userName").value;<br />&nbsp;　hello.sayHello(person,callBackHello);<br />&nbsp;}<br />&nbsp;function callBackHello(result){<br />　　　　　　dwr.util.setValue("userName",result);<br />&nbsp;}<br />　　　　　&lt;/script&gt;<br />&nbsp;&lt;/head&gt;<br />　　&lt;body&gt;<br />　　　&lt;input type="text" id="userName"&gt;<br />　　　&lt;input type="button" value="sayHello" onclick="sayHello();"&gt;<br />　　&lt;/body&gt;<br />&lt;/html&gt;</p>
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/226474#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 11 Aug 2008 09:00:00 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/226474</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/226474</guid>
      </item>
      <item>
        <title>以编程方式创建数据库表</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/223792" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/223792</a>&nbsp;
          发表时间: 2008年08月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前几天下了个开源的论坛系统JForum，看了一下，此论坛系统是以可编程的方式进行数据库表的创建。<br /><br />研究了一下，现把具体的代码分离一下，感兴趣的朋友可以看看，以后可能会用到的。 <br /><br />下面是解析SQL文件的语句代码： <br /><br /><pre name="code" class="java">
public class ParseDBStructFile {
 /**
  * 读取Sql文件，得到Sql语句信息列表
  * @param operation 控制Sql语句的数组
  * @param filename Sql文件所在的路径
  * @return Sql语句的信息列表
  */
 @SuppressWarnings("unchecked")
 public static List parse(String[] operation,String filename) {
  //保存Sql语句的List
  List statements = new ArrayList();

  BufferedReader reader = null;
  try {
   reader = new BufferedReader(new FileReader(filename));
   StringBuffer sb = new StringBuffer(512);

   boolean processing = false;
   char delimiter = ';';
//   String[] creators = { "CREATE INDEX", "CREATE TABLE",
//     "CREATE SEQUENCE", "DROP TABLE", "IF EXISTS",
//     "DROP SEQUENCE", "DROP INDEX" };
   String[] creators = operation;
   String line;
   while ((line = reader.readLine()) != null) {
    if (line.length() == 0) {
     continue;
    }

    char charAt = line.charAt(0);

    // Ignore comments
    if (charAt == '-' || charAt == '#') {
     continue;
    }

    if (processing) {
     sb.append(line);

     if (line.indexOf(delimiter) > -1) {
      sb.delete(sb.length() - 1, sb.length());
      statements.add(sb.toString());
      processing = false;
     }
    } else {
     for (int i = 0; i &lt; creators.length; i++) {
      if (line.indexOf(creators[i]) > -1) {
       sb.delete(0, sb.length());

       if (line.indexOf(delimiter) > -1) {
        if (line.indexOf(';') > -1) {
         line = line.replace(';', ' ');
        }

        statements.add(line);
       } else {
        sb.append(line);
        processing = true;
       }

       break;
      }
     }
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (reader != null) {
    try {
     reader.close();
    } catch (Exception e) {
    }
   }
  }

  return statements;
 }
}
</pre><br /><br />此类用于对包含SQL语句的文件进行分析。<br /><br />把SQL语句添加至一个List对象里面。其中String数组中包含数据库表创建中的一些关键字段，比如CREATE INDEX, CREATE TABLE，DROP TABLE,DROP INDEX等语句。 <br /><br />接着就可以创建执行Sql语句的类，以创建数据库表信息，以下是具体代码： <br /><br /><pre name="code" class="java">
public class InstallTables {
 /**
  * 创建数据库表的方法
  * @param post 数据库对应的端口 
  * @param dbName 数据库名称
  * @param username 用户名
  * @param password 密码
  * @param operation 控制数据库创建表数组
  * @param filename Sql表文件的路径
  * @throws Exception
  */
 @SuppressWarnings("unchecked")
 public void install(String post,String dbName,String username,String password,String[] operation,String filename) throws Exception{
  Connection conn = DBConnection.getConnectionMySqlDB(post,dbName,username,password);
  boolean autoCommit = conn.getAutoCommit();
  Statement st = null;
  List queryList = ParseDBStructFile.parse(operation,filename);
  for(String sql:queryList){
   if (sql == null || "".equals(sql.trim())) {
    continue;
   }
   st = conn.createStatement();
   st.executeUpdate(sql);
   st.close();
  }
  conn.setAutoCommit(autoCommit);
 }
}

</pre><br /><br />其中DBConnection是一个建立与数据库连接的类，参数代表了数据库的端口号、要连接的目标数据库名称、用户名、密码。 <br /><br />DBConnection类的具体代码： <br /><br /><pre name="code" class="java">
public class DBConnection {

 public static Connection getConnectionMySqlDB(String post, String dbName,String userName,String password)
   throws Exception {
  String driver = "com.mysql.jdbc.Driver";
  String url = "jdbc:mysql://localhost:" + post + "/" + dbName;
  String user = userName;
  String pwd = password;
  Class.forName(driver);
  return DriverManager.getConnection(url, user, pwd);
 }
}

</pre><br /><br />当然你也可以自己进行扩展，比如再创建与SQLServer、Oracle的连接等。<br /><br />现在一切都已经完成啦，让我们做一个简单的测试： <br /><br /><pre name="code" class="java">
public class testCreator{ 

    @Test 

    public void testInstallTables(){ 

       InstallTables install = new InstallTables(); 

       try { 

          String[] operation = {"CREATE TABLE","DROP TABLE"}; 

          install.install("3306", "jackdemo", "root", "jack",operation, "F:\\tables.sql"); 

       } catch (Exception e) { 

          e.printStackTrace(); 

       } 

    } 

} 

</pre><br /><br />下面是tables.sql文件的内容： <br /><br /><pre name="code" class="java">
DROP TABLE IF EXISTS jackdemo1; 

CREATE TABLE jackdemo1 ( 

        id int primary key auto_increment, 

        name varchar(50), 

        age int, 

        address varchar(1000) 

); 

</pre><br /><br />以上就是全部的内容，当然还可以进行表内容的添加，只要你写的Sql语句正确。<br /><br />有时候看一些开源的东西，特别是看别人的代码的时候觉得自己的代码写的好不严谨呀，以后还要多多学习开源框架的源码，养成好的代码风格和习惯。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/223792#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 04 Aug 2008 11:15:31 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/223792</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/223792</guid>
      </item>
      <item>
        <title>关于RSS的聚合－－－OPML</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/216001" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/216001</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　OPML也是最近才发现的一个东东，以前只知道解析Rss，前几天老总问我要这个东西的时候我才知道，还有OPML的存在。<br /><br />　　什么是OPML呢？说白啦，就是把你的网站的RSS聚合在一起生成的一个OPML文件，主要也就是方便RSS文件的提交。<br /><br />　　对OPML还没有做太深入的理解，在网上查了查，发现没有那个开源项目可以用的，有Jakarta下的一个开源项目可以使用（FeedParser），可是好像是项目还没有完成啦，在Apache里没有找到下载。还有一个Informa也可以做，不过从２００４年之后就没有组织再对其进行更新和维护啦。<br /><br />　　想来想去决定用FreeMarker做去，以模板的形式生成一个opml.ftl模板文件。模板文件如下：<br /><br /><pre name="code" class="java">
&lt;?xml version="1.0" encoding="utf-8" ?> 
&lt;opml version="1.0">
  &lt;head>
   &lt;title>${title}&lt;/title> 
   &lt;dateCreated>${pubDate}&lt;/dateCreated> 
   &lt;ownerName>${owner}&lt;/ownerName> 
   &lt;ownerEmail>${email}&lt;/ownerEmail> 
   &lt;description>${title}&lt;/description> 
   &lt;createdBy>${builder}&lt;/createdBy> 
   &lt;link>${link}&lt;/link> 
  &lt;/head>
  &lt;body>
  &lt;outline title="${title}" text="${title}" opml="" kind="nkPath">
    &lt;#list typeList as type>
     &lt;outline title="${type.title}" text="${type.title}" type="rss" xmlUrl="${buildPath}/news/rss/${type.typecode}.xml" interval="60" itemMax="400" htmlUrl="" description="${type.title}" kind="nkFeed" /> 
    &lt;/#list> 
   &lt;/outline>
  &lt;/body>
&lt;/opml>

</pre><br /><br />完成所需要的模板文件后，就要对模板文件进行生成啦。我使用的技术是Struts2+Spring+Hibernate+Dwr实现的，生成文件的那点是使用Dwr去实现的。具体的生成代码如下：<br /><pre name="code" class="java">
public String opmlBuild(String typeCode, String fileName, String owner,
   String email, String builder, String link, String buildPath,
   HttpServletRequest request, HttpServletResponse response) {
  String result = "";
  try {
   response.setContentType("text/opml");
   response.setCharacterEncoding("utf-8");
   String ftlPath = request.getSession().getServletContext()
     .getRealPath("/")
     + "//WEB-INF//ftl//";
   String path = request.getSession().getServletContext().getRealPath(
     "/");
   // String ftlPath = ftl + "//ftl//";
   config.setDirectoryForTemplateLoading(new File(ftlPath));
   // 得到模板文件
   Template template = config.getTemplate("opml.ftl");
   // 设置编码格式
   template.setEncoding("utf-8");
   YxNewsType type = typeNews.getTypeByTypeCode(typeCode);
   List&lt;YxNewsType> typeList = typeNews
     .getAllChildTypeByTypeCode(typeCode);
   if (typeList != null) {
    Map root = new HashMap();

　 //设置发布的OPML的标题
    root.put("title", type.getTitle());

    //设置OPML的发布时间
    root.put("pubDate", new Date().toString());

    //设置OPML的所有者
    root.put("owner", owner);

　 //设置OPML的发布者的EMail地址
    root.put("email", email);

    //设置OPML的创建人
    root.put("builder", builder);

    //设置OPML文件的连接地址，可以直接你网站的连接地址
    root.put("link", link);

　 //设置自己的创建Rss的连接地址
    root.put("buildPath", buildPath);
    root.put("typeList", typeList);
    // 设置到生成的文件名称

    String file = "";

　 //判断当前操作系统，如果是Windows系统的做就是反斜杠，如果是Linux系统就使用正斜杠
    Properties properties = System.getProperties();
    Object object = properties.get("os.name");
    // System.out.println("当前操作系统：" + String.valueOf(object));
    if ("Windows".equals(String.valueOf(object))) {
     file = path + "\\rss\\opml\\" + fileName + ".opml";
    } else {
     file = path + "//rss//opml//" + fileName + ".opml";
    }

    //设置要生成的文件
    Writer out = new OutputStreamWriter(new FileOutputStream(file),
      "utf-8");
    template.process(root, out);

　 //清理写入流
    out.flush();

    // 关闭流文件
    out.close();
    result = "buildSuccess";
   } else {
    result = "noChild";
   }
  } catch (Exception e) {
   result = "error";
   e.printStackTrace();
  }
  return result;
 }
</pre><br />　<br />上面方法中的参数是通过Dwr传递过来的，下面是页面JSP文件：<br /><br /><pre name="code" class="java">
&lt;%@ page language="java" pageEncoding="GBK"%>
&lt;%@ taglib prefix="s" uri="/struts-tags"%>
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
&lt;html xmlns="http://www.w3.org/1999/xhtml">
 &lt;head>
  &lt;title>信源管理&lt;/title>
  &lt;link rel="stylesheet"
   href="${pageContext.request.contextPath}/common/css/admin/style.css"
   type="text/css" />
  &lt;script type="text/javascript"
   src="${pageContext.request.contextPath}/dwr/engine.js">&lt;/script>
  &lt;script type="text/javascript"
   src="${pageContext.request.contextPath}/dwr/util.js">&lt;/script>
  &lt;script type="text/javascript"
   src="${pageContext.request.contextPath}/dwr/interface/rssBuild.js">&lt;/script>
  &lt;script type="text/javascript">
   var typeCode;
   function showBuild(title,code){
    //alert(title);
    typeCode = code;
    var doc = document.getElementById("buildOpml");
    document.getElementById("tableTitle").innerHTML=title;
    document.getElementById("opmlName").value = "";
    document.getElementById("nameMessage").innerHTML = "请以英文名称命名";
    document.getElementById("startBuild").value = "生成OPML";
    doc.style.display = "block";
   }
   function buildOpml(){
    owner = document.getElementById("opmlOwner").value;
    email = document.getElementById("opmlEmail").value;
    builder = document.getElementById("opmlBuilder").value;
    url = document.getElementById("opmlUrl").value;
    fileName = document.getElementById("opmlName").value;
    prefix = document.getElementById("opmlPrefix").value;
    msg = document.getElementById("nameMessage");
    btnBuild = document.getElementById("startBuild");
    if(""!=fileName){
     msg.innerHTML = "&lt;font color='green'>文件生成中，请等待……&lt;/font>";
     btnBuild.disabled = true; 
     btnBuild.value = "文件生成中";
     rssBuild.opmlBuild(typeCode,fileName,owner,email,builder,url,prefix,callBackResult);
    }else{
     msg.innerHTML = "&lt;font color='red'>请填写你的OPML文件名称&lt;/font>";
    }
   }
   function callBackResult(result){
    msg = document.getElementById("nameMessage");
    btnBuild = document.getElementById("startBuild");
    if(result=="buildSuccess"){
     msg.innerHTML = "&lt;font color='green'>文件已经成功生成&lt;/font>";
     btnBuild.disabled = false;
     btnBuild.value = "生成成功";
    }else if(result=="noChild"){
     msg.innerHTML = "&lt;font color='red'>此类别没有子信息，无法生成&lt;/font>";
     btnBuild.disabled = false;
     btnBuild.value = "没有子类可供生成";
    }else{
     msg.innserHTML = "&lt;font color='red'>生成出现错误，请联系管理员&lt;/font>";
     btnBuild.disabled = false;
     btnBuild.value = "生成失败";
    }
   }
   function showHideDIV(){
    var doc = document.getElementById("buildOpml");
    doc.style.display =(doc.style.display == "none"?"block":"none");
   }
  &lt;/script>
 &lt;/head>
 &lt;body>
  &lt;div id="container">
   &lt;table class="tableBorder" align="center" border="0" cellpadding="2"
    cellspacing="1" style="width: 98%;">
    &lt;tr>
     &lt;th height="25" colspan="10">
      类别名称
     &lt;/th>
    &lt;/tr>
    &lt;tr>
     &lt;s:iterator value="listType">
      &lt;td class="TableRow2">
       &lt;a href="javascript:showBuild('${title }','${typecode }');"
        style="text-shadow: none;"> &lt;s:property value="title" /> &lt;/a>
      &lt;/td>
     &lt;/s:iterator>
    &lt;/tr>
   &lt;/table>
   &lt;div id="buildOpml" style="display:none;">
    &lt;table class="tableBorder" align="center" border="0" cellpadding="2"
    cellspacing="1" style="width: 98%;">
     &lt;tr>
      &lt;th colspan="3">
       &lt;div id="tableTitle">&lt;/div>
      &lt;/th>
     &lt;/tr>
     &lt;tr>
      &lt;td class="TableRow2">请输入OPML的所有者：&lt;/td>
      &lt;td class="TableRow2">
       &lt;input type="text" id="opmlOwner" value="中国分告传媒" disabled="disabled"/>
      &lt;/td>
      &lt;td class="TableRow2">
       &lt;div id="ownerMessage">请正确填写OPML的所有者&lt;/div>
      &lt;/td>
     &lt;/tr>
     &lt;tr>
      &lt;td class="TableRow2">请输入OPML所有者的联系邮箱：&lt;/td>
      &lt;td class="TableRow2">
       &lt;input type="text" id="opmlEmail" value="zyj-jack@163.com"/>
      &lt;/td>
      &lt;td class="TableRow2">
       &lt;div id="emailMessage">请正确填写邮箱地址&lt;/div>
      &lt;/td>
     &lt;/tr>
     &lt;tr>
      &lt;td class="TableRow2">请输入OPML创建者的名字：&lt;/td>
      &lt;td class="TableRow2">
       &lt;input type="text" id="opmlBuilder" value="河南亿禧软件有限公司" disabled="disabled"/>
      &lt;/td>
      &lt;td class="TableRow2">
       &lt;div id="builderMessage">请正确填写创建者&lt;/div>
      &lt;/td>
     &lt;/tr>
     &lt;tr>
      &lt;td class="TableRow2">请输入网站的连接URL：&lt;/td>
      &lt;td class="TableRow2">
       &lt;input type="text" id="opmlUrl" value="www.fansgoo.com" disabled="disabled"/>
      &lt;/td>
      &lt;td class="TableRow2">
       &lt;div id="urlMessage">请输入合法的网络地址&lt;/div>
      &lt;/td>
     &lt;/tr>
     &lt;tr>
      &lt;td class="TableRow2">请填写您生成文件前缀地址：&lt;/td>
      &lt;td class="TableRow2">
       &lt;input type="text" id="opmlPrefix" value="http://www.fansgoo.com" disabled="disabled"/>
      &lt;/td>
      &lt;td class="TableRow2">请填写您生成文件所在的位置&lt;/td>
     &lt;/tr>
     &lt;tr>
      &lt;td class="TableRow2">请输入您的生成的OPML名称：&lt;/td>
      &lt;td class="TableRow2">&lt;input type="text" id="opmlName" name="opmlName"/>&lt;/td>
      &lt;td class="TableRow2">&lt;div id="nameMessage">请以英文名命名&lt;/div>&lt;/td>
     &lt;/tr>
     &lt;tr>
      &lt;td class="TableRow2" colspan="3" align="center">
       &lt;input type="button" id="startBuild" value="生成OPML" onclick="buildOpml();"/>
      &lt;/td>
     &lt;/tr>
    &lt;/table>
   &lt;/div>
   &lt;br />
   &lt;jsp:include page="admin_bottom.jsp" />
  &lt;/div>
 &lt;/body>
&lt;/html>
</pre><br />OPML是对Rss资源的整合，避免了反复提交Rss文件所带来的负担，从而提高Rss的可收录度，相信不久以后OPML和Rss可以更完美的结合，人们可以更好的使用Rss资源。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/216001#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 09:31:23 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/216001</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/216001</guid>
      </item>
      <item>
        <title>电信拨号器</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/215990" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/215990</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          　　公司用的是电信的网络，前段时间公司的电脑总是拨不上去号，自己写了一个基于Java的电信拨号程序，感兴趣的朋友可以下载下看看。<br /><br />　　下面是拨号程序的原代码，大家可以看看，有什么不合理的地方请指出来。<br /><br /><pre name="code" class="java">
package com.jack.telecom.dial;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Dial extends JFrame{
 private JLabel lblConName;
 private JTextField txtConName;
 private JLabel lblConNum;
 private JTextField txtConNum;
 private JLabel lblStartNum;
 private JComboBox cmbStartNum;
 private JLabel lblMaxNum;
 private JComboBox cmbEndNum;
 private JLabel lblPwd;
 private JPasswordField txtPwd;
 private JLabel label;
 private JLabel lblEndMessage;
 private JLabel lblStartMessage;
 private JLabel lblConNameMessage;
 private JTextArea txaConMessage;
 private JLabel lblMessage;
 private JTextArea txaMessage;
 private JButton btnConn;
 private StringBuffer showMessage;
 private String conNum;
 private String resultStr = "";

 public Dial() {
  initComponents();
  this.setTitle("电信拨号程序");
  this.getContentPane().setLayout(null);
  this.setSize(400, 500);
  this.setVisible(true);
  // this.setBounds(100, 100, 400, 472);

  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }

 private void initComponents() {
  lblConName = new JLabel();
  lblConName.setText("网络连接名称：");
  lblConName.setBounds(10, 26, 91, 18);
  this.getContentPane().add(lblConName);

  txtConName = new JTextField();
  txtConName.setText("jack");
  txtConName.setBounds(107, 24, 87, 22);
  this.getContentPane().add(txtConName);

  lblConNum = new JLabel();
  lblConNum.setText("连接帐号：");
  lblConNum.setBounds(10, 54, 66, 18);
  this.getContentPane().add(lblConNum);

  txtConNum = new JTextField();
  txtConNum.setText("n037113051");
  txtConNum.setBounds(107, 50, 87, 22);
  this.getContentPane().add(txtConNum);

  lblStartNum = new JLabel();
  lblStartNum.setText("起始数：");
  lblStartNum.setBounds(10, 103, 66, 18);
  this.getContentPane().add(lblStartNum);

  cmbStartNum = new JComboBox();
  cmbStartNum.setBounds(107, 99, 87, 27);
  this.getContentPane().add(cmbStartNum);

  lblMaxNum = new JLabel();
  lblMaxNum.setText("最大拨号数：");
  lblMaxNum.setBounds(10, 138, 91, 18);
  this.getContentPane().add(lblMaxNum);

  cmbEndNum = new JComboBox();
  cmbEndNum.setBounds(107, 132, 87, 27);
  for (int i = 1; i &lt;= 99; i++) {
   cmbStartNum.addItem(i);
   cmbEndNum.addItem(i);
  }
  this.getContentPane().add(cmbEndNum);

  lblPwd = new JLabel();
  lblPwd.setText("密码：");
  lblPwd.setBounds(10, 179, 91, 18);
  this.getContentPane().add(lblPwd);

  txtPwd = new JPasswordField();
  txtPwd.setText("123456");
  txtPwd.setActionCommand("*");
  txtPwd.setBounds(107, 177, 94, 22);
  this.getContentPane().add(txtPwd);

  label = new JLabel();
  label.setText("默认密码为123456");
  label.setBounds(211, 179, 118, 18);
  this.getContentPane().add(label);

  lblEndMessage = new JLabel();
  lblEndMessage.setText("选择您要进行拨号的最大限制");
  lblEndMessage.setBounds(200, 138, 178, 18);
  this.getContentPane().add(lblEndMessage);

  lblStartMessage = new JLabel();
  lblStartMessage.setText("选择您要进行拨号的起始数");
  lblStartMessage.setBounds(200, 103, 178, 18);
  this.getContentPane().add(lblStartMessage);

  lblConNameMessage = new JLabel();
  lblConNameMessage.setText("此名称为您拨号连接的名称");
  lblConNameMessage.setBounds(200, 26, 178, 18);
  this.getContentPane().add(lblConNameMessage);

  txaConMessage = new JTextArea();
  String msg = "请将您拨号帐号的前10位写上\n其中最后２位可以修改";
  txaConMessage.setText(msg);
  txaConMessage.setBounds(200, 54, 158, 40);
  this.getContentPane().add(txaConMessage);

  lblMessage = new JLabel();
  lblMessage.setText("连接显示信息：");
  lblMessage.setBounds(10, 248, 118, 18);
  this.getContentPane().add(lblMessage);

  txaMessage = new JTextArea();
  txaMessage.setEditable(false);
  JScrollPane scroll = new JScrollPane(txaMessage,
    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
  scroll.setBounds(10, 272, 368, 155);
  this.getContentPane().add(scroll);

  btnConn = new JButton();
  btnConn.addActionListener(new ActionListener() {
   public void actionPerformed(final ActionEvent e) {
    Thread t = new Thread() {
     public void run() {
      Process p = null;
      String conn = txtConNum.getText();
      int startNum = ((Integer) cmbStartNum.getSelectedItem()).intValue();
      int endNum = ((Integer) cmbEndNum.getSelectedItem()).intValue();
      String user = txtConName.getText();
      String password = txtPwd.getText();
      showMessage = new StringBuffer();
      for (int i = startNum; i &lt; endNum; i++) {
       if (i &lt; 10) {
        conNum = conn + "0" + i;
       } else {
        conNum = conn + i;
       }
       try {
        p = Runtime.getRuntime().exec(
          "rasdial.exe " + user + " " + conNum
            + " " + password);
        int result = p.waitFor();
        if (result == 0) {
         resultStr = "连接成功";
         // break;
        } else {
         resultStr = result + "";
        }
        showMessage.append("当前连接帐号为：" + conNum + "\n"
          + "连接结果：" + resultStr + "\n");
        txaMessage.setText(showMessage.toString());
        // new Thread().start();
        // showMsg(conNum, resultStr);
        // System.out.println("得到的数据：" + conNum + "\n" +
        // "连接结果："
        // + resultStr + "\n");
       } catch (Exception e1) {
        e1.printStackTrace();
       }
      }
     }
    };
    t.start();
   }
  });
  btnConn.setText("开始拨号");
  btnConn.setBounds(107, 214, 106, 28);
  this.getContentPane().add(btnConn);
 }

 public void radial(String conNum,int startNum,int endNum,String user,String password){
  Process p = null;
  String conn = txtConNum.getText();
  showMessage = new StringBuffer();
  for (int i = startNum; i &lt; endNum; i++) {
   if (i &lt; 10) {
    conNum = conn + "0" + i;
   } else {
    conNum = conn + i;
   }
   try {
    p = Runtime.getRuntime().exec(
      "rasdial.exe " + user + " " + conNum
        + " " + password);
    int result = p.waitFor();
    if (result == 0) {
     resultStr = "连接成功";
     // break;
    } else {
     resultStr = result + "";
    }
    showMessage.append("当前连接帐号为：" + conNum + "\n"
      + "连接结果：" + resultStr + "\n");
    txaMessage.setText(showMessage.toString());
   } catch (Exception e1) {
    e1.printStackTrace();
   }
  }
 }
 
 public static void main(String[] args) {
  Dial d = new Dial();
 }
}

</pre><br /><br />你也可以自己运行一下代码，不过请确定你的网络是电信的。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/215990#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 08:58:55 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/215990</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/215990</guid>
      </item>
      <item>
        <title>自动生成Rss</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/214644" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/214644</a>&nbsp;
          发表时间: 2008年07月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          前几天写了个解析Rss文件的一个例子，这几天写了个基于Rome生成Rss文件的工具类，发布上来共享下。希望对大家有所帮助。<br /><br />　　工具类里用的Jar包为Rome.jar，JDom.jar，感兴趣的朋友可以自己下载，也可以从我的上篇文件里下载到。<br /><br />　　存在两个POJO类：ChannelItem类和ChannelEItem类，ChanneEItem类继承自ChannelItem类，多一个Enclosure属性，用于存在流媒体文件的类里使用。<br /><br />　　具体代码如下，ChannelItem类：<br /><br /><pre name="code" class="java">
import java.util.Date;

/**
 * 频道下的子信息
 * 此类无流媒体播放文件
 * @author jackZhang
 *
 */
public class ChannelItem{
 private String title;//Rss文件中Item的标题
 private String link;//Rss文件中Item对应的连接
 private String description;//Item的描述
 private Date pubDate;//Item发布的时间
 private String author;//Item作者
 private String category;//Item所属的频道范畴
 
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getLink() {
  return link;
 }
 public void setLink(String link) {
  this.link = link;
 }
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }
 public Date getPubDate() {
  return pubDate;
 }
 public void setPubDate(Date pubDate) {
  this.pubDate = pubDate;
 }
 public String getAuthor() {
  return author;
 }
 public void setAuthor(String author) {
  this.author = author;
 }
 public String getCategory() {
  return category;
 }
 public void setCategory(String category) {
  this.category = category;
 }
}
</pre><br /><br />ChannelEItem类，具体代码：<br /><br /><pre name="code" class="java">
/**
 * 用于添加频道的子项
 * 当存在流媒体播放文件时使用此类
 *
 * @author jackZhang
 *
 */
public class ChannelEItem extends ChannelItem{
 private String enclosure;//流媒体文件

 public String getEnclosure() {
  return enclosure;
 }

 public void setEnclosure(String enclosure) {
  this.enclosure = enclosure;
 }
}

</pre><br /><br />以下是具体的Rss生成器封装类RssBuildFactory，具体代码：<br /><pre name="code" class="java">
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndCategoryImpl;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEnclosureImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.io.SyndFeedOutput;
import com.yx.xml.bo.ChannelEItem;
import com.yx.xml.bo.ChannelItem;

/**
 * 用于生成Rss文件
 * @author jackZhang
 *
 */
public class RssBuildFactory {
 private SyndFeed feed;
 @SuppressWarnings("unchecked")
 private List entries;
 private SyndEntry entry ;
 @SuppressWarnings("unchecked")
 public RssBuildFactory(){
  feed = new SyndFeedImpl();
  feed.setFeedType("rss_2.0");
  entries = new ArrayList();
 }
 /**
  * 创建一个频道
  * @param title　频道标题
  * @param link　频道对应的连接
  * @param description　频道描述
  * @param language　频道所用语言
  * @param pubDate　频道发布时期
  * @param copyright　版权所有
  * @throws Exception
  */
 public void buildChannel(String title,String link,String description,String language,Date pubDate,String copyright) throws RuntimeException {
  feed.setTitle(title);
  feed.setLink(link);
  feed.setDescription(description);
  feed.setLanguage(language);
  feed.setPublishedDate(pubDate);
  feed.setCopyright(copyright);
 }
 
 /**
  * 添加频道的子内容
  * @param item <a href="mailto:{@link">{@link</a> ChannelItem}
  * @throws Exception
  */
 @SuppressWarnings("unchecked")
 public void buildItems(ChannelItem item) throws RuntimeException {
  entry = new SyndEntryImpl();
  //设置新闻标题
  entry.setTitle(item.getTitle());
  //设置新闻的连接地址
  entry.setLink(item.getLink());
  //设置新闻简介
  SyndContent content = new SyndContentImpl();
  content.setType("text/plain");
  content.setValue(item.getDescription());
  entry.setDescription(content);
  //设置发布时间
  entry.setPublishedDate(item.getPubDate());
  //设置频道所属的范围
  SyndCategory cate = new SyndCategoryImpl();
  cate.setName(item.getCategory());
  List cateList = new ArrayList();
  cateList.add(cate);
  entry.setCategories(cateList);
  //设置作者
  entry.setAuthor(item.getAuthor());
  //将新闻项添加至数组中
  entries.add(entry);
 }
 
 /**
  * 添加频道的内容项
  * @param item <a href="mailto:{@link">{@link</a> ChannelEItem}此类继承自ChannelItem类
  * @throws Exception
  */
 @SuppressWarnings("unchecked")
 public void buildItems(ChannelEItem item) throws RuntimeException {
  entry = new SyndEntryImpl();
  //设置新闻标题
  entry.setTitle(item.getTitle());
  //设置新闻的连接地址
  entry.setLink(item.getLink());
  //设置新闻简介
  SyndContent content = new SyndContentImpl();
  content.setValue(item.getDescription());
  entry.setDescription(content);
  //设置发布时间
  entry.setPublishedDate(item.getPubDate());
  //设置频道所属的范围
  SyndCategory cate = new SyndCategoryImpl();
  cate.setName(item.getCategory());
  List cateList = new ArrayList();
  cateList.add(cate);
  entry.setCategories(cateList);
  //设置作者
  entry.setAuthor(item.getAuthor());
  //设置流媒体播放文件
  SyndEnclosure en = new SyndEnclosureImpl();
  en.setUrl(item.getEnclosure());
  List enList = new ArrayList();
  enList.add(en);
  entry.setEnclosures(enList);
  //将新闻项添加至数组中
  entries.add(entry);
 }
 
 /**
  * 生成XML文件
  * @param filePath　文件保存路径和名称
  * @throws Exception
  */
 public void buildChannel(String filePath) throws Exception {
  feed.setEntries(entries);
  SyndFeedOutput output = new SyndFeedOutput();
  Writer writer; 
  writer = new OutputStreamWriter(new FileOutputStream(filePath), "UTF-8");
  output.output(feed, writer);  
 }
}

</pre><br /><br /><br />下面是一个示例，用于测试生成Rss：<br /><br />前提说明本人测试使用的Mysql数据库，数据库存在一个newsitem表用于储存Rss内容。<br /><br /><pre name="code" class="java">
public void testBuildObject() {
  try {

　//建立数据库的连接
   DBConnection db = new DBConnection();

　//查询Sql语句
   String querySql = "select * from newitem";

   //getAllResult方法是一个查询方法，感兴趣的话也可以自己写
   ResultSet rs = db.getAllResult(querySql);

　//建立Rss生成器工厂
   RssBuildFactory builder = new RssBuildFactory();

   //循环遍历数据库记录生成Rss中的Item项
   while (rs.next()) {
    ChannelEItem item = new ChannelEItem();
    item.setTitle(rs.getString("title"));
    item.setLink(rs.getString("link"));
    item.setDescription(rs.getString("description"));
    item.setPubDate(rs.getDate("pubdate"));
    item.setCategory(rs.getString("category"));
    item.setAuthor(rs.getString("author"));
    item.setEnclosure(rs.getString("enclosure"));
    builder.buildItems(item);
   }

   //建立Rss的Channel信息
   builder.buildChannel("Jack的测试", "<a href="http://www.fansgoo.com/" target="_blank">www.fansgoo.com</a>", "测试生成", "zh-cn",
     new Date(), "河南亿禧软件有限公司");

　//设置Rss文件的生成路径
   builder.buildChannel("E:\\demo.xml");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

</pre><br /><br />感兴趣的朋友也可以直接下载本人提供的上面类的Jar文件，方面于使用。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/214644#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 14 Jul 2008 17:36:03 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/214644</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/214644</guid>
      </item>
      <item>
        <title>Rome解析Rss</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/214099" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/214099</a>&nbsp;
          发表时间: 2008年07月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          用Rome已经有好长时间啦，今天把自己的学习东西拿出来和大家一起分享下，有什么不足的地方还请指出：<br /><br />下面是一个简单的对Rome进行解析的操作，使用JUnit进行测试，Rome文件可以自己下载，具体代码如下：<br /><br /><pre name="code" class="java">
import java.net.URL;
import java.util.List;

import org.junit.Test;

import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class TestParse {
 @Test
 public void parseRss() {
  String rss = "<a href="http://news.baidu.com/n?cmd=1&class=civilnews&tn=rss&sub=0" target="_blank">http://news.baidu.com/n?cmd=1&class=civilnews&tn=rss&sub=0</a>";
  try {
   URL url = new URL(rss);
   // 读取Rss源
   XmlReader reader = new XmlReader(url);
   System.out.println("Rss源的编码格式为：" + reader.getEncoding());
   SyndFeedInput input = new SyndFeedInput();
   // 得到SyndFeed对象，即得到Rss源里的所有信息
   SyndFeed feed = input.build(reader);
   // 得到Rss新闻中子项列表
   List entries = feed.getEntries();
   // 循环得到每个子项信息
   for (int i = 0; i &lt; entries.size(); i++) {
    SyndEntry entry = (SyndEntry) entries.get(i);
    // 标题、连接地址、标题简介、时间是一个Rss源项最基本的组成部分
    System.out.println("标题：" + entry.getTitle());
    System.out.println("连接地址：" + entry.getLink());
    SyndContent description = entry.getDescription();
    System.out.println("标题简介：" + description.getValue());
    System.out.println("发布时间：" + entry.getPublishedDate());
    // 以下是Rss源可先的几个部分
    System.out.println("标题的作者：" + entry.getAuthor());
    // 此标题所属的范畴
    List categoryList = entry.getCategories();
    if (categoryList != null) {
     for (int m = 0; m &lt; categoryList.size(); m++) {
      SyndCategory category = (SyndCategory) categoryList
        .get(m);
      System.out.println("此标题所属的范畴：" + category.getName());
     }
    }
    // 得到流媒体播放文件的信息列表
    List enclosureList = entry.getEnclosures();
    if (enclosureList != null) {
     for (int n = 0; n &lt; enclosureList.size(); n++) {
      SyndEnclosure enclosure = (SyndEnclosure) enclosureList
        .get(n);
      System.out.println("流媒体播放文件：" + entry.getEnclosures());
     }
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

</pre><br /><br />上面就是具体的代码，有什么不明白的地方或不合理的地方还请指出，会及时做出调整。
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/214099#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 12 Jul 2008 10:14:20 +0800</pubDate>
        <link>http://jackzhangyunjie.javaeye.com/blog/214099</link>
        <guid>http://jackzhangyunjie.javaeye.com/blog/214099</guid>
      </item>
      <item>
        <title>为别人提供方法工具类的时候传递参数有什么特别的要求吗？</title>
        <author>jackzhangyunjie</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://jackzhangyunjie.javaeye.com">jackzhangyunjie</a>&nbsp;
          链接：<a href="http://jackzhangyunjie.javaeye.com/blog/213854" style="color:red;">http://jackzhangyunjie.javaeye.com/blog/213854</a>&nbsp;
          发表时间: 2008年07月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>昨天花时间为别人写了个工具类，作用就是生成Rss文件，具体代码如下：</p>
<p>public class RssBuilder {<br />&nbsp;private SyndFeed feed;<br />&nbsp;private List entries;<br />&nbsp;private SyndEntry entry ;<br />&nbsp;public RssBuilder(){<br />&nbsp;&nbsp;feed = new SyndFeedImpl();<br />&nbsp;&nbsp;feed.setFeedType("rss_2.0");<br />&nbsp;&nbsp;entries = new ArrayList();<br />&nbsp;}<br />&nbsp;<br />&nbsp;<br />&nbsp;public void createChannelImage(String title,String link,String url,String description) throws Exception{<br />&nbsp;&nbsp;SyndImage image = new SyndImageImpl();<br />&nbsp;&nbsp;image.setTitle(title);<br />&nbsp;&nbsp;image.setLink(link);<br />&nbsp;&nbsp;image.setUrl(url);<br />&nbsp;&nbsp;image.setDescription(description);<br />&nbsp;&nbsp;feed.setImage(image);<br />&nbsp;}<br />&nbsp;<br />&nbsp;/**<br />&nbsp; * 创建一个频道<br />&nbsp; * @param title　频道标题<br />&nbsp; * @param link　频道对应的连接<br />&nbsp; * @param description　频道描述<br />&nbsp; * @param language　频道所用语言<br />&nbsp; * @param pubDate　频道发布时期<br />&nbsp; * @param copyright　版权所有<br />&nbsp; * @throws Exception<br />&nbsp; */<br />&nbsp;public void createChannel(String title,String link,String description,String language,Date pubDate,String copyright) throws Exception{<br />&nbsp;&nbsp;feed.setTitle(title);<br />&nbsp;&nbsp;feed.setLink(link);<br />&nbsp;&nbsp;feed.setDescription(description);<br />&nbsp;&nbsp;feed.setLanguage(language);<br />&nbsp;&nbsp;feed.setPublishedDate(pubDate);<br />&nbsp;&nbsp;feed.setCopyright(copyright);<br />&nbsp;}<br />&nbsp;<br /><br />&nbsp;<br />&nbsp;/**<br />&nbsp; * 添加新闻子项<br />&nbsp; * @param title　标题<br />&nbsp; * @param link&nbsp;连接地址<br />&nbsp; * @param description　简单描述<br />&nbsp; * @param pubDate　发布日期<br />&nbsp; * @param category　所属范围<br />&nbsp; * @param author　发布作者<br />&nbsp; * @throws Exception<br />&nbsp; */<br />&nbsp;public void createItems(String title,String link,String description,Date pubDate,String category,String author) throws Exception {<br />&nbsp;&nbsp;entry = new SyndEntryImpl();<br />&nbsp;&nbsp;//设置新闻标题<br />&nbsp;&nbsp;entry.setTitle(title);<br />&nbsp;&nbsp;//设置新闻的连接地址<br />&nbsp;&nbsp;entry.setLink(link);<br />&nbsp;&nbsp;//设置新闻简介<br />&nbsp;&nbsp;SyndContent content = new SyndContentImpl();<br />&nbsp;&nbsp;content.setType("text/plain");<br />&nbsp;&nbsp;content.setValue(description);<br />&nbsp;&nbsp;entry.setDescription(content);<br />&nbsp;&nbsp;//设置发布时间<br />&nbsp;&nbsp;entry.setPublishedDate(pubDate);<br />&nbsp;&nbsp;//设置频道所属的范围<br />&nbsp;&nbsp;SyndCategory cate = new SyndCategoryImpl();<br />&nbsp;&nbsp;cate.setName(category);<br />&nbsp;&nbsp;List cateList = new ArrayList();<br />&nbsp;&nbsp;cateList.add(cate);<br />&nbsp;&nbsp;entry.setCategories(cateList);<br />&nbsp;&nbsp;//设置作者<br />&nbsp;&nbsp;entry.setAuthor(author);<br />&nbsp;&nbsp;//将新闻项添加至数组中<br />&nbsp;&nbsp;entries.add(entry);<br />&nbsp;}<br />&nbsp;<br />&nbsp;/**<br />&nbsp; * 添加新闻子项<br />&nbsp; * @param title　标题<br />&nbsp; * @param link&nbsp;连接地址<br />&nbsp; * @param description　简单描述<br />&nbsp; * @param pubDate　发布日期<br />&nbsp; * @param category　所属范围<br />&nbsp; * @param author　发布作者<br />&nbsp; * @param enclosure　流媒体播放文件地址<br />&nbsp; * @throws Exception<br />&nbsp; */<br />&nbsp;public void createItems(String title,String link,String description,Date pubDate,String category,String author,String enclosure) throws Exception {<br />&nbsp;&nbsp;entry = new SyndEntryImpl();<br />&nbsp;&nbsp;//设置新闻标题<br />&nbsp;&nbsp;entry.setTitle(title);<br />&nbsp;&nbsp;//设置新闻的连接地址<br />&nbsp;&nbsp;entry.setLink(link);<br />&nbsp;&nbsp;//设置新闻简介<br />&nbsp;&nbsp;SyndContent content = new SyndContentImpl();<br />&nbsp;&nbsp;content.setValue(description);<br />&nbsp;&nbsp;entry.setDescription(content);<br />&nbsp;&nbsp;//设置发布时间<br />&nbsp;&nbsp;entry.setPublishedDate(pubDate);<br />&nbsp;&nbsp;//设置频道所属的范围<br />&nbsp;&nbsp;SyndCategory cate = new SyndCategoryImpl();<br />&nbsp;&nbsp;cate.setName(category);<br />&nbsp;&nbsp;List cateList = new ArrayList();<br />&nbsp;&nbsp;cateList.add(cate);<br />&nbsp;&nbsp;entry.setCategories(cateList);<br />&nbsp;&nbsp;//设置作者<br />&nbsp;&nbsp;entry.setAuthor(author);<br />&nbsp;&nbsp;//设置流媒体播放文件<br />&nbsp;&nbsp;SyndEnclosure en = new SyndEnclosureImpl();<br />&nbsp;&nbsp;en.setUrl(enclosure);<br />&nbsp;&nbsp;List enList = new ArrayList();<br />&nbsp;&nbsp;enList.add(en);<br />&nbsp;&nbsp;entry.setEnclosures(enList);<br />&nbsp;&nbsp;//将新闻项添加至数组中<br />&nbsp;&nbsp;entries.add(entry);<br />&nbsp;}<br />&nbsp;/**<br />&nbsp; * 生成XML文件<br />&nbsp; * @param filePath　文件保存路径和名称<br />&nbsp; * @throws Exception<br />&nbsp; */<br />&nbsp;public void buildChannel(String filePath) throws Exception {<br />&nbsp;&nbsp;feed.setEntries(entries);<br />&nbsp;&nbsp;SyndFeedOutput output = new SyndFeedOutput();<br />&nbsp;&nbsp;Writer writer; <br />&nbsp;&nbsp;writer = new OutputStreamWriter(new FileOutputStream(filePath), "UTF-8");<br />&nbsp;&nbsp;output.output(feed, writer);&nbsp; <br />&nbsp;}<br />}</p>
<p>&nbsp;</p>
<p>　　让我们的项目负责人看了，他要我把createItems()方法中的多个参数再封装一个类，让用户传的时候只传一个包含这个类的List对象，想来想去就是不明白，为什么要这样呢？</p>
<p>　　按照我现在的写法的话，别人用的时候也不用再写什么特别的类啦，只用把自己从数据库里查询出来的结果的对象以参数的形式传递过来就可以啦，这样不就更简单啦。</p>
<p>　　为什么一定要传一个List对象呢？</p>
<p>　　写工具类的时候有什么特别的要求吗？</p>
          <br/>
          <span style="color:red;">
            <a href="http://jackzhangyunjie.javaeye.com/blog/213854#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北