脚本,模型驱动等。。

Posted on 2018-05-10 13:18  _wahaha  阅读(343)  评论(0)    收藏  举报

基本概述

脚本简单地说就是一条条的文字命令,这些文字命令是可以看到的(如可以用记事本打开查看、编辑),脚本程序在执行时,是由系统的一个解释器,将其一条条的翻译成机器可识别的指令,并按程序顺序执行。因为脚本在执行时多了一道翻译的过程,所以它比二进制程序执行效率要稍低一些。
脚本通常可以由应用程序临时调用并执行。各类脚本被广泛地应用于网页设计中,因为脚本不仅可以减小网页的规模和提高网页浏览速度,而且可以丰富网页的表现,如动画、声音等。举个最常见的例子,当点击网页上的Email地址时能自动调用Outlook ExpressFoxmail这类邮箱软件,就是通过脚本功能来实现的。也正因为脚本的这些特点,往往被一些别有用心的人所利用。例如在脚本中加入一些破坏计算机系统的命令,这样当用户浏览网页时,一旦调用这类脚本,便会使用户的系统
  脚本
受到攻击。所以用户应根据对所访问网页的信任程度选择安全等级,特别是对于那些本身内容就非法的网页,更不要轻易允许使用脚本。通过“安全设置”对话框,选择“脚本”选项下的各种设置就可以轻松实现对脚本的禁用启用

相关语言

脚本语言是比较多的,一般的脚本语言的执行只同具体的解释执行器有关,所以只要系统上有相应语言的解释程序就可以做到跨平台。脚本(Script),就是含有bind和alias等命令的集合,你可以把这个集合存为一个独立的文件然后在需要的时候执行,这样就可以方便你在CS中的使用。脚本可以存为后缀名为.cfg的文件放在cstrike文件夹下,执行时在控制台输入:exec(脚本文件名).cfg即可。比如将一个脚本存为 buys.cfg文件,则在控制台中输入:execbuys.cfg则可以实现我们所需要的功能。要实现一个命令只要把这一过程定义(alias)好,并且分配一个键位给这个命令,以后只要按分配好的键位,就可以实现这一过程。所有的脚本都是通过这一方法实现的。

常见语言

ScalaJavaScriptVBScriptActionScript,MAX Script,ASPJSPPHPSQLPerlShellpythonRubyJavaFXLuaAutoIt

主要特性

语法和结构通常比较简单
学习和使用通常比较简单
通常以容易修改程序的“解释”作为运行方式,而不需要“编译”
程序的开发产能优于运行效能

所以说,要是打比喻:
你打开资源管理器,用鼠标把一个文件拖到另外一个地方,这是即兴表演。
你写几行命令,把他保存下来, 一执行就做了上面的事情,这就是脚本。


即兴表演,你重复100次,累死了。
脚本,你重复执行100次,全是计算机搞定了。

模型驱动

把数据跟处理分开,用单独的JavaBean封装数据(不管是请求的,还是返回的,可以在一起封装),把处理类完全孤立成一个框架,用这个模型作为灵魂在驱动整个骨架。
 
模型驱动:把数据跟处理分开,用单独的JavaBean封装数据(不管是请求的,还是返回的,可以在一起封装),把处理类完全孤立成一个框架,用这个模型作为灵魂在驱动整个骨架。
特性:血肉分开,使结构更清晰,职能划分更清楚,免得局长管权力又管财务的,弄不好贪污。
核心:模型(model)就是值对象Vo(value object)
对比:属性驱动--你把一大堆属性搞到你的处理类里面,完全可以。方便而快捷,不过结构清晰度当然就不好了。
开发:模型驱动开发(Model-driven development,MDD)是软件开发的一种样式,其中主要的软件工件是模型,根据最佳实践,可以从这些模型生成代码和其他工件。模型是从特定角度对系统进行的描述,它省略了相关的细节,因此可以更清楚地看到感兴趣的特性。例如,结构工程师会创建适合于确定建筑物承载特性的模型。

模型驱动 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中的信息

  }

}

 

博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3