《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就可以解决了
暂时写到这里,以后在补充