Struts2 学习笔记之(一)——Hello Struts2

之前自学了Struts1,感觉用起来很方便,而对于Struts2的学习更多的是“赶鸭子上架”型学习,被项目逼着仓促的学了些,现在终于等到放假,打算写一系列日志用以总结归纳,同时留作学习笔记。本次自学我使用的参考书籍为《Struts2权威指南》及《struts-2-in-action》,有兴趣的童鞋可以下载下来详细阅读。

Ok,废话不多说,我们开始。

Struts2虽然跟Struts1就差一个数字,但是这之间是没什么联系的哈,如果想不通的可以参照王凯&王八,同样都是两个字,但是相差了一个字,这意思可就相差十万八千里咯~!Struts2更接近WebWork,是从WebWork扩展而来的。虽然这三个构架差别蛮大,但是他们都实现了共同的一个东西——MVC模型,具体的说应该是MVC2模型哈,详细的内容及区别大家可以参照我给出的参考书籍:)

想要配置Struts2非常简单, 这里我使用一个用户登录的例子来做演示。首先呢,我们需要一个让用户输入用户名密码的页面(index.jsp),以及一个登录成功的转入页(welcome.jsp)外加一个登录失败的提示页(error.jsp)。

index.jsp

 1: <%@page language="java" contentType="text/html; charset=UTF-8"%>
 2: <html>
 3: <head>
 4:     <title>User Login</title>
 5: </head>
 6: <body>
 7: <form action="Login.action" method="post">
 8:     <table>
 9:         <tr>
 10:             <td>用户登录</td>
 11:         </tr>
 12:         <tr>
 13:             <td>用户名:</td>
 14:             <td><input name="username" type="text"/></td>
 15:         </tr>
 16:         <tr>
 17:             <td>密码:</td>
 18:             <td><input name="password" type=password /></td>
 19:         </tr>
 20:         <tr>
 21:             <td><input type="submit" value="登录"/></td>
 22:         </tr>
 23:     </table>
 24: </form>
 25: </body>
 26: </html>

做好了基础的页面之后,我们需要写一个action用以处理用户的请求,这个action就是一个非常普通的POJO对象,他甚至不需要继承任何父类,也不需要实现任何接口,这为我们的测试以及重用,提供了非常大的便利。

LoginAction.Java

 1: package com.kaisir.www.struts2demo;
 2:
 3: public class LoginAction {
 4:     private String username;
 5:     private String password;
 6:     public String getUsername() {
 7:         return username;
 8:     }
 9:     public void setUsername(String username) {
 10:         this.username = username;
 11:     }
 12:     public String getPassword() {
 13:         return password;
 14:     }
 15:     public void setPassword(String password) {
 16:         this.password = password;
 17:     }
 18:
 19:     public String execute() throws Exception{
 20:         if (username.equals("Kaisir")&&password.equals("123456")) {
 21:             return "success";
 22:         }else{
 23:             return "error";
 24:         }
 25:     }
 26: }

可以看出,我们的Action中有两个字段,分别对应我们index.jsp中的两个文本框username及password。提交页面之后,系统会自动的获取我们这两个字段的值,并使用set方法填入到对应的变量之中。这样,我们在JavaBean中便获得了用户表单中输入的内容。

完成了Action之后,我们需要编写一个struts.xml文件,让系统知道我们当前都有哪些Action可用,以及根据Action的执行结果可以跳转到哪些View中进行结果的显示。

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:         </action>
 11:     </package>
 12: </struts>

在这个struts.xml文件中,我定义了一个action名为Login,他产生了两个输出跳转,一个跳转到了welcome.jsp,一个跳转到了error.jsp

最后,我们需要修改web.xml,以过滤器的形式加载Struts2。

 1: <?xml version="1.0" encoding="UTF-8"?>
 2: <web-app version="3.0"
 3:     xmlns="http://java.sun.com/xml/ns/javaee"
 4:     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5:     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6:     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 7:   <display-name></display-name>
 8:   <welcome-file-list>
 9:     <welcome-file>index.jsp</welcome-file>
 10:   </welcome-file-list>
 11:   <filter>
 12:       <!-- 定义核心Filter的名字 -->
 13:       <filter-name>Struts2</filter-name>
 14:       <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
 15:   </filter>
 16:   <filter-mapping>
 17:       <filter-name>Struts2</filter-name>
 18:       <url-pattern>/*</url-pattern>
 19:   </filter-mapping>
 20: </web-app>

要注意的是,在2.xx后期的版本中,这个过滤器的类已经变成了“org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter”如果还按照以前的过滤器来,当你部署到tomcat中时会出现莫名其妙的500错误。

当然,拷贝必要的类库也是必要的~我从Struts2自带的例子中提取了一份类库列表,应该是最简的列表了,即要实现最基本的Struts2必须引入下列jar包。

 1: lib目录下必须存在的包
 2: asm-3.3.jar
 3: asm-commons-3.3.jar
 4: asm-tree-3.3.jar
 5: commons-fileupload-1.2.2.jar
 6: commons-io-2.0.1.jar
 7: commons-lang-2.5.jar
 8: freemarker-2.3.18.jar
 9: javassist-3.11.0.GA.jar
 10: ognl-3.0.3.jar
 11: struts2-core-2.3.1.jar
 12: xwork-core-2.3.1.jar

好了,至此,将项目部署到你的tomcat,输入用户名Kaisir,密码123456,看看有没有成功跳转到Welcome页面吧 :)大家有任何问题欢迎与我交流,Webmaster#Kaisir.Com ,借用一句广告语“大家好,才是真的好!”

记一个很奇怪的火狐验证码问题(未解决)

今天闲来无事打算封装一个Java的验证码类,实现基本功能很容易,可是测试的时候却发现了一个奇怪的问题,而且暂时还未找到答案。要想说清楚这个问题,首先给大家看一张图片,请大家注意图中标注1,2,3处的验证码。

checkcode

问题描述:

我在java中写了一个servlet实现构造一个验证码,servlet负责返回java生成的一张图片(其实是jpeg的流),使用IE直接浏览这个生成地址正常,但是使用火狐浏览时却发现显示出来的验证码跟实际的验证码是不同的。后来我使用了firebug对访问情况进行跟踪,得到了上面的结果:

1处是用户看到的验证码;2处是当前实际的验证码;3处是系统生成的验证码。

这就好像火狐在请求完图像之后,又重新请求了一遍一样,但是使用FireBug却仅仅抓到了第二次请求。而且更奇怪的是,我将这个地址嵌入到<img>标签中,却又变得正常了,看到的跟实际请求的验证码又是相同的了。实在搞不清楚这是怎么回事了……

后续打算:

打算使用WireShark抓包试试看,看看是不是发起了两次请求。这个问题暂时无解,欢迎大家广泛讨论。

WT19i不解锁不丢DRM不丢TrackID刷入Recovery!

seet

这几天一直在纠结要不要刷Recovery,刷入这个东西吧,以后刷机啊做镜像啊都很方便,可是呢常规刷入Recovery需要解锁,而解锁就会抹掉系统内自带的DRM信息,从而造成TrackID无法使用。说实话这一段时间试用下来,Kaisir觉得这个TrackID还是蛮好用的,尤其是在收听收音机的时候,遇到一首你不知道是什么的歌曲,轻触一下右下角的图标,嘿,系统就能自动的录制一小段音频然后联网查询就能告诉你你听的是啥歌,识别的成功率可以说是接近100%的,所以说很不想失去这个功能。

功夫不负有心人啊,今天终于让我从XDA论坛找到一个小程序,可以在WT19i上不解锁刷入Recovery,还可以给WT19i安装Java运行环境,还可以开启索爱特有的MB音效(这个我没成功),开启Bravia Engine(我也没看出变化:( )但是这个不解锁刷Recovery就足够我兴奋的啦!

软件默认的说明语言为越南话,但是软件很简单,应该一看就会用了,当然,在这里我还是要简单说一下使用方法:

1)手机中的ROM必须是原厂ROM,且必须ROOT
2)要求手机中安装有BusyBox (不知道如何安装的可以参看我之前写的日志 传送门:在Sony Ericsson WT19i 上安装BusyBox
3)在手机设置菜单–应用程序中将“未知来源”打上勾,同时在“开发”项中将“USB调试”打上勾。
4)手机通过USB连接电脑,电脑端运行“SE_Extreme_Tweak_Installer.exe”(要求系统中必须安装.Net framework 3.5)
5)之后选择需要进行的操作,然后点击“Install”
6)Done!

向MySql数据库导入数据的方法

0931062362-0

之前w童鞋编写了一套计算机等级考试成绩查询系统部署在了服务器上,可是貌似系统做的很简单,JavaBean+MySql构成了整套查询的主体,同时也没有提供数据导入功能,这不今天又过来一批通过二级的人员名单,是使用Excel表格的形式发过来的,没办法只能直接操作数据库进行导入了。

由于系统不是我开发的,而且没有开发文档,此外数据库的链接字符串也都是写死在程序中了,故我只好在服务器上直接使用MySql Commond Line来进行操作,Win+R 运行,Cmd 回车之后我们输入:

mysql –u root –p

回车之后提示输入密码,密码验证之后,我们得到了MySql的命令提示符,接下来如何确定用的哪个数据库呢?好在这台服务器跑的业务很单一,使用以下命令就能得到所有数据库列表了:

show databases;

从列表中查阅可知,只有哪个cjcx看起来最像 :) 于是我们执行:

use cjcx;

Ok,系统提示我们数据库切换成功,那他有哪些表呢?我们接着执行:

show tables;

返回的结果让我大跌眼镜,只有一个表,且表名为“a”(大家不要学此童鞋,数据库及表的命名一定要规范,尽量见名知意,且尽量使用英文避免中午的歧义)好吧,知道了表名还没有用,我们还需要知道表的定义,接着执行:

describe a;

好的,回显的提示让我们知道了表的数据,虽然都是汉语拼音缩写,但是差不多能猜出意思,把我手里拿到的Excel按照这个字段的排列进行排序,之后选择“另存为——文本文件(制表符分隔)”好的,这样我们就得到了一个以“t”分隔的文本文件,每行为一条记录,接下来我们需要把这个文件导入,执行:

load data local infile ‘文件路径’ into table 表名;

一会系统会给出导入信息,如果此时导入的条数与你Excel中去掉表头的数据条数一致,那么恭喜你,数据导入成功 :)

在Sony Ericsson WT19i 上安装BusyBox

DSC_0011

前几天入了两部索爱的WT19i,Qualcomm MSM8255 1GHz的处理器,512M的RAM,500W+30W的摄像头,WIFI跟GPS当然也是标配,几天用下来感觉还算不错,网上都在评论说320*480分辨率太小不爽,但是可能我用G8用习惯了,看着这个分辨率感觉也还是不错的。但是说真的这个手机的电池确实不顶用啊不顶用: (

手机拿到手,不摆弄摆弄它不符合Kaisir我的风格,发现这个型号的Root有人搞了,XR也已经有人搞了,好像还没有人涉足这个机型的BusyBox,好吧,那我就来搞搞:)

继续阅读“在Sony Ericsson WT19i 上安装BusyBox”

从exe文件中提取flash文件,进而提取flash中的音频

今天收到Emnkcn的一封邮件,他说他有某考研视频是个exe文件,他想把里面的音频提取出来放到mp3中听,无奈他试了多种方法都不能将flash自这个exe文件中分离出来。今天小搞了下,终于成功,特将思路与方法记录于下:

拿到这个exe文件,第一反应就是得先判断下这个程序是用何种软件写成的,毕竟里面的Flash是嵌入在资源文件中的,只有了解了exe的编译软件才能找到相应的提取资源文件的方法。这个步骤很简单,我们请出大名鼎鼎的“language2000”,很简单就得出了我们需要的信息。此软件是使用Delphi编写的。

c1

知道了编写工具,我们就得想办法提取资源,我先后使用了eXeScope,PE Explorer以及ResHacker,都没能取得其中内嵌的资源文件。于是换了种想法,既然是内嵌资源,程序源文件中应该包含此文件的完整副本,于是

继续阅读“从exe文件中提取flash文件,进而提取flash中的音频”

Ubuntu 10.10安装Vmware Tools

VMware

      Kaisir的部落格是部署在Ubuntu 10.10之上的,而这个Ubuntu又是安装在Vmware Server 2.0之上的,一直觉得网页访问起来有些慢(难道因为校园网网速问题?)今天通过探针一查,发现虚拟出来的这个Ubuntu的eth0流量及虚拟机的内存占用都很大,于是登录Vmware控制台查看,发现运行这么长时间以来虚拟机上竟然没有安装Vmware Tools,于是挂载Vmware Tools,安装,安装过程是需要Linux内核源码的,可是所有的源码都在,可是依然编译不成功,查询了网络上的资料,有说安装的包不全,有说需要做几个软连接,可是尝试下来,都没有成功,最后终于在某国外站点上找到一篇日志,他提到了Open-Vm-Tools,大体讲因为Linux发行版众多,Vmware没有办法一一涵盖这些发行版,于是就有了这样一个小组,来提供编译好之后的Vmware Tools(以及源代码包),在Ubuntu下的使用方法很简单,用apt-get install 安装完成就好了,只需要执行下面两个命令:

   1: apt-get install --no-install-recommends open-vm-dkms

   2: apt-get install open-vm-tools

然后,reboot 你的Ubuntu , All Done.

PhotoShop 自动添加边框及EXIF信息的脚本

DSC_0008

作为一名“摄影爱好者”(好吧我承认我不太合格,我才玩摄影没几天-_-!!)总有一件事情避免不了,就是让照片带上EXIF的参数,虽然本人的部落格已经安装了插件可以显示出EXIF信息,但是感觉插件还是不太给力,此外还要考虑到一些综合的操作,比如批量的调整大小,增加版权信息等等。

当然,好在我们还要PS,我们还可以写PS的脚本让他来按照我们的想法来进行某些操作:)嘿嘿,从无忌论坛的一个帖子找到了一个PS脚本,按照自己的想法略加了一些修改(主要是时间,镜头识别,以及焦距识别)效果图见题图。有了脚本就方便许多了,比如你想要批量的增加EXIF边框,那么很简单,录制个动作,然后批处理运行这个动作就好啦:)

最后,附上这个脚本:

关于Hibernate出现illegal attempt to dereference collection..的错误处理

今天使用Hibernate查询某个实体时出现标题中所示的错误,百思不得其解,查阅资料后发现,这个问题是因为Hibernate的版本问题造成的,具体原因见这里

在我的项目中,两个实体类AppUser与AppRole,AppUser类中有一个List<AppRole>d的属性用来存放此用户的角色。我现在想要做的是通过AppRole的rname查询出这个权限下所有的AppRole。我定义了命名查询:

[codesyntax lang=”xml”]

  <query name="UserDao.findByRoleName">
        <![CDATA[
         select u
         from com.kaisir.tms.pojo.AppUser as u
         where u.AppRoles.rname=:rname
        ]]>
  </query>

[/codesyntax]

可是查询出现了标题中的错误,查阅资料,后期版本的Hibernate必须“显式”的指定子查询,不会再自动的添加隐含的查询了,故将定义修改如下:

[codesyntax lang=”xml”]

  <query name="UserDao.findByRoleName">
        <![CDATA[
         select u
         from com.kaisir.tms.pojo.AppUser as u inner join fetch u.appRoles r
         where r.rname=:rname
        ]]>
  </query>

[/codesyntax]

这样我显式的告诉Hibernate先去查询AppUser中的appRoles属性,然后再从属性中查询其rname为指定值的AppUser对象,这样问题就解决了 :)

html表单美化插件

说实话Kaisir我很头疼于UI的设计与制作,弄个表单还弄得很丑,昨天网上找了找,嘿 您别说,还真让我找到一个表单美化的插件。

这个插件名叫“niceforms”可以对现存的表单进行美化(当然需要引入CSS与JS)上几张图给大家看看效果:)

 

 

怎么样,很漂亮吧,今天还看到“温柔”童鞋写的几篇关于textinput file美化的日志,这下,嘿嘿 有了这个就省事咯 :)

嘿嘿 点此下载 此款插件