基本概述
相关语言
脚本语言是比较多的,一般的脚本语言的执行只同具体的解释执行器有关,所以只要系统上有相应语言的解释程序就可以做到跨平台。脚本(Script),就是含有bind和alias等命令的集合,你可以把这个集合存为一个独立的文件然后在需要的时候执行,这样就可以方便你在CS中的使用。脚本可以存为后缀名为.cfg的文件放在cstrike文件夹下,执行时在控制台输入:exec(脚本文件名).cfg即可。比如将一个脚本存为 buys.cfg文件,则在控制台中输入:execbuys.cfg则可以实现我们所需要的功能。要实现一个命令只要把这一过程定义(alias)好,并且分配一个键位给这个命令,以后只要按分配好的键位,就可以实现这一过程。所有的脚本都是通过这一方法实现的。常见语言
主要特性
所以说,要是打比喻:
你打开资源管理器,用鼠标把一个文件拖到另外一个地方,这是即兴表演。
你写几行命令,把他保存下来, 一执行就做了上面的事情,这就是脚本。
即兴表演,你重复100次,累死了。
脚本,你重复执行100次,全是计算机搞定了。
-
模型驱动
模型驱动 ModelDriven(引自他人博客)
ModelDriven:模型驱动,对所有action的模型对象进行批处理.
我们在开发中, 在action中一般是用实体对象,然后给实体对象get,set方法。
RegAction{
User user ;
//get/set
}
然后在jsp页面中给action中的user属性绑定值是通过如下方式
<s:textfield name="user.name" />
<s:textfield name="user.age" />
<s:textfield name="user.birthday" />
这样都要加上user.因为在值栈中action进入值栈的时候,值栈中存储的值就是以user.name这种形式存在的,所以ognl搜索值栈的时候,也要按这个名字来搜索。
这样就 比较麻烦,于是就引入了模型驱动。
引入模型驱动后在jsp页面绑定属性值的时候就可以不用加上user. 如:
<s:textfield name="name" />
<s:textfield name="age" />
<s:textfield name="birthday" />
原理是什么:ognl在搜索name值的时候,会把模型驱动user压入栈顶。ognl在值栈扫描的时候,会从上往下找,这样就会搜到user中的name,等等
是模型拦截器把模型压入栈顶的。
<html>
<head>
<title>reg.jsp</title>
</head>
<body>
<s:actionerror/>
<s:form namespace="/md" action="MdAction_reg" method="post" theme="xhtml" validate="true">
<s:textfield name="name" label="UserName" />
<s:textfield name="age" label="UserAge" />
<s:submit />
</s:form>
</body>
</html>
user类
public class User {
private Integer id ;
private String name ;
private Integer age ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String toString() {
return "User("+id+","+name + ","+ age + ")";
}
}
/**
* MdAction:某型驱动
*/
public class MdAction extends ActionSupport implements ModelDriven<User>,Preparable {
private String name;
由于使用了模型驱动,user处于栈顶,
user中也有name,那么jsp页面绑定的name是user中name,并不是这里的name,所以该name值为null,
同理在修改功能传id的时候,如果user中有id属性,而在action中也定义了一个id来接收该参数,这样id也接收不到值
,因为使用了模型驱动后,模型驱动拦截器会把id的值传给user中的id,而不是action中的id属性,为了解决这个问题,需要把action中接收参数id的属性定义为别的名称。
比如uid,同时修改jsp中的传参为uid,这样就解决了这个问题。这是在使用模型驱动的时候需要注意的地方。
private User user = new User();属性user,模型驱动栈顶的对象
public String reg() {
return "success";
}
@SkipValidation
public String toRegView() {
System.out.println("toRegView");
return "regView";
}
public User getModel() {
return user;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getModel() {
return user;//这里返回的就是action中的属性user,如果在action中的其他方法里,使用了User user=new User(),那么这个user对象就不是模型驱动的的对象,
也就是不处在栈顶。即使把当前new出的user赋值给属性user也不行,因为在值栈中是通过引用来实现,即值栈中是对象的地址。
}
public String Edit()
{
User u = new User();
u.setId(uid);
u.setName("jerry");
u.setAge(30);
user = u ;注意,这里的user并不是栈顶的user,引用已经指向了新对象u
如果要把u对象放到栈顶,可以手动的push
ServletActionContext.getContext().getValueStack().push(u) ;//把u对象放到栈顶,那么执行修改时回显的就是该对象的数据。
}
}
上面的方法是手动把u对象压入栈顶,还有一种方法可以解决这个问题。
模型驱动拦截器的高级应用:
struts在调用模型驱动拦截器的之前会调用prepare拦截器,prepare拦截器中会调用一个prepare方法,该方法在模型驱动拦截器之前调用,也就是在模型驱动
拦截器中的getModel方法之前执行,getModel方法返回的就是栈顶的对象,那么可以在prepare中把getModel方法中要返回到栈顶的对象给换掉,也就是重新引用。
这样就不用手动的push到栈顶了。
/**
* MdAction:某型驱动
*/
public class MdAction extends ActionSupport implements ModelDriven<User>,Preparable {
private static final long serialVersionUID = -6933309304624396640L;
private String name;
private Integer uid ;
private User user = new User();//模型驱动的getModel方法返回到栈顶的对象。user
private List<User> userList ;
public String reg() {
return "success";
}
@SkipValidation
public String toRegView() {
System.out.println("toRegView");
return "regView";
}
/**
* 查询所有用户
*/
public String findAllUsers(){
userList = new ArrayList<User>();
User u = null ;
for(int i= 0 ; i < 10 ; i ++){
u = new User();
u.setId(1 + i);
u.setName("tom" + i);
u.setAge(20 + i);
userList.add(u);
}
return "userListView";
}
public String edit(){
return "editView" ;
}
//
public User getModel() {
return user;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
/**
* 该方法在getModel之前运行,在modelDriven拦截器之前先运行
*/
public void prepareEdit() throws Exception { 该命名规则说明在执行Edit的时候才会执行该方法。
//
User u = new User();
u.setId(uid);
u.setName("jerry");
u.setAge(30);
user = u ;把user对象换掉,换成新new出的对象。
}
public void prepare() throws Exception {
}
}
但是由于使用的是默认拦截器栈,prepare拦截器在params拦截器之前执行,这样在编辑的时候,就无法获取到id值,因为此时还没有经过参数params烂机器的处理。
所以这种方法不能使用默认的拦截器栈,struts-default.xml提供了一个拦截器栈paramsPrepareParamsStack,所以要引入该拦截器栈。
<struts>
<package name="MdPkg" namespace="/md" extends="struts-default">
<action name="MdAction_*" class="struts2.modeldriven.MdAction" method="{1}">
<result name="success">/md/reg.jsp</result>
<result name="regView">/md/reg.jsp</result>
<result name="editView">/md/edit.jsp</result>
<result name="userListView">/md/userList.jsp</result>
<interceptor-ref name="paramsPrepareParamsStack" /> 不能引入默认拦截器栈,要在prepare拦截器之前执行params拦截器
</action>
</package>
</struts>
模型驱动的应用:
假设在开发中有很多实体对象,比如用户类User,订单类Order,部门类Department等等
对应的有很多Action,如UserAction,OrderAction,DepartmentAction等等。
UserAction{
User user;
}
OrderAction{
Order order;
}
如果在开发中需要开发一个处理模型的拦截器
ProcessModelInterceptor{
if(action instanceof(UserAction){
Object o=getUser();//得到该实体类的对象
}
else if(action instanceof(OrderAction){
Order o=getOrder();//得到该实体类的对象
}
....
这样如果有很多的类几十甚至上百个实体类,都要这么去判断,将是十分的麻烦。引入了模型驱动后就解决了这个问题。
}
引入模型驱动后的做法:模型驱动的好处是对所以的action模型对象进行批处理
ProcessModelInterceptor{
if(action instanceof(ModelDriven){//判断action是否实现了模型驱动接口
Object o=((ModelDriven)action).getModel();//得到action的模型对象
然后用反射获取action中的信息
}
}

浙公网安备 33010602011771号