struts小白入门学习(第一次写)

《struts小白》

简单的写下一关于Struts2.3.31的使用,学习该框架一个多星期,改了很多遍的代码,在这里做一个笔记。

开发工具:eclipse j2ee neon、struts2.3.31、jdk1.8、tomcat7.0

【第1步】配置web.xml:(TimerInterceptor\WebContent\WEB-INF\web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>TimerInterceptor</display-name>

    <filter>
        <filter-name>struts2</filter-name>
        <!-- struts2.3 -->
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
     <filter-mapping>
           <filter-name>struts2</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>

//打开项目默认页面
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

【第2步】编写jsp页面(TimerInterceptor\WebContent\index.jspTimerInterceptor\WebContent\success.jsp) 

index.jsp

 <%@ page language="java" contentType="text/html; charset=utf8"
        pageEncoding="utf8"%>
    <!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=utf8">
    <title>Insert title here</title>
    </head>
    <body>
    //访问name为timerAction的action(在struts.xml中配置)
        <a href="timerAction">访问Action</a>
    </body>
    </html>

success.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    This is success.jsp
</body>
</html>

【第3步】 配置Struts2(TimerInterceptor\src\struts.xml)
这一步对于Struts1.x和Struts2都是必须的,只是安装的方法不同。Struts1的入口点是一个Servlet,而Struts2的入口点是一个过滤器(Filter)。因此,Struts2要按过滤器的方式配置。下面是在web.xml中配置Struts2的代码

<?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="default" namespace="/" extends="struts-default">
            <action name="timerAction" class="action.TimerAction">
            //若返回success则跳转到success.jsp页面,无参数则默认为SUCCESS
                <result>success.jsp</result>
        </package>
    </struts>

【第4步】引入开发时所用的JAR包

struts2-core-2.1.6.jar --------------- struts2的核心包
freemarker-2.3.13.jar--------------- FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具
commons-logging.jar ----------- Jakarta的通用日志记录包
ognl-2.6.11.jar -------------- 支持ognl表达式
xwork-2.1.2.jar -------------- xwork的包 由于Struts2是由xwork的延伸 有些类依然关联着 xwork的类

【第5步】TimerAction的编写(TimerInterceptor\src\action\TimerAction.java)

   package action;
    import com.opensymphony.xwork2.ActionSupport;
    public class TimerAction extends ActionSupport {
        //各个版本的兼容性
        private static final long serialVersionUID = 1L;
        @Override
        public String execute() throws Exception {
        //控制台打印信息
            for(int i=0;i<10000;i++){
                System.out.println("love");
            }
            //返回一个字符串
            return SUCCESS;
        }
    }

现在来阐述一下整个程序运行的过程。

1.tomcat部署项目,浏览器打开index.jsp
 2.点击链接,访问struts.xml中配置名称为timerAction的Action
 3.访问timerAction对应的Class:action.TimerAction
 4.执行for循环代码,返回SUCCESS字符串
 5.name为timerAction的action接受参数,打开success对应的success.jsp

第一个简单的struts的小实例就这样完成了。
下面详细介绍一个struts.xml配置

1.1.包配置:
Struts2框架中核心组件就是Action、拦截器等,Struts2框架使用包来管理Action和拦截器等。每个包就是多个Action、多个拦截器、多个拦截器引用的集合。

 <?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>
        <!-- struts2的action必须放在一个指定的包空间下定义 -->
        <package name="default" extends="struts-default">
        <!-- 定义处理请求URL为login.action的Action -->
            <action name="login" class="org.qiujy.web.struts.action.LoginAction">
            <!-- 定义处理结果字符串和资源之间的映射关系 -->
                <result name="success">/success.jsp</result>
                <result name="error">/error.jsp</result>
            </action>
        </package>
    </struts>

1.2 包含配置:
在Struts2中可以将一个配置文件分解成多个配置文件,那么我们必须在struts.xml中包含其他配置文件。

<struts>
    <include file="struts-default.xml"/>
    <include file="struts-user.xml"/>
    <include file="struts-book.xml"/>
    <include file="struts-shoppingCart.xml"/>

    ......
</struts>

1.3 拦截器配置

定义一个拦截器,此处定义的拦截器是用来计算整个action所执行的时间

package interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class TimerInterceptor extends AbstractInterceptor {

    private static final long serialVersionUID = 1L;

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        //action执行开始的时间
        long start = System.currentTimeMillis();
        //执行action
        String result = invocation.invoke();
        //action执行结束的时间
        long end = System.currentTimeMillis();
        //控制台打印所花费的时间
        System.out.println("执行action花费的时间:"+(end-start)+"ms");
        //返回结果
        return result;
    }

}
在struts.xml中注册拦截器,并在action中引用

<?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="default" namespace="/" extends="struts-default">

        <!-- 拦截器注册 -->
        <interceptors>
            <interceptor name="timerInterceptor" class="interceptor.TimerInterceptor"></interceptor>        
        </interceptors>

        <!-- acition注册 -->
        <action name="timerAction" class="action.TimerAction">
            <result>success.jsp</result>
            <!--拦截器引用-->
            <interceptor-ref name="timerInterceptor"></interceptor-ref>
        </action>

    </package>
</struts>

配置好了拦截器,在调用action之前会一次调用拦截器,拦截器执行完后将执行下一个调用的拦截器,最后执行action。

1.4 在Struts2中动态方法调用有三种方式,动态方法调用就是为了解决一个Action对应多个请求的处理,以免Action太多

第一种方式:指定method属性
这种方式我们前面已经用到过,类似下面的配置就可以实现

    <action name="chainAction" class="chapter2.action.Chapter2Action"method="chainAction">
         <result name="chainAction" type="chain">redirect</result>
    </action>  

    <action name="plainText"class="chapter2.action.Chapter2Action" method="plainText">
        <result name="plainText" type="plainText">/WEB-INF/JspPage/chapter2/plaintext.jsp</result>
    </action>

第二种方式:感叹号方式(需要开启),官网不推荐使用这种方式,建议大家不要使用.用这种方式需要先开启一个开关

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

将此常量设置为true,这种方式才能使用,使用见示例

package chapter3.action;

public class Chapter3Action {
     public String result1(){
         return "result1";
     }

     public String result2(){
        return "result2";
     }
}

Jsp中访问方式

<body>
    <a href="basePath/chapter3/chapter3Action!result1">result1</a><br>
    <a href="basePath/chapter3/chapter3Action!result1">result1</a><br>
    <a href="{basePath}/chapter3/chapter3Action!result2">result2</a><br>
</body> 

如果配置了后缀,必须这样写:

/chapter4/chapter4Action!create.action

XML中配置方式

<package name="chapter3" namespace="/chapter3" extends="struts-default">
   <action name="chapter3Action" class="chapter3.action.Chapter3Action">
        <result name="result1">/WEB-INF/JspPage/chapter3/result1.jsp</result>
        <result name="result2">/WEB-INF/JspPage/chapter3/result2.jsp</result>
        <result name="chapter3">/WEB-INF/JspPage/chapter3/chapter3.jsp</result>
   </action>
</package>

第三种方式:通配符方式(官网推荐使用)
首先得关闭开关

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

这一种方式是由第一种转变过来的,我们可以看到,第一种方式有很多重复的代码,那么我们可以进行变形,看下面的代码

<action name="chapter3_*" class="chapter3.action.Chapter3Action" method="{1}">
    <result name="test">/…/test.jsp</result>
</action> 

chapter3_这里的就是你呆会要匹配的字符串,即你在后面的请求中得这样写

http://...../ chapter3_create 或 http://...../ chapter3_update

注意,这时你action中必须有create和update方法与之匹配,甚至还可以这样匹配

<action name="chapter3_*" class="chapter3.action.Chapter3Action" method="{1}">
    <result name="test">/…/{1}.jsp</result>
</action> 

{1}—-第一个传的参数,{2}—-第二个传的参数

谨记:在struts2.5版中这样不能够这样写,与之前版本相比有了许多别的特性,这里不做详细解释

最后再讲一个容易出现的BUG

error:Action class [userAction] not found - action

先检查action中的class有没有拼写错误,比如:可能是多了一个空格
如果拼写没有错误的话,clean一下project就可以解决了

暂时写到这里,以后在补充

点赞