本文讲述怎样通过JBoss AS的命令行接口连接到服务器。从JBossAS7版开始,引入了一个名为CLI的新工具,它位于%JBOSS_HOME%\bin目录。
进入%JBOSS_HOME%\bin目录,查看jboss-cli.bat脚本文件是否存在。在执行此脚本前,需要先运行JBoss服务器。
启动JBoss应用服务器:
> %JBOSS_HOME%\bin\standalone.bat
CLI命令行脚本执行如下:
> %JBOSS_HOME%\bin\jboss-cli.bat You are disconnected at the moment. Type ‘connect’ to connect to the server or ‘help’ for the list of supported commands. [disconnected /]
注意:经检查,jboss-as-7.0.2.Final版和jboss-as-web-7.0.2.Final版都不含此工具。下载最新的JBossAS 7.1.1版包含了此工具。
正如Shell中看到的那样,会话开始了,现在我们需要连接到正在运行的JBoss实例。命令如下:
[disconnected /] connect 127.0.0.1:9999 [standalone@127.0.0.1:9999 /]
可以看到,cli命令行工具已经连接到位于127.0.0.1:9999地址的独立运行的JBoss实例。
现在,我们可以使用JBoss的cli工具停止JBoss服务器,命令为:
[standalone@127.0.0.1:9999 /] :shutdown
屏幕上输出:
{“outcome” => “success”}
现在让我们使用JBoss的cli工具重启服务器,运行命令:
[standalone@127.0.0.1:9999 /] :reload {"outcome" => "success"} [standalone@127.0.0.1:9999 /]
还有很多功能有待于大家挖掘。
在hibernate中,对于一对多和多对多的关联会使用Set集合来操作,但是有时候在业务中需要对set集合中的对象进行排序,当然,我们可以将Set集合改成list集合来存放对象,但是用list的话又要在数据库中新增一个字段,我不想改变数据的结构,那么,我们应该怎么样对Set排序呢?
部门表(dept)-------------员工表(emp)
部门的pojo类:
public classDept{
private Integer deptId;
private String dname;
private Set emps = newHashSet(0);
}
员工的pojo类:
public classEmp{
private Integer empId;
private String ename;
private Dept dept;
}
方法一:
在pojo中不用hashSet , 改用treeSet;
private Set emps = new TreeSet();
很简单吧,没错,但是是为什么呢?看一下的HashTable和TreeSet的区别就知道了
HashSet实现Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证集合的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null 元素。HashSet为基本操作提供了稳定性能,这些基本操作包括 add、remove、contains 和 size,假定哈希函数将这些元素正确地分布在桶中。对此集合进行迭代所需的时间与 HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。HashSet的实现是不同步的。如果多个线程同时访问一个集合,而其中至少一个线程修改了该集合,那么它必须 保持外部同步。
TreeSet类实现 Set 接口,该接口由 TreeMap 实例支持。此类保证排序后的 set 按照升序排列元素,根据使用的构造方法不同,可能会按照元素的自然顺序 进行排序,或按照在创建 set 时所提供的比较器进行排序。是一个有序集合,元素中安升序排序,缺省是按照自然顺序进行排序,意味着TreeSet中元素要实现Comparable接口;我们可以构造TreeSet对象时,传递实现了Comparator接口的比较器对象
方法二:
在dept的配置文件中:Dept.hbm.xml中的<set ></set> 元素上增加order-by="empId"
<set name="emps"inverse="true"order-by="empId">
<key>
<columnname="deptId"/>
</key>
<one-to-manyclass="hwt.pojo.Emp"/>
</set>
方法三:
也是在配置文件中修改:
先自己写一个类,实现Comparator接口,实现里面的compare方法
public class HwtSorter implements Comparator {
public int compare(Objecto1, Object o2) {
Emp emp1 = (Emp) o1;
Emp emp2 = (Emp) o2;
//按照id排序
Integer empId = emp1.getEmpId();
Integer empId2 = emp2.getEmpId();
return empId>empId2?1:(empId==empId2?0:-1);
}
}
同样,在dept的配置文件中:Dept.hbm.xml中的<set ></set> 元素上增加
<set name="emps"inverse="true"sort="hwt.pojo.HwtSort">
<key>
<columnname="deptId"/>
</key>
<one-to-manyclass="hwt.pojo.Emp"/>
</set>
用Struts2做了个简单的登录例子,下面对开发Struts 2应用的过程做一个总结。
Struts 2应用的开发步骤:
(0)将Struts核心jar文件拷贝到项目的lib文件夹下。
(1)在web.xml文件中定义核心Filter来拦截用户请求。
由于Web应用是基于请求/响应架构的应用,所以不管哪个MVC Web框架,都需要在web.xml中配置该框架的核心Servlet或Filter,这样才可以让该框架介入Web应用中。
例如,开发Struts 2应用第1步就是在web.xml文件中增加如下配置片段:
<!-- 定义Struts 2的核心Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- 让Struts 2的核心Filter拦截所有请求 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(2)如果需要以POST方式提交请求,则定义包含表单数据的JSP页面。如果仅仅只是以GET方式发送请求,则无须经过这一步。
(3)定义处理用户请求的Action类。
这一步也是所有MVC框架中必不可少的,因为这个Action就是MVC中的C,也就是控制器,该控制器负责调用Model里的方法来处理请求。
MVC框架的底层机制是:核心Servlet或Filter接收到用户请求后,通常会对用户请求进行简单预处理,例如解析、封装参数等,然后通过反射来创建Action实例,并调用Action的指定方法(Struts 1通常是execute,Struts 2可以是任意方法)来处理用户请求。这里又产生了一个问题:当Servlet或Filter拦截用户请求后,它如何知道创建哪个Action的实例呢?这有两种解决方案:
² 利用配置文件:例如,可以配置login.action对应使用LoginAction类。这就可以让MVC框架知道创建哪个Action的实例了。
² 利用约定:这种用法可能是受Rails 框架的启发,例如,可以约定xxx.action总是对应XxxAction类。如果核心控制器收到login.action请求后,将会调用LogoinAction类来处理用户请求。
在MVC框架中,控制器实际上由2个部分共同组成,即拦截所有用户请求,处理请求的通用代码都由核心控制器完成,而实际的业务控制(诸如调用Model,返回处理结果等)则由Action处理。
(4)配置Action。对于Java领域的绝大部分MVC框架而言,都非常喜欢使用XML文件来配置管理。配置Action就是指定哪个请求对应用哪个Action进行处理,从而让核心控制器根据该配置来创建合适的Action实例,并调用该Action的业务控制方法。例如,通常需要采用如下代码片段来配置Action。
<action name="login" class="org.crazyit.app.action.LoginAction">
...
</action>
上面配置片段指定如果用户请求URL为login,则使用org.crazyit.app.action.LoginAction来处理。
现在Struts 2的Convention插件借鉴了Rails框架的优点,开始支持“约定优于配置”的思想,也就是采用约定方式来规定用户请求地址和Action之间的对应关系。
(5)配置处理结果和物理视图资源之间的对应关系。
当Action处理用户请求结束后,通常会返回一个处理结果(通常使用简单的字符串就可以了),可以认为该名称是逻辑视图名,这个逻辑视图名需要和指定物理视图资源关联才有价值。所以还需要配置处理结果之间的对应关系。
例如,通过如下代码片段来配置处理结果和物理视图的映射关系。
<action name="login" class=" org.crazyit.app.action.LoginAction ">
<!-- 定义3个逻辑视图和物理资源之间的映射 -->
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
上面粗体字代码指定了3个处理结果和3个物理视图之间的映射关系,配置片段指定当lee.LoginAction返回input时,实际将进入/login.jsp页面;当返回error时,实际将进入/error.jsp页面;当返回success时,实际将进入/welcome.jsp页面。
(6)编写视图资源。如果Action需要把一些数据传给视图资源,则可以借助于OGNL表达式。