2011年11月 的存档

MyBatis3自定义typeHandlers

2011年11月28日 没有评论

mybatis3中默认了标准的java类型的typeHandlers,对枚举类型也内置了一个叫EnumTypeHandler的处理器,但是有一个问题,如果在数据库里面的字段类型是SMALLINT、TYININT、INTEGER等数据类型,默认的EnumTypeHandler就不能处理了,http://asialee.iteye.com/blog/1013238,这个地方有比较详细的说明。解决这个问题有两种方法,一是修改数据库字段的类型为枚举类型,并且枚举值用字符表示;另外一种方法就是自己实现一个typeHandlers。实现的方法很简单,官方的手册上就一个例子。配置的时候需要注意,不光只在 MapperConfig.xml 配置

<typeHandlers>
<typeHandler javaType="String" jdbcType="VARCHAR"
handler="org.mybatis.example.ExampleTypeHandler"/>
</typeHandlers>

还需要在对应的字段在resultMap中配置jdbcType属性,而且select的返回结果类型不能使用resultType,必须用resultMap,否则mybatis就无法应用用自定义的typeHandlers。为何一定要配置jdbcType呢?因为MyBatis为POJO中字段设置typeHandlers是根据在javaType和jdbcType来确定的,javaType可以根据POJO来获取,MyBatis不会审视数据库元信息来决定jdbcType,如果没有指定,那么都是按null来处理,因而获取typeHandlers通过javaType了,就算在MapperConfig.xml中配置的全局typeHandlers也无法正确应用。

另外一种配置是直接在resultMap中指定对应字段的typeHandlers,这样可以不在MapperConfig.xml配置typeHandlers和设置jdbcType。

官方文档中有如下说明:

使用这样的类型处理器将会覆盖已经存在的处理Java的String类型属性和VARCHAR参数及结果的类型处理器。要注意MyBatis不会审视数据库元信息来决定使用哪种类型,所以你必须在参数和结果映射中指定那是VARCHAR类型的字段,来绑定到正确的类型处理器上。这是因为MyBatis直到语句被执行都不知道数据类型的这个现实导致的。

由于没有很好的理解“不会审视数据库元信息来决定使用哪种类型”导致走了很多弯路,一直无法使用自定义的typehandler。

Tomcat-6.0.33之APR based Apache Tomcat Native library

2011年11月25日 没有评论

最近使用tomcat 6.0.33这个版本,启动的时候有个提示:

The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path:...

tomcat可以整合本地apr,在处理静态资源的时候速度更快,总而言之就是使用本地的apr库提升处理效率。在网上一查,很多人提到了这个问题,解决这个问题其实很简单,但window和linux处理方法不太一样。下面就分别给出解决方法。

  • window平台

在window下启动的时候会提示was not found on the java.library.path: C:\Tools\jdk1.6.0_29\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS …,这个根据每个人的环境不同,可能给出的路径也不太一样,只要把Native library拷贝到上述路径之一即可,Native library是什么呢,网上有提供下载,其实不要那么麻烦,在tomcat的bin目录下就有,文件名是:tcnative-1.dll。例如我把这个文件拷贝到C:\Tools\jdk1.6.0_29\bin下,然后再启动tomcat就没有上述的提示了。

  • linux平台

linux下比较复杂一点,因为tomcat包中没有提供编译好的so文件,所以需要自己编译,tomcat发行版中提供了源码,文件为tomcat的bin/tomcat-native.tar.gz,另外编译时候需要依赖APR 1.2、OpenSSL,如果机器上没有安装,可以使用 yum -y install apr-devel openssl-devel 来进行安装。解压tomcat-native.tar.gz后会得到一个tomcat-native-1.1.20-src的目录,Native library的源文件位于tomcat-native-1.1.20-src/jni/native下,进入该目录,执行./configure,可能会看到configure: error: APR could not be located. Please use the –with-apr option.的错误提示,这个时候用–with-apr制定一下apr的位置即可,我使用的是

./configure --with-apr=/usr/bin/apr-1-config

,顺利通过,然后执行 make && make install 编译就算搞定,此时应该可以在/usr/local/apr/lib/下看到一个名为 libtcnative-1.so 的文件,拷贝该文件到tomcat启动时提示的任何一个路径即可。

更多关于apr的信息可以查看官方资料,地址:http://tomcat.apache.org/tomcat-5.5-doc/apr.html

eclipse的Toggle Block Selection Mode功能

2011年11月25日 没有评论

用eclipse3.6一段时间了,今天无意中发现了Toggle Block Selection Mode功能,其用途就是文本编辑器支持块选择模式。何为块选择模式呢,就是类似于ultraedit的列模式。似乎这个功能在eclipse3.5版本就推出来了的。

这个功能其实蛮有用的,比如一个文件有很多行,现在只想把每行前面的10个字符复制出来,那么在块选择模式下就很容易做到了;另外在html之类的文件中可以辅助找出html标签是否不匹配,前提的html文件写的比较规范。

启用此功能的快捷键为:Alt+Shift+A,通过这个它可以在快选择模式和普通模式间进行切换。

分类: Java 标签:

深入理解struts2的namespace

2011年11月23日 没有评论

struts2提供了一个命名空间的概念,可以通过package的namespace属性来设置,使用它可以避免action的名字冲突,同时也可以在逻辑上给action分类。关于namesapce的很多信息,可以参考strtus的官方文档,地址是:http://struts.apache.org/2.2.3.1/docs/namespace-configuration.html

个人觉得,这个里面还是很多信息没有表达清楚。例如该文档最后有一段话如下:

Namespaces are not a path!
Namespace are not hierarchical like a file system path. There is one namespace level. For example if the URL /barspace/myspace/bar.action is requested, the framework will first look for namespace /barspace/myspace. If the action does not exist at /barspace/myspace, the search will immediately fall back to the default namespace “”. The framework will not parse the namespace into a series of “folders”. In the Namespace Example, the bar action in the default namespace would be selected.

大概意思就是说,如果在某个命令空间下没有找到对应的action,然后就直接去缺省的命名空间下。但事实真的如此吗?

通过一些测试,发现似乎遵循如下的规则:

1.假设请求路径的URI,例如url是:http://www.netingcn.com/path1/path2/test.do

2.首先寻找namespace为/path1/path2的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,否则转步骤5;如果不存在这个package则转步骤3。

3.寻找namespace为/path1的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,否则转步骤5;如果不存在这个package则转步骤4。

4. 寻找namespace为/的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,转步骤5;如果不存在转步骤5。

5. 如果存在缺省的命名空间,就在该package下查找名字为test的action,若找到则执行,否则页面提示找不到action;否则提示面提示找不到action。

上述一个很重要的地方就是一旦找到对应的namespace的package就停止向上级路径查找了,另外缺省命名空间(package中没有指明namespace属性或namespace属性值为空)的package的可以不存在。

以前一直比较困惑的是,当访问http://www.netingcn.com/test.do成功,那类似http://www.netingcn.com/x/test.do,http://www.netingcn.com/x/y/test.do也能正常访问,而且执行的同一个action。而上述的试验结果可以很好的解释这个疑惑了。但是个人觉得这样的设计不是太好,决定去源码看个究竟,在org.apache.struts2.dispatcher.mapper.DefaultActionMapper找到关于如何在namespace中查找action的操作,有如下代码:

    protected void parseNameAndNamespace(String uri, ActionMapping mapping, ConfigurationManager configManager) {
        String namespace, name;
        int lastSlash = uri.lastIndexOf("/");
        if (lastSlash == -1) {
            namespace = "";
            name = uri;
        } else if (lastSlash == 0) {
            // ww-1046, assume it is the root namespace, it will fallback to
            // default
            // namespace anyway if not found in root namespace.
            namespace = "/";
            name = uri.substring(lastSlash + 1);
        } else if (alwaysSelectFullNamespace) {
            // Simply select the namespace as everything before the last slash
            namespace = uri.substring(0, lastSlash);
            name = uri.substring(lastSlash + 1);
        } else {

注意到其中alwaysSelectFullNamespace这个信息,原来它属于struts.properties常用配置的一项,其作用是控制是否一直在最后一个slash之前的任何位置选定namespace。由于struts2默认是设置是false,所以导致按照上述试验结果成功,当把alwaysSelectFullNamespace在strtus.properties中设置为true时,此时struts2查找action就不会递归路径去查找package,而是直接找路径对应的package,如果没有找到就去默认命名空间下查找,这就是官方文档中所采用的说法。

个人建议把alwaysSelectFullNamespace设置为true,明确指定action在属于命名空间的package中,不会操作url路径随便输入的问题,同时执行效率也会略有提高。

linux的uniq命令

2011年11月21日 没有评论

使用uniq命令可以过滤掉文本文件中重复的行以及统计等等功能,同时它也接受来着管道的输入。借助awk,甚至可以对行中的列进行操作,例如统计nginx日志信息中独立ip数、列出访问次数最多的ip等。需要注意的地方是uniq只对相连的行进行处理,所以一般情况下要先进行sort操作。

假设有名为test.txt文本文件,其信息为:

ab
ac
ab
ac
ac
ad
ac

执行命令

uniq test.txt

此时得到的结果为:

ab
ac
ab
ac
ad
ac

从结果可以看到,这里只对3,4行的ac进行过滤,这显然不是我们需要的结果,原因就是uniq只对相连的行进行运算了,现在先用sort排序,然后再执行uniq,例如:

sort test.txt | uniq

这时的结果为:

ab
ac
ad

可以看到再没有重复行了。

例如通过nginx日志统计独立ip的个数:

awk '{print $1}' /path-to-log-dir/access.log | sort | uniq | wc -l

查询访问最多的前10个ip

awk '{print $1}' /path-to-log-dir/access.log  | sort | uniq -c | sort -nr | head -10
分类: Linux 标签: ,

使用neuxs搭建maven私服

2011年11月18日 评论已被关闭

私服的好处很多,可以在私服上建立公司内部仓库,把公司的内部构件部署上去供其他人或项目使用;能够部署第三方构件,某些第三方构建在公共的仓库中没有,如果项目中需要使用,就可以把第三方构建部署到自己的私服上,这样mavne中就能正常使用了;在没有私服的情况,项目开发的每个人都需要从远程的中央库下载依赖的构建,浪费带宽不说,效率还低;等等……。

  • 安装nexus

1、下载

下载地址:http://nexus.sonatype.org/downloads/,这里列出了所有版本,挑一个最新版本来使用。Nexus提供了两种安装方式,一种是内嵌Jetty的bundle,只要你有JRE就能直接运行。第二种方式是WAR,你只须简单的将其发布到web容器中即可使用。为了方便就直接选用bundle版本。本文下载的是nexus-oss-webapp-1.9.2.3-bundle.tar.gz 。

2、安装

在指定的目录解压下载的文件

tar xvf nexus-oss-webapp-1.9.2.3-bundle.tar.gz

解压后会看到两个文件夹,分别是nexus-oss-webapp-1.9.2.3和sonatype-work,前者包含了nexus的运行环境和应用程序,后者包含了你自己的配置和存储构件的地方。nexus-oss-webapp-1.9.2.3/conf/plexus.properties中可以修改端口信息已经工作区的路径。

3、启动nexus
进入nexus-oss-webapp-1.9.2.3/bin/jsw/目录,然后根据OS的版本进入相应的目录,在linux下,运行./nexus start即启动了服务,直接运行./nexus会看到提示信息。neuxs默认监听端口是8081,此时在浏览器中运行访问http://nexus-server-ip:8081/nexus应该可以看到neuxs的界面。

  • 配置nexus

新搭建的neuxs环境只是一个空的仓库,需要手动和远程中心库进行同步,nexus默认是关闭远程索引下载,最重要的一件事情就是开启远程索引下载。登陆nexus系统,默认用户名密码为admin/admin123。 点击左边Administration菜单下面的Repositories,找到右边仓库列表中的三个仓库Apache Snapshots,Codehaus Snapshots和Maven Central,然后再没有仓库的configuration下把Download Remote Indexes修改为true。然后在这三个仓库上分别右键,选择Repari Index,这样Nexus就会去下载远程的索引文件。

新建公司的内部仓库,步骤为Repositories –> Add –> Hosted Repository,在页面的下半部分输入框中填入Repository ID和Repository Name即可,比如分别填入myrepo和 my repository,另外把Deployment Policy设置为Allow Redeploy,点击save就创建完成了。

修改neuxs仓库组

Nexus中仓库组的概念是Maven没有的,在Maven看来,不管你是hosted也好,proxy也好,或者group也好,对我都是一样的,我只管根据groupId,artifactId,version等信息向你要构件。为了方便Maven的配置,Nexus能够将多个仓库,hosted或者proxy合并成一个group,这样,Maven只需要依赖于一个group,便能使用所有该group包含的仓库的内容。

neuxs-1.9.2.3中默认自带了一个名为“Public Repositories”组,点击该组可以对他保护的仓库进行调整,把刚才建立的公司内部仓库加入其中,这样就不需要再在maven中明确指定内部仓库的地址了。同时创建一个Group ID为public-snapshots、Group Name为Public Snapshots Repositories的组,把Apache Snapshots、Codehaus Snapshots和Snapshots加入其中。

到这里neuxs的安装配置就完成了,下面介绍如何在mavne中使用自己的私服。 阅读全文…

分类: Java, Linux 标签: ,

netstat命令的常见用法

2011年11月17日 没有评论
  • 查看系统服务监听状况
netstat -tunlp
  • 查看连接某服务端口最多的的IP地址
netstat -nat | grep "10.150.185.178:80" | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | head -20
  • TCP各种状态列表
netstat -nat | awk '{print $6}' | sort | uniq -c | sort -rn
或
netstat -na | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

另外分析access.log获得访问前10位的ip地址可以用如下命令:

awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10
分类: Linux 标签: ,

maven部署构件至Nexus私服

2011年11月17日 没有评论

首先在Nexus中创建一个自己私有的仓库,步骤为Repositories –> Add –> Hosted Repository,在页面的下半部分输入框中填入Repository ID和Repository Name即可,比如分别填入myrepo和 my repository,点击save就创建完成了。

如果要把构建部署至私服中,需要在构建的 pom.xml 文件增加 distributionManagement 配置项,有多种协议可以用来部署构建,这里主要讲两种。

  • 第一种配置如下:
<project>
	[...]	
	<distributionManagement>
		<repository>
			<id>myrep</id>
			<name>my repository</name>
			<url>file:/usr/local/mvn-private-server/nexus-oss-webapp-1.9.2.3/./../sonatype-work/nexus/storage/myrep/</url>
		</repository>
	</distributionManagement>
	[...]
</project>

说明:其中id就是需要部署构建的仓库Id,name似乎不重要,可以随便输入,url就是仓库的configuration中Default Local Storage Location项的对应的信息。采用此种方法,服务器不会对部署操作进行认证,同时配置也把仓库的物理存储地址完全暴露,感觉不是太好。

  • 第二种配置如下:
<project>
	[...]	
	<distributionManagement>
	  <repository>
		<id>tagphi</id>
		<url>http://nexus-server-ip:8081/nexus/content/repositories/myrep</url>
	  </repository>
	</distributionManagement>
	[...]
</project>

说明:上述的distributionManagement信息可以在对于的仓库的Summary中找到。

配置好后,此时执行mvn deploy,部署应该不会成功,根据提示信息,重新执行 mvn deploy -e 或 mvn deploy -X,此时能看到具体的错误信息,报Return code is: 401错,这个是因为发布者没有权限,需要把用户认证信息配置在maven的settings.xml中,该文件在mavne安装包下的conf目录下,这是一个全局配置,同时可以把该文件复制到 userdir/.m2 目录下,这样配置就只对当前用户生效。在settings.xml文件中servers段中添加如下信息

    <server>
      <id>myrep</id>
      <username>deployment</username>
      <password>password</password>
    </server>

其中id就是部署仓库的id,username是作为部署用户,Nexus系统默认的deployment,密码为deployment123,可以在security — users中找到,如果需要设置密码,在用户列表中找到该用户,在该用户上点击右键,会出来一个菜单供重置密码或修改密码。此时在执行 mvn deploy,应该可以看到成功发布了。当第二次执行 mvn deploy 又失败,这次失败原因是Return code is: 400,该错误的原因是在创建仓库时在configuration中的Deployment Policy设置为了Disable Redeploy,修改为Allow Redeploy即可。

the NTP socket is in use, exiting

2011年11月16日 没有评论

centos下使用如下命令手动同步服务器时间

	ntpdate ntp.fudan.edu.cn
	或
	ntpdate ntp.api.bz

出现“the NTP socket is in use, exiting”错误。造成该原因是系统ntpd服务器正在运行中,可以通过 ps aux | grep ntpd 查看,如果还是要手动同步时间,就必须先停止该服务,命令为:

	service ntpd stop

然后再通过 ntpdate ntp.fudan.edu.cn 即可手动同步时间了。另外注意,如果想把它加入到crontab中,最好把ntpdate命令的完整路径带上,即/usr/sbin/ntpdate ntp.fudan.edu.cn,否则可能在某些版本的linux中不会被执行,同时用chkconfig把ntpd修改成不是自动运行的状态。

分类: Linux 标签:

清理MySql的日志文件mysql-bin.00000

2011年11月15日 1 条评论

有一个应用运行在aws的ec2上面,由于存储硬盘比较小,只有8G左右的容量,最初刚配置好环境(按照了php、mysql、nginx等),使用的硬盘只有不到3G,运行一段后,发现硬盘已经用了5G多了,即使清除了nginx的日志,硬盘还是接近5G。决定找出是谁占用了硬盘空间。

通过命令

du -h --max-depth=1 /

查看根目录下每个文件夹所占用存储的大小,发现/var占用了快3G,进一步使用du命令,发现是存放mysql数据文件的文件夹占用了绝大部分空间,进入该文件夹,发现有很多mysql-bin.00000开头的文件,而且其中的某些达到了1G以上,google发现原来这些用户是mysql记录的日志文件,用于数据库崩溃后恢复数据和主从数据库进行数据同步的。如果没有进行主从数据库,可以通过修改配置文件让mysql关闭记录操作日志功能,关闭只需要在log-bin=mysql-bin前加上一个“#”即可,不要忘记重启mysql服务。

清理日志方法为:

PURGE MASTER LOGS TO 'mysql-bin.000013'; 
或
PURGE MASTER LOGS BEFORE '2010-10-18 00:00:00';

另外可以通过 RESET MASTER 来删除整个日志文件,注意,如果使用主从数据库,在操作前先确保从数据库已经完全同步了主数据库的数据。
上述命令都是登陆到mysql后执行的。

无觅相关文章插件,快速提升流量