Struts2

01_sturts2入门01

ppt参照

1.struts1和struts2的区别

struts1是2001年发布的世界上第一个MVC模式的框架,而struts2并不是struts1的升级版本,struts2是在webwork基础上发展起来的

它们是两个不同的框架,但是struts2吸收了struts1和webwork的优点

2.struts2在javaweb中的作用 

我们都知道javaweb分四层:显示层,控制层,业务层,持久化层(数据层),struts2在javaweb中的作用就是显示层和控制层

3.模拟struts2的工作原理

总结:struts2的工作原理,其实就是在javaweb基础上多了一个struts.xml文件,这里我们用map集合和模拟xml文件,由于map集合的局限性(在实际开发中需要编译才能用,不想xml文件那样可以直接读取),对于多个请求连接对应的action,我们这里通过map的键值对形式来表现,但在struts2中则用xml文件来表示

/itcast_struts2/WebRoot/index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
  <head>
    <title>Struts2入门案例</title>
  </head>
  
  <body>
      实例链接 <br>
      <a href="${pageContext.request.contextPath}/primer/userAction.action">userWorld</a><br>
      <a href="${pageContext.request.contextPath}/helloWorld/helloWorldAction.action">helloWorld</a><br>

  </body>
</html>

 /itcast_struts2/src/cn/itcast/struts2/struts2Filter.java

package cn.itcast.struts2;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class struts2Filter implements Filter {
    //这里之所以用map集合,而且在init方法中添加请求路径和对应路径的action
    //是由于在可发中可能有多个请求路径需要判断,这里就通过在map中获取路径,然后找到对应的action
    //虽然这种方法解决了多个请求路径对应多个action的问题,但是在实际开发中一旦要加入新的请求路径和action就需要
    //再次想map集合中添加请求路径和对应的action,而且还需要重新编译,所以我们需要用xml文件来代替map集合
    //这个xml文件就是struts2的核心文件
    Map<String,String> map = new HashMap<String,String>();
    public void init(FilterConfig arg0) throws ServletException {
        //当过滤器初始化的时候就向map集合中添加键值对
        map.put("/primer/userAction.action", "cn.itcast.struts2.userAction");
        map.put("/helloWorld/helloWorldAction.action", "cn.itcast.struts2.helloWorldAction");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        
        //先强制转换
        HttpServletRequest request = (HttpServletRequest) req;
        ServletResponse response = (ServletResponse) res;
        //判断一下请求路径
        String path = request.getServletPath();
        if(path!=null&&path.equals("/index.jsp")){
            chain.doFilter(request, response);
        }else{
            System.out.println(path);
            try {
                Action action = (Action) Class.forName(map.get(path)).newInstance();
                action.excute();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            //转发
            request.getRequestDispatcher("/success.jsp").forward(request, response);
        }
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}

 

/itcast_struts2/src/cn/itcast/struts2/Action.java

package cn.itcast.struts2;
//定义了一个公共接口
public interface Action {
    public String excute();
}

 

/itcast_struts2/src/cn/itcast/struts2/helloWorldAction.java

package cn.itcast.struts2;

public class helloWorldAction implements Action {

    @Override
    public String excute() {
        System.out.println("HelloWorldAction执行!");
        return "HelloWorldAction";

    }

}

 

/itcast_struts2/src/cn/itcast/struts2/userAction.java

package cn.itcast.struts2;

public class userAction implements Action {

    @Override
    public String excute() {
        System.out.println("UserAction执行!");
        return "UserAction";

    }

}

 

/itcast_struts2/WebRoot/success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>页面返回结果</title>
  </head>
  <body>
        操作成功!
  </body>
</html>

 

4.struts2的工作流程

说明:首先tomcat服务器启动加载web.xml文件,web.xml文件中加载struts2提供的过滤器,过滤器加载并解析struts2.xml文件,当客户端页面点击一个请求连接时,

就会转到对应的action去。

 

总结:1.struts2并不是struts1的升级版本,它是在webwork基础上发展起来的,吸收了webwork和struts1的优点

     2.它解决了javaweb中的显示层和控制层的问题

        3.它与javaweb最大的不同在于它多了一个sturts.xml文件,这个是它的核心文件,这个文件以xml文件的形式存放了请求连接和对应action的关系,之所以用xml文件而不用map集合去存放

    请求连接和action的关系是由于map集合需要编译,而xml文件不需要编译

—————————————————————————————————————————————————————————————————————————————————————————————

 02_struts2入门01

1.搭建struts2开发环境的步骤

1.创建javaweb项目工程

2.导入struts2必须的最基本的12个jar包文件

3.创建jsp文件

4.创建action文件

5.配置struts.xml文件

6.在web.xml文件中配置struts2的过滤器

struts2最基本的12个jar包文件包括:

struts2-core-2.3.1.1.jar

xwork-core-2.3.1.1.jar

ognl-3.0.3.jar

freemarker-2.3.8.jar

commons.logging-1.1.x.jar

commons-fileupload-1.2.2.jar

commons-io-2.0.1.jar

commons-lang-2.5.jar

asm-3.3.jar

asm-commons-3.3.jar

asm-tree-3.3.jar

javassist-3.11.0.GA.jar

下面我们就开始来搭建struts2的开发环境

/struts2/WebRoot/index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>    
    <title>test</title>
  </head>
  <body>
      请求连接:
    <a href="${pageContext.request.contextPath}/primer/helloWorldAction">helloWorld</a>
  </body>
</html>

 

/struts2/WebRoot/primer/success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>结果页面</title>
  </head>
  
  <body>
           操作成功!
  </body>
</html>

 

/struts2/src/cn/itcast/primer/HelloWorldAction.java

package cn.itcast.primer;

import com.opensymphony.xwork2.Action;

public class HelloWorldAction implements Action {

    public String execute() throws Exception {
        System.out.println("HelloWorldAction执行!");
        return "success";
    }

}

/struts2/WebRoot/WEB-INF/web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    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_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <filter>
      <filter-name>StrutsPrepareAndExecuteFilter</filter-name>
      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>StrutsPrepareAndExecuteFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

 

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--这里要导入struts2文件的dtd约束文件引用,这个文件在struts2-core-2.3.3.jar中-->
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <!--
    package表示包,一个package下可以有多个action
    name表示包名,是唯一的,用于别的包名继承
    namespace表示命名空间,这个就是请求连接的前半部分(请求连接:/primer/helloWorldAction)
    -->
    <package name="primer" namespace="/primer" extends="struts-default">
        <!-- 
        action表示请求动作 
        name表示名称,就是请求连接的后半部分(请求连接:/primer/helloWorldAction)
        class表示要请求连接要执行的类的完整路径
        -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <!--
            result表示结果,它的值就是要返回的页面路径
            name表示执行类的返回值
            -->
            <result name="success">success.jsp</result>
        </action>
    </package>
</struts>

 

这里还要注意一点,在写struts.xml文件的时候,必须写在src目录下,另外注意一点如何配置自动提示sturts.xml

在myeclipse中点击Window-Preferences-搜索xml-找到xml Catalog-点击User Specified Entries-然后点击Add

如果是在联网的情况下则在Location哪行粘贴上网络上的路径,key哪行粘贴上后边的部分

如图

 

 

如果在没有联网的情况下,则需要把struts-2.3.dtd文件放到本地磁盘上,然后再Location哪行选好存放地址,key不变即可

总结:1.struts2的最基本的12个jar包

   2.struts.xml的语法格式以及提示配置

    语法格式:首先要从struts2-core核心文件引入dtd约束文件,然后注意它的标签,已经标签的各个含义

         其次是如何在myeclipse中配置struts自动提示功能

————————————————————————————————————————————————————————————————————————————————————————————

 03_struts2拦截器入门

 在前面基础上我们知道struts2主要通过struts2提供的过滤器StrutsPrepareAndExecuteFilter加载并读取struts.xml文件来处理页面请求资源的

 但是在实际开发中的请求有很多种,如果所有的请求都让这一个过滤器来处理,那将非常混乱,所以在过滤器的基础上衍生出连接器,拦截器就是处理各种各样的请求的

在struts2中有很多拦截器,这些拦截器都声明在struts-default.xml中,并且在struts-default.xml中定义了很多拦截器栈,在拦截器栈中按照顺序存放了一些拦截器

我们可以通过修改默认拦截器栈的名称来使用拦截器,但是通常我们不会这样去修改底层的东西

这里比较一下过滤器和拦截器

相同点:都是起拦击作用的

不同点:1.使用范围不同,过滤器是javaEE的范围,过滤器是struts2的范围,只能在struts2中有,

    2.作用不同,过滤器只拦截请求资源,而拦截器是用来处理不同请求的

      3.执行顺序不同,先过滤器然后再试拦截器

 

下面我们来认识一下struts-adult.xml这个底层文件 

 这个文件中申明了很多拦截器,并且这个文件中定义了很多拦截器栈存放着拦截器,然后通过调动拦截器栈来实现调用拦截器

 /struts2/src/config/理解struts-default.xml

 

<?xml version="1.0" encoding="UTF-8" ?>
<!-- 这里同样引用的struts2的约束文件 -->
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    
    <!-- 
        package表示包,name表示包名,这里为strust-default表示struts的默认包,abstract表示这个包抽象的,不会有action
     -->
    <package name="struts-default" abstract="true">
        <result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
        </result-types>
            <!-- 下面声明的全部是拦截器 -->
        <interceptors>
            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
            <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
            <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
            <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
            <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
            <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
            <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
            <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
            <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
            <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
            <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
            <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
            <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
            <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
            <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
            <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
            <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
            <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
            <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
            <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
            <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
            <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
            <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
            <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
            <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
            <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
            <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
            <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
            <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
            <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
            <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />
            <!-- 以下全部申明的是拦截器栈,拦截器栈中存入的是拦截器,通过调用拦截器栈调用拦截器 -->
            <!-- Basic stack -->
            <interceptor-stack name="basicStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                    <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
            </interceptor-stack>

            <!-- Sample validation and workflow stack -->
            <interceptor-stack name="validationWorkflowStack">
                <interceptor-ref name="basicStack"/>
                <interceptor-ref name="validation"/>
                <interceptor-ref name="workflow"/>
            </interceptor-stack>

            <!-- Sample file upload stack -->
            <interceptor-stack name="fileUploadStack">
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            <!-- Sample model-driven stack  -->
            <interceptor-stack name="modelDrivenStack">
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            <!-- Sample action chaining stack -->
            <interceptor-stack name="chainStack">
                <interceptor-ref name="chain"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            <!-- Sample i18n stack -->
            <interceptor-stack name="i18nStack">
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="basicStack"/>
            </interceptor-stack>

            

            <interceptor-stack name="defaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                    <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="debugging"/>
            </interceptor-stack>

            <!-- The completeStack is here for backwards compatibility for
                 applications that still refer to the defaultStack by the
                 old name -->
            <interceptor-stack name="completeStack">
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>

            <!-- Sample execute and wait stack.
                 Note: execAndWait should always be the *last* interceptor. -->
            <interceptor-stack name="executeAndWaitStack">
                <interceptor-ref name="execAndWait">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
                <interceptor-ref name="defaultStack"/>
                <interceptor-ref name="execAndWait">
                    <param name="excludeMethods">input,back,cancel</param>
                </interceptor-ref>
            </interceptor-stack>

       </interceptors>
        <!-- 默认调用的拦截器栈为defaultStack,我们可以通过修改这里改变调用的拦截器栈-->
        <default-interceptor-ref name="defaultStack"/>
     <!-- 如果在struts.xml中的包中action没有指名class,则会执行这里指定的类文件-->
        <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
    </package>

</struts>

 

 

 总结:在struts2中是通过过滤器来拦截请求资源,然后再通过拦截器处理不同的请求,在底层文件struts-adult.xml中申明了很多拦截器,并且定义了很多拦截器栈,在拦截器栈中存放了很多拦截器

   通过调用拦截器栈实现调用拦截器

   另外注意区分过滤器和拦截器的不同点和相同点,不同点主要有三点,1.使用范围不同,2.作用不同,3.执行顺序不同

————————————————————————————————————————————————————————————————————————————————————————————

 04_struts2基本配置

 1.struts2中前台请求的书写格式

 由于底层代码的规范,所以在struts2前台请求的书写格式必须是:包的命名空间+action名称(例如:/primer/helloWorldAction.action)

 我们都知道struts.xml是被struts2的过滤器StrutsPrepareAndExecuteFilter加载并读取的,在这个过滤器中就要求了请求连接的地址必须这样写

 

 2.action名称的搜索顺序

在struts2中的请求连接,如果请求连接有多个命名空间,则服务器会从前往后检索,直到在struts.xml中检索到该包名

比如以下的这个例子中(/primer/primer/primer/helloWorldAction.action),服务器会先在struts.xml中检索有没有/primer/primer/primer这个包名

如果没有这个包名则往后检索查看有没有这个/primer/primer,知道检索到最后一层/primer

 /struts2/WebRoot/index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>    
    <title>test</title>
  </head>
  <body>
      请求连接:
    <a href="${pageContext.request.contextPath}/primer/primer/primer/helloWorldAction.action">helloWorld</a>
    <a href="${pageContext.request.contextPath}/primer/primer/helloWorldAction.action">helloWorld</a>
    <a href="${pageContext.request.contextPath}/primer/helloWorldAction.action">helloWorld</a>
  </body>
</html>

 

 /struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--这里要导入struts2文件的dtd约束文件引用,这个文件在struts2-core-2.3.3.jar中-->
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <!--
    package表示包,一个package下可以有多个action
    name表示包名,是唯一的,用于别的包名继承
    namespace表示命名空间,这个就是请求连接的前半部分(请求连接:/primer/helloWorldAction)
    -->
    <package name="primer" namespace="/primer" extends="struts-default">
        <!-- 
        action表示请求动作 
        name表示名称,就是请求连接的后半部分(请求连接:/primer/helloWorldAction)
        class表示要请求连接要执行的类的完整路径
        -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <!--
            result表示结果,它的值就是要返回的页面路径
            name表示执行类的返回值
            -->
            <result name="success">/primer/success.jsp</result>
        </action>
    </package>
</struts>

 

3.如果没有为action指定class会则会使用默认配置类

 如果在struts.xml中没有为action指定class则会使用在struts-default.xml中默认配置的类(com.opensymphony.xwork2.ActionSupport)

这个类中也有execute方法,返回值是success,所以也可以跳转到结果页面success.jsp

<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />

 

 

4.如果在struts.xml中找不到对应的action则会报错,如果不想报错我们就可以在struts.xml中设置默认的action

 /struts2/WebRoot/index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>    
    <title>test</title>
  </head>
  <body>
      请求连接:
    <a href="${pageContext.request.contextPath}/primer/aaaWorldAction.action">aaaWorld</a><!--这里注意在primer包下并没有aaaWorldAction这个action-->
  </body>
</html>

 

 /struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="primer" namespace="/primer" extends="struts-default">    
        <default-action-ref name="helloWorldAction" />    <!-- 这里设置了如果找不到action则执行这里指定的action -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <result name="success">/primer/success.jsp</result>
        </action>
    </package>
</struts>

 

 

 5.ActionSupport

前面我们知道当我们在action中没有指定class时,系统会执行struts.xml中默认指定的类com.opensymphony.xwork2.ActionSupport这个类

这个类不但继承了Action接口,而且还进行了扩展,所以在以后写Action类的时候我们直接继承它就可以了,不用再实现Action这个接口了

 

6.关于struts2中请求连接的后缀名

struts2的请求连接后缀名不是唯一的,这里我们可以从底层文件default.properties可以得知,在struts2-core.jar包中我们找到这个文件

这个文件就设定了扩展名为action或者为空

default.properties

### Used by the DefaultActionMapper
### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do
### The blank extension allows you to match directory listings as well as pure action names
### without interfering with static resources, which can be specified as an empty string
### prior to a comma e.g. struts.action.extension=, or struts.action.extension=x,y,z,,
struts.action.extension=action,,

 

当然我们自己可以更改扩展名,只需要在src目录下建立一个struts.properties文件,然后指定struts.action.extension的值就可以,或者另一种方式直接在struts.xml中通过常量指定它的值

/struts2/src/struts.properties

struts.action.extension=go

 

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.action.extension" value="do,love"></constant> <!-- 这里通过常量指定了扩展名 -->
    <package name="primer" namespace="/primer" extends="struts-default">    
        <default-action-ref name="helloWorldAction" />    <!-- 这里设置了默认如果找不到action则执行这里指定的action -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <result name="success">/primer/success.jsp</result>
        </action>
    </package>
</struts>

 

但是我们必须注意一点,如果在多个文件中设置了请求连接的后缀名,那么执行的顺序是越晚执行的文件越有效

执行顺序是struts-default.xml,struts-plugin.xml,struts.xml,struts.properties,web.xml

所以我们这里设置的后缀名只有struts.properties中设置的后缀名为go的才有效果,但是我们在实际开发中不建议在struts.properties中设置常量,因为这样浪费了资源,本来可以直接写在struts.xml中的

我们没有必要多写一个文件专门来设置常量,而且这样也不便于后期维护查找

另外我们这里还要注意一点,在设置常量的时候,将开发模式设置为true则包含了国际化文件修改后是否自动加载和配置文件修改后是否自动加载,所以就不需要单独设置这些常量了

### when set to true, Struts will act much more friendly for developers. This
### includes:
### - struts.i18n.reload = true
### - struts.configuration.xml.reload = true
### - raising various debug or ignorable problems to errors
###   For example: normally a request to foo.action?someUnknownField=true should
###                be ignored (given that any value can come from the web and it
###                should not be trusted). However, during development, it may be
###                useful to know when these errors are happening and be told of
###                them right away.
struts.devMode = false

 

 7.引入自定义配置文件

 在实际开发中,开发一个软件需要很多人合作,每个人分工一个部分,常量是我们公用的,我们将其放入到struts.xml文件中,而不同的部分我们将其写入到我们自定义的xml文件中,最后在

struts.xml中引入文件即可

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.action.extension" value="do,love"></constant> <!-- 这里通过常量指定了扩展名 -->
    <constant name="struts.devMode" value="ture"></constant>
    <include file="cn/itcast/primer/Hello.xml"></include> <!-- 注意这里引入的时候是相对位置,必须这样写,不能用点代替斜杠 -->
</struts>

 

/struts2/src/cn/itcast/primer/Hello.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="primer" namespace="/primer" extends="struts-default">    
        <default-action-ref name="helloWorldAction" />    <!-- 这里设置了默认如果找不到action则执行这里指定的action -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <result name="success">/primer/success.jsp</result>
        </action>
    </package>
</struts>

 

 总结:本节课主要归纳7点

  1.struts2的请求资源的格式是由struts2底层规定这么写的,格式必须是(包的命名空间+action的名称,当然包的命名空间可以为/)

  2.struts2中请求资源如果有多个命名空间,则搜索顺序是从长到短搜索,比如(/aaa/bbb/cccc/xxx.action,则先在/aaa/bbb/ccc这个命名空间去搜索有没有xxx.action,如果没有则去/aaa/bbb找,如果   再没有则到/aaa下去找,以此类推)

  3.如果在struts.xml中action没有指定class,则struts2会执行在struts-adult.xml中指定的类ActionSupport(标签为defult-class-ref)

  4.如果请求路径在struts.xml中命名空间,但是没有action则会报错,如果不想报错则需要在命名空间下指定一个默认的action(标签为:defult-action-ref)

  5.由于ActionSupport是默认的class类,他既实现了接口Action,又扩展了很多功能,所以在以后写action类的时候继续它就可以了,不要在实现Action接口

  6.struts2中的请求连接的后缀名其实也是底层文件规定的,在struts2-core.jar包中找到default.properties,这个文件中就规定了请求连接的后缀名为action或者为空,我们可以通过在struts.xml文件中

   设置常量来更改,也可以单独在src目录下设置一个struts.proterties文件来更改后缀名,但是这里我们要注意当我们在多个文件中都设置了常量的时候执行顺序是越晚越有效,当然struts2的执行顺序是

  struts-default.xml,struts-plugin.xml,struts.xml,struts.properties,web.xml

  7.在实际开发中,公共的常量写在struts.xml中,分工的部分写在自定义的xml问价中,最后在struts.xml中引入即可(标签卫include)

 —————————————————————————————————————————————————————————————————————————————————————————————

 05_struts2结果类型

1.struts2的结果类型默认是转发,我们可以通过如下的实现得出

/struts2/WebRoot/form.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
    <title>Form</title>
  </head>
  
  <body>
    <form action="${pageContext.request.contextPath}/primer/HelloWorldAction.go" name="form" method="post">
        <input type="submit" value="提交" />
    </form>
  </body>
</html>

 

/struts2/src/struts.properties

struts.action.extension=go

 

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <include file="cn/itcast/primer/Hello.xml"></include> <!-- 注意这里引入的时候是相对位置,必须这样写,不能用点代替斜杠 -->
</struts>

 

/struts2/src/cn/itcast/primer/HelloWorldAction.java

package cn.itcast.primer;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.Action;

public class HelloWorldAction implements Action {

    public String execute() throws Exception {
        System.out.println("HelloWorldAction执行!");
        //这里是通过struts2的ServeltActionContext获取到request
        HttpServletRequest request = ServletActionContext.getRequest();
        //然后我们在requset域中存入一个结果
        request.setAttribute("result", "HelloWorldAction执行成功");
        return "success";
    }

}

 

/struts2/src/cn/itcast/primer/Hello.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="primer" namespace="/primer" extends="struts-default">    
        <default-action-ref name="helloWorldAction" />    <!-- 这里设置了默认如果找不到action则执行这里指定的action -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <result name="success">/primer/success.jsp</result>
        </action>
    </package>
</struts>

/struts2/WebRoot/primer/success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>结果页面</title>
  </head>
  
  <body>
           结果:${requestScope.result}
  </body>
</html>

 

 

 

2.struts2的结果类型有多重形式,这个可以再底层配置文件中struts-default.xml中可以可以找到

底层文件struts-default.xml的部分

        <result-types>
                <!--这个是转发到action -->
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
                <!--这个是转发到jsp,默认就是它-->
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
                <!--这个是重定向jsp-->
            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
                <!--这个是重定向到Action -->
            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
                <!--这个是转发到流,这个和下载有关系 -->
            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
        </result-types>

 

我们可以再package中指定结果类型,以下才是结果类型的完整写法

/struts2/src/cn/itcast/primer/Hello.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="primer" namespace="/primer" extends="struts-default">    
        <default-action-ref name="helloWorldAction" />    <!-- 这里设置了默认如果找不到action则执行这里指定的action -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction">
            <!--<result name="success">/primer/success.jsp</result>-->  <!--结果类型的简写形式-->
            <result name="success" type="dispatcher">    <!-- 这里我们可以通过修改type的值来改变结果类型,默认类型就是dispather(转发) -->
                <param name="location">/primer/success.jsp</param>
            </result>    
        </action>
    </package>
</struts>

 

 

3.当结果类型为重定向到Action时的写法

struts2的结果类型重定向,转发和冲定向到Action的区别就在于两个参数(namespace和actionName)

/struts2/WebRoot/form.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
    <title>Form</title>
  </head>
  
  <body>
    <form action="${pageContext.request.contextPath}/result/ResultAction.go" name="form" method="post">
        <input type="submit" value="提交" />
    </form>
  </body>
</html>

/struts2/src/struts.properties

struts.action.extension=go

/struts2/src/cn/itcast/primer/ResultAction.java

package cn.itcast.primer;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class ResultAction extends ActionSupport {

    public String execute() throws Exception {
        System.out.println("ResultAction执行成功!");
        //HttpServletRequest request = ServletActionContext.getRequest();
        //request.setAttribute("result","ResultAciton执行成功!");
        return "success";
        
    }
    
}

/struts2/src/cn/itcast/primer/result.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="result" namespace="/result" extends="struts-default">    
        <action name="ResultAction" class="cn.itcast.primer.ResultAction">
            <result name="success" type="redirectAction">    <!-- 这里我们重定向到一个action,这里我们就有两个参数-->
                <!-- 第一个参数时namespace,就是要转向到的action的package下的命名空间,我们这里转到helloWorldAction,所以命名空间是/primer -->
                <!-- 第二个参数时actionName,就是要转向到的action的名称,这里我们装到helloWorldAction,所以action的名称就是helloWorldAction -->
                <param name="actionName">helloWorldAction</param>
                <param name="namespace">/primer</param>
            </result>    
        </action>
    </package>
</struts>

 

/struts2/src/cn/itcast/primer/ResultAction.java

package cn.itcast.primer;

import com.opensymphony.xwork2.ActionSupport;

public class ResultAction extends ActionSupport {

    public String execute() throws Exception {
        System.out.println("ResultAction执行成功!");
        //HttpServletRequest request = ServletActionContext.getRequest();
        //request.setAttribute("result","ResultAciton执行成功!");
        return "success";
        
    }
    
}

/struts2/src/cn/itcast/primer/Hello.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="primer" namespace="/primer" extends="struts-default">    
        <default-action-ref name="helloWorldAction" />    <!-- 这里设置了默认如果找不到action则执行这里指定的action -->
        <action name="helloWorldAction" class="cn.itcast.primer.HelloWorldAction"><!-- 这里呀,特别要注意,没有扩展名而且不是斜杠,必须是点 -->
            <!--<result name="success">/primer/success.jsp</result>-->
            <result name="success" type="dispatcher">    <!-- 这里我们可以通过修改type的值来改变结果类型,默认类型就是dispather(转发) -->
                <param name="location">/primer/success.jsp</param>  <!--这里这个参数location是必不可少的,底层代码需要这个参数-->
            </result>    
        </action>
    </package>
</struts>

 

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.action.extension" value="do,love"></constant> <!-- 这里通过常量指定了扩展名 -->
    <constant name="struts.devMode" value="ture"></constant>
    <include file="cn/itcast/primer/Hello.xml"></include> <!-- 注意这里引入的时候是相对位置,必须这样写,不能用点代替斜杠 -->
    <include file="cn/itcast/primer/result.xml"></include> 
</struts>

 

 总结:struts2的结果类型有很多种,这个可以从底层文件struts-adault.xml文件可以找到,不过默认的结果类型为转发,如果我们要改变结果类型我们只需要改变result的属性type的值即可

   另外还注意一点,当结果类型是重定向到Action的时候,与转发和重定向的最大区别在于两个参数(namespece和actionName)

————————————————————————————————————————————————————————————————————————————————————————————

 06_struts2通配符和动态方法

1.action中执行指定的方法

/struts2/WebRoot/test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'test.jsp' starting page</title>
  </head>
  
  <body>
    测试连接:<a href="${pageContext.request.contextPath}/patter/bookAction.action">bookAction</a>
  </body>
</html>

/struts2/src/cn/itcast/patter/bookAction.java

package cn.itcast.patter;

import com.opensymphony.xwork2.ActionSupport;

public class bookAction extends ActionSupport {

    public String execute() throws Exception {
        System.out.println("bookAction执行成功");    
        return "success";
    }
    //现在诶bookAction添加一个新的方法,这个方法的要求就是和execute()方法一样
    //必须是public,返回值必须是String,没有传递参数,并且也要抛异常
    public String add() throws Exception {
        System.out.println("bookAction添加成功");
        return "add";
    }
}

/struts2/src/cn/itcast/patter/bookAction_struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="patter" namespace="/patter" extends="struts-default"> <!-- 注意这里没有加后缀名 -->
        <action name="bookAction" class="cn.itcast.patter.bookAction" method="add">    <!-- 我这里指定了add方法 -->
            <result name="success">/primer/success.jsp</result>
            <result name="add">/form/bookAction.jsp</result>
        </action>
    </package>
</struts>

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <include file="cn/itcast/patter/bookAction_struts.xml"></include>
</struts>

 

/struts2/WebRoot/form/bookAction.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>BookAction</title>
  </head>
  
  <body>
    书名:<input type="text" name="bookName" /><input type="submit" value="提交" />
  </body>
</html>

/struts2/WebRoot/primer/success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>结果页面</title>
  </head>
  
  <body>
           结果:${requestScope.result}
  </body>
</html>

 

 

2.struts2的通配符

在struts2中对于请求连接的重复,可以使用通配符来表示,这样可以简化action的书写

下面我们举两个例子来说明:

例子1:

/struts2/WebRoot/test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'test.jsp' starting page</title>
  </head>
  
  <body>
    struts2的通配符测试1:<br/>
                        <a href="${pageContext.request.contextPath}/patter/bookAction_aa.action">aa_bookAction</a><br/>
                        <a href="${pageContext.request.contextPath}/patter/bookAction_bb.action">bb_bookAction</a><br/>
                        <a href="${pageContext.request.contextPath}/patter/bookAction_cc.action">cc_bookAction</a><br/>
  </body>
</html>

 

/struts2/src/cn/itcast/patter/bookAction.java

package cn.itcast.patter;

import com.opensymphony.xwork2.ActionSupport;

public class personAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        System.out.println("personAction执行成功");
        return "success";
    }
    public String add() throws Exception {
        System.out.println("personAction添加成功");
        return "add";
    }
}

 

/struts2/src/cn/itcast/patter/bookAction_struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="patter" namespace="/patter" extends="struts-default"> <!-- 注意这里没有加后缀名 -->
        
        <action name="bookAction_*" class="cn.itcast.patter.bookAction" method="add">
            <result name="success">/primer/success.jsp</result>
            <result name="add">/form/bookAction.jsp</result>
        </action>
    </package>
</struts>

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <include file="cn/itcast/patter/bookAction_struts.xml"></include>
</struts>

 

 

例子2:

/struts2/WebRoot/test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'test.jsp' starting page</title>
  </head>
  <body>
      struts2的通配符测试2:<br/>
                          <a href="${pageContext.request.contextPath}/patter/bookAction_delete.action">bookAction_delete</a><br/>
                          <a href="${pageContext.request.contextPath}/patter/bookAction_add.action">bookAction_add</a><br/>
                          <a href="${pageContext.request.contextPath}/patter/personAction_delete.action">personAction_delete</a><br/>
                          <a href="${pageContext.request.contextPath}/patter/personAction_add.action">personAction_add</a><br/>                       
  </body>
</html>

 

/struts2/src/cn/itcast/patter/bookAction.java

package cn.itcast.patter;

import com.opensymphony.xwork2.ActionSupport;

public class bookAction extends ActionSupport {

    public String execute() throws Exception {
        System.out.println("bookAction执行成功");    
        return "success";
    }
    //现在诶bookAction添加一个新的方法,这个方法的要求就是和execute()方法一样
    //必须是public,返回值必须是String,没有传递参数,并且也要抛异常
    public String add() throws Exception {
        System.out.println("bookAction添加成功");
        return "add";
    }
    
    public String delete() throws Exception {
        System.out.println("bookAction删除成功");
        return "success";
    }
}

/struts2/src/cn/itcast/patter/personAction.java

package cn.itcast.patter;

import com.opensymphony.xwork2.ActionSupport;

public class personAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        System.out.println("personAction执行成功");
        return "success";
    }
    public String add() throws Exception {
        System.out.println("personAction添加成功");
        return "add";
    }
    public String delete() throws Exception {
        System.out.println("personAction删除成功");
        return "success";
    }
    
}

/struts2/src/cn/itcast/patter/bookAction_struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="patter" namespace="/patter" extends="struts-default"> <!-- 注意这里没有加后缀名 -->
<action name="*_*" class="cn.itcast.patter.{1}" method="{2}"> <result name="success">/primer/success.jsp</result> <result name="add">/form/{1}.jsp</result> </action> </package> </struts>

 

/struts2/WebRoot/form/bookAction.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>BookAction</title>
  </head>
  
  <body>
       书名:<input type="text" name="bookName" /><input type="submit" value="提交" />
  </body>
</html>

 

/struts2/WebRoot/form/personAction.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>BookAction</title>
  </head>
  
  <body>
   用户名:<input type="text" name="bookName" /><input type="submit" value="提交" />
  </body>
</html>

 

/struts2/WebRoot/primer/success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>结果页面</title>
  </head>
  
  <body>
           操作成功!
  </body>
</html>

 

3.struts2的动态方法

动态方法的格式:包名+命名空间!要执行的方法名.扩展名

虽然通常情况下动态方法是开启状态,这个我们可以再底层文件adault.propertiers中找到,但是我们通常不用动态方法,所以我们可以再struts.xml中通过设置常量来关闭

default.properties的部分文件

### Set this to false if you wish to disable implicit dynamic method invocation
### via the URL request. This includes URLs like foo!bar.action, as well as params
### like method:bar (but not action:foo).
### An alternative to implicit dynamic method invocation is to use wildcard
### mappings, such as <action name="*/*" method="{2}" class="actions.{1}">
struts.enable.DynamicMethodInvocation = true    ###此处就是动态方法调用的开关,默认是true,也就是开启状态

 

在struts.xml中通过设置常量关闭动态方法调用

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

 

/struts2/WebRoot/test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'test.jsp' starting page</title>
  </head>
  
  <body>                  
      struts2的动态方法测试:<br/>
                          <a href="${pageContext.request.contextPath}/patter/bookAction_add!add.action">bookAction_add</a>
                          <a href="${pageContext.request.contextPath}/patter/personAction_delete!delete.action">personAction_delete</a>                      
  </body>
</html>

 

/struts2/src/cn/itcast/patter/bookAction_struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="patter" namespace="/patter" extends="struts-default"> <!-- 注意这里没有加后缀名 -->
        
        <!--
            动态方法测试 
            <a href="${pageContext.request.contextPath}/patter/bookAction_add!add.action">bookAction_add</a>
              <a href="${pageContext.request.contextPath}/patter/personAction_delete!delete.action">personAction_delete</a>
         -->
        <action name="*_*" class="cn.itcast.patter.{1}">
            <result name="success">/primer/success.jsp</result>
            <result name="add">/form/{1}.jsp</result>
        </action>
    </package>
</struts>

 

/struts2/src/cn/itcast/patter/bookAction.java

package cn.itcast.patter;

import com.opensymphony.xwork2.ActionSupport;

public class bookAction extends ActionSupport {

    public String execute() throws Exception {
        System.out.println("bookAction执行成功");    
        return "success";
    }
    //现在诶bookAction添加一个新的方法,这个方法的要求就是和execute()方法一样
    //必须是public,返回值必须是String,没有传递参数,并且也要抛异常
    public String add() throws Exception {
        System.out.println("bookAction添加成功");
        return "add";
    }
    
    public String delete() throws Exception {
        System.out.println("bookAction删除成功");
        return "success";
    }
}

 

/struts2/src/cn/itcast/patter/personAction.java

package cn.itcast.patter;

import com.opensymphony.xwork2.ActionSupport;

public class personAction extends ActionSupport {

    @Override
    public String execute() throws Exception {
        System.out.println("personAction执行成功");
        return "success";
    }
    public String add() throws Exception {
        System.out.println("personAction添加成功");
        return "add";
    }
    public String delete() throws Exception {
        System.out.println("personAction删除成功");
        return "success";
    }
    
}

/struts2/src/struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <include file="cn/itcast/patter/bookAction_struts.xml"></include>
</struts>

 

/struts2/WebRoot/primer/success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>结果页面</title>
  </head>
  
  <body>
           操作成功!
  </body>
</html>

/struts2/WebRoot/form/bookAction.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>BookAction</title>
  </head>
  
  <body>
       书名:<input type="text" name="bookName" /><input type="submit" value="提交" />
  </body>
</html>

 

4.全局结果类型 

由于在各自的xml文件中都要用到相同的结果类型,比如这里的转向到success.jsp页面,但是必须注意一点全局结果类型只在包package包下起作用,所以定义在package包下

<result name="success">/primer/success.jsp</result>

 

/struts2/src/cn/itcast/patter/bookAction_struts.xml

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="patter" namespace="/patter" extends="struts-default"> <!-- 注意这里没有加后缀名 -->
        <global-results>
            <result name="success">/primer/success.jsp</result>
        </global-results>
        <action name="*_*" class="cn.itcast.patter.{1}">
            <!--<result name="success">/primer/success.jsp</result>由于多次用到重复的,所以讲这个结果类型转成了全局结果类型 -->
      <result name="add">/form/{1}.jsp</result> </action> </package> </struts>

 

 

5.struts2的action是多实现

当我们在action中放上构造方法的时候,当我们每次连接访问这个action的时候搜会打印构造方法中的内容,这说明struts2是多实现,多实现的好处就是线程安全

 /struts2/src/cn/itcast/patter/bookAction.java

package cn.itcast.patter;

import com.opensymphony.xwork2.ActionSupport;

public class bookAction extends ActionSupport {
   //构造方法
public bookAction(){ System.out.println("我是bookAction的构造方法"); } public String execute() throws Exception { System.out.println("bookAction执行成功"); return "success"; } //现在诶bookAction添加一个新的方法,这个方法的要求就是和execute()方法一样 //必须是public,返回值必须是String,没有传递参数,并且也要抛异常 public String add() throws Exception { System.out.println("bookAction添加成功"); return "add"; } public String delete() throws Exception { System.out.println("bookAction删除成功"); return "success"; } }

 

总结:本节课主要讲了struts2的通配符和动态方法,共有5个知识点

  1.action的xml文件中通过设定action的属性method的值来指定执行那个方法

  2.通配符:struts2的通配符主要是用来简化书写的,由于请求连接的重复性,所以在各自的action的xml文件中通过*来代替重复的字符串部分,人后用{1},{2}...来代替第一个重复字符串,第二个重复字符   串,以此类推

  3.动态方法:首先动态方法在请求连接上的格式就必须有要求,格式是:包名+命令空间+!+要执行的action的方法名+扩展名,由于在连接上指定了action执行的方法,所以在xml文件中就不用指定      method的值了,但是动态方法通常不用,我们可以通过在struts.xml中设置常量<constant name="struts.enable.DynamicMethodInvocation" value="false"></constant>来禁用它

  4.全局结果类型,对于在action的xml中重复出现的结果类型,我们可以单独提取出来作为一个全局的结果类型,但是全局结果类型只能在package下有效,所以只能定义在package下

  5.struts2的连接访问是多实现,这个我们可以通过在action中设置它的构造方法,当一个连接指向这个action时构造方法中的内容就会执行,这就说明了struts2中的连接是多实现,多实现是线程安全的

—————————————————————————————————————————————————————————————————————————————————————————————

 07_struts2类型转换

 1.struts2中表单提交后获取表单数据的方式(两种方式比较)

struts2中获取普通表单数据的方式可以通过传统的javaweb方式获取,还可以通过struts2框架提供的反射机制获取(只要在对应的action文件中给予对于表单的属性名,并给予get,set方法,我们就可以直接获取),但是以上获取表单数据的方式只局限于能够转换成字符串的表单数据,而像时间日期类的数据则需要手动转化

 2.struts2中表单时间日期提交后需要手动转换才能获取到时间日期,否则出错

 对于表单提交的时间日期数据,需要手动转换才能获取,不然要出错(这里出错,我们必须添加一个错误页面,并在action的结果类型中添加一个结果类型,name为input),这里我们需要手动建立转换器,这个转换器必须实现TypeConverter或者继承ClassDefaultTypeConverter或则继承ClassStrutsTypeConverter,然后重写convertValue()方法2,在这个方法中实现转换时间日期,并返回转换后的数据,还要注意一点,由于这个转换器是我们手动建立的,struts2并不识别,所以,我们必须在action的目录下建立(action名称-convert.properties)这样一个文件,并在这个文件中写上(需要转换的属性名称=转换器的全类名)

 

 3.struts2中提交了错误的时间日期表单后,也会转向成功页面,这是因为,在转换失败后struts2虽然捕获了异常,但是没有抛出去

在struts2中获取提交错误的时间日期表单数据也会转向成功页面,这是因为struts2虽然捕获了异常但是没有抛出,struts2就认为转换成功,但实际上没有转换成功,我们需要手动抛出异常,这样才能解决问题

 

 4.当时间日期转换失败之后再struts2中错误页面的友好提示

 当数据转换失败之后,我们需要得到错误页面的友好提示,这个时候我们需要在错误页面顶端引入struts2的友好错误提示标签<%@ taglib uri="/struts-tags" prefix="s"%>,然后再<body>标签内

引用这个标签<s:fielderror fieldName="createTime"/>,这里注意fieldName的值就是需要转换的属性名称

这里的错误提示是英文的,这个错误提示的内容在底层文件xwork-core.jar包中的xwork-massages.properties这个文件中

 

 5.当时间日期转换失败后将错误提示改成中文

前面我们知道底层文件xwork-massages.properties中规定了英文提示,但是我们这里想改成中文提示,所以我们做如下操作

在于action同级目录中新建一个convert.properties的文件(名字可以自定义),并在这个文件中添加如下内容

xwork.default.invalid.fieldvalue=无效的字段值"{0}"

由于这个资源文件也是我们手动建立的,所以需要载入资源文件,

让struts2识别最后我们还要在struts.xml文件中通过常量形式载入这个资源文件,这里载入资源文件按是针对所有的字段

<constant name="struts.custom.i18n.resources" value="资源文件的路径(注意没有后缀名)"></constant>

 

对于这种方法我们我们还可以进一步优化一下,由于错误提示中的字段是根据{0}取到的,我们并不能明白错误提示的具体信息,所以我们可以再找个提示的下面添加如下内容

invalid.fidldvalue.createTime=生产时间转化异常

当我们添加了如上的对话后,错误提示就更加具体了,容易明白,同样我们通过这种方法我们可以为多个字段添加具体错误提示,只不过需要改变creatTime成对应的属性字段

6.当时间日起转换失败后错误提示的另一种方法

前面哪一种方式是基于字段的友好错误提示,这里我们说的是基于类配置,也就是基于全局的一种错误提示

这种方式我们只需要在WEB-INF/classes目录下创建xwork-conversion.properties文件,并在其中加入如下内容

待转换的类型=类型转换器的全类名(例如这里我们要转换的是日期,所以格式是java.util.Date=cn.itcast.convert.DataConverter)

 

总结:

————————————————————————————————————————————————————————————————————————————————————————————

 08_struts2与servlet解耦

 1.struts2中关于表单提交是数据是一个整体对象属性名称的时候,我们可以单独建立对象bean文件,然后设置表单的name为(对象.属性名称),这样我们就可以再action执行文件中直接获取到表单提交的数据

 比如这里在表单中填写人员的学历编号和学历名词的时候,我们可以讲学历编号和学历名词看做学历对象的两个属性,我们建立学历这个对象,并临济学历编号和学历名称这个两个属性和get,set方法

之后我们在表单页面中设置name的值为(学历对象名称.学历属性)

2.struts2中如果表单提交的数据是一个一个的整体对象,并且有无数个这个样的数据需要提交,则我们可以建立对象的bean文件,并且在action执行文件中通过集合Collection来接受对象,但是需要注意在写表单的name的时候需要这样写(集合名词[数字标号].属性名词)

 这里比如在表单中需要输入很多员工的姓名和员工的薪水,这两个属性是员工的两个属性,而且员工有很多个,需要输入的很多,这里我们就建立员工对象,并建立员工的两个属性的get,set方法,在表单页面设置(员工对象[数字标号].属性名称),在action执行类中可以通过(对象.对象属性)获取表单的数据H

 

3.struts2与servlet解耦

 这里所谓的解耦哇,其实就是struts2中获取四个域HttpServletRquest,HttpServletResponse,HttpSession,ServletContext可以不通过传统的javaweb获取

struts2中已经有自己获取这四个域的方法

这里struts2提供了两种方法获取

第一种方法通过ServletActionContext工具类获取

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

Map sessionMap = ServletActionContext.getContext().getSession();  //这个要注意一下,Struts2将Session封装成了Map

ServletContext sc = ServletActionContext.getServletContext();

这里我们可以通过在action执行页面在这些域中写入数据,然后在结果页面验证结果

 

第二种方法Action执行类需要实现接口ServletRequestAware,ServletResponseAware,SessionAware,ServletContextAware这四个接口

然后在action执行类中定义HttpServletRquest request,HttpServletResponse response,Map sessionMap,ServletContext sc四个属性,

还要建立对应的set方法,在set方法中赋值就可以获取到这个四个域对象

 

总结:

————————————————————————————————————————————————————————————————————————————————————————————

 

 

 

posted @ 2014-02-13 12:57  ysfox  阅读(407)  评论(0)    收藏  举报