??xml version="1.0" encoding="utf-8" standalone="yes"?> 那么Q我们可不可以通过E序讄一定的旉Q当E序q行过该时长后自行l止或者进行其他操作呢? 查了大量资料后发玎ͼFuturecd能满个需求?/p> FuturecM重要Ҏ包括get()和cancel()?/p> get()获取数据对象Q如果数据没有加载,׃d直到取到数据Q?cancel()是取消数据加载?/p> 另外一个get(timeout)操作Q表C如果在timeout旉内没有取到就p|q回Q而不再阻塞?/p> 通过q些Ҏ卛_实现我们要求?/p> Java 代码CZQ?/p> final ExecutorService exec = Executors.newFixedThreadPool(1); Callable public String call() throws Exception { // 攑օ耗时操作代码?/p> int cash = 300; String name = "张三"; System.out.println(name + "现在? + cash + "元存?); User u = new User(name, cash); String[] arr = { "U程A", "U程B", "U程C", "U程D", "U程E", "U程F", "U程G", "U程H", "U程I", "U程J" }; for (int i = 0; i < 10; i++) { MyThread th = new MyThread(arr[i], u, (int) (Math.random() * 1000 - 500)); th.start(); } //耗时代码块结?/p> Thread.sleep(1000 * 5); return "U程执行完成"; } }; try { Future String obj = future.get(1000 * 1, TimeUnit.MILLISECONDS); // d处理时旉设ؓ1 U?/p> System.out.println("d成功q回:" + obj); } catch (TimeoutException ex) { System.out.println("处理时?..."); System.exit(0); } catch (Exception e) { System.out.println("处理p|."); e.printStackTrace(); } exec.shutdown(); // 关闭U程?/p> 耗时的代码块攑օ标注的地方后Q即可满求?/p> System.out.println("处理p|."); e.printStackTrace(); System.out.println("处理p|."); e.printStackTrace(); 在该CZE序中,当运行超时后Q执行的是退出程序的操作?/p> 也可以根据需要放入其他代码进行相x作?/p> 例如可以讄当处理超时时忽?该错误l向下执?/p>
]]>
]]>
]]>
]]>
是在服务?/a>端v作用,当用forward()?Servlet engine传递HTTPh从当前的Servlet or JSP到另外一个Servlet,JSP 或普通HTML文g,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此时form提交的所有信息在 b.jsp都可以获?参数自动传? 但forward()无法重定向至有frame的jsp文g,可以重定向至有frame的html文g,同时forward()无法在后面带参数传?比如servlet?name=frank,q样不行,可以E序内通过response.setAttribute("name",name)来传至下一个页面?/p>
重定向后览器地址栏URL不变?/p>
例:在servlet中进行重定向 通常在servlet中用,不在jsp中用?/p>
2. response.sendRedirect() 是在用户的浏览器端工?sendRedirect()可以带参C?比如servlet?name=frank传至下个面,同时它可以重定向至不同的L?sendRedirect()可以重定向有frame.的jsp文g. 重定向后在浏览器地址栏上会出现重定向面的URL 例:在servlet中重定向 ׃response是jsp面中的隐含对象Q故在jsp面中可以用response.sendRedirect()直接实现重定位?/p>
注意Q?/strong> (1) 使用response.sendRedirectӞ前面不能有HTML输出Q?/p>
qƈ不是l对的,不能有HTML输出其实是指不能有HTML被送到了浏览器。事实上现在的server都有cache机制Q一般在8KQ我是说 JSP SERVERQ,q就意味着Q除非你关闭了cacheQ或者你使用了out.flush()强制hQ那么在使用sendRedirect之前Q有量的HTML输出也是允许的?/p>
(2) response.sendRedirect之后Q应该紧跟一句return?/p>
我们已经知道response.sendRedirect是通过览器来做{向的Q所以只有在面处理完成后,才会有实际的动作。既然你已经要做转向了,那么后的输出q有什么意义呢Q而且有可能会因ؓ后面的输出导致{向失败?/p>
比较Q?/strong> (1) Dispatcher.forward()是容器中控制权的转向Q在客户端浏览器地址栏中不会昄{向后的地址Q?/p>
(2) response.sendRedirect()则是完全的蟩转,览器将会得到蟩转的地址Qƈ重新发送请求链接。这P从浏览器的地址栏中可以看到跌{后的链接地址?/p>
前者更加高效,在前者可以满需要时Q尽量用RequestDispatcher.forward()Ҏ?/p>
注:在有些情况下Q比如,需要蟩转到一个其?a class="channel_keylink" target="_blank">服务?/a>上的资源Q则必须使用HttpServletResponse.sendRequest()Ҏ?/em>public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{ response.setContentType("text/html; charset=gb2312"); ServletContext sc = getServletContext(); RequestDispatcher rd = null; rd = sc.getRequestDispatcher("/index.jsp"); //定向的页面 rd.forward(request, response);}public void doPost(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException
{
response.setContentType("text/html; charset=gb2312");
response.sendRedirect("/index.jsp");
}
]]>
scp 文g?nbsp; root@q程ip:/路径/
本地home目录下的test.tar的文件拷贝到q程L192.168.1.23?home/adm/目录下,则命令ؓQscp /home/test.tar root@192.168.1.23:/home/adm/ 回R后输入密码就可以?br />
scp提供了几个选项 在scp后加p?br />
-p 拯文g的时候保留源文g建立的时间?br />
-q 执行文g拯Ӟ不显CZQ何提C消息?br />
-r 拯整个目录
-v 拯文gӞ昄提示信息?br />
二、linux中cp强制覆盖拯
1Q?取消cp的alias,不是怹生效
#unalias cp
#cp a /test/a
2Q??\cp 执行cp命o时不走alias
#\cp a /test/a
3Q?Blinux最开始有自己的方?br />
]]>
构造函C下面开始在map中初始化自己的events属?
this.events = new OpenLayers.Events(this,
this.div,
this.EVENT_TYPES,
this.fallThrough,
{includeXY: true});
再往下就注册?
if(this.eventListeners instanceof Object) {
this.events.on(this.eventListeners);
}
通过map自己的Events属?其实也是个object,是eventscȝ实例)中的onq个函数注册上,
我们要进入OpenLayers.Eventsc?br />---------------------------------------------------------------------------
---------------------------------------------------------------------------
看这个onҎ
/**
* Method: on
* Convenience method for registering listeners with a common scope.
*
* Example use:
* (code)
* events.on({
* "loadstart": loadStartListener,
* "loadend": loadEndListener,
* scope: object
* });
* (end)
*/
on: function(object) {
for(var type in object) {
if(type != "scope") {
this.register(type, object.scope, object[type]);
}
}
},
onq个函数参数q是W一步中我们传入的eventListenersQ就是那个哈希表
遍历Q这个“scope”键值是事g的“生源”对象,是q个键值对应的对象触发我们注册的事?br />register(type, object.scope, object[type])
type是事g名称
object[type]是处理事g的函数名
可以看一下第一步中传入的参?
eventListeners: {
"moveend": mapEvent,
"zoomend": mapEvent,
"changelayer": mapLayerChanged,
"changebaselayer": mapBaseLayerChanged
}
再进入eventscȝ另一个函?this.register(type, object.scope, object[type])
/**
* APIMethod: register
* Register an event on the events object.
*
* When the event is triggered, the 'func' function will be called, in the
* context of 'obj'. Imagine we were to register an event, specifying an
* OpenLayers.Bounds Object as 'obj'. When the event is triggered, the
* context in the callback function will be our Bounds object. This means
* that within our callback function, we can access the properties and
* methods of the Bounds object through the "this" variable. So our
* callback could execute something like:
* : leftStr = "Left: " + this.left;
*
* or
*
* : centerStr = "Center: " + this.getCenterLonLat();
*
* Parameters:
* type - {String} Name of the event to register
* obj - {Object} The object to bind the context to for the callback#.
* If no object is specified, default is the Events's
* 'object' property.
* func - {Function} The callback function. If no callback is
* specified, this function does nothing.
*
*
*/
register: function (type, obj, func) {
if ( (func != null) &&
(OpenLayers.Util.indexOf(this.eventTypes, type) != -1) ) {
if (obj == null) {
obj = this.object;
}
var listeners = this.listeners[type];
listeners.push( {obj: obj, func: func} );
}
},
到这里,我们能看到我们所说的核心Q那个哈希表Q把自己的值都赋给了eventscȝ一个属?listeners
/**
* Property: listeners
* {Object} Hashtable of Array(Function): events listener functions
*/
listeners: null,
q个事g机制的核心哈希表Q键名就是事件的名称,也就是参C的type,键值是一个对象{obj: obj, func: func}
当然q个对象中还有对象。。。?/p>
现在事g已经注册上了Q还有一个问题,register函数中提Cthis.eventTypesQthis.object
所以我们再回来看下eventscȝ构造函数?br />mapcM实例化events属性的情景:
this.events = new OpenLayers.Events( this, //指的是map
this.div,
this.EVENT_TYPES,
this.fallThrough,
{includeXY: true});
我们可以和eventscȝ构造函数对比一下参敎ͼ׃明白了?
/**
* Constructor: OpenLayers.Events
* Construct an OpenLayers.Events object.
*
* Parameters:
* object - {Object} The js object to which this Events object is being
* added element - {DOMElement} A dom element to respond to browser events
* eventTypes - {Array(String)} Array of custom application events
* fallThrough - {Boolean} Allow events to fall through after these have
* been handled?
* options - {Object} Options for the events object.
*/
initialize: function (
object,
element,
eventTypes,
fallThrough,
options)
{
OpenLayers.Util.extend(this, options);
this.object = object;
this.element = element;
this.fallThrough = fallThrough;
this.listeners = {};
// keep a bound copy of handleBrowserEvent() so that we can
// pass the same function to both Event.observe() and .stopObserving()
this.eventHandler = OpenLayers.Function.bindAsEventListener(
this.handleBrowserEvent, this
);
// if eventTypes is specified, create a listeners list for each
// custom application event.
this.eventTypes = [];
if (eventTypes != null) {
for (var i=0, len=eventTypes.length; i<len; i++) {
this.addEventType(eventTypes[i]);
}
}
// if a dom element is specified, add a listeners list
// for browser events on the element and register them
if (this.element != null) {
this.attachToElement(element);
}
},
上面events的初始化是发生在map的初始化中,this.events.on(this.eventListeners);之前的,所以上面提到的register函数中的this.eventTypesQthis.object 明意思了Q?br /> this.object(this是指的eventsc?是map,也就是说map是我们第一步传入参C的注册事件的“发生源”,Q比如button是onclik的“发生源”,“发生源”是本h自定义的。。不知道是否有合适的U呼Q术语应该就是srcElementQ?br />this.eventTypes(this是指的eventsc?是mapcM定义的一个常?this.EVENT_TYPES(this是指的mapc?
查到mapcM的这个常?EVENT_TYPES: [
"preaddlayer", "addlayer", "removelayer", "changelayer", "movestart",
"move", "moveend", "zoomend", "popupopen", "popupclose",
"addmarker", "removemarker", "clearmarkers", "mouseover",
"mouseout", "mousemove", "dragstart", "drag", "dragend",
"changebaselayer"],
所以我们在初始化map的时候传入的参数中,注册的事仉是来自于q个帔R中的
MapGuide ?/span> Fusion 框架最为核心的地图 Widget Q就是采用了 OpenLayers 框架?/span> Fusion 框架?/span> OpenLayers q行包装Qؓ其添加了更多的功能,从而之能够更W合 Fusion 框架q与其余 Fusion lgq行交互?br />
非常有趣的是Q由?/span> OpenLayers 所采用的术语跟 Fusion 采用的ƈ不是十分一_甚至 Fusion 不同部分采用的术语也不是十分一_所以同一个名字在不同地方表达的意思却很可能ƈ不相同。所以,在详l介l?/span> Fusion 如何?/span> OpenLayers q行包装之前Q有必要对两者之间的术语q行一下区分,以免当您阅读到相x料时感到疑惑?/span>
OpenLayers 认ؓQ用L到的由多个图?/span> (layer) l成的一张地?/span> (map) 。地图本w与加蝲的数据源格式无关Q与数据源格式相关的是图层。因此,地图cd有一个( OpenLayers.Map Q,而图层类却有很多Q这些类都以 OpenLayers.Layer 作ؓ命名I间Q如 OpenLayers.Layer.Google/Yahoo/MapGuide/WMS/Vector {等?/span>
q样的结构有一个问题,那就是所有的囑ֱ之间是^行的关系Q这是很不利于图层管理的。我们假设有q样一张地图:该地囑含有十二个图层,有九个来自于不同数据源的囑ֱ和三个位于顶层的 Vector 层。那么,我如果想用代码去处理所?/span> Vector 的层Q就必须遍历所有的层,依次比较是不?/span> Vector 层,再对 Vector 层进行处理。解册个问题的Ҏ很简单,那就是引入层U结构,允许用户把图层分l。比如上面的例子中,把三?/span> Vector 分成一l,比如命名为“标记”组Q届时只需要对标记l中的每一个层q行处理卛_?/span>
q也正是 Fusion 对于 OpenLayers 众多改进中的一个。而问题也正是q里引入的:地图 Widget 在给q种层l构命名的时候,Zh意料地采用了另外的命名方式:地图 Widget 把图层组命名为“地囄?/span> (map group) Q把l里面的囑ֱ命名?/span> (map) 。下面代码是CZ数据?/span> Library://Samples/Sheboygan/FlexibleLayouts/Slate.ApplicationDefinition 布局文g对于地图定义的那一部分Q用户可以在 MapGuide Studio 中通过点击位于 Map 面板上的 “Edit Map Group?/span> 按钮来查看这部分内容?/span>
<?xml version="1.0" encoding="utf-8"?> <MapSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <MapGroupType id="Sheboygan"> <Map> <Type>MapGuide</Type> <SingleTile>true</SingleTile> <Extension> <ResourceId>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</ResourceId> <SelectionAsOverlay>true</SelectionAsOverlay> <SelectionColor>0x0000FFA0</SelectionColor> </Extension> </Map> <Extension /> </MapGroupType> </MapSet> |
布局文g中地囑֮义的部分代码
其实Q?/span> MapGuide q样做是有原因的。这个问题源于不同品之间定位的不同Q?/span> OpenLayers 框架的目的是在同一张地图上面显C多个数据源。所以在 OpenLayers 看来Q一个来?/span> MapGuide 的地图仅仅是一个层而已。然而,?/span> MapGuide 内部Q一?/span> MapGuide 地图内是包含多个 Layer Q具体表现就是一?/span> MapDefinition 里可以包含多?/span> LayerDefinition 。所以,如果 Fusion ?/span> MapGuide 叫做一?/span> Layer 的话Q又该如何称呼里面的 Layer 呢?
鉴于q样的考虑Q?/span> Fusion 才做了这U概念上的映: Fusion 中的地图 Widget 对应 OpenLayers 里面的地图; Fusion 里面的地囄是一个逻辑概念Q从而Ş成一U逻辑上的层l构以便理Q?/span> Fusion 中的地图实际对应?/span> OpenLayers 里面的图层?/span>
但事情到q里q没有结束,接下来的事情可能会让您有些意外:在编写地?/span> Widget 实现代码ӞZ能够便于?/span> OpenLayers 中的cd应v来, Fusion 地图(也就?/span> OpenLayers 中的囑ֱQ称?/span> Layers Q注意,不是 Layer Q,q要求每一个地囄代码都承自 Fusion.Layers 。比如, MapGuide ?/span> Layers 的名U就叫做 Fusion.Layers.MapGuide ?/span>
下表ȝ?/span> Fusion ?/span> OpenLayers 之间q种概念映射关系
Fusion 概念 |
Fusion 代码命名 |
OpenLayers 概念 |
OpenLayers 代码命名 |
地图 |
Fusion.Layers |
囑ֱ |
OpenLayers.Layer |
地图l?/span> |
|
无对应概?/span> |
|
地图 Widget |
Fusion.Widget.Map |
地图 |
OpenLayers.Map |
Fusion ?/span> OpenLayers 之间的概忉|关p?/span>
在阅?/span> Fusion ?/span> OpenLayers 的源代码或学习他们的 API Ӟ一定要注意两者术语上的区别?/span>
本节中,我们提到?/span>
Fusion
引入了地囄q一个概c这只是
Fusion
对于
OpenLayers
众多改动中的一个。下面我们来看看到底
Fusion
?/span>
OpenLayers
q做了哪些改动?/span>
Fusion 对于 OpenLayers 的改q?
Z便于 Fusion 的其他组件能够与地图q行交互Q?Fusion 对于 OpenLayers q行了较为全面的包装。一般来_如果您不是开?Fusion.Layers 的开发h员,除了使用一?OpenLayers 的一些工h的函数之外Q您甚至都不需要知?OpenLayers 的存在。但是,仅仅q行包装是不够的Q由?OpenLayers ?Fusion 定位的不同, Fusion 必须?OpenLayers q行扩展才能适应更ؓ复杂的模型?
1. Fusion 中添加了选择集的概念?OpenLayers 在同一张地N面显C多U不同数据源的方面确实做的很好,遗憾的是Q它~少选择集这一臛_重要的概c对?OpenLayers 来说Q选择集完全是可有可无的,因ؓ它的目的在于地囑ֱC出来,而且Q很多地图根本就没有选择集这L API Q比?Google 地图{等。但对于 Fusion 则不同,我们很难惌没有选择集,用户该如何利?MapGuide q行理。所以, Fusion 加入了选择集这个概念,q且要求实现 Layers 的地图(比如 MapGuide Q实现选择集功能。我们可以看刎ͼ Fusion.Widget.Map 中不但有诸如 get/set/clear/hasSelection q样控制和读取选择集的函数Q而且?MAP_SELECTION_ON ?MAP_SELECTION_OFF q两个事件来通知监听者地N择集的当前状况?
2. Fusion 开放了更多的事件。借助?Fusion 自己独立实现的事件机Ӟ Fusion 允许用户接收到更多种cȝ事gQ比?Session 是否已创建、地囑ֽ前忙与否、选择集状态变更、当前图层(q个?Fusion 中的囑ֱQ不?OpenLayers 的)变化{等?
3. Fusion 允许地图的实现类q回自n支持哪些比例,q就使得用户可以直观的知道自己当前羃攑֜囑ֈ什么程度?
4. 允许用户随时讄当前地图的背景图片和地图上的光标形状。这对于直观地反应地囑ֽ前状态是是否有用的?
5. 支持右键菜单。虽然在览器上实现右键菜单相对单一些,但是通过使用地图 Widget ?setContextMenu Q代码编写者就可以直接把已l准备好?div 作ؓ右键菜单Q再也不需要直接与底层鼠标事g打交道了?
地图的定?
前面在介l?Fusion ?OpenLayers 术语不同的时候,摘录了应用程序定义中对于地图部分的定义。通过解析q个定义Q?Fusion 了解了应该如何加载该地图。下面,我们来看看q个定义中到底都定义了哪些东ѝ?
?Fusion 中,一个地囄用一?MapGroup q行标签定义Q?MapGroup 里面?Map 标签是对于一个地囄定义了?
1. Type: 该标{标CZ地图的类型。所?MapGuide 地图该标{值均?MapGuide 。当 Fusion d到该地图?Type Ӟ׃用对应的 “Fusion.Layers. 标签??来初始化该地图。比?MapGuide 地图׃?Fusion.Layer.MapGuide 来初始化?
2. SingleTile: 如果该项为真Q则表示该项不采用分块服务?
3. Extension: 该于扩展 Map 标签Q来为地囑ֈ始化提供更多的信息。各?Fusion.Layers 的实现类可以自行军_光要的内容Q以及如何解释这些内宏V对?MapGuide 而言Q有以下常见的扩展:
a) ResourceId: MapDefinition 的资?Id Q通过?Id Q?Fusion 可以知道加蝲哪一个地囑֮义?
b) SelectionAsOverLay: 如果该项?true Q那么将会?GETDYNAMICOVERLAY 来获取地图,否则采用 GETMAPIMAGE 来获取地图。前者是新版本才支持的,可以把选择集和地图本nl制成两张地图。如果您使用?MapGuide 版本比较旧,您可以把该项讄成ؓ false
c) SelectionColor: 该项表示用什么颜色来昄选中的要素?
现在成熟的地囑^台均不同E度上支持瓦片生成方式,而且每个WebGIS产品均有各自不同的瓦?Tile)l织方式。MapGuide OS/E 的和Bing Map、Google Map、TMS的组l方式有很大不同Q如果可以知道存储方式就可以自己实现MapGuide ProviderQ部|地图时则不需要安装MapGuide OS/E。现分析下以供有~h使用?/p>
public override Uri GetUri(int x, int y, int zoomLevel)
{//适用于MS Silverlight mapControlQxy列号QzoomLevel为当前地图比例?br /> string tileRowGroup = “?
string tileColGroup = “?
if (x >= 0 && y >= 0 )
{
tileRowGroup += (Math.Floor(x/tileRowsPerFolder) * tileRowsPerFolder).ToString();//tileRowsPerFolder=30
tileColGroup += (Math.Floor(y / tileColumnsPerFolder) * tileColumnsPerFolder).ToString();
string tilePath = ?S?+ Math.Floor(zoomLevel)
+ ??+ basemaplayergroupname
+ ?R?+ tileRowGroup
+ ?C?+ tileColGroup
+ ??+ (x % tileRowsPerFolder)
+ “_?+ (y % tileColumnsPerFolder)
+??+ this.format;//png
return new Uri(this.url + tilePath);
}
return null;
}