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>,但动态方法调用以及使用通配符却要指定
转载请于明显处标明出处