这里我有一点需要说明一下,在学习JPA——Hibernate Annotation使用实例一文中,我将generator_table设了一个id主键字段,其实这个字段是不需要的,直接将g_key设为主键。这样设计更好些,因为表名不可能一样,所以这个存放各个表主键的键名也不会一样。
user与role这两张表只设了一个主键,没有建立外键关联,而且大象也很反对建立表之间的外键关联。因为这样做之后,约束太多,在实际开发中,很容易出问题,这是我亲身体会过的。所以我建议只对表设置一个流水号主键,其它的都可以根据业务关系来设计字段,这样会更灵活。
这里对各个字段都默认将它们设置为null,因为针对不同的表,你都会实现相应的功能,你当然会知道哪些字段是不能为空的,哪些是可以为空的。而且在做数据库设计的时候,你也不可能在短时间内,面面俱到的把所有问题都考虑进去,根据需求的变化,在开发过程中,也是经常会遇到修改数据库的情况。如果之前过于强调字段的非空设置,在编写代码时,为了减少出错,脑袋里可能会不停的想,啊,这个字段是非空的吗?哪个字段不是非空的吧?然后反复对比数据库进行检查,会使人束手束脚很不舒服。因为这些全部都可以人为来控制,所以除了主键外,将其它字段都设为null有利于开发人员更好的进行工作。 有人会说了,进行非空设置是一种约束,当程序出错时,很容易发现问题。当然,这话说得没错。大象只是建议,从没说过一定要这样做,我只是说下自己的一点经验总结,仅此而已!想怎么实现都是你的自由。
struts2-convention
既然说了是全注解开发,而且我们已经实现了Hibernate与Spring的注解。同样的,Struts2也能够做到用注解来代替配置文件,struts2-convention插件可以帮助我们完成这一功能。它是struts2提供的一个插件,目前网上相关的中文文档主要是一个叫石太洋的人根据官方文档翻译的,很多网站与博客都有转载。我看了原文与译文,感觉讲的不够清楚,例子也很简单。大象根据自己在项目中的实际使用情况,现将个人对这个插件的经验总结写出来与各位分享,希望与大家多交流,共同提高。 官方文档https://cwiki.apache.org/WW/convention-plugin.html
请不要把地址中的两个大写W换成小写,否则是打不开页面滴!这个插件的使用其实非常简单,如果光看文档可能会觉得好像很麻烦。那么大象来告诉你怎样快速学习这个插件。
首先你要搞清楚,这个插件它会默认扫描所有包名为struts、struts2、action、actions下面的类。然后它会对实现了Action接口以及类名以Action结尾的这些类,作为Action来进行处理。 你可以重新定义按哪种包名进行扫描。比如本例设定,只扫描web包下面的所有类,因为我们将Action类都放在这个包下面。
那这个插件是怎么实现原来的配置信息的呢?它的映射规则是这样的,对于以Action结尾的的类,去掉Action,取剩下的部分,将所有的字母转换为小写,如果有驼峰式的写法,则用\连接符来连接不同的单词,这是此插件的默认方式。最终转换之后的就是请求地址,还是用例子说明。 com.bolo.examples.web.base.UserAction
按照上面的规则,请求地址就应该是UserAction去掉Action后缀,将其余部分转换为小写,所以user就是我们的请求地址。不过,这还没有完,因为这里面还有一个命名空间的路径,在通常的配置文件中,一般会将不同的功能进行划分,在package标签里加上namespace属性。使用这个插件,它会为你自动配上命名空间,默认的就是前面说到的以那四种名称为根目录的命名空间,它们之后的都将成为命名空间的名称。
com.bolo.examples.struts.UserAction映射为 /user.action
com.bolo.examples.struts.base.UserAction映射为 /base/user.action
要是我们不以struts或其它几种默认值为包名,又该怎么办呢?没关系,插件为我们提供了一种自定义根包的配置方式
com.bolo.examples.web.HelloWorldAction映射为 /hello-world.action 请一定注意驼峰写法的映射方式,假如这里不是HelloWorld,而是Helloworld,那就不会再是hello-world.action,而是helloworld.action了。 既然已经知道了它的映射方式,接下来再看看这个插件是如何定义结果页面的。 convention默认会到/WEB-INF/content文件夹下面查找对应的结果页面,这个文件夹的名字可以修改,需要在struts.xml中定义 比如上面这段代码,HelloAction处于我们定义的根包(web)下面,因此,它的action请求为hello.action。这时,会默认执行execute()方法,由于返回的是success字符串,所以页面的名称可以简写为hello.jsp,但是当执行welcome方法时,由于返回的字符串为welcome,这时的页面名称则为hello-welcome.jsp。convention就是遵循这样的规则来进行命名,当然这只是最基本的,我们再来看看稍微复杂点的东东。 这个RoleAction类的外部,加了两种注解,它们的作用相当于配置文件中的result标签。Results是一个Result类型的数组注解,里面可以包含多个Result配置。使用Result注解来设置返回类型与返回页面,是不准备采取默认的定义方式。比如HelloAction就是我们采取的默认方式。另外对于有些特殊的返回类型,也需要显式的进行定义。 因为我对RoleAction中的execute()方法返回结果进行了显式的定义,所以,它将不再返回默认的role.jsp,而是location指定的role-list.jsp,Result注解中的name值要与返回值对应。 当请求路径为role!input.action时,会执行input()方法,对于这个方法来说,由于没有进行显式的定义,所以它会按照默认的命名规则返回role-input.jsp。 而redirectUser方法的返回结果指定了一个type为redirectAction的值,这表示要对Action重定向,在location中也说明了是跳转到哪个Action。请注意这里指定的是user.action,当程序跳转到UserAction时,会默认执行execute方法。 假如说,你想执行其它方法该怎么办呢?可以在location里面这样定义,location=\。请记住,重定向时,如果是跳转到其它Action或本Action中的其它方法,type要写成redirectAction。 更进一步,我还想带些参数过去,又该如何呢?请添加params属性,它是一个数组类型。可以这样定义,params={\,\,\,\超级管理员\}。convention文档中有说明,里面的参数是一个键值对,总是形如key,value,key,value。所以第一个role_id与第三个role_name都叫参数名,二和四则是参数值。另外注意下\的含义,这是使用的OGNL表达式取出存在于值栈中的名叫role_id的值。这是一种动态获取并赋值的方式,在采用配置文件的方式中,也可以这样运用,而role_name参数则是一个固定字符串值。需要特别注意的就是,作为参数名的role_id与role_name,一定要在指向的Action中有这两个同名的属性,并且还有set方法,这是用来给这两个属性赋值。而对于${role_id},则要在当前这个Action中,有它的get方法。用于取值。 补充说明一下,在Action类中定义的全局变量,不是非得给它都加上set、get方法,这是根据实际情况来设置的。简单的说get()是获得值,set()是设置值。比如,你现在要在页面上显示username,那 么就对这个属性设置get方法,如果只是对username设置值,从页面传值到Action,那只需要对它设置set方法就可以了。除此之外,我们也可以不采用struts2提供的值栈方式得到参数值,而是使用非常熟悉的request.getParameter()方法来获取参数。至于实际怎么使用,由各位自己决定,不知道我这样说,大家能不能明白? 大象根据实际使用情况,发现动态参数的传递在struts2.1.6存在BUG,如果需要使用这个功能,请将struts2升级到2.1.8.1版。 大象根据实际应用,建议大家统一在类名上面定义Results设置,这样做有利于开发与维护;不建议单独对方法使用@Action注解来重新定义它的访问地址与返回结果,因为这样做有些破坏统一性,不过可以根据实际情况进行处理,但不要过多的使用。 struts.xml 整个struts.xml的配置文件就这么多,当然你自己还可以扩展,因为采用了注解,所以以前的那些配置就再也看不到了。在这个文件中,package是继承convention-default,而没有继承struts-default,为什么呢?查看convention的struts-plugin.xml文件,我们可以发现convention-default继承了struts-default,所以这样写是没错的。另外的几个constant配置就是对convention的常量设置,请看注释。 关于paramsPrepareParamsStack拦截器栈,我准备在第五篇,对基础框架进行扩展的时候再详细的说明。大家如果等不急想学习下,可以在网上查找这方面的资料先看看。 web 大象是这样想的,如果一次讲的太多太复杂不利于理解和吸收,所以对于web层,大家从前面也看到了,代码很简单,因为本篇主要是讲convention插件的知识,然后实现一部分功能用于演示它的效果。下面贴上web和WebRoot目录结构、UserAction的代码,以及jsp代码。 请注意web包下面的层次结构,这与你的请求路径相关。content文件夹是插件默认指定的名字,你可以修改为别的名字。同样请注意在这个目录下面的文件与子文件夹的定义方式是和web层相同的。如果还没有理解,请再看下我对convention插件的说明。 在web.xml文件中,设置了一个 ${ctx}是一个EL表达式,设置的是当前项目名称。我在文件开头加了一个静态包含,<%@ include file=\%> 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库Struts2.1.6+Spring2.5.6+Hibernate3.3.1全注解实例详解 - 图文(4)在线全文阅读。
相关推荐: