欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Struts2的配置 struts.xml Action详解

程序员文章站 2024-04-01 20:00:58
在学习struts的时候,我们一定要掌握struts2的工作原理。只有当我们明确了在struts2框架的内部架构的实现过程,在配置整个struts 的框架时,可以很好的进行...

在学习struts的时候,我们一定要掌握struts2的工作原理。只有当我们明确了在struts2框架的内部架构的实现过程,在配置整个struts 的框架时,可以很好的进行逻辑上的配置。接下来我就先简单的讲解下struts2的框架工作原理:

一、struts2的工作原理

Struts2的配置 struts.xml Action详解

1、客户端初始化一个指向servlet容器(例如tomcat)的请求;
2、这个请求经过一系列的过滤器(filter)(这些过滤器中有一个叫做actioncontextcleanup的可选过滤器,这个过滤器对于struts2和其他框架的集成很有帮助,例如:sitemesh plugin);
3、接着filterdispatcher被调用,filterdispatcher询问actionmapper来决定这个请求是否需要调用某个action;
4、如果actionmapper决定需要调用某个action,filterdispatcher把请求的处理交给actionproxy;
5、actionproxy通过configurationmanager询问框架的配置文件,找到需要调用的action类;
6、actionproxy创建一个actioninvocation的实例。
7、actioninvocation实例使用命名模式来调用,在调用action的过程前后,涉及到相关拦截器(intercepter)的调用。
8、一旦action执行完毕,actioninvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个action链)一个需要被表示的jsp或者freemarker的模版。在表示的过程中可以使用struts2框架中继承的标签。在这个过程中需要涉及到actionmapper。

二、部署一个struts2项目的一般步骤

1)在myeclipse中创建一个web项目,并将struts2需要的jar包导入进项目中,如下图

2)在项目中的web.xml中进行配置struts2的框架,在web.xml中需要包含在<filter></filter>,在该节点下可以包含<filter-name>和<filter-mapin

<?xml version="1.0" encoding="utf-8"?> 
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
  xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" 
  xsi:schemalocation="http://java.sun.com/xml/ns/javaee  
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
  <display-name></display-name> 
  <welcome-file-list> 
    <welcome-file>index.jsp</welcome-file> 
  </welcome-file-list> 
 
  <filter> 
    <filter-name>struts2</filter-name> 
    <filter-class>org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter</filter-class> 
  </filter> 
  <filter-mapping> 
    <filter-name>struts2</filter-name> 
    <url-pattern>*.action</url-pattern> 
  </filter-mapping> 
  <filter-mapping> 
    <filter-name>struts2</filter-name> 
    <url-pattern>*.jsp</url-pattern> 
  </filter-mapping> 
   
</web-app> 

3)编写action类
4)创建好了action类中要对action进行配置struts.xml,注意该配置文件的位置要在src的根目录下
5)创建jsp的文件,进行测试

三、struts.xml的配置初探

先来看看struts的基本配置的大概情况

<?xml version="1.0" encoding="utf-8"?> 
<!doctype struts public 
  "-//apache software foundation//dtd struts configuration 2.1.7//en" 
  "http://struts.apache.org/dtds/struts-2.1.7.dtd"> 
   
<struts> 
  <package name="user" namespace="/" extends="struts-default"> 
    <action name="*user" class="com.zzjmay.action.vaildateaction" method="{1}"> 
      <result name="success">/success.jsp</result> 
      <result name="input">/{1}.jsp</result> 
    </action> 
  </package> 
</struts> 

从上面的代码中可以看出,xml中包含的再根节点下<struts></struts>下。在实际项目中的编写时,头部信息需要更改,那么我们给以在导入的jar中的jar包中进行获取

在struts-core-2.2.1.1.jar包下的struts2.0.dtd中进行获取。

四、struts.xml中的package的配置

看着前面的代码可以很清晰的看到package的属性

属性有:

1.     name:逻辑上的包名
2.     namespace:命名空间,用来区分同意struts下的相同action(注意是一种逻辑上的的路径)
3.     extends: 继承某个配置文件
4.     abstract

具体使用过程中要注意,有与命名空间的命名,我们要在相应的过程中加上对应的命名空间的路径,例如:

<s:form action="db/login.action" method="post">

此代码说明的就是将会去调用db命名空间下的login对应的action

还需要注意的是:

<result>标签的下的是物理路径(绝对路径),即指在项目中的实际位置,代码如下

<result name="success">/login/error.jsp</result>

六、struts.xml中的result的配置

对于action的配置我这里面只是简单的概括,具体很多细节性的东西我将专门写一篇博客,主要讲解的动态的对action进行配置

属性有:

1.     name:action类的映射名称
2.     class:action类的完整路径
3.     method:默认使用的execute()方法,如果要自定义触发方法,需要使用method自定义

七、struts.xml配置过程中的注意信息

在实际开发的项目中,我们可能需要配置很多的action,有时候为了便于我们的分类,我们一般需要创建不同包下的struts-user.xml文件,不过最终我们的这些配置都是要导入进我们的struts.xml文件中。使用的标签和jsp编程中<include>

struts.xml

[<?xml version="1.0" encoding="utf-8"?> 
<!doctype struts public 
  "-//apache software foundation//dtd struts configuration 2.1.7//en" 
  "http://struts.apache.org/dtds/struts-2.1.7.dtd"> 
 
<struts> 
  <include file="struts-user.xml"></include> 
</struts> 

struts-user.xml

<?xml version="1.0" encoding="utf-8"?> 
<!doctype struts public 
  "-//apache software foundation//dtd struts configuration 2.1.7//en" 
  "http://struts.apache.org/dtds/struts-2.1.7.dtd"> 
 
<struts> 
  <constant name="struts.ui.theme" value="simple"></constant> 
  <package name="user" namespace="/ss" extends="struts-default"> 
    <action name="login" class="com.zzjmay.action.useraction" 
      method="execude2"> 
  <!--result下的路径是物理路径 --> 
      <result name="success">/login/success.jsp</result> 
      <result name="error">/login/error.jsp</result> 
    </action> 
  </package> 
  <!-- 包名不能相同 --> 
  <package name="user123" namespace="/db" extends="struts-default"> 
    <action name="login" class="com.zzjmay.action.useraction" 
      method="execude2"> 
  <!--result下的路径是物理路径 --> 
      <result name="success">/login/error.jsp</result> 
      <result name="error">/login/success.jsp</result> 
    </action> 
  </package> 
</struts> 

一、action的创建方法

1)实现action接口
2)继承actionsupport类,覆写其中的方法
3)不继承任何类都可以实现,关键是在struts.xml中进行配置

二、action动态方法的调用

在实际的项目中,一个action类的中,可能存在多个方法,而不同的方法执行的效果是不一样的,如果按照了一般性的配置,将无形的增加了程序员的负担

第一种方法:在struts.xml中的action属性标签中用method属性指定方法名(不怎么推荐使用)

第二种方法: jsp页面中指定你要调用的那个方法

<form action=”login!myfun.action”,method=”post”>

在客户端请求中进行动态的配置:映射名!方法名.action

这样可以动态的调用action中的myfun方法,就不要在action标签中进行method的配置

第三种方法:使用通配符进行配置(推荐使用:适用情况当一个类中存在较多的响应方法)

在配置<action> 时,可以在 name,class,method 中使用通配符,这是 另外一种形式的动态方法调用

<action name="*user" class="com.zzjmay.action.useraction" method="{1}"> 
//这种通配是针对的是同一个action中,响应不同的方法 
 
在jsp页面中调用的时候 
<form action="loginuser.action" method="post"> 
  <!-- 需要注意的是要保证表单中的name的命名要和action中属性的命名保持一致 --> 
    用户名:<input type="text" name="username" id="username"><br> 
    密   码:<input type="password" name="password" id="password"> 
    <br> 
    <input type="submit" value="提交"> 
     
  </form> 

注意:通过使用通配符的时候相当于占位操作,其中的{1}表示第一个通配符,就上面的例子来讲,当jsp页面中是loginuser.action进行调用的时候,实际上出发的action类中的login()方法

通过通配符实现,不同的类响应不同的类中的方法:

<action name=“*_*" class="action.{1}action" method="{2}">
  <result >/{2}.jsp</result>
</action>

三、 action的动态结果的配置

含义:在实际运行当中,action类的处理业务的过程中,可能由于业务条件的复杂,会跳转到不同页面,那么为了节省result的配置,我们一般会采用动态结果的配置。其实很像我们在servlet中进行全局的forward的配置。

useraction.java

public class useraction extends actionsupport {
  private string nextresult;
  ...
}

struts2.xml

<action name="user" class="action.useraction">
  <result>/{nextresult}</result>
</action>

四、接收用户数据(推荐使用的实现modeldriven的接口)

在这篇博客中我只是介绍常用的,并且在实际项目中效率较高的方法。我之所以推荐modeldriven接口的方法,原因就是可以很好的分离显示界面和业务逻辑的分离(解耦性)。

实现modeldriven接口

步骤:
u    实现用户登录功能
u    创建user.java类
ø          声明用户登录信息
ø          创建无参构造
u   创建action类
ø          实现com.opensymphony.xwork2.modeldriven接口
ø          声明user类对象并实例化
ø         实现getmodel ()方法,返回user类对象
u    创建jsp页面
ø         表单元素使用”属性”设置name属性

注意:
1)  首先,action要实现modeldriven的接口,默认实现getmodel()方法
2)  要在action中自己来实例化user的对象,而不像前面一种方法是有struts2的框架实现的
3)  比较突出的就是在jsp页面中,表单元素的name属性,直接用名字就可以来

useraction.java

public class useraction implements modeldriven<user> { 
  //要实例化 
  private user user=new user(); 
   
  public user getuser() { 
    return user; 
  } 
 
  public void setuser(user user) { 
    this.user = user; 
  } 
  public string myfun() throws exception { 
    system.out.println("username="+user.getusername()); 
    system.out.println("password="+user.getpassword()); 
    system.out.println("myfun....."); 
    //用来进行处理 
    if(user.getusername().equals(user.getpassword())){ 
      return "success"; 
    }else{ 
      return "error"; 
    } 
     
     
  } 
 
  public user getmodel() { 
    // todo auto-generated method stub 
    return user; 
  } 
 
} 

login.jsp

<form action="loginuser.action" method="post"> 
  <!-- 需要注意的是要保证表单中的name的命名要和action中属性的命名保持一致 --> 
    用户名:<input type="text" name="username" id="username"><br> 
    密   码:<input type="password" name="password" id="password"> 
    <br> 
    <input type="submit" value="提交"> 
     
  </form> 

五、在action中访问servlet api

访问servlet api的实际项目中有两种的方法访问servlet api

1)解耦的方法(实现三大接口程序requestaware,applicationaware,sessionaware)

public class useraction2 implements modeldriven<user> ,requestaware,sessionaware,applicationaware{ 
 
  private user user = new user(); 
   
  private map<string, object> requestmap; 
  private map<string, object> sessionmap; 
  private map<string, object> applicationmap; 
   
   
  public void setapplication(map<string, object> applicationmap) { 
    this.applicationmap=applicationmap; 
     
  } 
 
  public void setsession(map<string, object> sessionmap) { 
    this.sessionmap=sessionmap; 
  } 
 
  public void setrequest(map<string, object> requestmap) { 
      this.requestmap=requestmap; 
     
  } 
 
 
  public user getuser() { 
    return user; 
  } 
 
  public void setuser(user user) { 
    this.user = user; 
  } 
 
  public string myfun() throws exception { 
    system.out.println("username=" + user.getusername()); 
    system.out.println("password=" + user.getpassword()); 
    system.out.println("myfun2....."); 
    // 用来进行处理 
    if (user.getusername().equals(user.getpassword())) { 
 
      sessionmap.put("succ", "成功的哇2!!!"); 
      bookbiz bookbiz=new bookbiz(); 
       
      applicationmap.put("books",bookbiz.getbooks()); 
       
      return "success"; 
    } else { 
 
      requestmap.put("errormsg", "登陆失败了2"); 
      return "error"; 
    } 
 
  } 
 
 
  public user getmodel() { 
    // todo auto-generated method stub 
    return user; 
  } 



注意:在非解耦的方式中,struts2框架已经将对应的四大应用作用域给封装到了map集合中,所以这里一开始定义的三个map集合中可以相当于操作四大作用域对象

2)非解耦的方法(实现两大接口程序servletreuqestaware,servletcontextaware):非解耦的意思就是说直接操作的servlet api对象

public class useraction4 implements modeldriven<user>,servletrequestaware,servletcontextaware{ 
 
  private user user = new user(); 
   
  private httpservletrequest request; 
  private httpsession session; 
  private servletcontext application; 
 
  public void setservletcontext(servletcontext application) { 
    this.application = application; 
 
  } 
 
  public void setservletrequest(httpservletrequest request) { 
    this.request = request; 
 
  } 
 
  public user getuser() { 
    return user; 
  } 
 
  public void setuser(user user) { 
    this.user = user; 
  } 
……………… 

注意:在实现接口中只实现了request和application的获取

在实际项目开发当中,需要的获取session的方法是通过httpsession session= request.getsession();

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。