struts2教程&实例

Posted ikun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了struts2教程&实例相关的知识,希望对你有一定的参考价值。

1.第一个struts2项目

参考官方配置 http://struts.apache.org/getting-started/

github地址:https://github.com/unbelievableme/maven_hibernate-struts-spring/tree/master/struts2/first

建议:参考官方配置操作一遍,因为技术不断更新,不同版本的struts的类可能不同,老版本的多个类可能在新版本中集成了一个

2.struts2工作流程原理

2.1步骤

1.创建Web Project

2.导入Jar(使用maven控制的话,配置pom.xml)

3.在web.xml配置struts2的过滤器

<filter>
       <filter-name>struts2</filter-name>
<!--该类会因struts版本不同而变化,在struts2.0-2.1.2为org.apache.struts2.dispatcher.FilterDispatcher,在之后版本为下述-->       
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>struts2</filter-name>
       <!-- 所有的url都会被url过滤器解析 -->
       <url-pattern>/*</url-pattern>
    </filter-mapping>

 

4.创建Struts核心xml文件

5.创建action类继承与ActionSupport

6.配置struts.xml

<!--详细配置及介绍见:http://www.cnblogs.com/kundeg/p/7188699.html-->

2.2流程

1、客户端浏览器发出HTTP请求

2、该请求被StrutsPrepareAndExecuteFilter接收

3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton

4、Action调用业务逻辑组件处理业务逻辑

5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面

6、返回HTTP响应到客户端浏览器

2.3原理

 

 注意:在struts2.1.2后FilterDispatcher被替换为了StrutsPrepareAndExecuteFilter

1、 客户端初始化一个指向Servlet容器(例如Tomcat)的请求

2、 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)

3、 接着被StrutsPrepareAndExecuteFilter(能够拦截请求对象ServletRequest和ServletResponse结合Struts.xml构建独立于servlet的ActionContxt)调用,StrutsPrepareAndExecuteFilter询问ActionMapper(含有struts.xml中Action配置的name,namespce,result等的HashMap)来决定这个请是否需要调用某个Action

4、 如果ActionMapper决定需要调用某个Action,StrutsPrepareAndExecuteFilter把请求的处理交给ActionProxy

5、 ActionProxy通过Configuration Manager询问框架的配置文件struts.xml,找到需要调用的Action类

6、 ActionProxy创建一个ActionInvocation的实例。

7、 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。

8、 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

3.拦截器介绍

3.1Interceptor基础介绍

拦截器基础介绍以及与过滤器的对比见StrutsPreparedAndExcuteFilter与Interceptor

3.2 计时拦截器实例

 TimerAction.java

public class TimerAction extends ActionSupport{
  public String excute(){
      //下面为耗时代码段
      int sum = 0;
      for(int i =0;i<10000;i++){
          sum+=i;
      }
      return SUCCESS;
  }
}

TimerInterceptor.java

public class TimerInterceptor extends AbstractInterceptor{
public String intercept(ActionInvocation invocation) throws Exception {
     //1.执行action之前
    long start = System.currentTimeMillis();
    //2.执行下一个拦截器,如果已经是最后一个拦截器,则执行目标Aciton
    String result = invocation.invoke();
    //3.执行Action之后
    long end = System.currentTimeMillis();
    System.out.println("执行Action花费时间:"+(end-start+"ms"));
    return result;
}
}

struts.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />  
    <package name="/" extends="struts-default" strict-method-invocation="false">
             <!--注册拦截器-->
     <interceptors>
     <interceptor name="myTimer" class="Interceptor.TimerInterceptor"> </interceptor>
     </interceptors>
        <action name="TimerAction" method="excute" class="action.TimerAction"> 
            <result name="success">/success.jsp</result>
            <!-- 引用拦截器 -->
            <interceptor-ref name="myTimer"></interceptor-ref>
        </action>
    </package>
</struts>

项目路径(maven管理):

4.深入struts

4.1 Action搜索顺序

http://localhost:8080/struts2/path1/path2/path3/student.action

第一步:判断package是否存在,如:path1/path2/path3/

第二步:如果package存在,则判断该package中action是否存在,如果不存在则去默认namespace的package里面寻找action

第三步:如果package不存在,检查上一级路径的package是否存在(直到默认namespace),重复第一步 第三步:如果没有则报错

4.2 动态方法调用

目的:一个action对应多个请求的处理,避免action过多

举例:下述为类为action.helloworld的action,该action可以处理请求../add.action和../update.action,下面介绍动态调用的几种常见方法

public class helloworld extends ActionSupport{
public String add(){
    /*  */
    return SUCCESS;
}
public String update(){
    /*  */
    return SUCCESS;
}
}

4.2.1 method方法

在struts.xml中的配置如下:

<struts>
   <package name="defalut" extends="struts-default">
        <action name="addAction" class="action.helloworld" method="add"> 
            <result name="success">/add.jsp</result>
        </action>
        <action name="updateAction" class="action.helloworld" method="update">
            <result name="success">/update.jsp</result>
        </action>
    </package>
</struts>

   访问方式:http://localhost:8080/工程名/addAction.action(addAction可以换成updateAction)

   缺点:当一个action中方法过多的时候哦,配置过于冗余

4.4.2 感叹号方式

修改entity为:   

public class helloworld extends ActionSupport{
public String add(){
    /*  */
    return "add";
}
public String update(){
    /*  */
    return "update";
}
}

 在struts.xml中配置如下

<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />  
    <package name="default" extends="struts-default" strict-method-invocation="false">
        <action name="helloworldAction" class="action.helloworld"> 
<!--result的name属性值和action.helloworld类中方法处理的返回值相同-->
            <result name="add">/add.jsp</result>
            <result name="update">/update.jsp</result>
        </action>
    </package>
</struts>

  访问方式:http://localhost:8080/工程名/helloworldAction!add.action(!后面的add表示方法,可以换成update)

4.4.3 通配符方式(推荐使用)

在struts.xml中配置如下

<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />  
    <package name="default" extends="struts-default" strict-method-invocation="false">
<!--{1}表示*的内容-->
        <action name="helloworld_*" method="{1}" class="action.helloworld"> 
            <result name="success">/{1}.jsp</result>
        </action>
    </package>
</struts>

  或者如下:

<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />  
    <package name="default" extends="struts-default" strict-method-invocation="false">
<!--{1}代表第一个*的内容,{2}代表第二个*的内容-->
        <action name="*_*" method="{2}" class="action.{1}"> 
            <result name="success">/{2}.jsp</result>
        </action>
    </package>
</struts>

  访问方式:http://localhost:8080/工程名/helloworld_add.action(add表示方法)

4.3 指定多个配置文件

目的:为了解决在struts.xml中配置过多,或者为了在不同的xml中配置实现更好的分类

要求:多个xml配置都必须遵守struts的dtd规范,同时要注意编码方式要相同

举例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <constant name="struts.devMode" value="true" />
   <package name="/" extends="struts-default">
        <action name="index">
            <result>/index.jsp</result>
        </action>
        <action name="hello" class="action.hello" method="execute">
            <result name="success">/HelloWorld.jsp</result>
        </action>
    </package>
</struts>

 可以用下述两个xml文件来表示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <constant name="struts.devMode" value="true" />
    <include file="helloworld.xml"></include>
</struts>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <package name="/" extends="struts-default">
        <action name="index">
            <result>/index.jsp</result>
        </action>
        <action name="hello" class="action.hello" method="execute">
            <result name="success">/HelloWorld.jsp</result>
        </action>
    </package>
   </struts>

4.4 默认Action(主要讨论通配符配置方式)

目的:为了改进用户体验,解决http404和500错误(不能完全解决)

举例 :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />  
    <package name="/" extends="struts-default" strict-method-invocation="false">
    <default-action-ref name="index"></default-action-ref>
       <action name="index">
       <result>/error.jsp</result>
    </action>
        <action name="helloworld_*" method="{1}" class="action.helloworld"> 
            <result name="success">/{1}.jsp</result>
        </action>
    </package>
</struts>

注意:非默认action的name属性值一定不要以*为开头进行通配。否则错误的action地址不能由默认action进行响应处理,会进入以*开头的action。

缺点:但即使是不以*开头的action也存在与它匹配的但工程中不存在的action地址,例如在上述配置的基础上访问http://localhost:8080/工程名/helloworld_ad.action还是会出现异常界面(下图所示)。

 

解决:通过method配置可以完全解决404或500错误,感叹号方式不行(不再详述)

4.4 struts后缀 

目的:为了看起来xx,比如访问xx.html很容易以为静态页面,掩盖了本质:经过action处理跳转后的jsp页面

配置方式(三种):

1.在struts.xml中加上

<constant name="struts.action.extension" value="action,do,struts2"></constan

2.在struts.properties中加上

struts.action.extension=action,do,struts2

3.在web.xml中加上

  <filter>
       <filter-name>struts2</filter-name>
       <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!--添加内容-->
  <init-param>
  <param-name>struts.action.extension</param-name>
  <param-value>do,action,strtus2</param-value>
</init-param>
    </filter>
    <filter-mapping>
       <filter-name>struts2</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>

4.5 struts传参

4.5.1 直接用Action属性

下列代码依次为:前端jsp,后台action(省略struts.xml配置)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="./login.action" method="post">
用户名:<input name="username" type="text"><br>
密码:   <input name="password" type="password"><br>
<input type="submit" value="登陆">
</form>
</body>
</html>
View Code
public class User extends ActionSupport{
 private String username;

 public String excute(){
     System.out.println(username);
     return SUCCESS;
 }
 
public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
    
}
}
View Code

4.5.2 DomainModel

下列代码依次为:前端jsp,后台Action,实体类model

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="./login.action" method="post">
<!-- 要指明那个对象的object.xxx -->
用户名:<input name="user.username" type="text"><br>
密码:   <input name="user.password" type="password"><br>
<input type="submit" value="登陆">
</form>
</body>
</html>
View Code
public class loginAction extends ActionSupport{
private User user;
public String excute(){
    System.out.println(user.getUsername());
    return SUCCESS;
}
public User getUser() {
    return user;
}
public void setUser(User user) {
    this.user = user;
}
 
}
View Code
public class User extends ActionSupport{
 private String username;
 private String password;
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}
}
<

以上是关于struts2教程&实例的主要内容,如果未能解决你的问题,请参考以下文章

Struts2学习资料

免费下载全套最新011Struts2视频教程+教学资料+学习课件+源代码+软件开发工具

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段

php中引用&的一个小实例

struts2 官方系列教程三:使用struts2 标签 tag

Struts2远程代码执行漏洞S2-052 复现&防御方案