Struts2学习(二)

Struts2配置文件

1、可能需要使用的配置文件

  • web.xml(必须 ,根据需要去填写)
  • struts.xml ( 自己创建,必须 )
  • struts.properites ( 自己创建,不是必须 )
  • struts-default.xml ( struts2-core-2.5.10.1.jar 必须 )
  • default.properites ( org/apache/struts2/default.properties,当需要找常量名称时候打开他)
  • struts-plugin.xml ( 每个插件都有一个 配置文件 )

2、struts-default.xml的组成(struts2-core-2.5.10.1.jar)

  • 定义常量 ( constant )
  • 定义内部需要的组件Bean ( bean )
  • 定义了一个名称是 struts-default 的抽象包 ( package ),所谓抽象包,是指该package内部没有一个<action>

3、struts-default 的包组成

  • 在 result-types 标签内部定义了一批 result-type
  • 在 interceptors 标签定义了一批 interceptor 和 一批 interceptor-stack
  • 使用 default-interceptor-ref 指定了默认的拦截器栈 ( <default-interceptor-ref name="defaultStack"/>)
  • 使用 default-class-ref 定义了默认的 Action 类 ( ActionSupport )
  • 使用 global-allowed-methods 声明了全局范围内允许被访问的方法 ( execute,input,back,cancel,browse,save,delete,list,index

Action类

1、查看ActionSupport(默认的 Action 类)的源码

public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
............................
}

ActionSupport实现了Action接口,Action接口的源码如下

package com.opensymphony.xwork2;

public interface Action {

    public static final String SUCCESS = "success";

    public static final String NONE = "none";

    public static final String ERROR = "error";

    public static final String INPUT = "input";

    public static final String LOGIN = "login";

    public String execute() throws Exception;

}

2、实现 Action 类的方法

  • 实现 com.opensymphony.xwork2.Action 接口(推荐使用的方法,因为struts.xml中未指定method时候回找execute方法)
  • 继承 com.opensymphony.xwork2.ActionSupport 类
  • 不实现 Action 接口 、 也不继承 ActionSupport 类 ,而是自己写自己的类,但是方法参考 Action 中的 execute 方法的形式去声明(public String),返回的是一个名称

3、Action的三种访问方式,在同一个Action中定义不同的方法测试案例

  • 第一种配置,使用 <action> 标签的 method 属性指定相应的方法

    index.jsp

    <%@ page language = "java" pageEncoding = "UTF-8" %>
    <%@ page contentType = "text/html; charset= UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Apache Struts</title> <style type="text/css"> .container { width: 90% ; margin: 10px auto ; box-shadow: 0px 0px 5px 4px #dedede ; padding: 5px 5px ; } ul .required { color : blue ; } ul li { font-size: 16px ; padding: 5px 5px ; } </style> </head> <body> <div class="container"> <h4>在同一个 Action 中定义不同的 方法:</h4> <form action="${ pageContext.request.contextPath }/customer/action/action/register" method="post" > <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <input type="password" name="confirm" placeholder="确认密码"> <input type="submit" value="注册"> </form>     <hr> <form action="${ pageContext.request.contextPath }/customer/action/action/login" method="post" > <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <input type="submit" value="登录"> </form> <a href="${ pageContext.request.contextPath }/customer/action/action/logout">注销</a> </div> </body> </html>

     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>
       <!-- 允许在 action 的 名称 中使用 / 字符 -->
        <constant name="struts.enable.SlashesInActionNames" value="true" />
        <!-- 在每个 <action> 标记 , 用 method 属性中指定对应的方法名称,包名不要重复 -->
        <package name="customer-action" namespace="/customer/action" extends="struts-default" >
        
            <!-- 可以在自己的包中通过  default-class-ref 来自定义默认的 Action 类-->
            <default-class-ref class="ecut.action.action.CustomerAction" />
        
            <action name="action/register" class="ecut.action.action.CustomerAction" method="register" >
                <!-- 重定向到另一个action的配置,<result type="redirectAction">xxxx<result name="success" type="redirectAction">默认是actionName -->
                <result name="success" type="redirectAction">
                    <!-- 不在同一个包内需要指定命名空间 ,在同一个包可以省略(customer-action)-->
                    <!-- <param name="namespace">/customer/action</param> -->
                    <param name="actionName">page/success/register</param>
                </result>
            </action>
            
            <!-- 对于 action 标签 如果没有指定 class 属性,则默认以 default-class-ref 所定义的类为准 -->
            <action name="page/success/register" >
                <!-- 对于任意的 一个 result 来说,默认的 名称是 success ,默认的 type 是 dispatcher -->
                <!-- dispatcher 相当于 Servlet 中的 forward 操作 -->
                <result name="success" type="dispatcher">/WEB-INF/pages/action/register_success.jsp</result>
            </action>
            
            <action name="action/login" class="ecut.action.action.CustomerAction" method="login" >
                <result name="success" type="dispatcher">/WEB-INF/pages/action/login_success.jsp</result>
            </action>
            
            <action name="action/logout" class="ecut.action.action.CustomerAction" method="logout" >
                <result name="success" type="dispatcher">/WEB-INF/pages/action/logout_success.jsp</result>
            </action>
            
        </package>
    </struts>

    包名不能重复,使用redirectAction可以解决表单重复提交的问题,redirectAction可以参照API中ServletActionRedirectResult类的例子来完成,default-class-ref 默认是struts-default.xml中struts-default 的包所指定的ActionSupport,Action类,要使 action 的 名称 中使用 / 字符,则参照default.properites进行配置

    Action类

    package ecut.action.action;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    import com.opensymphony.xwork2.Action;
    
    public class CustomerAction implements Action {
        
        private static final Logger logger = LogManager.getLogger();
    
        @Override
        public String execute() throws Exception {
            logger.info( "我执行了" );
            return SUCCESS;
        }
        
        public String register() throws Exception {
            logger.info( "register" );
            return SUCCESS;
        } 
        
        public String login() throws Exception {
            logger.info( "login" );
            return SUCCESS;
        } 
        
        public String logout() throws Exception {
            logger.info( "logout" );
            return SUCCESS;
        } 
    
    }
  • 第二种配置,启动动态方法调用

    index.jsp

    <%@ page language = "java" pageEncoding = "UTF-8" %>
    <%@ page contentType = "text/html; charset= UTF-8"%>
    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Apache Struts</title> <style type="text/css"> .container { width: 90% ; margin: 10px auto ; box-shadow: 0px 0px 5px 4px #dedede ; padding: 5px 5px ; } ul .required { color : blue ; } ul li { font-size: 16px ; padding: 5px 5px ; } </style> </head> <body>   <div class="container"> <h4>动态方法调用:</h4> <form action="${ pageContext.request.contextPath }/dynamic/student!register" method="post" > <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <input type="password" name="confirm" placeholder="确认密码"> <input type="submit" value="注册"> </form> <hr> <form action="${ pageContext.request.contextPath }/dynamic/student!login" method="post" > <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <input type="submit" value="登录"> </form> <a href="${ pageContext.request.contextPath }/dynamic/student!logout">注销</a> </div> </body> </html>

     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" />
       <!-- 动态方法调用,页面上的路径的形式: "/命名空间/<action>名称!方法名称" -->
        <package name="dynamic" namespace="/dynamic" extends="struts-default">
    
            <default-class-ref class="ecut.action.action.StudentAction" />
    
            <action name="student">
                <result name="register-success" type="redirectAction">
                    <!-- 不在同一个包内需要指定命名空间 ,在同一个包可以省略(customer-action)-->
                    <param name="namespace">/customer/action</param>
                    <param name="actionName">page/success/register</param>
                </result>
                <result name="login-success" type="redirectAction">
                    <param name="actionName">page/success/login</param>
                </result>
                <result name="logout-success" type="redirectAction">
                    <param name="actionName">page/success/logout</param>
                </result>
                <!-- 声明哪些方法支持动态调用 -->
                <allowed-methods>register,login,logout</allowed-methods>
            </action>
            
            <action name="page/success/login" >
                <result name="success" type="dispatcher">/WEB-INF/pages/action/login_success.jsp</result>
            </action>
            
             <action name="page/success/logout" >
                <result name="success" type="dispatcher">/WEB-INF/pages/action/logout_success.jsp</result>
            </action>
            
        </package>
    </struts>

    要启用动态变量需要参照default.properites增加一个常量,否则会将student!register当成是actionName,在action标签内需要通过allowed-methods来指定哪些方法可以被调用,否则会抛出Method register for action student is not allowed!的异常,在页面使用时,在相应的URL之后使用!对action名称和方法名称进行分割 。 在Action类中的不同的方法中,其返回值需要不同,以便于<action>中的不同<result>相对应。

    Action类

    package ecut.action.action;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    import com.opensymphony.xwork2.Action;
    
    public class StudentAction implements Action {
        
        private static final Logger logger = LogManager.getLogger();
    
        @Override
        public String execute() throws Exception {
            logger.info( "我执行了" );
            return SUCCESS;
        }
        
        public String register() throws Exception {
            logger.info( "register" );
            return "register-success";
        } 
        
        public String login() throws Exception {
            logger.info( "login" );
            return "login-success";
        } 
        
        public String logout() throws Exception {
            logger.info( "logout" );
            return "logout-success";
        } 
    
    }
  • 第三种配置,使用通配符

    index.jsp

    <%@ page language = "java" pageEncoding = "UTF-8" %>
    <%@ page contentType = "text/html; charset= UTF-8"%>
    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Apache Struts</title> <style type="text/css"> .container { width: 90% ; margin: 10px auto ; box-shadow: 0px 0px 5px 4px #dedede ; padding: 5px 5px ; } ul .required { color : blue ; } ul li { font-size: 16px ; padding: 5px 5px ; } </style> </head> <body> <div class="container"> <h4>使用通配符:</h4> <form action="${ pageContext.request.contextPath }/wildcard/teacher/register" method="post" > <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <input type="password" name="confirm" placeholder="确认密码"> <input type="submit" value="注册"> </form> <hr> <form action="${ pageContext.request.contextPath }/wildcard/teacher/login" method="post" > <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <input type="submit" value="登录"> </form> <a href="${ pageContext.request.contextPath }/wildcard/teacher/logout">注销</a> </div> <hr> </body> </html>

    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>
    <package name="wildcard" namespace="/wildcard/teacher" extends="struts-default">
    
            <default-class-ref class="ecut.action.action.TeacherAction" />
            <!--与所允许的动作名不匹配[a-zA-Z0-9._!/\-]*,将使用默认动作索引index,*只能匹配xxx,不能匹配到xx_xxx -->
            <action name="*" method="{1}">
                <result name="success" type="dispatcher">/WEB-INF/pages/action/{1}_success.jsp</result>
                <!-- 声明哪些方法支持动态调用,不加会报错There is no Action mapped for namespace -->
                <allowed-methods>register,login,logout</allowed-methods>
            </action>
    
        </package>
    
    </struts>

    需要声明动态调用以及在action标签内需要声明哪些方法支持动态调用

    Action类

    package ecut.action.action;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    import com.opensymphony.xwork2.Action;
    
    public class TeacherAction implements Action {
        
        private static final Logger logger = LogManager.getLogger();
    
        @Override
        public String execute() throws Exception {
            logger.info( "我执行了" );
            return SUCCESS;
        }
        
        public String register() throws Exception {
            logger.info( "register" );
            return SUCCESS;
        } 
        
        public String login() throws Exception {
            logger.info( "login" );
            return SUCCESS;
        } 
        
        public String logout() throws Exception {
            logger.info( "logout" );
            return SUCCESS;
        } 
    
    }

 待解决问题

Struts2使用 <action> 标签的 method 属性指定相应的方法不需要指定<allowed-methods>,但动态方法调用以及使用通配符却要指定

转载请于明显处标明出处

https://www.cnblogs.com/AmyZheng/p/9196458.html

posted @ 2018-06-19 18:30  AmyZheng  阅读(319)  评论(0编辑  收藏  举报