Struts2

作者: 笔者7 | 来源:发表于2017-05-12 11:43 被阅读0次
    在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处?
    

    设计目标
    1.Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。</br>
    技术优势
    Struts2有两方面的技术优势,一是所有的Struts2应用程序都是基于client/server HTTP交换协议,The Java Servlet API揭示了Java Servlet只是Java API的一个很小子集,这样我们可以在业务逻辑部分使用功能强大的Java语言进行程序设计。
    二是提供了对MVC的一个清晰的实现,这一实现包含了很多参与对所以请求进行处理的关键组件,如:拦截器、OGNL表达式语言、堆栈。

    下面,我们在深入剖析一下struts的工作原理。
    原理图:(structs2核心控制器StrutsPrepareAndExecuteFilter)。老版本structs1是FilterDispatcher

    QQ截图20170512104736.png
    工作原理:

    在Struts2框架中的处理大概分为以下几个步骤** (这边官方说法有点啰嗦了,其实几句话就说明白了)**
    1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
    2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
    3 接着StrutsPrepareAndExecuteFilte被调用,StrutsPrepareAndExecuteFilte询问ActionMapper来决定这个请是否需要调用某个Action
    4 如果ActionMapper决定需要调用某个Action,StrutsPrepareAndExecuteFilter把请求的处理交给ActionProxy
    5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
    6 ActionProxy创建一个ActionInvocation的实例。
    7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
    8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

    流程图:

    运行流程.png
    工作流程:

    1、客户端浏览器发出HTTP请求.
    2、根据web.xml配置,该请求被FilterDispatcher接收
    3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton
    4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
    5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面
    6、返回HTTP响应到客户端浏览器

    废话不多说,下面我们开始进入Structs2的学习吧!!!!!!!

    一、建立第一个struts2的程序

      a:找到struts目录下对应的apps目录
      b:解压struts2-blank.war
      c:copy对应的lib的jar文件
      d:copy对应的struts.xml到src目录
      e:注释掉struts.xml的多余内容
      f:建立HelloStruts2.jsp文件
      g:在struts.xml中照原配置进行对应的配置
      h:修改对应的web.xml,建立Struts2的filter(参考struts自带的项目)
    

    二、模块讲解

    • Demo1讲解

    <package name="default" namespace="/" extends="struts-default">
    <action name="hello">
    <result name="success">/hello.jsp</result>
    </action>

    (1)当你改<action name="hello">的name时,程序不能及时给反馈,需要重新启动
    服务,这里有一个<constant name="struts.devMode" value="true" />
    devMode-->develepment Mode  开发模式改为true
    
    *    Demo2讲解: namespace="/" 和访问的路径一一对应
    >```
    <constant name="struts.devMode" value="true" />
          <package name="font" namespace="/font" extends="struts-default">
            <action name="hello">
                <result name="success">/hello.jsp</result>
            </action>
    

    (1)Namespace:决定了action的访问路径,默认为””,可以接收所有路径的action可以写为/,或者/XXX,或者/XXX/yyy,对应的action访问路径为/index.action,/XXX/index.action,/XXX/yyy/index.action.Namespace最好也用模块来命名
    <package name="font".......><action name="hello">
    A:这里的package name="",在java里可以建很多包,包下面可以建相同的类名。这里意思一样,当有两个action name都叫hello,这里可以写不同的 package name ,比如一个前台jspfont,后台backfont,下面action都叫hello,这样就不容易混乱了。
    B:<result name="success"> 默认就是success可以不加

    • Demo3讲解: Action问题

    public class demoAction {
    public String execute(){
    return "shaca";
    }
    }
    <action name="hello" class="com.aiyin.struts2.action.demoAction">
    <result name="shaca">/index.jsp</result>

    当action中有class时,这是会去到对应的类里面,找类里面的execute()方法,然后根据对应返回值“sucess”找到对应的jsp,然后再返回回来。。
     当你没有配置class时,会默认走自己默认的class--->extends ActionSupport
    implements Action
    在企业开发只用extends ActionSupport
    
    *    Demo4讲解: 路径问题
    >当没有对应的namespace,会返回到web.xml中丢给Tomcat去处理,会访问index.jsp
    struts2中的路径问题是根据action的路径而不是jsp路径来路径,所以尽量不要使用相对路径。<a href="path/path.action">路径问题</a>
      解决办法非常简单,统一使用绝对路径(在jsp中用request.getContextPath()方法拿到webapp路径)或者basePath
    
    *    Demo5讲解:Action执行的时候并不一定要执行execute()方法
    >    可以在配置文件中配置Action的时候用method=来指定执行哪个方法。也可以在url   地址中动态指定(动态调用DMI) DynamicMethodInvocation
    

    <action name="path" class="com.aiyin.struts2.action.demoAction" method="add">

    动态调用 需要打开下面这个:
    

    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    <a href="path/user!add">添加用户</a>

    *    Demo6讲解:通配符
    

    <package name="actions" namespace="/actions" extends="struts-default">
    <action name="Student" class="com.aiyin.struts2.action.StudentAction" method="{1}">
    <result>/Student{1}_success.jsp</result>
    </action>
    <action name="
    *" class="com.aiyin.struts2.action.{1}Action" method="{2}">
    <result>/{1}
    {2}_success.jsp</result>
    </action>
    </package>

    <a href="actions/Studentadd">添加学生</a><br />
    
    *    Demo7讲解:用Action的属性接收参数
    

    //<a href="user/user!add?name=a&age=8">添加用户</a>
    在类里面生成对应的name和age的get和set方法,会自动获取到

    
    *    Demo8讲解:简单数据验证
    点击进入网页:[自定义Struts2表单验证后的错误信息显示格式](http://www.blogjava.net/lishunli/archive/2010/10/17/335384.html)
    

    this.addFieldError("name", "name is error");
    A:<s:fielderror cssStyle="color: red"></s:fielderror>
    为什么报的错前面有小点:解压core jar包,template\simple下fielderror.ftl里有ul,所以我们可以自己重新定义它
    B:<s:property value="errors.name[0]"></s:property>
    <s:debug></s:debug>
    C:使用Struts2验证框架实现输入校验
    出现提示,window-->preferences-->catalog.关联xwork里的dtd

    
    *    Demo9讲解:访问Web元素
    >方一手动获取:
    取得request,session,application,HttpServletRequest,HttpServletResponse
    HttpServletContext
     方二:
    implements RequestAware,SessionAware,ApplicationAware
    

    private Map<String,Object> request;
    private Map<String,Object> session;
    private Map<String,Object> application;
    // DI dependency injection
    // Ioc inverse of control
    public String execute(){
    ServletActionContext.getRequest().setAttribute("name", name);
    ActionContext.getContext().put("pass", pass);
    request.put("r1","request2" );
    session.put("s1","session2" );
    application.put("a1","application2" );
    return "success";
    }
    public void setApplication(Map<String, Object> application) {
    this.application=application;
    }
    public void setSession(Map<String, Object> session) {
    this.session=session;
    }
    public void setRequest(Map<String, Object> request) {
    this.request=request;
    }

    jsp页面
    >>${name} ${pass}
         <%=request.getAttribute("r1") %>
         <%=session.getAttribute("s1") %>
         <%=application.getAttribute("a1") %><br />
         <s:debug></s:debug><br />
          ONGL<s:property value="#request.r1"/><br />
          <s:property value="#session.s1"/><br />
          <s:property value="#application.a1"/>
    
    
    *    模块包含
      ```<include file="login.xml"></include>```
    
    ####三:result类型
    

    result的目的就是告诉Struts2框架,在执行完一个Action后,需要系统做什么?
    是把一个视图资源呈现给用户还是执行另外一个Action,result配置起到了一个“路标”的作用。
    dispatcher:默认就是这个,用来转向页面,通常处理JSP
    redirect:实际上dispatcher和redirect的区别就是在于转发和重定向的区别。
    chain:用来处理Action链,可以forward跳到另外一个action
    redirectAction:重定向到一个Action

    <package name="resultTypes" namespace="/r" extends="struts-default">
    <action name="r1">
    <result type="dispatcher">/r1.jsp</result>
    </action>

        <action name="r2">
          <result type="redirect">/r2.jsp</result>
        </action>
        
         <action name="r3">
          <result type="chain">r1</result>
        </action>
        
        <action name="r4">
          <result type="redirectAction">r2</result>
        </action>
    

    </package>

    ####四:通配符配置
    

    在开发的过程中,有时候我们需要对于每个action配置一个error result页面,一般情况下,
    这个error result页面都是同一个页面。如果在每一个action中单独配置error result的话就太麻烦了,
    这时候我们就可以配置一个全局的result。这个全局的result在我们的包中,被所有的action共享,
    但是不会被别的包共享

    *struts.xml*
    

    <package name="user" namespace="/user" extends="struts-default">
    <global-results>
    <result name="mianpage">/global.jsp</result>
    </global-results>
    <action name="user" class="com.aiyin.web.action.UserAction" >
    <result name="success">/success.jsp</result>
    <result name="error">/error.jsp</result>
    </action>
    </package>

    *Index.jsp*
    

    <a href="user/user?type=1">返回success</a>
    <a href="user/user?type=2">返回error</a>
    <a href="user/user?type=3">返回global result</a>

    
    *其他包如果也想用则可以继承user包*
    
    

    <package name="admin" namespace="/admin" extends="user">
    <action name="admin" class="com.aiyin.web.action.AdminAction" >
    <result>/admin.jsp</result>
    </action>
    </package>
    public String execute() {
    return "mianpage";
    }

    相关文章

      网友评论

          本文标题:Struts2

          本文链接:https://www.haomeiwen.com/subject/skrztxtx.html