目录

1、Action基本原理

2、在Action中访问Session/Application/

3、Action属性注入

4、Action通配符

5、struts2常量定义(请求后缀)

6、为应用指定多个struts配置文件

7、Action动态方法调用


1、Action基本原理

1)当客户端发出请求,请求到达控制器。

2)控制器根据请求创建一个ValueStack对象,每个请求创建一个Action对象,Action对象存入到ValueStack对象的root栈项。将ValueStack对象存入到request中。存储的key为“struts.valueStack”。

3)控制器调用Action对象接受请求参数,执行业务方法处理。

4)控制器根据Action返回值调用result视图组件处理。

5)请求处理完成后,将ValueStack对象和Action对象销毁。

2、在Action中访问Session/Application/

)利用ActionContext返回Map方式类型(servlet不相关的非IoC取得Request等对象的方式)

这种方法先取得ActionContext,然后获取Map类型的request等对象

ActionContext context = ActionContext.getContext();        


         Map<String,Object> session = context.getSession();        


         Map<String,Object> request = (Map<String,Object>)         this         .context.get(         "request"         );        


         Map<String,Object> application =         this         .context.getApplication();


)利用ServletActionContext返回的是Servlet类型(servlet 相关的非IoC 取得Request等对象的方式)

这种方法可以获取servlet相关的request等对象,取出的request对象不单单是设定属性的作用,而是可以获取http相关的信息。

HttpServletRequestrequest = ServletActionContext.getRequset();        


         HttpSessionsession = request.getSession();        


         ServletContextapplication = ServletActionContext.getgetServletContext();


)实现接口(servlet 不相关的 IoC 取得Request等对象的方式)

实现特定的RequestAware, SessionAware, ApplicationAware等接口,由container来设定request等对象。

publicabstractclassBaseAction implementsSessionAware {        


         // 自定义属性来接收注入的Session        


         privateMap<String, Object> session;        


         // 用于子类取得Session        


         publicMap<String, Object> getSession() {        


         returnsession;        


         }        


         // Struts2通过此方法注入Session        


         publicvoidsetSession(Map<String, Object> m) {        


         System.out.println(         "BaseAction.setSession()..."         );        


         session = m;        


         }        


         }

publicclassLoginAction  extendsBaseAction {        


         privateAdmin admin;        


         privateString errorMsg;        


         publicAdmin getAdmin() {        


         returnadmin;        


         }        


         publicvoidsetAdmin(Admin admin) {        


         this         .admin = admin;        


         }        


         publicString execute() {        


         // 1、校验输入参数是否为空        


         if         (admin ==          null         ) {        


         errorMsg =          "用户名或密码不能为空!"         ;        


         return         "error"         ;        


         }             


         //2、取得帐号及密码        


         String code = admin.getAdminCode();        


         String pwd = admin.getPassword();             


         //3、根据帐号及密码,查询是否存在用户数据        


         IAdminDao dao = DAOFactory.getAdminDAO();        


         Admin user =          null         ;        


         try         {        


         user = dao.findByCodeAndPwd(code, pwd);        


         }          catch         (DAOException e) {        


         e.printStackTrace();        


         errorMsg =          "对不起,系统出现错误,请联系管理员!"         ;        


         return         "error"         ;        


         }             


         // 4、判断取到底user是否为空        


         if         (user ==          null         ) {        


         // 若为空,则输入的是非法的帐号密码,继续登录        


         errorMsg =          "用户名或密码不匹配!"         ;        


         return         "error"         ;        


         }          else         {        


         // 若不为空,则合法,进入首页        


         getSession().put(         "user"         , user);        


         System.out.println(         "user:"         +getSession().get(         "user"         ));        


         return         "success"         ;        


         }             


         }        


         publicString getErrorMsg() {        


         returnerrorMsg;        


         }        


         publicvoidsetErrorMsg(String errorMsg) {        


         this         .errorMsg = errorMsg;        


         }        


         }



)实现接口(servlet相关的 IoC 取得Request等对象的方式)

这种方法也可以获取servlet相关的request等对象,也就是说这种方式取出的request对象不单单是设定属性的作用,而是可以获取http相关的信息。

但是取出方法是通过接口ServletRequestAware, ServletContextAware进行实现,也就是由struts2的container来设定。

privateHttpServletRequest request;        


         privateHttpSession session;        


         privateServletContext application;        


         publicString execute() throwsException {        


         this         .request =ServletActionContext.getRequest();        


         this         .session =          this         .request.getSession();        


         this         .application =ServletActionContext.getServletContext();        


         returnSUCCESS;        


         }



3、Action属性注入

为Action中的属性提供例如依赖注入功能,在配置文件中我们可以很方便的为Action中的属性注入值,但是,属性必须提供setter方法。

Action:

publicclass ActionTest1 {        


         privateStringsavePath;        


         publicStringgetSavePath() {        


         returnsavePath;        


         }        


         publicvoid setSavePath(StringsavePath)  {        


         this         .savePath = savePath;        


         }        


         publicStringexecute() {        


         return         "success"         ;        


         }        


         }



struts.xml:

<         packagename         =         "Test5a"         namespace         =         "/test5"         extends         =         "struts-default"         >        


         <         actionname         =         "list"         class         =         "cn.action.ActionTest1"         method         =         "execute"         >        


         <!--为这个属性注入值为/images -->        


         <         paramname         =         "savePath"         >/images</         param         >        


         <         resultname         =         "success"         >/WEB-INF/page/savePath.jsp</         result         >        


         </         action         >        


         </         package         >




上面通过<param>节点为Action的savePath属性注入了值/images

4、Action通配符

publicclass UserAction {         


         // 模拟user新增功能        


         publicString add() {        


         System.out.println(         "模拟user的新增..."         );        


         return         "success"         ;        


         }         


         //模拟user的修改        


         publicString modify() {        


         System.out.println(         "模拟user的修改..."         );        


         return         "success"         ;        


         }         


         publicString query() {        


         System.out.println(         "模拟user的查询..."         );        


         return         "success"         ;        


         }        


         }


<         struts         >        


         <         packagename         =         "user"         namespace         =         ""         extends         =         "struts-default"         >        


         <         actionname         =         "*_*_*"         class         =         "com.tarena.action.{1}Action"         method         =         "{2}"         >        


         <         resultname         =         "success"         >/WEB-INF/jsp/{3}.jsp</         result         >        


         </         action         >        


         </         package         >        


         </         struts         >



5、struts2常量定义(请求后缀)

1)、请求后缀

struts2默认使用.action后缀访问Action。其实默认后缀是可以通过常量

“struts.action.extension”进行修改的,例如:我们可以配置Struts2只处理以.do为后缀的请求路径:

<struts>

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

</struts>

如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。如:

<constantname="struts.action.extension" value="do,go"/>

2)、常量定义

常量可以在struts.xml或struts.properties中配置,建议在struts.xml中配置,两种配置方式如下:

在struts.xml文件中配置常量

<struts>

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

</struts>

在struts.properties中配置常量:struts.action.extension=do


因为常量可以在下面多个配置文件中进行定义,所以我们需要了解struts2加载常量的搜索顺序:

struts-default.xml

struts-plugin.xml

struts.xml

struts.properties

web.xml

如果在多个文件中配置了同一个常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值。

3)、常量介绍:

<!--指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法和freemarker 、velocity的输出 -->        


         <         constantname         =         "struts.i18n.encoding"         value         =         "UTF-8"         />        


         <!-- 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。        


         如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。-->        


         <         constantname         =         "struts.action.extension"         value         =         "do"         />        


         <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭-->        


         <         constantname         =         "struts.serve.static.browserCache"         value         =         "false"         />        


         <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开-->        


         <         constantname         =         "struts.configuration.xml.reload"         value         =         "true"         />        


         <!-- 开发模式下使用,这样可以打印出更详细的错误信息-->        


         <         constantname         =         "struts.devMode"         value         =         "true"         />        


         <!-- 默认的视图主题-->        


         <         constantname         =         "struts.ui.theme"         value         =         "simple"         />        


         <!– 与spring集成时,指定由spring负责action对象的创建-->        


         <         constantname         =         "struts.objectFactory"         value         =         "spring"         />        


         <!–该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false。-->        


         <         constantname         =         "struts.enable.DynamicMethodInvocation"         value         =         "false"         />        


         <!--上传文件的大小限制-->        


         <         constantname         =         "struts.multipart.maxSize"         value=“10701096"/>


6、为应用指定多个struts配置文件

<struts>

        <includefile="struts-user.xml"/>

        <includefile="struts-order.xml"/>

</struts>

7、Action动态方法调用

如果Action中存在多个方法时,我们可以使用!+方法名调用指定方法。如下:

publicclassHelloWorldAction{        


         privateString message;        


         publicString execute() throwsException{        


         this         .message=          "我的第一个struts2应用"         ;        


         return         "success"         ;        


         }              


         publicString other() throwsException{        


         this         .message=          "第二个方法"         ;        


         return         "success"         ;        


         }        


         }


假设访问上面action的URL路径为:

要访问action的other() 方法,我们可以这样调用:

/struts/test/helloworld!other.action

如果不想使用动态方法调用,我们可以通过常量struts.enable.DynamicMethodInvocation关闭动态方法调用。

<constant name="struts.enable.DynamicMethodInvocation"value="false"/>