IE9中Script438: 对象不支持“createContextualFragment”属性或方法

这个问题在Extjs的官网有人讨论,详见

http://www.sencha.com/forum/showthread.php?125869-Menu-shadow-probolem-in-IE9&p=579336

至于解决办法也很简单,只要在网页什么地方加上

   1: <script type="text/javascript">  

   2: if ((typeof Range !== "undefined") && !Range.prototype.createContextualFragment)  

   3: {  

   4:   Range.prototype.createContextualFragment = function(html)  

   5:   {  

   6:   var frag = document.createDocumentFragment(),    

   7:   div = document.createElement("div");  

   8:   frag.appendChild(div);  

   9:   div.outerHTML = html;  

  10:   return frag;  

  11:   };  

  12: }  

  13: </script>  

此外还有一个问题,网页报Script438:对象不支持“createRange”属性或方法

这个问题解决也很简单,看看<body>标签后面的东西,后面不能直接跟文本,文本内的东西一定要放在标签中~

记一则马虎引起的日期错误

Error

周末忙着做毕设,其中有从数据库中取出时间,然后进行了下格式化,结果发现格式化后的日期如上图,显然月份数据是不对的,怎么可能出来30月…

查阅代码,一开始竟也没有发现错误:

   1: public void setCreatetime(Date createtime) {

   2:     SimpleDateFormat df=new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");

   3:     this.createtime = df.format(createtime).toString();

   4: }

看了以上代码,我想细心的同学已经发现了,月份的掩码应该是MM,而不是mm,哈哈 看来英雄难过MM关啊!(MM=网络用语,美眉)

 

附录:

常见的时间掩码

y 年 Year 1996; 96
M 年中的月份 Month July; Jul; 07
w 年中的周数 Number 27
W 月份中的周数 Number 2
D 年中的天数 Number 189
d 月份中的天数 Number 10
F 月份中的星期 Number 2
E 星期中的天数 Text Tuesday; Tue
a Am/pm 标记 Text PM
H 一天中的小时数(0-23) Number 0
k 一天中的小时数(1-24) Number 24
K am/pm 中的小时数(0-11) Number 0
h am/pm 中的小时数(1-12) Number 12
m 小时中的分钟数 Number 30
s 分钟中的秒数 Number 55
S 毫秒数 Number 978
z 时区 General time zone Pacific Standard Time; PST; GMT-08:00
Z 时区 RFC 822 time zone -0800

.Net与Java时间处理上的一点区别

这两天在做与某知名一卡通公司的单点登录集成(我们的产品使用Java编写,对方的程序使用.Net编写)其中有一项参数是时间戳。即当前时间相对于公元1970-1-1 00:00:00的秒数。按照他们给出的文档我完成了Java部分的编写,时间戳部分很简单,一句话:

[codesyntax lang=”php”]

    private String createTimestamp() //timestamp
    {
        return System.currentTimeMillis() / 1000 + "";
    }

[/codesyntax]

使用System.currentTimeMillis()方法就能得到自1970年1月1日0时0分0秒的毫秒数,除以1000自然是秒数。但是意外却发生了,我产生的时间戳跟他们公司产生的时间戳差了一大截,查阅资料后发现.Net跟Java在处理时间上有出入。

.Net产生的时间都是当前时区的当前时间,而Java的currentTimeMillis()方法得到的却是相对于GMT来的时间。中国所在时区是+8区,故时间整整差了8小时!

所以当童鞋们再遇到.Net跟Java时间不一致的时候,多往时区方面考虑考虑,说不定就能找到解决办法了 :)

当然我会给出解决方案:

方法一:JVM运行时增加参数,指定时区 -D user.timezone=GMT+08

方法二:直接在程序中设置时区。System.setProperty(“user.timezone”,”GMT +08″);

方法三:直接加上28800就好了(8hours*60min*60sec=28800)

Struts2中从一个Action跳转到另一个Action

最近在做毕业设计,依然使用了SSH2作为基础框架,同时引入了JBPM来做工作流框架,因为牵扯大量的业务逻辑,故一些Action之间的跳转是在所难免了。

Action之间的跳转主要有两种方法:

1)需要保存前一个Action的属性,我们可以使用

 1: <result type=”chain”>action2</result>

 

2)仅跳转,我们可以使用

 1: <result type=”redirect-action”>ActionName</result>

 

再追根究底一些,我们到底可以使用哪些result类型呢?我们可以参考struts-core-xxxx包中的struts-default.xml文件,里面记录了可以使用的result类型及其实现类。

 1: <result-types>
 2:     <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
 3:     <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
 4:     <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
 5:     <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
 6:     <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
 7:     <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
 8:     <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
 9:     <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
 10:     <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
 11:     <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
 12: </result-types>

SQL Server 数据恢复

今天下午接到大张老师电话,问能不能恢复SQL Server中已经被删除的一条记录,忽然想起若干年前牙牙老师也问过我这个问题,于是放狗搜索了下,找到了解决方案。

因为SQL Server是基于日志管理的数据库系统,每一笔操作都有详细的日志作为记录,这为我们做恢复提供了非常有利的先决条件,通过搜索引擎,我查找到了一款名为“LogExplorer”的商业软件,可以对SQL Server的日志进行分析,并通过日志恢复数据。

这是一款商业软件,未注册版本可以使用30天,安装的时候需要同时安装客户端及服务器端。软件运行界面如下图。

LogExplorer

而我们要做的非常简单,点击左侧的“View Log”即可查询所有的日志信息,如下图:

LogExplorer-1

因为我们的日志数量非常多,而日志中又记录了全部的CRUD操作,我们只想筛选某一时间的某种操作,怎么办呢,很简单,点选上图工具栏的第一个图标即可。点击之后,他会让你选择筛选条件,如下图:

LogExplorer-2

除了可以设置筛选的时间之外,我们还可以按照操作进行筛选~如下图:

LogExplorer-3

在这里我仅仅针对删除的记录做筛选,从上图中看出,我们几乎可以对所有的操作进行筛选~筛选完成点击“Apply”。系统便会给出我们筛选结果~

LogExplorer-4

经过我们的筛选,列表中只剩下一条记录啦,经查,这条记录就是被我们误删的记录。那我们想要恢复这条记录,也只是仅仅需要在记录上面点右键,选择“Undo Transaction”如下图。

LogExplorer-5

他的恢复并不是直接作用于数据库,而是生成对应操作的逆操作脚本,所以在选择“Undo Transaction”之后,系统会让你给出脚本的保存位置。系统导出的脚本如下:

LogExplorer-6

最后再通过SQL Server自带的查询分析器执行生成的脚本,即可恢复记录。

点此下载:LogExpress

更多关于Log Explorer的使用,可以参考:

LogExplore的一个详细操作手册

Windows 不能与Linux NTP时间服务器同步的解决方案

因为服务器区限制,仅有某几台服务器可以上外网,但是Linux服务器时间经常跑偏,于是决定搭建网内的NTP时间服务器,时间搭建服务器的过程我不详述,网上很多,在这里我说说一个奇怪的问题——搭建好的Windows服务器无法与之进行同步,就是在Internet时间那填上服务器地址点同步,老是失败,查看日志报接收到错误的时间数据。

从网上搜了一下,找到一个解决办法,只要在命令提示符内使用如下命令就搞定:

   1: net time /setsntp:time.sdyu.edu.cn

   2: net stop w32time

   3: net start w32time

然后,就搞定啦!嘿嘿

初探USB 3.0

_DSC0022

我的ThinkPad x201算算买了也已经一年了,原机标配的320G的日立已经不能满足我这个Programer & Photoer & Downloader & PTer 的需求,故考察了一下硬盘,虽说很想体验下SSD的速度,但是由于升级最紧迫的事情就是为了容量,而且SSD一旦损坏数据很难修复,为了兼顾容量及速度,以及文件的安全性,我选择了希捷最新推出的混合硬盘——ST750LX003,至于这块混合硬盘的性能如何,这留作下篇日志的内容 :)

今天我们的重点是我换下来的这块日立的320G 7200转硬盘该如何处置,当初考虑的就是上个硬盘盒,做成移动硬盘,可因为普通USB 2.0 传输速度也就在30MB/s的样子上,于是我动了USB 3.0的念头。

说干就干,既然想上USB 3.0,那么一款支持USB 3.0的硬盘盒是必不可少的,一开始比较倾向SSK的产品,可后来听某大说元谷的主控要好一些,恰好京东元谷的T250这款盒子又搞促销,嘿嘿,这样的机会对于我这个患有“选择性障碍”的天秤座来说,简直不用选择哇,于是我就有了这款盒子。

_DSC0020

看外观确实很有质感,铝合金的外壳在冬天摸起来凉凉的,接口部分仅仅带了USB 3.0跟电源接口,三下五除二的拆开硬盘盒,装入老的硬盘,嘿嘿,硬盘的事情搞定。而让心感觉很爽的就是这个元谷的数据线,真是粗(见本页第一张图片),而蓝色的数据线,蓝色的接口,都散发着USB 3.0的光辉……不过缺点也是有的,这线太粗了,如果往电脑上插的时候发现你的接口正好反了180度,你需要费很大的力气,才能把它转过来 –_- !

哈哈,硬盘盒的问题搞定了,迫切的把它连入计算机,打开HDTune,选中移动硬盘,测速,速度令人无奈——还不到30MB/s !

USB2.0

想了想,对我的ThinkPad x201 上没有USB 3.0的口,怎么可能达到3.0的速度嘛,幸好本本上还有ExpressCard接口,我可以入个ExpressCard转USB 3.0的适配卡。又是一番考察,我发现目前主流的ExpressCard2USB3.0的芯片就两家公司在做NEC与FL,NEC的应用最广泛,但是发热量巨大,FL1000评论很少,而且性价比高一些,发热量信息未知,好吧,为了做实验,忍……京东入手SSK的UH-S401。

_DSC0017

看做工一般,下面给张接口的特写。

_DSC0023

瞧,也是非常简洁,一个USB 3.0的口,一个额外供电的电源口。细心的同学肯定注意到了,USB3.0跟USB2.0接口很大的一个区别就是2.0只有一排触电,而USB3.0变成了两排。

迫不及待的插到ExpressCard插槽里去,装上驱动,连接上硬盘盒,测速,哇哇!

USB3.0-1

这速度几乎已经达到了我日立7200转硬盘的传输速度!不过测试完毕我也郁闷了,插ExpressCard的左下角位置已经能感受到些许温度了。而且我发现即使不使用这个USB 3.0的接口,光插上这个扩展卡它也是会发热的,但是跟这传输速度相比,我认为这个缺点可以忽略——大不了文件传输完成我就拔下来呗!

修改DNS以及清空IE临时文件的vbs脚本

今早接到山青院电话,说需要一个修改DNS为校内DNS,并且清空IE临时文件的脚本,想都没想,用批处理写了一个:

[codesyntax lang=”dos”]

rem programed by Kaisir
@echo off
echo 本脚本的作用为修改您的DNS为山东青年政治学院专用DNS 222.194.76.2 同时帮您清除了电脑中的临时文件。若有疑问,请致电网络中心。
pause
echo 修改DNS中...
netsh interface ip set dns "本地连接" source=static addr=222.194.76.2
echo DNS已经修改成功,接下来将开始清空ie临时文件...
pause
echo 清除临时文件中...
del /f /s /q "%userprofile%Local SettingsTemporary Internet Files*.*"
del /f /s /q "%userprofile%AppDataLocalMicrosoftWindowsTemporary Internet Files*.*"
echo 全部操作已成功完成!感谢您的使用。
pause

[/codesyntax]

你瞧,思路很简单,用netsh把dns改了就是了,因为要适应Win7跟Xp临时目录的不同,于是删除语句写了两遍。

但是,仔细想想,这个脚本有很多问题,

1)若用户有多块网卡,这个脚本只会修改“本地连接”的那一个。

2)若用户自己手动修改了临时文件的位置,则这个脚本也无能为力。

于是,有了下面这个vbs版的脚本。

[codesyntax lang=”vb”]

'Program By Kaisir
Const T_NEWDNS1 = "222.194.76.2" 'DNS1
Const T_NEWDNS2 = "8.8.8.8" 'DNS2
set os=createobject("wscript.shell") '把wscript脚本执行外壳特性赋予给 os变量

lret = MsgBox ("本脚本可以帮助您修改DNS为山东青年政治学院内部DNS并清空浏览器临时文件,是否运行?",vbYesNo)
if lret=vbYes Then
	strWinMgmt="winmgmts:{impersonationLevel=impersonate}"
	Set NICS = GetObject( strWinMgmt ).InstancesOf("Win32_NetworkAdapterConfiguration")
	For Each NIC In NICS
		If NIC.IPEnabled Then '检索所有启用的网卡
			NIC.SetDNSServerSearchOrder Array(T_NEWDNS1,T_NEWDNS2)
		End If
	Next
	'开始执行清空临时文件
	net_temp=os.regread("HKCUSoftwareMicrosoftWindowsCurrentVersionExplorerShell Folderscache") '---通过读取注册表特殊位置获知系统ie浏览器的缓存文件夹位置,并赋值给变量net_temp
	MsgBox(net_temp)
	'删除目录下的所有文件及文件夹
	Const DeleteReadOnly = True
	Set objFSO = CreateObject("Scripting.FileSystemObject")
		objFSO.DeleteFile(net_temp&"*.*"), DeleteReadOnly
	strComputer = "."
	Set objWMIService = GetObject("winmgmts:" & strComputer & "rootcimv2")
	Set colSubfolders2 = objWMIService.ExecQuery _
        ("Associators of {Win32_Directory.Name='" & net_temp & "'} " _
            & "Where AssocClass = Win32_Subdirectory " _
                & "ResultRole = PartComponent")

    For Each objFolder2 in colSubfolders2
        objFSO.deleteFolder objFolder2.name , DeleteReadOnly
    Next
	MsgBox("所有操作已成功执行!")
else
end if

[/codesyntax]

这个就比较智能了,通过winmgmts获取系统中的网卡列表,然后遍历启用的网卡,然后进行修改。而临时文件部分,也是通过读取注册表“HKCUSoftwareMicrosoftWindowsCurrentVersionExplorerShell Folderscache”项的键值来获取文件夹位置。之后通过创建的fso对象的相应方法给他干掉~

FreeNas修改卷权限时出现“对不起,发生了错误”的解决方法

今天在部署FreeNas服务器的时候,设置完用户权限之后,再点击卷的权限设置时出现了上图的错误~~百思不得其解,当时还以为是程序Bug,中午吃饭回来以后突然想到会不会是权限出问题了,以至于他没有权限读取要设置的那个卷~通过ssh登录上FreeNas一瞧,嘿,当前挂载点的用户组竟然是乱码!!经排查,发现之前部署用户组的童鞋的用户组名称全都是中文~~竟然是这个引起了FreeNas奇怪的错误,将所有的组名改为英文,并通过ssh重置挂载点的权限后,故障解决!

总结:使用原生英文版的时候一定要注意,尽可能使用全部英文的描述,不然很容易出莫名其妙的问题。使用英文版软件,出现问题,先从本地化的原因找起,往往能快速解决问题。

Struts2学习笔记之(二)——验证及国际化

昨天通过一个简单的实例程序完成了Struts2的基本功能,但是昨天的那个程序那是相当的丑陋哇,前台部分代码量多不说,还都没加验证,输入用户名密码的地方留空点提交他也木有提示直接验证了,哎,作为一个程序员,怎么能忍受这样滴代码呢?而且现在软件国际化趋势明显,你的程序仅仅支持简体中文出门你都不好意思跟别的程序员打招呼,要是支持上英语、法语、韩语、日语、阿拉伯语、土耳其语……¥#&……*你瞧,倍儿有面子吧!

好啦,依然废话不多说,我们用代码说话。我们将昨天的登录页(index.jsp)使用Struts2中的标签进行改写,改写后的结果如下:

login.jsp

   1: <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

   2: <%@ taglib prefix="s" uri="/struts-tags"  %>

   3:  

   4: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

   5: <html>

   6:   <head>

   7:     <title>My JSP 'login.jsp' starting page</title>

   8:   </head>

   9:   

  10:   <body>

  11:       <s:form action="Login">

  12:           <s:textfield name="username" label="用户名"></s:textfield>

  13:           <s:textfield name="password" label="密码"></s:textfield>

  14:           <s:submit label="提交"></s:submit>

  15:       </s:form>

  16:   </body>

  17: </html>

大家可以看出,无非就是引入了一个taglib,并将表单啊,文本域啊按钮啊全部改写成了Struts2中的标签,怎么样,是不是简洁了不少?嘿嘿,这里只体现出了标签的一个优势,接下来,我们给昨天的登录页增加一个验证功能——若用户输入为空,则给出错误提示,禁止用户提交。在Struts2中,我们有两种方法来实现这种功能,1)实现validate()方法 2)编写验证脚本(*-validation.xml)。要注意的是,无论使用哪种验证方法,我们都必须让我们编写的Action基础ActionSupport父类对象。不然验证会出错的哟~~

在这里,我们着重说下方法2,毕竟这是我们在实际项目中会常常用到的方法,而且因为其验证字符串写于配置文件中,想要修改验证规则的时候,仅仅需要修改配置文件中的规则即可。

LoginAction-validation.xml

   1: <?xml version="1.0" encoding="UTF-8"?>

   2: <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"

   3: "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

   4: <validators>

   5:     <field name="username">

   6:         <field-validator type="requiredstring">

   7:             <message key="user.required"/>

   8:         </field-validator>

   9:     </field>

  10:     <field name="password">

  11:         <field-validator type="requiredstring">

  12:             <message key="password.required"/>

  13:         </field-validator>

  14:     </field>

  15: </validators>

怎么样,这个xml结构是不是非常清晰易懂?使用<filed>段标识我们需要进行验证的字段,使用<filed-validator>中的type字段指定我们需要进行何种验证,而<message>部分则定义了出错时如何显示信息。这里要注意的是,当你使用了Struts2中的验证器之后,你需要给Action增加一个input的映射,此映射应该指向我们最初提交动作发生的页面,如实例中的Login这个Action,我们需要将input指向我们的login.jsp页面。修改后的struts.xml文件如下:

   1: <?xml version="1.0" encoding="UTF-8"?>

   2: <!DOCTYPE struts PUBLIC

   3:     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

   4:     "http://struts.apache.org/dtds/struts-2.0.dtd">

   5: <struts>

   6:     <package name="struts2" extends="struts-default">

   7:         <action name="Login" class="com.kaisir.www.struts2demo.LoginAction">

   8:             <result name="success">/welcome.jsp</result>

   9:             <result name="error">/error.jsp</result>

  10:             <result name="input">/login.jsp</result>

  11:         </action>

  12:     </package>

  13: </struts>

此时我们部署项目,并进行测试,会发现若不填用户名、密码,则系统会给出相应的提示。

小贴士:
当初实现验证的时候我以为不继承ActionSupport即可,但是发现不行,系统会报如下错误:
“严重: Validation error for password:password.required”
所以当你出现类似的错误时,应先检查是否忘记继承ActionSupport类。

说完了验证部分,我们来侃侃国际化部分,Struts2中对国际化的支持几乎是自动的,他会自动的检索你浏览器的首选语言,并按照首选语言来读取相应的语言文件。不说废话,上代码。

首先我们需要完成语言文件,在这里我以中文(zh_CN)及英文(en_US)作为实例语言,其语言文件如下:

messageResource_zh_CN.properties:

loginPage=u767Bu5F55u9875u9762

errorPage=u9519u8BEFu9875u9762

successPage=u767Bu5F55u6210u529F

failTip=u5BF9u4E0Du8D77uFF0Cu4F60u4E0Du80FDu767Bu5F55uFF01

successTip=u6B22u8FCE,{0},u4F60u5DF2u6210u529Fu767Bu5F55u3002

user.required=u7528u6237u540Du5FC5u586B

password.required=u5BC6u7801u5FC5u987Bu586Bu5199

username=u7528u6237u540D

password=u5BC6u7801

在这里,要注意的是,我使用了myeclipse编写配置文件,故他自动的将中文转义了,若是手动编写,需要手工调用native2ascii.exe文件来完成转义工作。

messageResource_en_US.properties

loginPage=LoginPage

errorPage=ErrorPage

successPage=SuccessPage

failTip=Sorry,You can't login in!

successTip=Welcome,{0},you has logged in!

user.required=Require Username!

password.required=Require Password!

username=Username

password=Password

光有语言文件还不够,我们还需要创建一个struts.properties文件来告诉Struts2我们有语言文件可用。

struts.properties

struts.custom.i18n.resources=messageResource

最后剩下的就是改写我们的jsp文件,让他调用语言文件了,主要使用<s:text name=””>这个标签~

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%@ taglib prefix="s" uri="/struts-tags"  %>

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <title><s:text name="loginPage"/></title>

  </head>

  

  <body>

      <s:form action="Login">

          <s:textfield name="username" label="%{getText('username')}"></s:textfield>

          <s:textfield name="password" label="%{getText('password')}"></s:textfield>

          <s:submit label="提交"></s:submit>

      </s:form>

  </body>

</html>

要注意的是,在这里Struts2中不允许标签的嵌套,所以想要在textfield标签中嵌套国际化支持的标签是不行了,但是我们可以变通一下,毕竟国际化的字符串就像全局的资源,故可以使用”%{getText(‘name’)}”这样的形式来调用国际化文件 :)

Ok,部署到Web容器中,看看怎么样?