YuBo's profileyoung98PhotosBlogListsMore ![]() | Help |
|
July 06 天津行(三) 就这样,五一节后我被迫在天津多呆12天...... 时值猪流感开始流行之时,并且赴津后第四天开始觉得喉咙有点痛,于是周末只能呆在酒店养病。 话说天津的泰诺只要9块5毛钱。 工作上还好不是很忙,所以也不算太遭。班车的司机仍然蛮横。 最后一天坐班车回酒店居然还坐错车,到一半的地方就说必须全部下车了。我无奈,司机说可以再多带我一段,一路上都是教训我的话。我只回了他一句:“没下次了。” 因为没有带自己的笔记本电脑,所以2个礼拜晚上都在看吴宗宪的《王牌大明星》。感觉吴宗宪真是有够逗,是我学习的榜样。 最后的回沪之旅是一个人。第一次一个人坐飞机,不过因为已经是经验丰富,所以没什么太多波折。在飞机上全程戴着口罩,这里要谢谢客户公司的同事,帮我问他们厂里医务室要了个口罩。 工作后的第一次出差就这么结束了,也算是去过我国的北方了,呵呵。 June 12 天津行(二)就这样,我被公司发配到天津出差24天......
工作日:
2009-4-12 ~ 2009-4-29
06:10 起床
06:30 出门去等班车
07:35 到客户公司厂区
08:00 吃完早饭(一般是蒙牛早餐牛奶加3个萨其马),上开心网
08:15 开始工作
12:00 去工厂食堂吃午饭
12:30 吃完回来再上会开心
13:00 开始工作
17:00 下班,收拾东西坐班车会酒店
18:20 到酒店,去“大成家”吃晚饭
19:00 吃完晚饭到达酒店,稍做整顿,上会网,或者看看书,或者看看电视
21:30 洗澡
22:00 上床睡觉
2009-4-30
最后一天了,很兴奋,中午吃完饭就出发了,坐在飞机上时很激动,因为过完五一还要回天津,所以非常珍惜五一假期。坐在从机场到家的出租车上差点情不自禁唱起歌来。听到了久违的上海话,好亲切呀......
双休日:
2009-4-18(星期六)
在天津的网友带我逛天津。去了天津大学,南开大学,鼓楼,文化街,海河沿岸的酒吧街(在建)等地方,吃了耳朵眼炸糕(不咋地,其实上海也有类似小吃),吃了所谓正宗天津菜(很难吃,不过也许这就是人家的口味,不好乱说话),买了纪念品。
2009-4-19(星期天)
在酒店休息
2009-4-25(星期六)
早上坐和谐号城际列车到达北京,下午参观鸟巢水立方,晚上吃了全聚德烤鸭。
2009-4-26(星期天)
早上起得很晚,匆匆吃了点麦当劳下午去了天安门故宫及天坛公园(天坛没进去,去得太晚了),晚上吃了KFC,坐和谐号城际列车返回天津。
April 11 天津行(一)就这样,我被公司发配到天津出差24天......
2009-04-07
早上老大早(7点)赶到虹桥机场。
坐上飞机后我才意识到我要去出差了,莫名地有些兴奋......这可是我工作以来第一次出差哦!不是谁说过么,第一次都很珍贵的......哈哈。
飞机下来,已经是10点15分的样子。没有感觉到干燥,叫了车赶到客户工厂。
客户工厂在郊区,路很难走,应该说极端难走......工厂周围极端荒凉,甚至还有坟地......
稍事工作交接,去工厂食堂吃饭。这可是我到天津的第一顿饭啊。食堂的菜么......味道方面还过得去,就是......这菜总让我觉得乱七八糟的,不是一样样的......
下班后坐客户的厂车去酒店。因为带大箱子上车还跟司机大爷闹了点小误会,大爷的天津话真是......居然完全听不懂......
在车上居然发现邻座的MM在拿小P(这个称呼还真是不太习惯......)看《ありふれた奇跡》,于是聊了起来。了解到天津最热闹的地方原来叫滨江道。
晚上打车去了大卖场。天津的出租车起步费8元,1.7元/公里。
在一家叫“大成家”的中式快餐店吃了晚饭,居然是买一送一,赚到了......
2009-04-08
早上6点40分的厂车......好早......
客户工厂里早上还要做广播体操......
中午吃饭才发现食堂里装了监视摄像装置,谁要是浪费的话,哼哼......还好,我们不受管制......
下午5点下班,可到了5点20分厂车才发车,到酒店都快晚上6点40分了......直接去大成家吃晚饭,又是买一送一,呵呵......
2009-04-09
早上太早啦......还好某人给了我一个小垫枕,(某人真是太谢谢啦,么么)可以在车上睡会。
现在早饭全是牛奶加面包,天津牛奶没“光明”的,只好喝蒙牛了。还有这里大卖场居然没日清方便面!也没立丰牛肉干,只好吃棒棒娃了......
晚上网友来电说周末的北京之行需要延期......好吧,周末一个人到滨江道兜一圈吧。
2009-04-10
总算熬到周五啦......
总算能晚睡晚起啦......
总算能有一个完整的晚上啦......
可是居然被同事拉去玩什么《三国杀》游戏......
晚饭也没吃陪他们玩到晚上10点30分,我诈称明天要早起,想走,于是他们也散了,搞得我有点负罪感的闹。
到了酒店一边上网一边泡面果腹了......
2009-04-11
早上醒过来就很纠结:到底是出去吃早饭还是继续睡,或者吃泡面当早饭呢?后来不知不觉就继续睡了,呵呵。
中午背着包就出发啦,天津半日游,哈哈,这里不多说了详见照片了。
March 14 ミシェル・コラン・ドレジェ シュヴァリエ・モンラッシェ(2000)このワインは、巨大でけわしい
孤高の頂は神秘に包まれ、わたしを誘う 高い理想をいだき、はやる気持ちを抑えながら 踏み締めるようにわたしは、頂を目指した 困難な道のりは、あらぶる魂となって牙を向き まものに魅入られたかのような執念を駆り立てる どれだけの時が流れたのか、わたしは気がつくと頂に立っていた 眼下の峰、すべてはひれふすように美しく沈黙し 岩はだに張り付く白銀は、絹のドレスをまとうかのように なめらかに輝いている なんと言う至福、なんと言う透明 この頂からすべてを鳥瞰できる喜び わたしは、それを胸にいっぱい吸い込み 頂を後にした...... March 11 庸人自扰吞下绿药丸,你将在自己的床上舒服地醒来。或者吞下红药丸,我将引领你去到兔子洞的深处......
最近一周的早上,起床时总有一种“啊,我又回来了。”的感觉。 每天都会有很多事,却又好像什么都没做。 白天上班会突然发呆很久。 晚上忙于应酬。说是被迫到处应酬,还不如说是我拼命想去应酬。 上周六表弟结婚,领教了一下西郊宾馆4位数住一天的房间。感觉......和连锁酒店的区别也不是特别大吧,就是家具豪华些,东西还是那几样,房间比较大而已。当然周围的环境肯定比连锁酒店出色多了,丹顶鹤,黑天鹅......
结婚是件高兴的事情,至少表面上是高兴的事情。 感觉能让我真正高兴的事情变得越来越少,很多时候是出于需要,表面高兴一下,去高兴别人的高兴。 梦里经常遇到被追赶的场景,感觉无处可逃,躲到哪里都会被追杀。 唉......
February 04 033-使用JCo远程调用SAP系统函数要用Java程序远程调用ABAP函数可以使用SAP提供的RFC针对Java程序的API——JCo。
0.JCo的安装
很不幸,虽然JCo是用Java语言编写的但却是平台相关的。(具体来说,JCo的Java包sapjco.jar确实是平台无关的,但是运行JCo需要RFC库支持,而RFC库是平台相关的) 目前为止我还只有在Windows系统中安装的版本,因为JCo不是一个开源组件,甚至在SAP官方下载它是需要SAP Service MarketPlace的用户帐号的。目前我手上的是JCo2.1.6Windows版本。 除了API文档和一些DEMO程序,你需要用到的有3个文件:librfc32.dll,sapjcorfc.dll,sapjco.jar。 安装配置步骤如下:
(1).将sapjco.jar导入到你的项目库路径中。SAP官方的指导是要你配置CLASSPATH,这种方法在我看来不值得提倡,因为eclipse或netBeans这样的IDE可以帮你轻松导入jar库而无需摆弄系统环境变量。 (2).将sapjcorfc.dll文件拷贝至sapjco.jar所在的文件夹中。注意,这两个文件必须放在同一个文件夹里,它们俩必须像热恋中的情人一样一直黏在一起才能使JCo正常工作。 (3).将librfc32.dll文件拷贝至C:\WINDOWS\system32中。如果系统中已安装过SAP客户端,那么可能本来就已经有一个librfc32.dll在那里了,SAP官方要求你覆盖那个文件,这是一种很不负责的方法。当你覆盖这个文件后很可能你的SAPLogon就无法工作了。正确的做法是备份原来的文件,然后尝试覆盖后使用SAPLogon,如果出问题了,把原来那个文件找回来。我在安装了710 Final Release版本的SAPLogon机器上使用原来的librfc32.dll运行JCo目前还没有发生什么异常。 好了,到现在为止,JCo算是安装好了,我们可以开始编写程序了。
1.使用JCo调用远程ABAP函数
使用Java程序远程调用ABAP函数的大致流程是这样地:先要有SAP系统所在服务器的IP地址、要登录的SAP系统的客户端号、系统编号、用户名、用户密码,有了这些后,就可以建立一个到该SAP系统的连接,然后在这个连接上调用允许远程调用的函数,得到调用后的结果,关闭连接。 这其中牵涉到一些细节,我们先看程序: package jcousage;
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO; import java.util.Properties; public class TestJCo {
public static void main(String[] args) {
/*获得一个到SAP系统的连接 START */ Properties logonProperties = new Properties(); logonProperties.put("jco.client.ashost","192.168.1.123"); //系统的IP地址 logonProperties.put("jco.client.client","800"); //要登录的客户端 logonProperties.put("jco.client.sysnr","00"); //系统编号 logonProperties.put("jco.client.user","young98"); //登录用户名 logonProperties.put("jco.client.passwd","password"); //用户登录口令 //用上述条件创建一个连接对象 JCO.Client myConnection = JCO.createClient( logonProperties ); /*获得一个到SAP系统的连接 END */ myConnection.connect(); //进行实际连接 //如果连接不为null并且处于活动状态 if (myConnection != null && myConnection.isAlive()) { //从连接获得一个逻辑意义上的“仓库”对象(Repository) JCO.Repository myRepository = new JCO.Repository("Repository", //只是一个名字 myConnection); //活动的连接 //要调用的SAP函数名称 String strFunc = "BAPI_FLIGHT_GETLIST"; //从“仓库”中获得一个指定函数名的函数模板 IFunctionTemplate ft = myRepository.getFunctionTemplate(strFunc.toUpperCase()); //从这个函数模板获得该SAP函数的对象 JCO.Function function = ft.getFunction(); //获得函数的import参数列表 JCO.ParameterList input = function.getImportParameterList(); //设定一个import参数的值。参数名为“MAX_ROWS”,设定值为10
input.setValue(10, "MAX_ROWS"); /*设定结构参数 START */
//如果参数是一个结构,用参数名获得一个对应类型的结构对象 JCO.Structure sFrom = input.getStructure("DESTINATION_FROM"); //设定结构中的变量。变量名为“CITY”,设定值为“NEW YORK” sFrom.setValue("NEW YORK", "CITY"); //将处理好的结构赋给该参数 input.setValue(sFrom, "DESTINATION_FROM"); /*设定结构参数 END */ /*设定table参数 START */ //用参数名获得一个对应类型的内部表对象 JCO.Table tDateRange = function.getTableParameterList().getTable("DATE_RANGE"); //接下来基本属于体力活了......
//新增一条空行 tDateRange.appendRow(); //定位到第0行 tDateRange.setRow(0); //设定该行对应变量 tDateRange.setValue("I", "SIGN"); tDateRange.setValue("EQ", "OPTION"); tDateRange.setValue("20040330", "LOW"); //新增一条空行
tDateRange.appendRow(); //定位到第1行 tDateRange.setRow(1); //设定该行对应变量 tDateRange.setValue("I", "SIGN"); tDateRange.setValue("EQ", "OPTION"); tDateRange.setValue("20040427", "LOW"); //...... /*设定table参数 END */ //执行函数 myConnection.execute(function); //在执行函数后可用相同方式获得输出结果
JCO.Table flights = function.getTableParameterList().getTable("FLIGHT_LIST"); //JCO.Table对象可以直接输出到html文件 flights.writeHTML("C:/function.html"); //也可以如下单独获得表中个别变量 System.out.println("Airline" + "\t\t" + "from city" + "\t" + "to city" + "\t\t" + "departure time" + "\t\t" + "price" + "\t" + "CURR"); for (int i = 0; i < flights.getNumRows(); i++) { flights.setRow(i); System.out.println(flights.getString("AIRLINE") + "\t" + flights.getString("CITYFROM") + "\t" + flights.getString("CITYTO") + "\t" + flights.getDate("FLIGHTDATE") + "\t" + flights.getDouble("PRICE") + "\t" + flights.getString("CURR")); } //断开连接 myConnection.disconnect(); } else { System.out.println(false); } }
}//:~ 首先,将连接需要的信息放到一个Properties里,对应的键值都是固定的。需要注意的是给定的用户名必须有足够的权限进行远程调用。
JCO.Client myConnection = JCO.createClient( logonProperties ); 这样就创建了一个到SAP系统的连接对象了。接着只要在这个对象上调用connect()方法就能激活连接。为了保证这个连接确实可用,加上这一句: if (myConnection != null && myConnection.isAlive()) 接下来比较麻烦,先要从这个活动的连接上拿到一个“仓库”,然后从这个“仓库”里拿到函数模板,再从函数模板里拿到对应函数对象。 JCO.Repository myRepository = new JCO.Repository("Repository", //只是一个名字 myConnection); //活动的连接 String strFunc = "BAPI_FLIGHT_GETLIST"; IFunctionTemplate ft = myRepository.getFunctionTemplate(strFunc.toUpperCase()); JCO.Function function = ft.getFunction(); 整个过程很唬人,其实也就那么回事。这里我们调用的是一个叫“BAPI_FLIGHT_GETLIST”函数,这个函数在SAP系统中被声明为Remote-Enabled Module,能够被远程调用的函数都必须声明为Remote-Enabled Module。 好了,我们现在有函数对象了。我们知道,SAP函数主要就是有5个输入输出接口:Import、Export、Changing、Tables、Exceptions。其中除了Changing在远程调用中是不被允许的外,其他都是可用的属性: Import:通过在函数对象上调用getImportParameterList()方法获得Import变量列表。 JCO.ParameterList input = function.getImportParameterList(); Export:在函数被执行后通过在函数对象上调用getExportParameterList()方法获得Export变量列表。 JCO.ParameterList output = function.getExportParameterList(); Changing:不支持。 Tables:通过在函数对象上调用getTableParameterList()方法获得Tables变量列表。 JCO.ParameterList tables = function.getTableParameterList(); Exceptions:可通过在函数对象上调用getExceptionList()方法获得Exceptions变量数组,也可调用getException(java.lang.String key)获得单个异常对象。 JCO.AbapException[] abapExceptions = function.getExceptionList(); JCO.AbapException abapException = function.getException( "1" ); Import、Export、Tables所获得的都是JCO.ParameterList对象。 如果参数是基本类型,则可直接设定:
input.setValue(10, "MAX_ROWS"); Object object = output.getValue("MAX_ROWS"); 当然你这样getValue得到的只能是一个Object对象,如果你知道你会得到什么类型(一般情况下你应该知道),你可以直接get这个类型。比如,我们知道"MAX_ROWS"是个int值,所以: int maxRows = output.getInt("MAX_ROWS"); 如果参数是一个结构(如果你是个面向对象的程序员,请回忆一下C语言中的结构变量,谢谢),那么你得先得到一个对应此参数的结构对象,然后对结构中的变量成员get或者set:
JCO.Structure sFrom = input.getStructure("DESTINATION_FROM"); sFrom.setValue("NEW YORK", "CITY"); 当然如果是Import的话最后别忘了把这个结构放回列表中: input.setValue(sFrom, "DESTINATION_FROM"); 在对Tables的参数进行操作时,也得先得到一个与该参数内部表对应的内部表对象:
JCO.Table tDateRange = tables.getTable("DATE_RANGE");
现在这个内部表对象还是空的,所以要先加一行数据,然后将一个逻辑指针指向该行,再进行各个元素的赋值或取值: tDateRange.appendRow(); tDateRange.setRow(0); tDateRange.setValue("I", "SIGN"); tDateRange.setValue("EQ", "OPTION"); tDateRange.setValue("20040330", "LOW"); 内部表对象支持直接将表内容发送到HTML文件: JCO.Table flights = function.getTableParameterList().getTable("FLIGHT_LIST"); flights.writeHTML("C:/function.html"); 想知道内部表中有几条数据,可以调用getNumRows()方法: int rows = flights.getNumRows(); 结束调用时要记得断开连接:
myConnection.disconnect(); 2.使用连接池
很多时候我们需要进行大量连接,SAP系统本来就脆弱,连接再一多那真的是老牛拉车了。所以我们要用连接池进行连接。下面是一个使用连接池的例子: package jcousage;
import com.sap.mw.jco.JCO;
import java.util.Properties; public class UsageForPool {
public static void createConnectionPool( String poolName, int maxConnection, Properties logonProperties) { JCO.Pool pool = JCO.getClientPoolManager().getPool(poolName); if(pool == null) { JCO.addClientPool( poolName, // 连接池名 maxConnection, // 最大连接数 logonProperties ); // logon设定参数 } } public static JCO.Client getConnectionInPool( String poolName ) { JCO.Client connection = null; JCO.Pool pool = JCO.getClientPoolManager().getPool(poolName); if(pool != null) { connection = JCO.getClient(poolName); } return connection; } public static void releaseConnection( JCO.Client connection ) { JCO.releaseClient( connection ); } public static void removeConnectionPool(String poolName) { JCO.removeClientPool(poolName); } public static void main(String[] args) {
Properties logonProperties = new Properties(); logonProperties.put("jco.client.ashost","192.168.1.123"); logonProperties.put("jco.client.client","800"); logonProperties.put("jco.client.sysnr","00"); logonProperties.put("jco.client.user","young98"); logonProperties.put("jco.client.passwd","password"); String poolName = "ThePool";
createConnectionPool(poolName, 6, logonProperties); JCO.Client connection = getConnectionInPool(poolName); connection.connect(); if (connection != null && connection.isAlive()) { System.out.println("Connection is alive!"); releaseConnection(connection); removeConnectionPool(poolName); } else { System.out.println("Connection FALSE!"); } } } 首先,我们仍然需要一个Properties对象用来建立连接,不过这次是建立的连接是一个连接池:
JCO.addClientPool( poolName, maxConnection, logonProperties ); 这个方法同时还需要池的名字以及最大连接数一起作为参数。当然在新建一个连接池之前,检查一下有没有相同名字的池已经存在是一个好习惯。 有了池我们就可以在连接池里获得连接啦: JCO.Client connection = JCO.getClient(poolName); 然后在这个连接对象上激活连接就可以啦: connection.connect(); 接下来就跟上面说的一样用啦,简单吧。 用完别忘了释放连接: JCO.releaseClient( connection ); 如果连接池也不用了就删了它: JCO.removeClientPool(poolName); 你学会了吗?
December 05 吻别今天早上上班路上的一幕给我触动蛮大的。
地铁下来走到平时一直过马路的红绿灯口,很多人,我站到旁边,突然发现旁边2个外国人,一男一女,都是一袭黑风衣,十分亲密。
他们当然也是在等红绿灯啦。女的从侧面看很漂亮,男的似乎也很帅,典型的欧洲男人。
女的深情地抬头看着男的,男的也微笑着看着她。
绿灯了,我从他们旁边走过,听到了清脆的接吻声,然后男的穿过了马路,女的朝另一个方向走了。
那个男的走着走着就到我前头去了。从背后看,这个男的......真他妈帅啊!(允许我爆个粗口吧,呵呵)
......
有人明白我想说什么吗?
November 03 032-关于Servlet与javascript间的传值问题_静态页面(2)我们来看第一个方法。“全选”与“清空”的操作其实是一样的,只是方向不同。
function fn_moveAll(fromId, toId){
var from = document.getElementById(fromId); var to = document.getElementById(toId); var size = from.options.length; for (var i = 0; i < size; i++) { var opt = document.createElement("option"); var txt = document.createTextNode(from.options[0].text); opt.appendChild(txt); to.appendChild(opt); from.remove(0); } fn_counter(); fn_selectSort(toId); } 我尽量使用DOM模型提供的方法进行操作,这样可以保证函数在大多数浏览器中都能工作。首先我定义了2个变量,我要做的就是把from变量代表的节点下的所有option子节点复制到to变量代表的节点下。我要得到option的数量:
var size = from.options.length;
接着是一个循环体,创建一个新的option节点,将from的第一个option的text节点的内容拷贝到新建的option节点下,再将新建的option节点“嫁接”到to变量指向的节点下,再从from删除原来的那个节点。我知道我比较罗嗦,不过我还是要提一下:当删除了第一个option时,select会自动将后续的option元素顶上来,所以正如大家所看到的,循环体中我一直在对数组中的第一个元素进行操作。
fn_conter()和fn_selectSort(Id)这2个方法是用来改变画面中的选择合计数以及对select中的option节点进行排序的,现在可以先不考虑,后面我会介绍的。 接着是移动单个option的方法:
function fn_move(fromId, toId){
var from = document.getElementById(fromId); var to = document.getElementById(toId); var size = from.options.length; for (var i = 0; i < size; i++) { if (from.options[i] != null && from.options[i].selected) { var opt = document.createElement("option"); var txt = document.createTextNode(from.options[i].text); opt.appendChild(txt); to.appendChild(opt); from.remove(i); i--; } } fn_counter(); fn_selectSort(toId); } 这个方法跟前一个差不多,需要解释的只有2个地方:
if (from.options[i] != null && from.options[i].selected)
这个if语句是用来找到被选中的那条option的。不过由于可能同时选中了好几个option,所以当第一个option被删除后会产生null的option元素,因此还要判断一下option不为null。
i--;
刚才说过,当删除时select会自动把后面的option顶上来,所以顶上来的那个option不能漏了。(这也是刚才为什么会出现null数组元素的原因)
未完待续......
October 20 开始发烧正式进入无损音频压缩的世界。我知道可能有点晚,但希望不是太晚。
0.软件准备
Exact Audio Copy,以下简称“EAC”,用于抓取CD音轨;(推荐版本:0.9beta4) Monkey's Audio,以下简称“MAC”,用于ape文件的编码解码;(推荐版本:4.01加汉化包) FLAC frontend,以下简称“FLAC”用于flac文件的编码解码;(推荐版本:1.71汉化版) LAME,用于压缩mp3文件;(推荐版本:3.91) foobar2000,用于播放ape、flac、mp3、wav文件。(推荐版本:0.83) 1.一切都从一张正版CD开始
如图所示:
我想我不太会再把文件回刻到CD里去了,没有那个必要了。 October 18 031-关于Servlet与javascript间的传值问题_静态页面(1)心急的人已经在那里痛骂我了:你到底想说什么??!!稍安毋躁,请再忍耐片刻。
我们先来看一个静态网页,如下图所示:
页面上有两个<select>元素,其中的内容分别是待选择部门编号和名词以及已选择的部门编号及名称。这个页面实现如下功能:
1.当用户选中左边<select>元素中的某一行或几行,然后点击中间的“选择”按钮时,选中的部门就会从左边移到右边; 2.相反,在右边选中部门然后点击“取消”按钮时,选中的部门就会从右边移到左边; 3.当点击“全选”按钮时,所有部门都会被移动到右边,反之点击“清空”按钮时,所有部门都会被移动到左边; 4.在部门编号输入框中输入部门对应的编号,再按旁边的“选择”按钮,对应的部门就会从左边移动到右边; 5.如果输入的部门编号不在左边的待选部门列表中时,点击旁边的“选择”按钮会弹出提示对话框,返回时清空部门编号输入框; 6.当输入的部门编号不是由数字或大写字母组成时,点击旁边的“选择”按钮也会弹出提示对话框,返回时清空部门编号输入框; 7.右边的已选择部门下方会实时更新已选择的部门数。 这是一个典型的<select>用例,你甚至能在网上找到类似“2个select间移动option”的现成javascript代码。但是你也会很快发现那些代码不怎么好用。我在这里提供一个完全使用DOM解决问题的方案,供有这方面需要的朋友参考。 首先,我们要建立2个select: <select size="20" style="width:100%;" id="source" multiple> <option>01:AAA部门</option> <option>02:BBB部门</option> <option>03:CCC部门</option> <option>04:DDD部门</option> <option>05:EEE部门</option> <option>06:FFF部门</option> <option>07:GGG部门</option> <option>08:HHH部门</option> <option>09:III部门</option> <option>10:JJJ部门</option> </select> . . . . . . <select size="20" style="width:100%;" id="selected" multiple> </select> 分别给2个select分配ID,我用的是source和selected,备用。第二个select初始状态是没有option的。(没有选择任何部门)
我们再添加一些按钮和输入框: <input type="button" name="qx" value="全选>>" onclick="fn_moveAll('source', 'selected');"> <input type="button" name="xz" value="选择>" onclick="fn_move('source', 'selected');"> <input type="button" name="qx" value="<取消" onclick="fn_move('selected', 'source');"> <input type="button" name="qk" value="<<清空" onclick="fn_moveAll('selected', 'source');"> <input type="text" name="" maxlength="2" size="2" id="cd">
<input type="button" name="xz2" value="选择>" onclick="fn_selectByNo();"> 我已经把每个按钮所对应要执行的javascript方法都写上了,(可能这有些违背分层设计的理念)接下来我们要做的是去实现这些方法。
未完待续...... October 07 030-关于Servlet与javascript间的传值问题_准备篇(下)我现在需要一个Servlet,我并不想搞得很复杂,所以我不准备使用任何框架。虽然知道在Servlet里写很多的逻辑是件很糟糕的事情,但是我现在不是在做项目,我只想用尽量少的代码完成需要的东西,这是自己写代码和做项目的最大区别,你可以随心所欲。
我将在这个Servlet里完成对DepartmentList.csv文件内容的读取,并且以半角逗号分割每一行内容,然后将它们装填到一个Department对象中,再将这些Department对象全部放进一个ArrayList里。完整的代码如下: //SelectServlet.java
package servlet; import java.io.BufferedReader;
import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import model.Department;
public class SelectServlet extends javax.servlet.http.HttpServlet {
static final long serialVersionUID = 1L; @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Department> deptList = new ArrayList<Department>(); BufferedReader br = new BufferedReader(new FileReader(getInitParameter("DepartmentList"))); br.readLine(); String tempString; while((tempString = br.readLine()) != null) { String[] deptArray = tempString.split(","); Department dept = new Department(); dept.setNo(deptArray[0]); dept.setSortNo(Integer.parseInt(deptArray[1])); dept.setName(deptArray[2]); deptList.add(dept); } br.close(); request.setAttribute("departments", deptList); RequestDispatcher rd = request.getRequestDispatcher("selecter.jsp");
rd.forward(request, response); } @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }//:~ 在声明List时我使用了一个范型,但其实那是多余的。读取文件的路径我准备作为一个Servlet初始化参数传入,这样即便我改变文件的存储位置,只要修改web.xml部署描述文件即可,程序不需要做任何修改。最后我把装着所有Department对象的List作为一个属性放入了request中,它将同request一同传给selecter.jsp页面,是的,也就是我最终要在里面说明问题的页面。
将department对象放入一个Set并不是一个好主意,因为我在Department对象中并没有覆盖equals()方法和hashCode()方法,放入Set的对象需要具有唯一性,我们现在并没有类似的需求。 把selectServlet.java保存在servlet包中,让我们来看看部署描述文件web.xml,内容如下: <?xml version="1.0" encoding="UTF-8"?>
<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"> <servlet> <servlet-name>SelectServlet</servlet-name> <servlet-class>servlet.SelectServlet</servlet-class> <init-param> <param-name>DepartmentList</param-name> <param-value>/home/young98/DepartmentList.csv</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>SelectServlet</servlet-name> <url-pattern>/SelectServlet</url-pattern> </servlet-mapping> </web-app> 这是一个非常简单的部署描述文件,声明了一个Servlet,同时声明了一个初始化参数,也就是我刚才提到的,文件的路径。现在的路径是“/home/young98/DepartmentList.csv”,我会把文件保存到这个路径下备用。
至此,我们已经有了我想要的所有东西了,现在我们可以把注意力移到jsp文件的内容中了。 未完待续...... October 06 029-关于Servlet与javascript间的传值问题_准备篇(上)听题目似乎不知所以,待我慢慢道来。 (事先声明,本系列内容讨论的是非Ajax解决方案)
//Department.java public class Department { public String getNo() {
无需太多的注释,这是一个“部门”对象,它有3个属性:部门编号,排序号,以及部门名称。其中排序号顾名思义是用来排序的,至于为什么不以部门编号排序,到了jsp页面上大家自会明白。
No. , SortNo. , DepartmentName
我把这些内容保存在一个DepartmentList.csv文件中,备用。
未完待续...... September 08 爱丽丝梦游仙境症一直以来我都以为别人也跟我一样,但是一个偶然的机会,我才发现原来这是一种病......
爱丽丝梦游仙境症(AIWS),或者叫“视微症”,是神经学上的一种高度迷惑性现象,以致影响到人类的视觉感知。患此视觉疾病的人类和动物,会把部分人以及无生命目标看得比真实的要小很多。常常这些被感知的物体,会在同一时间被看来非常得远或者非常得近。例如,一辆尺寸正常的汽车,可能被看来是一个小玩具。而一只宠物狗也可能被看作只有老鼠大小。
爱丽丝梦游仙境综合征是偏头痛的一种罕见先兆。该综合征的主要症状是变形,也就是说身体感觉和视觉扭曲,而患者本人也明确知道这是幻觉。爱丽丝梦游仙境综合征可能发生在任何年龄,但更多地发生于儿童时期。从一些报道来看,很多患者长大后便自行痊愈,但也有例外。这种病症无药可医,唯一改善的方法只有学习与之共生。
我还清楚记得小时候,那天晚上我在发高烧,当我开眼看天花板时,我觉得天花板比平时高出数倍......
在那以后,我看书时经常会觉得书上的字变得很小很小,但是尽管它变得再小,我还是能看清是什么字......
后来不知什么时候开始这种情况逐渐好转,发生的次数逐渐减少。
我现在已经非常偶尔才发生这种症状了。
September 02 韩国游——吃2008-8-21~24去高丽国兜了一圈。
第一次出国旅游,兴奋,激动,好奇,不安…… 报流水账实在不是我的强项,只能想到什么说什么了。 21日,晚餐,首尔,韩国之味餐厅
刚到首尔,从机场直接把我们拉到了这个餐厅。进门以后菜已经全都放在桌上了,火锅也已经放好料,就等点火了。后来才发现我们每到一处餐馆都是如此,所有的菜都已经放在桌上了,就等你进来点火吃了。每个桌子都是4个人的,比国内普通的4人餐桌要小,桌子上的餐具盒里放满了银筷子和调羹,还有一瓶辣椒酱也是免不了的。菜也就是些泡菜啊,泡萝卜啊什么的蔬菜,荤菜只有一盆薄得惨不忍睹的牛肉,一个人都吃不饱,还要分4个人吃。不过菜都是可以免费加的,这点不错。火锅锅底也是净素,汤完全没有味道,牛肉只是在里面涮熟而已,拿出来还是要蘸辣椒酱吃的。那个辣椒酱看上去火红,实际是完全不怎么辣,怪不得看到一些韩剧里吃饭时往碗里猛倒辣椒酱,那时还以为韩国人都特能吃辣呢。石锅拌饭是后来上的,石锅很烫,所以韩国人吃饭是不把饭碗拿在手里的,主要是温度关系。(银饭碗传热也很快的) 这是在韩国吃的第一顿饭,实在不怎么样...... 22日,早餐,首尔,乐天世界酒店早餐厅
没有想到在韩国吃得最满意的一餐居然是早饭。5星级的酒店早餐确实也不赖。 完全是自助形式,刚开始不知道该怎么操作,只见里面有几个大区,经过侦查后发现有一个供应牛奶果汁等饮品的区域,一个是面包蛋糕黄油等,一个是水果区,一个是西式早餐,还有一个专门供应面点。本来想拿盒牛奶,再去拿些面包,去西式早餐区叫他给煎个荷包蛋什么的,不过觉得毫无新意,而且自己也不喜欢。于是跑到面点区。 面点区有一个女服务员站在中间,(人还挺漂亮的)不停的煮着面,周围排着一圈人。这个时候正好有个韩国中年人过来排队,于是我就跟在他后面。我想看前面这个中年人怎么弄,我也就怎么弄,哈哈。原来是这样的,围着这个女服务员一圈都是煮面的材料,比如面有乌冬和荞麦,还有一种是黑绿色的,不知道是什么面。然后是蟹肉棒啊,鱼饺啊,鸡毛菜啊,牛肉片啊,绿豆芽啊,贡丸鱼丸啊......等等,反正都是放进去和面一起煮的东西,你只要拿一个大碗,把你想一起煮的东西全都放到碗里,到时候把碗交给那个女服务员,她就会帮你煮熟再放回碗里,到时候你再自己加点葱花,海苔,紫菜,香菜,碎花生什么的,一碗香喷喷的面就能吃啦。我点的是乌冬面,非常美味。(当然我材料配得好也有关系,嘿嘿) 22日,午餐,首尔,人参炖鸡专门店
韩国的餐厅都是专门店,吃面的就只有面,吃盖浇饭的就只有盖浇饭,甚至烤肉如果是烤猪肉就绝不会供应牛肉,烤牛肉的绝不会供应猪肉。这家是专门吃人参炖鸡的店。店堂里到处都放着人参酒的摆设,桌子上的小菜也还是那些。(泡菜是默认必有的)说实话我觉得高丽人参酒很好喝。一个人有一整只鸡吃,听上去很吓人,其实鸡不大,很多女生也都吃完了,连鸡汤也喝完。来的路上导游把韩国的米说得怎么怎么好吃,这鸡肚子里的米饭吃上去也不过如此么,还没我家的米好吃呢。 22日,晚餐,济州,某海鲜小饭馆
到济州的第一顿饭。济州是个岛,那自然是吃海鲜啦。饭店布局还是那样,开了火煮上海鲜汤。说实话海鲜汤也不怎么好吃,不过大家都饿了,顾不上了。除了花蛤还凑合外,其他的比如梭子蟹啊,蛏子啊实在不敢恭维。不过最后的汤底还是很鲜的。 23日,早餐,济州,CityCon酒店早餐厅
吃过了5星级的早餐再来吃4星级的早餐。我不知道韩国这星级是怎么评的,实在差太多了吧。这次是拿个盘子自己去食品区拿,几乎每个菜里都有火腿肠或方腿,吃得我好胀,很不舒服。不过其中有一个白菜炒猪肉倒是不错,我吃了很多,靠这个菜我对付掉一碗粥。 23日,午餐,济州,某黑毛猪烤肉店
这顿厉害了,绝对是吃肉。黑毛猪肉都是腌好了的,放锅里烤熟了,包上生菜......真是满嘴留香啊。我除了用海苔包了饭吃以外,其他配菜(也就那几个菜,到处都差不多)基本没怎么动过。这顿猪肉算是吃够本了。不过我们吃完就被领去看又臭又脏的猪圈...... 23日,晚餐,济州,某生鱼片料理店
据说是我们在韩国吃的最贵的一顿,看来生鱼片到了哪里都是算贵的。不过也就是家很小的私人料理店么,服务员就是老板娘她儿子(长得极像),店面就跟我们这里的个体饭店差不多。韩国的生鱼片也就那味道,也是酱油和芥末,完全没啥两样,就是多了一个火锅,又是海鲜,不过比上次的海鲜汤更难吃,一锅汤我们一桌4个就没怎么动过。席间我们还喝了韩国烧酒,也就那样了。 24日,早餐,济州,CityCon酒店早餐厅
与前一天的早餐一样,我吃了更多的白菜炒猪肉......里的猪肉。(准确地说我觉得是韩式回锅肉,呵呵) 24日,午餐,首尔,香菇火锅专门店
总算是坐8个人的圆桌了,可其实是换汤不换药,桌子上的每样东西都是双份的,明显是2个桌子的东西放一起了。还吃了韩国饺子,跟中国的也差不多,就是肉少点。 后记:
韩国的饭店点菜很简单,基本上一个样,你进来吃这些,我进来也是吃这些。 韩国饭店完全没有茶水供应,只有冷的矿泉水,倒在银杯子(不锈钢?)里喝,而且没有热水一说。 每个店里都有辣椒酱,而且装的塑料瓶也是统一的,味道也是惊人的一样。 韩国饭店的服务员多数是中年妇女。 想吃点荤的,不太容易...... August 28 韩国游——坐飞机2008-8-21~24去高丽国兜了一圈。
第一次出国旅游,兴奋,激动,好奇,不安…… 报流水账实在不是我的强项,只能想到什么说什么了。 (虽然是城里人,但是实在没见过世面,所以上来只好先从坐飞机开始了,呵呵)
这次在4天里坐了4次飞机,最后一天里坐了2次飞机。
说一下登机过程吧:用机票换登机牌,然后用登机牌托运行李,然后过安检,然后过海关,再过安检门,进候机厅等飞机,凭登机牌登机。最近开奥运,安检比较严。 出飞机场就比较简单了,等飞机停稳下来后直奔行李区找自己的行李,然后去海关敲个章就算过了。至于要填的申报海关的卡片完全没有太大意义。由于奥运的关系,最后一天回来时过中国海关过了好久,即便无申报也要检查,致使无申报通道居然堵塞。 去韩国和回来的时候坐的是东方航空的飞机,经济舱一排有8个位子2-4-2隔开,飞机看上去有些陈旧,在韩国国内坐的是韩亚航空的飞机,经济舱一排6个位子3-3隔开,飞机看上去挺新的。东方航空的飞机较大,着陆和起飞时比较稳,但是机内装修,特别是颜色上的搭配让人看着很不舒服,蓝色和红色的座椅和空姐的蓝色和红色旗袍与整体很不协调,完全破坏了飞机内部色调。韩亚航空的飞机在这方面就做得很不错,不光飞机外观让人看着舒服,内装修也是以土黄色为基调,连空姐的衣服也是同一色调,体现出一种完整感。不过韩亚的飞机小,着陆的时候明显“咯噔”一下。 在候机厅里观察了一些飞机的外观,感觉中国的飞机最难看。国外航空公司的飞机机身喷漆都很漂亮,大韩航空的浅蓝色和尾翼上的红蓝八卦,韩亚航空的三色尾翼,日本航空的太阳旗风格加上机身JAL的字样,以及全日空的蓝色条纹……这些飞机让人一看就觉着舒服。反观国内航空公司的飞机,看上去就让人很不舒服了,也许是我们的飞机比较旧的缘故吧。 坐在飞机上还是很开心的,特别是起飞和着陆的时候,如果挨着窗坐就能看风景啦。不过到了中段就没啥意思了,下面全是云,什么都看不到。国际航班好像是有免费餐享用的,不管饿不饿,先吃了再说。东方航空韩国路线的套餐有2种选择,去的时候吃了牛肉餐,回来的时候吃了海鲜餐,味道么……不算好吃,但也不难吃。免费饮品很多人都点咖啡,我是没习惯喝咖啡的,所以前2次喝了矿泉水,后2次喝了可乐。当然还有橙汁等其他选择。在飞机上可以看看免税商品目录什么的,如果是黄昏或晚上登机的话在飞机入口处可以免费拿报纸看。每个位子夹目录的地方都会有一个垃圾袋,有什么垃圾都可以丢进去,当然还可以当呕吐袋用。空中小姐都是按下呼叫按钮就满脸堆笑地过来了,你跟她提任何无理要求她都会满脸堆笑回答你,当然不一定满足你的要求。另外就是空中小姐并不像我们平时想得那么漂亮,都化很浓的妆,长发的话都是盘着的,身材倒都是一流。 最后一点是飞机起飞和着陆时由于大气压力变化耳朵会有堵住的感觉,吃点东西或经常咽口水可以缓解这种感觉。 总结:坐飞机比坐船坐车开心有趣多了……(允许我乡巴佬一下,呵呵) August 25 2008北京奥运的最后一篇日志2008年北京奥运会就这么结束了。
对我来说,结束得很匆忙,因为最后4天完全得不到关于奥运的具体消息。
中国拿到了51枚金牌,是最大的赢家,美国仍然是体育强国,俄罗斯后来居上排在第三。
东亚国家,韩国拿到了13枚金牌,其中包括一枚分量很重的男子棒球金牌;日本拿到了9枚金牌。
牙买加让人眼前一亮,拿到6枚金牌,而且所有奖牌全部来自田径。
......
北京奥运还是办得不错的。
而且这届奥运会也帮了我不少忙。
第46~51金由于21日去了高丽国,等奥运闭幕那天晚上才回来。
错过了中国最后的6枚金牌,好像损失还不算大。
女子10米跳台——第46金
中国跳水真是人才辈出,永远都有新人顶上去,这次这个小姑娘从照片上看好像长得很水灵啊,呵呵。
乒乓球女子单打——第47金
金银铜牌都是中国的,太无聊了。
据说王楠后来哭了?是真的吗??
男子500米双人划艇——第48金
不熟悉这个项目,不好作太多评论。
乒乓球男子单打——第49金
又是金银铜牌包圆了。
我觉得这没什么值得我们庆祝的,就等着奥委会取消奥运乒乓球项目吧。
到时候看你们再去开心吧。
拳击男子48公斤级——第50金
这块金牌也是奥运还没开始就在那里猛吹的,现在拿下来了,还算好。呵呵......
拳击男子81公斤级——第51金
以前看过一个介绍片,说中国拳击队都是在新疆那里什么地方集训的,每天吃羊肉水果,看那些羊肉串,当时就流下了哈喇子......
August 20 第44金、第45金女子帆板RS:X——第44金
又是我非常陌生的项目......
中国很奇怪的,有一些完全没有群众基础的运动,唉,会得金牌的,让人难以想象。
跆拳道女子49公斤级——第45金
跆拳道啊,柔道啊,这些项目在奥运会上的比赛到底有多少可观赏性?我觉得这是一个很值得探讨的问题。
另外就是跆拳道比赛的时候一脚踢出去往往伴随声嘶力竭的叫喊,很不喜欢......
另外:男子跳马已经比过了?波兰人拿了金牌??李小鹏上哪去了?为啥不参加啊???
August 19 第40金、第41金、第42金、第43金体操男子双杠——第40金
我又要提到李小鹏的手臂伤了。
就凭这伤,双杠金牌也该他拿啊,真的不容易。
上街双杠也是他吧。
体操男子单杠——第41金
邹凯这次第一次参加奥运居然已经拿了3块金牌了。
不得了不得了,单杠一直是我们的弱项啊,现在居然都拿金牌了。
自由体操、鞍马、吊环、双杠、单杠......好像就缺跳马了吧。
男子蹦床——第42金
又是这个让我很无语的项目......
跳水男子3米板——第43金
我们可是跳水梦之队,这种金牌我们应该拿。
这届奥运俄罗斯很低迷啊,本来跳水还可以跟我们有得一拼,现在是完全不行了。
第38金、第39金女子蹦床——第38金
蹦床?这次奥运的新项目?
怎么比啊?跟体操一样评分?还是怎么?
完全不清楚具体情况,不过我们国家蹦床很强吗?一头雾水......
乒乓球男子团体——第39金
又是一块含金量比较低的金牌,不作评论,也无需作评论。
|
|
|