tag:blogger.com,1999:blog-266481502023-11-16T00:49:48.480+08:00yuweijun'blog俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.comBlogger722125tag:blogger.com,1999:blog-26648150.post-33576334401179455962011-12-20T11:37:00.001+08:002011-12-20T11:37:07.949+08:00apache2.2 日志中的一些注意事项<span class="Apple-style-span" style="color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;line-height:22px;background-color:rgb(255,255,255)">一些说明</span><br style="word-wrap:break-word;color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;text-align:left;background-color:rgb(255,255,255)"> <span class="Apple-style-span" style="color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;line-height:22px;text-align:left;background-color:rgb(255,255,255)">出于安全考虑,从2.0.46版本开始,%r, %i, %o 中的特殊字符,除了双引号(")和反斜线(\)分别用 \" 和 \\ 进行转义、空白字符用C风格(\n, \t 等)进行转义以外,非打印字符和其它特殊字符使用 \xhh 格式进行转义(hh是该字符的16进制编码)。在2.0.46以前的版本中,这些内容会被完整的按原样记录。这种做法将导致客户端可以在日志中插入控制字 符,所以你在处理这些日志文件的时候要特别小心。</span><br style="word-wrap:break-word;color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;text-align:left;background-color:rgb(255,255,255)"> <br style="word-wrap:break-word;color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;text-align:left;background-color:rgb(255,255,255)"><span class="Apple-style-span" style="color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;line-height:22px;text-align:left;background-color:rgb(255,255,255)">在2.0版本中(不同于1.3),%b 和 %B 格式字符串并不表示发送到客户端的字节数,而只是简单的表示HTTP应答字节数(在连接中断或使用SSL时与前者有所不同)。mod_logio提供的 %O 格式字符串将会记录发送的实际字节数。</span><br style="word-wrap:break-word;color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;text-align:left;background-color:rgb(255,255,255)"> <div><span class="Apple-style-span" style="color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;line-height:22px;text-align:left;background-color:rgb(255,255,255)"><br></span></div><div><span class="Apple-style-span" style="color:rgb(68,68,68);font-family:Verdana,Helvetica,Arial,sans-serif;font-size:14px;line-height:22px;text-align:left;background-color:rgb(255,255,255)"><div> <span class="Apple-tab-span" style="white-space:pre"> </span>String url = "<a href="http://www.baidu.com/s?cl=3&wd=\\xe6\\x90\\x9e\\xe7\\xac\\x91\\xe6\\xbc\\xab\\xe7\\x94\\xbb\\xe9\\x9b\\x86">http://www.baidu.com/s?cl=3&wd=\\xe6\\x90\\x9e\\xe7\\xac\\x91\\xe6\\xbc\\xab\\xe7\\x94\\xbb\\xe9\\x9b\\x86</a>";</div> <div><span class="Apple-tab-span" style="white-space:pre"> </span>String replaced = url.replaceAll("\\\\x", "%");</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>String decode = URLDecoder.decode(replaced, "utf-8");</div> </span></div> 俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-47313799320719532062011-07-02T15:31:00.001+08:002011-07-02T15:32:41.546+08:00clear run history in gnome panelrun "gconf-editor" and find "gnome-panel", modify "history-gnome-run".俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-11325435148507473072011-07-02T15:26:00.002+08:002011-07-02T15:30:37.054+08:00Xen and ntpdatentpdate在XEN虚拟机上执行后,不能更新当前时间。<br />修复方法:<br />将下面的指令加入/etc/rc.local文件后重启机器就可以,不重启的话手动在命令行中运行此命令。<br /><div class="pre"><br />echo 1 > /proc/sys/xen/independent_wallclock<br />ntpdate ntp.ubuntu.com > /dev/null<br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-45347764174829241192011-07-02T15:16:00.000+08:002011-07-02T15:18:06.469+08:00nginx rewrite command specrewrite<br />syntax: rewrite regex replacement flag<br /><br />default: none<br /><br />context: server, location, if<br /><br />This directive changes URI in accordance with the regular expression and the replacement string. Directives are carried out in order of appearance in the configuration file.<br /><br />Flags make it possible to end the execution of rewrite directives.<br /><br />If the replacement string begins with http:// then the client will be redirected, and any further rewrite directives are terminated.<br /><br />Flags can be any of the following:<br /><br />last - completes processing of rewrite directives, after which searches for corresponding URI and location<br />break - completes processing of rewrite directives<br />redirect - returns temporary redirect with code 302; it is used if the substituting line begins with http://<br />permanent - returns permanent redirect with code 301<br />Note that if a redirect is relative (has no host part), then when redirecting Nginx uses the "Host" header if the header match name of server_name directive or the first name of server_name directive, if the header does not match or is absent. If no server_name is set, then the local hostname is used. If you want Nginx to always use the "Host" header, you can use a wildcard "*" server_name (but see the restrictions on doing so). Example:<br /><div class="pre"><br />rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;<br />rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;<br />return 403;<br /></div><br />But if we place these directives in location /download/, then it is necessary to replace flag "last" by "break", otherwise Nginx will hit the 10 cycle limit and return error 500:<br /><div class="pre"><br />location /download/ {<br /> rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;<br /> rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;<br /> return 403;<br />}<br /></div><br />If in the line of replacement arguments are indicated, then the rest of the request arguments are appended to them. To avoid having them appended, place a question mark as the last character:<br /><div class="pre"><br /> rewrite ^/users/(.*)$ /show?user=$1? last;<br /></div><br />Note: for curly braces( { and } ), as they are used both in regexes and for block control, to avoid conflicts, regexes with curly braces are to be enclosed with double quotes (or single quotes). For example, to rewrite URLs like:<br /><br />/photos/123456<br />to:<br /><br />/path/to/photos/12/1234/123456.png<br />use the following (note the quotes enclosing the regex):<br /><div class="pre"><br />rewrite "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;<br /></div><br />If you specify a ? at the end of a rewrite then Nginx will drop the original $args (arguments). When using $request_uri or $uri&$args you should specify the ? at the end of the rewrite to avoid Nginx doubling the query string.<br /><br />Example using $request_uri in a rewrite from www.example.com to example.com<br /><div class="pre"><br />server {<br /> server_name www.example.com;<br /> rewrite ^ http://example.com$request_uri? permanent;<br />}<br /></div><br />Also rewrite operates only on path, not parameters. To rewrite a URL with parameters to another URL, use this instead:<br /><div class="pre"><br />if ($args ^~ post=100){<br /> rewrite ^ http://example.com/new-address.html? permanent;<br />}<br /></div><br />Note that the $args variable is not decoded, unlike URIs during location matching.俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-77458379113455471922011-07-02T15:12:00.002+08:002011-07-02T15:15:21.625+08:00phpunit error in ubuntu 11.04Got below warning when run phpunit in ubuntu 11.04:<br /><br />PHP Warning: require_once(PHP/CodeCoverage/Filter.php): failed to open stream: No such file or directory in /usr/bin/phpunit on line 38<br />PHP Stack trace:<br />PHP 1. {main}() /usr/bin/phpunit:0<br />PHP Fatal error: require_once(): Failed opening required 'PHP/CodeCoverage/Filter.php' (include_path='.:/usr/share/php:/usr/share/pear') in /usr/bin/phpunit on line 38<br />PHP Stack trace:<br />PHP 1. {main}() /usr/bin/phpunit:0<br /><br />repair commands:<br /><div class="pre"><br />sudo apt-get remove phpunit<br />sudo pear channel-discover pear.phpunit.de<br />sudo pear channel-discover pear.symfony-project.com<br />sudo pear channel-discover components.ez.no<br />sudo pear update-channels<br />sudo pear upgrade-all<br />sudo pear install --alldeps phpunit/PHPUnit<br />sudo apt-get install phpunit<br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com1tag:blogger.com,1999:blog-26648150.post-27614414418599273762011-07-02T15:09:00.001+08:002011-07-02T15:11:45.688+08:00修复 ubuntu 11.04 亮度调节组合键功能安装N卡驱动之后,Thinkpad的Fn+Home调节亮度的组合键失效。<br />修改/etc/X11/xorg.conf 文件,加入Option那一行,重启生效。<br /><div class="pre"><br />Section "Device"<br /> Identifier "Device0"<br /> Driver "nvidia"<br /> VendorName "NVIDIA Corporation"<br /> BoardName "NVS 3100M"<br /> <span style="color: red;">Option "RegistryDwords" "EnableBrightnessControl=1"</span><br />EndSection<br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-56221617617149105142011-07-02T15:08:00.000+08:002011-07-02T15:09:04.829+08:00IDE aptana menu problem in ubuntu 11.04<div class="pre"><br />#!/bin/bash<br />export UBUNTU_MENUPROXY=0<br />/path/to/AptanaStudio3<br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-12177389377180820942011-07-02T15:06:00.000+08:002011-07-02T15:07:33.702+08:00Modifying the Query String In mod_rewrite of Apache2RewriteRule backreferences: These are backreferences of the form $N (0 <= N <= 9), which provide access to the grouped parts (in parentheses) of the pattern, from the RewriteRule which is subject to the current set of RewriteCond conditions..<br />RewriteCond backreferences: These are backreferences of the form %N (1 <= N <= 9), which provide access to the grouped parts (again, in parentheses) of the pattern, from the last matched RewriteCond in the current set of conditions.<br /><br />By default, the query string is passed through unchanged. You can, however, create URLs in the substitution string containing a query string part. Simply use a question mark inside the substitution string to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine new and old query strings, use the [QSA] flag.<br /><div class="pre"><br /> # rewrite without old query string<br /> RewriteCond %{QUERY_STRING} ^page_id=(.*)$<br /> RewriteRule ^index.php$ /index/%1.php? [R=301,L]<br /><br /> # rewrite with new query string<br /> RewriteCond %{QUERY_STRING} ^page_id=(.*)$<br /> RewriteRule ^index.php$ /index/%1.php\?test=1 [R=301,L]<br /><br /> # rewrite with combined old query string<br /> RewriteCond %{QUERY_STRING} ^page_id=(.*)$<br /> RewriteRule ^index.php$ /index/%1.php\?test=1 [QSA,R=301,L]<br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-43034229015834048902011-07-02T14:53:00.000+08:002011-07-02T14:59:09.641+08:00globalEval function of jQuery changed in version 1.6globalEval function of jquery before version 1.6, such as 1.5.2 and 1.2.6, source code:<br /><div class="pre">// Evalulates a script in a global context<br /> globalEval: function( data ) {<br /> if ( data && rnotwhite.test(data) ) {<br /> // Inspired by code by Andrea Giammarchi<br /> // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html<br /> var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,<br /> script = document.createElement( "script" );<br /><br /> if ( jQuery.support.scriptEval() ) {<br /> script.appendChild( document.createTextNode( data ) );<br /> } else {<br /> script.text = data;<br /> }<br /><br /> // Use insertBefore instead of appendChild to circumvent an IE6 bug.<br /> // This arises when a base node is used (#2709).<br /> head.insertBefore( script, head.firstChild );<br /> head.removeChild( script );<br /> }<br /> },</div><br />globalEval function of jquery 1.6 source code:<br /><div class="pre"> // Evaluates a script in a global context<br /> // Workarounds based on findings by Jim Driscoll<br /> // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context<br /> globalEval: function( data ) {<br /> if ( data && rnotwhite.test( data ) ) {<br /> // We use execScript on Internet Explorer<br /> // We use an anonymous function so that context is window<br /> // rather than jQuery in Firefox<br /> ( window.execScript || function( data ) {<br /> window[ "eval" ].call( window, data );<br /> } )( data );<br /> }<br /> },</div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-56376797394481831872011-07-02T14:51:00.001+08:002011-07-02T14:51:57.185+08:00rails 3.0.7 在ubuntu 11.04中安装问题<div class="pre"><br />$> sudo gem install rails<br /></div><br />This is the problematic part:<br /><br /> File not found: lib<br />ERROR: While generating documentation for rails-3.0.7<br />... MESSAGE: exit<br />...<br /><br />这个问题是因为Rails新版本使用了最新的Rdoc/ri版本,而系统中原来的版本有些功能不是兼容的,因此报错。<br />卸载已经安装的rails3,先安装rdoc-data成功后再安装rails3。<br /><div class="pre"><br />$> sudo gem uninstall rails --version 3.0.7<br />$> sudo gem install rdoc-data<br />$> sudo rdoc-data --install<br />$> sudo gem install rails<br /></div><br />安装成功信息:<br />Successfully installed rails-3.0.7<br />1 gem installed<br />Installing ri documentation for rails-3.0.7...<br />Installing RDoc documentation for rails-3.0.7...俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-15645106669887160532011-05-18T17:25:00.000+08:002011-05-18T17:26:18.073+08:00configure php xdebug in ubuntu先安装php和xdebug,并配置php.ini文件<br />$> sudo apt-get install apache2 php5 xdebug<br />$> sudo vi /etc/php5/apache2/php.ini<br />在php.ini文件最后面添加下面3行内容,其他如zend_extension的值ubuntu在xdebug安装完会自动在/etc/php5/conf.d/xdebug.ini中设置:<br /><div class="pre"><br />[Xdebug]<br />xdebug.remote_autostart=On<br />xdebug.remote_enable=On<br /></div><br /><br />然后从eclipse.org官网下载eclipse for php版本:<br />我的电脑是ubuntu 11.04 64位的机器,所以下载64位的版本:<br />$> wget http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/helios/SR2/eclipse-cpp-helios-SR2-linux-gtk-x86_64.tar.gz&url=http://mirrors.ustc.edu.cn/eclipse/technology/epp/downloads/release/helios/SR2/eclipse-cpp-helios-SR2-linux-gtk-x86_64.tar.gz&mirror_id=1093<br /><br />打开eclipse之后,进入window-Performances-PHP-Debug设置面板,在右边的“PHP Debuger”中选择Xdebug,然后点击Xdebug的Configure,再选择其中的Xdebug进行编辑,将"Accept remote session(JIT)"的值设置为"localhost",(默认值为off时,是不会开启xdebug调试功能的),这个设置和php.ini设置必须要都做到才会开启debug功能。<br />这样配置就完成了,可以打开浏览器访问PHP页面,在eclipse中的PHP源码,如果有设置断点就会进入Debug模式。<br /><br />在Debug模式中的Server就使用默认的http://localhost,"PHP Executeable"原来是"None Defined",这个没有关系,也可以手动设置一个值,如"/usr/bin/php5",这个不影响debug功能。<br /><br />抄录部分xdebug远程调试相关的参数说明,官网可参考http://xdebug.org/docs/remote中的说明。<br /><div class="pre"><br />xdebug.remote_autostart<br />类型:布尔型 默认值:0<br />一般来说,你需要使用明确的HTTP GET/POST变量来开启远程debug。而当这个参数设置为On,xdebug将经常试图去开启一个远程debug session并试图去连接客户端,即使GET/POST/COOKIE变量不是当前的。<br /><br />xdebug.remote_enable<br />类型:布尔型 默认值:0<br />这个开关控制xdebug是否应该试着去连接一个按照xdebug.remote_host和xdebug.remote_port来设置监听主机和端口的debug客户端。<br /><br />xdebug.remote_host<br />类型:字符串 默认值:localhost<br />选择debug客户端正在运行的主机,你不仅可以使用主机名还可以使用IP地址<br /><br />xdebug.remote_port<br />类型:整型 默认值:9000<br />这个端口是xdebug试着去连接远程主机的。9000是一般客户端和被绑定的debug客户端默认的端口。许多客户端都使用这个端口数字,最好不要去修改这个设置。<br /></div><br />Windows的设置可以参考下面这个链接中说明:http://be-evil.org/post-70.html<br />Mac中可以下载一个MacGDBp,这个用来调试PHP,非常好用,与IDE就完全脱离关系了。俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-15420669752180089892011-04-19T14:28:00.000+08:002011-04-19T14:29:08.731+08:00get window scroll bar width浏览器因为操作系统或者系统主题不同,导致当前窗口中的scrollbar的宽度不一致,在web应用中影响了页面布局,下述方法可以获取到当前浏览器的滚动条宽度:<br /><div class="pre"><br />function getScrollBarWidth () {<br /> var inner = document.createElement('p');<br /> inner.style.width = "100%";<br /> inner.style.height = "200px";<br /><br /> var outer = document.createElement('div');<br /> outer.style.position = "absolute";<br /> outer.style.top = "0px";<br /> outer.style.left = "0px";<br /> outer.style.visibility = "hidden";<br /> outer.style.width = "200px";<br /> outer.style.height = "150px";<br /> outer.style.overflow = "hidden";<br /> outer.appendChild (inner);<br /><br /> document.body.appendChild (outer);<br /> var w1 = inner.offsetWidth;<br /> outer.style.overflow = 'scroll';<br /> var w2 = inner.offsetWidth;<br /> if (w1 == w2) w2 = outer.clientWidth;<br /><br /> document.body.removeChild (outer);<br /><br /> return (w1 - w2);<br />};<br /></div><br /><br />Reference:http://www.alexandre-gomes.com/?p=115 <br />http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-73067700462028957922011-04-18T18:34:00.002+08:002011-04-19T14:27:59.875+08:00The classpath*: prefix of javaWhen constructing an XML-based application context, a location string may use the special classpath*: prefix:<br /><div class="pre"><br /> ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");<br /></div><br />This special prefix specifies that all classpath resources that match the given name must be obtained (internally, this essentially happens via a ClassLoader.getResources(...) call), and then merged to form the final application context definition.<br /><br />Classpath*: portability<br />The wildcard classpath relies on the getResources() method of the underlying classloader. As most application servers nowadays supply their own classloader implementation, the behavior might differ especially when dealing with jar files. A simple test to check if classpath* works is to use the classloader to load a file from within a jar<br />on the classpath:<br /><div class="pre"><br /> getClass().getClassLoader().getResources("someFileInsideTheJar").<br /></div><br />Try this test with files that have the same name but are placed inside two different locations.<br />In case an inappropriate result is returned, check the application server documentation for settings that might affect the classloader behavior.<br /><br />The "classpath*:" prefix can also be combined with a PathMatcher pattern in the rest of the location path, for example "classpath*:META-INF/*-beans.xml". In this case, the resolution strategy is fairly simple: a ClassLoader.getResources() call is used on the last non-wildcard path segment to get all the matching resources in the class loader hierarchy, and then off each resource the same PathMatcher resoltion strategy described above is used for the wildcard subpath.<br /><br />Memo: This article content copied from spring 3.0 framework reference PDF file.俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-33398256868362646972011-04-18T18:26:00.002+08:002011-04-18T18:33:35.428+08:00linux命令nc使用实例说明使用netcat检查服务器的指定的端口是否开通:<br />root@localhost:~$ nc -z -v 192.168.1.242 80<br />linux.local [192.168.1.242] 80 (www) open<br /><br />使用netcat扫描端口:<br />root@localhost:~$ nc -z -v -w 1 192.168.1.242 1-100<br />linux.local [192.168.1.242] 80 (www) open<br />linux.local [192.168.1.242] 22 (ssh) open<br /><br />使用netcat模拟HTTP请求:<br />root@localhost:~$ nc www.google.com.hk 80<br />GET / HTTP/1.1<br />Host: www.google.com.hk<br />User-Agent: google-chrome9<br /><br />HTTP/1.1 200 OK<br />Date: Mon, 18 Apr 2011 08:56:03 GMT<br />Expires: -1<br />Cache-Control: private, max-age=0<br />Content-Type: text/html; charset=Big5<br />Set-Cookie: PREF=ID=5006f5c292697224:FF=0:NW=1:TM=1303116963:LM=1303116963:S=Lr6ijyXSbmjA6bmZ; expires=Wed, 17-Apr-2013 08:56:03 GMT; path=/; domain=.google.com.hk<br />Set-Cookie: NID=46=ky6egq_YajJNEzdnM39_2u3CFq2hJLvSVuQm6BokYXSBKhAefFIuL-ZsZOvnDpMISnI2glY25IZxS8_5G0V-EHj-oEc7KRGW4rSZk9yIRnCgsPnm43qhLUMb9hJuKeVW; expires=Tue, 18-Oct-2011 08:56:03 GMT; path=/; domain=.google.com.hk; HttpOnly<br />Server: gws<br />X-XSS-Protection: 1; mode=block<br />Transfer-Encoding: chunked<br />[......]俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-71666256376472494442011-01-28T15:53:00.001+08:002011-01-28T15:58:52.717+08:00Tomcat URL 支持中文文件名在tomcat的默认配置情况下,如果访问一个"中文.html"页面,服务器会抛出文件找不到的错误提示,这需要对tomcat的配置文件略作改动,为Connector设置URIEncoding的参数。<br />在server.xml文件中找到8080服务器配置的一段设置:<br /><div class="pre"><Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8"/><br /></div><br /><br />加上 URIEncoding="UTF-8" 这句就可以识别中文文件名了,同时如果url中的参数值有中文,服务器端也可以正常解析对应的参数,否则服务器端Java程序中取到的参数是以ISO-8859-1编码的,有中文字符的参数值是乱码的,加了URIEncoding="UTF-8"之后,就可以正确获取到参数值了。<br />对于这个参数的说明,可以查看tomcat目录中的doc帮助文件,也可以从官网中找到此参数的解释。<br /><br />References: <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html">官方文档</a><br /><a href="http://confluence.atlassian.com/display/DOC/Configuring+Tomcat's+URI+encoding">Configure tomcat's uri encoding</a>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-19840632062996395862011-01-28T15:39:00.002+08:002011-01-28T15:40:18.430+08:00IE throw null object exception when flash call javascript function用open flash chart第一次正常载入一个图表到页面之后,当使用jQuery.fn.empty()方法移除此图表时,IE中会抛出一个错误,其他浏览器都是正常的,内容如下:<br /><div class="pre"><br />JScript - script block, line 1 character 124<br />'null' is null or not an object<br /></div><br />通过IE8的debug工具可以看到出错时,javascript正在执行的代码如下:<br /><div class="pre"><br />try { document.getElementById("report-charts").SetReturnValue(__flash__toXML(ofc_resize([66,-96,66,-87])) ); } catch (e) { document.getElementById("report-charts").SetReturnValue("<undefined/>"); }<br /></div><br />这个并不是页面中的javascript代码,应该是flash中调用外部javascript方法时,所使用的javascript代码,在IE8中断点调试,可以发现document.getElementById("report-charts")的结果为null,所以抛出了以上错误。<br />避过此问题的办法是在陊除已经载入的图表时,不调用jQuery.fn.empty()方法,而是直接使用jQuery.fn.html(''),将flash所在父元素的内容置空:<br /><div class="pre"><br /> $('#report-charts').parent().html('');<br /> // 如果使用$('#report-charts').parent().empty();在IE中则会报错<br /> // ... 重新生成report-charts对象并载入新的flash图表<br /> swfobject.embedSWF(ofc, "report-charts", "100%", "300", "9.0.0", "expressInstall.swf", {"get-data":"get_chart_0"});<br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com1tag:blogger.com,1999:blog-26648150.post-60966398919903382132011-01-27T17:46:00.001+08:002011-01-28T15:42:13.615+08:00sqlite3 database disk image is malformedsqlite3 报错提示: database disk image is malformed<br /><br />看提示意思是指数据库的数据文件格式发生异常,所以数据查询和写入不正常,在网上google了一些文章,找到了一个解决方法。<br />一般来说,sqlite3的数据文件发生这个问题,想直接修复数据是行不通了,<br />在进入sqlite3后的命令行中,运行以下命令:<br />PRAGMA integrity_check<br />*** in database main ***<br />On tree page 120611 cell 0: 3 of 4 pages missing from overflow list starting at 120617<br />On tree page 120616 cell 0: 3 of 4 pages missing from overflow list starting at 120621<br />On tree page 3309 cell 0: 3 of 4 pages missing from over<br /><br />假设原数据库名: abc.db<br /><br />运行命令:<br />$> sqlite3 abc.db<br /><br />.output "data.sql"<br />.dump<br />.quit<br /><br />再建个新数据库 abcd.db<br />$> sqlite3 abcd.db<br /><br />然后<br /><br />.read "data.sql"<br />.quit<br /><br />然后修复原来的数据库名和文件权限,应该就没事了。<br /><br />References: <a href="http://vi-i.blogspot.com/2009/02/sqlite3-database-disk-image-is.html">sqlite3 database disk image malformed</a>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-411632759614051212011-01-27T17:24:00.000+08:002011-01-27T17:25:25.578+08:00Open Flash Chart IO ERROR Loading test data Error #2032在IE6中使用open flash chart2加载图表的json数据时,第一次载入数据,图表渲染正常,第二次就会报一个错误,提示数据加载错误:<br /><div class="pre"><br />Open Flash Chart<br />IO ERROR<br />Loading test data<br />Error #2032<br /></div><br />而在其他的浏览器,如IE8/firefox/chrome中都是正常的,在网上搜索了一些回答,其中有人提到说这是因为浏览器的缓存造成的问题,只要在用swfobject加载open-flash-chart.swf时,在url后面加上一个动态参数,让浏览器不要使用本地缓存:<br /><div class="pre"><br />swfobject.embedSWF("open-flash-chart.swf?t=" + (new Date()).getTime(), "charts-div-id", "100%", "300", "9.0.0", "expressInstall.swf", {"get-data":"get_chart_0"});<br /></div><br /><br />References: <a href="http://www.sodiy.com.cn/blog/201011/Open_Flash_Chart_IO_ERROR_2032.html">Open Flash Chart IO ERROR Loading test data Error #2032</a>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-64430455416907834582011-01-13T11:30:00.001+08:002011-01-13T11:42:52.399+08:00springmvc 中ajax提交发生乱码问题这个问题目前只是在springmvc项目中碰到,在IE和Chrome中,当用jQuery.post()方法发起ajax请求时,Controller中收到的中文内容变成乱码了,而在firefox中用jQuery.post()进行ajax请求时是正常的。<br />在Controller中调用如下代码(项目为UTF-8编码):<br /><div class="pre"><br /> // name 是post收到的字符串变量名<br /> System.out.println(new String(name.getBytes(HTTP.ISO_8859_1), HTTP.UTF_8));<br /></div><br />可以看到乱码恢复正常,说明IE和Chrome提交的ajax请求中的内容被编码成 ISO-8859-1 编码了。<br />而实际上,对于IE而已,所有的ajax请求都是以UTF-8方式发起的,通过以下方式设置ajax请求的编码为GBK实际是没有用的,服务器收到仍然是UTF-8编码的请求体:<br /><div class="pre"><br /> xmlhttp.setRequestHeader( "Content-Type", "text/html;charset=GBK" ); <br /> // or<br /> xmlhttp.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=GBK");<br /></div><br />因此可以肯定是springmvc在收到POST请求后,将请求体的数据用 ISO-8859-1 编码来处理了,最后传到Controller中时变成了乱码,但是为何firefox中提交的却仍然是正确的呢?<br />在firebug中观察firefox中的ajax请求头,可以看到firebug中的提示:<br /><div class="pre"><br /> Content-Type application/x-www-form-urlencoded; charset=UTF-8<br /></div><br />而在IE中用http analysis工具看到的却是:<br /><div class="pre"><br /> Content-Type application/x-www-form-urlencoded<br /></div><br />google Chrome中与IE一样,ajax请求头中没有指明编码,所以Chrome和IE一样将发生乱码了。<br />查看jquery-1.4.4.js源码可以看到,jQuery中原来的 contentType设置为"application/x-www-form-urlencoded",IE和Chrome中的请求头显示是正确的,没有问题,反而是firefox将contentType中设置了编码。<br />从这个请求头分析来看,应该是springmvc没有得到请求的编码,而将其内容设置为ISO-8859-1了,因此发生了乱码的情况。<br /><br />解决方法还是参考firefox的请求头,在contentType中指定编码,明确告诉服务器端,当前请求体的编码方式为UTF-8。<br /><div class="pre"><br /> xmlhttp.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");<br /></div><br />如果使用jQuery发起ajax请求,javascript的代码改为如下方式发起ajax请求,而不是以$.post()和$.get()等快捷方法:<br /><div class="pre"><br /> $.ajax({<br /> url: url,<br /> type: "POST",<br /> dataType: "html",<br /> contentType: "application/x-www-form-urlencoded; charset=UTF-8",<br /> data: data,<br /> complete:function(data) {<br /> }<br /> });<br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-44241074961187614032010-12-19T15:36:00.002+08:002010-12-19T15:40:53.652+08:00spring的属性编辑器CustomDateEditor及日期对象转化在spring mvc的Controller中,属性在通过依赖注入(DI)时,普通数据类型都能够辨识。但诸如Date之类,就需要自定义属性编辑器解决。否则报如下错误:<br />org.springframework.beans.TypeMismatchException:<br />Failed to convert property value of type [java.lang.String] to required type<br />[java.util.Date] for property 'date'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'date': no matching editors or conversion strategy found<br />这表示spring无法找到合适的转换策略,需要自己写一个转换器,在spring中称之为属性编辑器。<br />spring中的属性编辑器可以将字符串转换为相应的对象,然后注入到其它对象中去。<br />编写自己的属性编辑器的步骤很简单,属性编辑器类需要从java.beans.PropertyEditorSupport类继承,在这个类中有一个setAsText方法,这个方法有一个String类型的参数,通过这个方法,可以将String类型的参数值转换成其他类型的属性。在这个方法中我们还需要使用一个setValue方法,就来指定转换后的对象实例。<br />spring 中有个 CustomDateEditor 的类就是继承 PropertyEditorSupport 的一个属性编辑器,在Controller中添加一个@InitBinder的Annotation到某个方法上,在方法中指明日期字符串的格式,就可以将符合此格式的字符串转化为日期对象,代码如下:<br /><div class="pre"><br />/**<br /> * <pre><br /> * HTML forms work with string values only, when your Authority is a complex bean. You need to configure a PropertyEditor to perform conversion between Authority and String:<br /> * <br /> * @InitBinder <br /> * public void initBinder(WebDataBinder b) {<br /> * b.registerCustomEditor(Authority.class, new AuthorityEditor());<br /> * }<br /> * <br /> * private class AuthorityEditor extends PropertyEditorSupport {<br /> * @Override<br /> * public void setAsText(String text) throws IllegalArgumentException {<br /> * // 另外一个例子是根据字符串,从数据库中查找返回对象<br /> * setValue(authorityService.findById(Long.valueOf(text))); <br /> * }<br /> * <br /> * @Override<br /> * public String getAsText() {<br /> * return ((Authority) getValue()).getId();<br /> * }<br /> * }<br /> * </pre><br /> * <br /> * 这个方法用来将页面表单上传的Date字符串转化成java的Date对象<br /> * <br /> * @param binder<br /> */<br />@InitBinder<br />public void initBinder(WebDataBinder binder) {<br /> DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");<br /> dateFormat.setLenient(false);<br /> binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));<br />}<br /></div><br /><br />Reference: <a href="http://www.mkyong.com/spring/spring-how-to-pass-a-date-into-bean-property-customdateeditor/">how to pass a date into bean property</a>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-64977285150216566912010-12-19T15:08:00.003+08:002010-12-19T15:16:23.090+08:00comments bug on firefox<div class="pre"><br /><body><br /><!--<br /><br />这段HTML注释代码因为中间多了2个连字符,在firefox中会导致解析出错,这段内容被做为正常的文本内容显示在浏览器中。<br />This entire comment -- will show in web browser<br /><br />--><br /></body></div><br />Reference: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=214476"> (SGMLComment) Mozilla interprets a -- (two dashes in a row) inside of a comment or an include improperly </a>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-10069935584327763812010-12-19T15:06:00.001+08:002010-12-19T15:07:56.063+08:00javascript中array方法调用返回window对象array中的很多方法通过call和apply调用时会返回window对象,如下写法在Firefox、Chrome等浏览器中会取到window对象:<div class="pre"><br />window === ([]).sort.call();<br />window === ([]).reverse.call();<br />([]).concat.call()[0] === window</div><br /><br />可以将这些array的方法重写,避免它在运行时的this指向window,如重写sort方法:<br /><div class="pre"><br />Array.prototype.sort = (function(sort) { return function(callback) {<br /> return (this == window) ? null : (callback ? sort.call(this, function(a,b) {<br /> return callback(a,b)}) : sort.call(this));<br />}})(Array.prototype.sort);</div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-23415467442502917102010-11-27T13:28:00.000+08:002010-11-27T13:30:15.807+08:00用maven来运行一个main方法或者启动Server在maven项目的pom.xml文件的plugins中加入"exec-maven-plugin"这个插件,这个在运行"mvn package"时,会在当前的mvn进程中直接执行指定的class文件的main方法,也可以配置其他的参数,让此main在另一个java进程中启动。如果其中将phase的内容改为"test",就会在运行"mvn test"时执行main方法,也可以在命令行里直接用mvn运行,如下注释说明。<br />更详细的信息和配置方法,可参考<a href="http://mojo.codehaus.org/exec-maven-plugin/usage.html">http://mojo.codehaus.org/exec-maven-plugin/usage.html</a>说明。<br /><div class="pre"><!-- commandline: mvn exec:java -Dexec.mainClass="org.phpfirefly.test.Server" --><br /><plugin><br /> <groupId>org.codehaus.mojo</groupId><br /> <artifactId>exec-maven-plugin</artifactId><br /> <version>1.1</version><br /> <executions><br /> <execution><br /> <phase>package</phase><br /> <goals><br /> <goal>java</goal><br /> </goals><br /> </execution><br /> </executions><br /> <configuration><br /> <mainClass>org.phpfirefly.test.Server</mainClass><br /> </configuration><br /></plugin><br /></div>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-50121706825733770682010-11-27T13:06:00.003+08:002010-11-27T13:12:40.701+08:00maven2 repository server install以下为安装免费版本的nexus maven2服务器和简单的设置过程:<div class="pre"><br />$> wget http://nexus.sonatype.org/downloads/nexus-oss-webapp-1.8.0-bundle.tar.gz<br />$> tar zxvf nexus-oss-webapp-1.8.0-bundle.tar.gz<br />$> mv nexus-webapp-1.8.0-bundle /usr/local/nexus <br />$> cd /usr/local/nexus <br />$> ls bin/jsw/ <br />$> bin/jsw/linux-x86-32/nexus start <br />$> tail -f logs/wrapper.log </div><br />启动服务后默认URL为:http://localhost:8081/nexus<br />默认的登录名和密码:admin/admin123<br />nexus默认是关闭远程索引下载功能的,主要是担心会造成对服务器的巨大负担,需要我们手工开启。 <br />开启的方式: 点击Administration菜单下面的Repositories,将这4个仓库Apache Snapshots,Google code,Codehaus Snapshots,Maven Central的Configuration - Download Remote Indexes修改为true。然后在这三个仓库上分别右键,选择reIndex,这样Nexus就会去下载远程的索引文件。<br />部署构件至Nexus: Nexus提供了两种方式来部署构件,你可以从UI直接上传,也可以配置Maven部署构件,在上传一个版本时,可以将jar包和source jar包一起上传。<br /><br />本地maven仓库配置文件,默认位置在用户根目录下的".m2"目录,文件名为settings.xml,如果没有,则创建一份,更新内容如下:<div class="pre"><br /><?xml version="1.0" encoding="UTF-8"?><br /><br /><settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"><br /><br /> <pluginGroups><br /> <!-- pluginGroup<br /> | Specifies a further group identifier to use for plugin lookup.<br /> <pluginGroup>com.your.plugins</pluginGroup><br /> --><br /> <pluginGroup>org.mortbay.jetty</pluginGroup><br /> </pluginGroups><br /><br /> <profiles><br /> <profile><br /> <id>nexus</id><br /> <repositories><br /> <repository><br /> <id>nexus</id><br /> <name>local nexus</name><br /> <url>http://localhost:8081/nexus/content/groups/public/</url><br /> <releases><br /> <enabled>true</enabled><br /> </releases><br /> <snapshots><br /> <enabled>true</enabled><br /> </snapshots><br /> </repository><br /> </repositories><br /> <pluginRepositories> <br /> <pluginRepository> <br /> <id>nexus</id> <br /> <name>local nexus</name> <br /> <url>http://localhost:8081/nexus/content/groups/public/</url><br /> <releases><enabled>true</enabled></releases> <br /> <snapshots><enabled>false</enabled></snapshots> <br /> </pluginRepository> <br /> </pluginRepositories> <br /> </profile><br /> </profiles><br /> <activeProfiles><br /> <activeProfile>nexus</activeProfile><br /> </activeProfiles><br /></settings><br /></div><br />References: http://juvenshun.javaeye.com/blog/349534<br />http://wj98127.javaeye.com/blog/306358俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0tag:blogger.com,1999:blog-26648150.post-52600441455388172412010-11-05T10:55:00.002+08:002010-11-05T15:11:19.529+08:00get Xpath of html element在Firefox中有二个非常有用的插件,可以直接得到HTML页面中元素的XPath:<br /><br /><a href="https://addons.mozilla.org/en-US/firefox/addon/1095?id=1095">XPath Checker</a> - suggests XPath and can be used to test XPath results.<br /><a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> - XPath suggestions are just one of the many powerful features of this very useful add-on.<br /> <br />XPath的参考资料:<br /><br /><a href="http://www.w3schools.com/Xpath/">W3Schools XPath Tutorial</a><br /><a href="http://www.w3.org/TR/xpath">W3C XPath Recommendation</a><br /><a href="http://www.zvon.org/xxl/XPathTutorial/General/examples.html">XPath Tutorial - with interactive examples</a>俞 伟军http://www.blogger.com/profile/17200405397542410318noreply@blogger.com0