Tomcat配置多域名等

1.Tomcat配置多域名

      <Host name="www.qunmenghui.com" appBase="vhost_qunmh"
        unpackWARs="true" autoDeploy="false"
        xmlValidation="false" xmlNamespaceAware="false">
        <Alias>xn--lswx9to4g.com</Alias>
        <Alias>www.xn--lswx9to4g.com</Alias>
        <Alias>xn--6oq728go1f.com</Alias>
        <Alias>www.xn--6oq728go1f.com</Alias>
      </Host>

2.中文域名解析
中文域名归根结底其实还是英文域名,只不过走了层国内的DNS,吧中文解析成了英文在走国际
1)吧中文域名转为punycode 链接:http://www.cnkuai.cn/zhuanma.asp
2)同英文域名一样解析

3.配置系统根目录为根目录,主要没有ROOT目录

     <Host name="file01.dalitodo.net" appBase="/data/todo_html"
        autoDeploy="true"
        xmlValidation="false" xmlNamespaceAware="false">
        <Context path="" docBase="." debug="0" reloadable="true" /> 
     </Host>

4.虚拟目录

     <Host name="file01.dalitodo.net" appBase="vhost_dltd"
        autoDeploy="true"
        xmlValidation="false" xmlNamespaceAware="false">
        <Context path="/uploads" docBase="/data/uploads" debug="0" reloadable="true" /> 
     </Host>

这样在tomcat里可以通过/uploads来访问/data/uploads功能,在图片文件上传时候特别有用

linux下删除乱码文件

根据inode 来修改或删除linux 下乱码的文件

1. 创建测试文件:
touch 1?.txt

2. 查询inode :
[oracle@test]$ ll -i
total 14694452
17956913 -rw-r–r– 1 oracle oinstall          0 Jan 18 20:24 1?.txt

3. 修改测试文件名:
find . -inum 17956913 -exec mv {} file.txt \;

4. 检查修改结果
[oracle@test]$ ll
total 14694452
….
-rw-r–r– 1 oracle oinstall          0 Jan 18 20:24 file.txt

记录:删除乱码的文件可使用 find . -inum 17956913 -exec rm {} \;

Mac OS编译node-webkit概要

1)下载depot_tools,zip下载不了,直接git clone下

2)depot_tools加环境变量

3)gclient sync

a)python下载安装不了,可以手动安装python2.7.6,复制python.exe到depot_tools

b)git下载安装不了,可以手动安装git,设置环境变量到bin路径

c)sync先会下载chromium.src,有1.5G,如果用gclient sync会老是出错,因为太大了,国内环境大家都懂的。所以推荐使用github客户端来clone,clone下来后重命名到node-webkit/src

d)以后会clone88个工程,这个过程很懊恼,会话很久时间,googlesource.com网络有不是很稳定,所以先自己加个域名解析,会快点,如果是github的项目,建议跟c)一样,用客户端下载后放入目录。这里clone的都是chromium.src下的DEPS.git文件里的配置项目

e)88个项目都clone完成后,gclient会安装llvm/clang,然后编译。我使用的是OS X 11,编译时候老是提示clang: error: invalid deployment target for -stdlib=libc++ (requires OS X 10.7 or later) ,解决方案为修改node_webkit/src/tools/clang/scripts/update.sh MACOSX_DEPLOYMENT_TARGET=10.5 ==> MACOSX_DEPLOYMENT_TARGET=10.7

f)On OSX you’ll see error messages reporting cycle in .gyp file dependency graph detected. It can be ignored because gclient wants to run gyp_chromium without a switch we need. Please move on to the Build section
Error: Command /usr/bin/python src/build/gyp_chromium returned non-zero exit status 1 in /Users/gexin/Documents/nw_workspace/node_webkit
Hook ‘/usr/bin/python src/build/gyp_chromium’ took 42.73 secs

g)cd node-webkit/src
export GYP_GENERATORS=‘ninja’
./build/gyp_chromium content/content.gyp
ninja -C out/Release nw -j4

Linux unzip解压后中文名乱码

1.vi uzip文件
2.复制一下内容(Python)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# uzip.py

import os
import sys
import zipfile

print "Processing File " + sys.argv[1]

file=zipfile.ZipFile(sys.argv[1],"r");
for name in file.namelist():
    utf8name=name.decode('gbk')
    print "Extracting " + utf8name
    pathname = os.path.dirname(utf8name)
    if not os.path.exists(pathname) and pathname!= "":
        os.makedirs(pathname)
    data = file.read(name)
    if not os.path.exists(utf8name):
        fo = open(utf8name, "w")
        fo.write(data)
        fo.close
file.close()

3.chmod +x uzip
4../uzip xxxx.zip

Tomcat中文路径/文件名问题

原因:Tomcat Connector所用的URI解码默认用的是 ISO-8859-1,而一般浏览器默认用的发送编码为UTF-8,这样问题就出现了
解决:
在server.xml中类似如下配置:

<Connector port=”8080″ maxThreads=”150″ minSpareThreads=”25″ maxSpareThreads=”75″ enableLookups=”false” redirectPort=”8443″ acceptCount=”100″ debug=”0″ connectionTimeout=”20000″ disableUploadTimeout=”true” URIEncoding=”UTF-8″ />

其中关键是 URIEncoding=”UTF-8″ 这项,其含义是指定URI的编码为:UTF-8

checkbox和其父级容器事件传递问题

首先看下一下代码:

function contactsSel() {
	var that = $(this);
	var checkbox = that.find('input[type="checkbox"]');
	if (checkbox.prop('checked') == true) {
		that.css('background', '#ffffff');
		checkbox.prop('checked', false);
	} else {
		that.css('background', '#9ecaf0');
		checkbox.prop('checked', true);
	}
}

$("._contactsContainer li").on('click', contactsSel);

这样的效果会在单击li时候整个li的背景替换,并选中checkbox,看似完美,但是实际效果中会发现一个bug:
单击li没什么问题,单击checkbox时候,没有任何反应。why?
究其原因为checkbox单击时候事件传递给了li,单击checkbox选中了它,然后传递给li后执行contactSel,看到checkbox被选中就会取消选中。结果就是没单击一样。
fix方法:加checkbox单击事件

$("._contactsContainer input[name=\"em\"]").on('click', function () {
	var that = $(this);
	that.prop('checked', !that.prop('checked'));
});

jquery实现几分钟前、几小时前、几天前等时间差显示效果

1.<span class=”time timeago” title=”1411874275236″></span>

2.jQuery(“span.timeago”).timeago();


(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['jquery'], factory);
  } else {
    // Browser globals
    factory(jQuery);
  }
}(function ($) {
  $.timeago = function(timestamp) {
    if (timestamp instanceof Date) {
      return inWords(timestamp);
    } else if (typeof timestamp === "string") {
      return inWords($.timeago.parse(timestamp));
    } else if (typeof timestamp === "number") {
      return inWords(new Date(timestamp));
    } else {
      return inWords($.timeago.datetime(timestamp));
    }
  };
  var $t = $.timeago;

  $.extend($.timeago, {
    settings: {
      refreshMillis: 60000,
      allowFuture: false,
      localeTitle: false,
      cutoff: 0,
      strings: {
        prefixAgo: null,
        prefixFromNow: null,
        suffixAgo: "前",
        suffixFromNow: "from now",
        seconds: "1分钟",
        minute: "1分钟",
        minutes: "%d分钟",
        hour: "1小时",
        hours: "%d小时",
        day: "1天",
        days: "%d天",
        month: "1月",
        months: "%d月",
        year: "1年",
        years: "%d年",
        wordSeparator: "",
        numbers: []
      }
    },
    inWords: function(distanceMillis) {
      var $l = this.settings.strings;
      var prefix = $l.prefixAgo;
      var suffix = $l.suffixAgo;
      if (this.settings.allowFuture) {
        if (distanceMillis < 0) {
          prefix = $l.prefixFromNow;
          suffix = $l.suffixFromNow;
        }
      }

      var seconds = Math.abs(distanceMillis) / 1000;
      var minutes = seconds / 60;
      var hours = minutes / 60;
      var days = hours / 24;
      var years = days / 365;

      function substitute(stringOrFunction, number) {
        var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
        var value = ($l.numbers && $l.numbers[number]) || number;
        return string.replace(/%d/i, value);
      }

      var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
        seconds < 90 && substitute($l.minute, 1) ||
        minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
        minutes < 90 && substitute($l.hour, 1) ||
        hours < 24 && substitute($l.hours, Math.round(hours)) ||
        hours < 42 && substitute($l.day, 1) ||
        days < 30 && substitute($l.days, Math.round(days)) ||
        days < 45 && substitute($l.month, 1) ||
        days < 365 && substitute($l.months, Math.round(days / 30)) ||
        years < 1.5 && substitute($l.year, 1) ||
        substitute($l.years, Math.round(years));

      var separator = $l.wordSeparator || "";
      if ($l.wordSeparator === undefined) { separator = " "; }
      return $.trim([prefix, words, suffix].join(separator));
    },
    parse: function(iso8601) {
        var s = $.trim(iso8601);
//      s = s.replace(/\.\d+/,""); // remove milliseconds
//      s = s.replace(/-/,"/").replace(/-/,"/");
//      s = s.replace(/T/," ").replace(/Z/," UTC");
//      s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
      return new Date(parseFloat(s));
    },
    datetime: function(elem) {
      var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
      return $t.parse(iso8601);
    },
    isTime: function(elem) {
      // jQuery's `is()` doesn't play well with HTML5 in IE
      return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
    }
  });

  // functions that can be called via $(el).timeago('action')
  // init is default when no action is given
  // functions are called with context of a single element
  var functions = {
    init: function(){
      var refresh_el = $.proxy(refresh, this);
      refresh_el();
      var $s = $t.settings;
      if ($s.refreshMillis > 0) {
        setInterval(refresh_el, $s.refreshMillis);
      }
    },
    update: function(time){
      $(this).data('timeago', { datetime: $t.parse(time) });
      refresh.apply(this);
    },
    updateFromDOM: function(){
      $(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) });
      refresh.apply(this);
    }
  };

  $.fn.timeago = function(action, options) {
    var fn = action ? functions[action] : functions.init;
    if(!fn){
      throw new Error("Unknown function name '"+ action +"' for timeago");
    }
    // each over objects here and call the requested function
    this.each(function(){
      fn.call(this, options);
    });
    return this;
  };

  function refresh() {
    var data = prepareData(this);
    var $s = $t.settings;

    if (!isNaN(data.datetime)) {
      if ( $s.cutoff == 0 || distance(data.datetime) < $s.cutoff) {
        $(this).text(inWords(data.datetime));
      }
    }
    return this;
  }

  function prepareData(element) {
    element = $(element);
    if (!element.data("timeago")) {
      element.data("timeago", { datetime: $t.datetime(element) });
      var text = $.trim(element.text());
      if ($t.settings.localeTitle) {
        element.attr("title", element.data('timeago').datetime.toLocaleString());
      } else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
        element.attr("title", text);
      }
    }
    return element.data("timeago");
  }

  function inWords(date) {
    return $t.inWords(distance(date));
  }

  function distance(date) {
    return (new Date().getTime() - date.getTime());
  }

  // fix for IE6 suckage
  document.createElement("abbr");
  document.createElement("time");
}));

postfix 实现 tls smtps pop3s

先安装好 postfix openssl courier-imap

mkdir /etc/postfix/etc/tls
cd /etc/postfix/etc/tls

openssl req -new -x509 -nodes -out cert.pem

———————————————-
Generating a 1024 bit RSA private key
…………………………………………………………………………….++++++
……++++++
writing new private key to ‘privkey.pem’
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [AU]:CN                               ←此处为国家名称代码
State or Province Name (full name) [Some-State]:GD                   ←此处为地域(省)名称
Locality Name (eg, city) []:SZ                                      ←此处为城市名称
Organization Name (eg, company) [Internet Widgits Pty Ltd]:test     ←此处为单位名称
Organizational Unit Name (eg, section) []:IT                           ←此处为部分名称                                                                             
Common Name (eg, YOUR name) []:test                        ←此处为你名称或服务器名字或省略
Email Address []:test@test.com                              ←此处为管理邮件

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:123456                              ←输入密码
———————————–

#chown root:postfix *
#chmod 640 *
cd ..

配置文件main.cf 添加

#smtpd-tls
smtpd_tls_cert_file = $config_directory/tls/cert.pem
smtpd_tls_key_file = $config_directory/tls/privkey.pem
smtpd_use_tls = yes
tls_random_source = dev:/dev/urandom
tls_daemon_random_source = dev:/dev/urandom

启动smtps的守护进程
配置文件master.cf

#===================================================
smtps     inet  n       –       n       –       –       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes

注意“-o”前面的空格

重新加载Postfix配置文件

#postfix reload

检查并测试TLS是否启动成功
Smtp默认SSL端口是465
[root@mail ~]# netstat -nat |grep 465
tcp        0      0 0.0.0.0:465                 0.0.0.0:*                   LISTEN

#telnet localhost 25    #测试是否启动TLS加密

Trying 127.0.0.1…
Connected to localhost.localdomain (127.0.0.1).
Escape character is ‘^]’.
220 Welcome to our mail.test.com ESMTP,Warning:Version not Available!
ehlo lanexpert.local
250-mail.lanexpert.local
250-PIPELINING
250-SIZE 14336000
250-VRFY
250-ETRN
250-STARTTLS      #多出一行
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
Starttls        #手动输入
220 2.0.0 Ready to start TLS     #显示此字样为成功启用
quit
quit
Connection closed by foreign host.

二、启用POP3及IMAP加密功能
1.设置POP3s  (Port:995)证书产生的配置文件

# vi /usr/local/courier-imap/etc/pop3d.cnf

根据自己的实据情况作出相应的修改

RANDFILE = /usr/local/courier-imap/share/pop3d.rand

[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no

[ req_dn ]
C=CN      #国家代码
ST=GD    #地域或省名称
L=SZ      #城市名称
O=test    #组织名称
OU=IT               #单位名称
CN=localhost   
emailAddress=test@test.com      #管理邮件

[ cert_type ]
nsCertType = server

2.设置IMAPs(Port:993)证书产生的配置文件

# nano /usr/local/courier-imap/etc/imapd.cnf


RANDFILE = /usr/local/courier-imap/share/imapd.rand

[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no

[ req_dn ]
C=CN
ST=GD
L=sz
O=test
OU=IT
CN=localhost
emailAddress=test@test.com


[ cert_type ]
nsCertType = server

3.        运行以下命令生成安全登陆认证的金钥imapd.pem和pop3d.pem文件,存放于/usr/local/courier-imap/share/目录下

#/usr/local/courier-imap/sbin/mkimapdcert
#/usr/local/courier-imap/sbin/mkpop3dcert

# ll /usr/local/courier-imap/share/*.pem
-rw——- 1 root root 1999 Jul 14 12:24 /usr/local/courier-imap/share/imapd.pem
-rw——- 1 root root 2003 Jul 14 12:24 /usr/local/courier-imap/share/pop3d.pem

4.        修改imapd-ssl及pop3d-ssl配置文件,启用imapd-ssl及pop3d-ssl

#vi /usr/local/courier-imap/etc/imapd-ssl
将 IMAPDSSLSTART=NO
改为:

IMAPDSSLSTART=YES

#vi /usr/local/courier-imap/etc/pop3d-ssl
将POP3_STARTTLS=NO
改为:

POP3_STARTTLS=YES

保存并退出,重启courier-imapd 服务

service courier-imapd restart

检查imapd-ssl及pop3d-ssl启动是否正常:

[root@mail ~]# netstat -nat |grep :99
tcp        0      0 :::993                      :::*                        LISTEN
tcp        0      0 :::995                      :::*                        LISTEN

pop3s服务可能会无法起动,j缺少文件,将couriertls 拷贝到/usr/local/courier-imap/bin下

SqlServer安装后允许远程登录

1.外围应用管理器 远程连接 启动tcp/ip访问

2.配置管理器 tcp all 端口固定1433

3.重启服务

SQLSERVER2008 18456错误

1.以windows验证模式进入数据库管理器

2.重新填写密码和确认密码(改成个好记的)。把强制实施密码策略去掉

mysql客户端登陆提示”client option ‘secure_auth’ enabled”错误

使用mysql workbench登陆mysql服务器时提示授权算法错误。

查阅资料发现,mysql密码使用有两个阶段,第一阶段是登陆时使用hash value进行验证,第二阶段用password()函数生成密码。
换句话说,第一阶段用加密字符串登陆,第二阶段需要更改密码(create user/grant/set password)时使用password()函数来生成。

而第一阶段的验证hash value有两种,一种是pre-4.1版本,另一种是4.1版本的,前者是16字节的字符串,后者是41字节的字符串。
user表的password的长度也调整到了41字节。新版本的hash value总是以*开头。

为了兼容,加入了old_password()函数和old_passwords变量,old_passwords为1时,old_password()函数和password()是一样的,
old_passwords为0时,old_password()返回16字节的hash,password()返回41字节的hash。

为了使DBA可以控制采用哪种验证方式,加入了secure_auth变量,mysql 5.6.5之前的版本默认为0,之后的默认为1。
同时加入了–secure-auth选项。

相关的命令:

mysql> SET @@session.old_passwords = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@session.old_passwords, @@global.old_passwords;
+-------------------------+------------------------+
| @@session.old_passwords | @@global.old_passwords |
+-------------------------+------------------------+
|                       0 |                      1 |
+-------------------------+------------------------+
1 row in set (0.00 sec)

mysql> CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'newpass';
Query OK, 0 rows affected (0.03 sec)

mysql> SET PASSWORD FOR 'existinguser'@'localhost' = PASSWORD('existingpass');
Query OK, 0 rows affected (0.00 sec)

参考资料:
6.1.2.4. Password Hashing in MySQL

来源:http://www.csdn123.com/html/itweb/20130824/79559_79556_79552.htm