一. 配置
1. 导入jar包
最少要struts.jar、commons-beanutils.jar、commons-digester.jar、commons-logging.jar这4个;
想使用其他功能要附加导入如:jstl-1.2.jar、commons-validator.jar、commons-fileupload.jar、antlr.jar……
2. 配置web.xml
ActionSerlvet:struts1核心控制器;
config:指定struts1配置文件路径多个逗号隔开;
debug:指定Servlet的调试级别,默认为0记录最少日志信息;
detail:指定Digester框架解析xml文件的解析日志级别,默认同debug;
load-on-startup:指定action在服务器启动时的加载顺序,为0时表示启动时加载。
示例:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/config/struts-config-XX.xml,/WEB-INF/config/struts-config-XX.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
3. struts配置文件
当应用程序只有一个模块时,配置文件一般使用默认名struts-config.xml,默认路径/WEB-INF/;
当多个时每个模块创建独立的配置文件一般使用struts-config-模块名.xml命名,位于/WEB-INF/config/之下。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="myForm" type="packagename.MyForm" />
</form-beans>
<action-mappings>
<action path="/myAction" type="packagename.MyAction" name="myForm" validate="true" parameter="method">
<forward name="index" path="/index.jsp" />
<forward ……
</action>
<action ……
</action-mappings>
</struts-config>
4. 视图调用
当服务器没有配置访问地址省项目名,action路径要去掉"/"。
<form name="myform" action="/myAction.do?method=myMethod" method="post">
二. 原理
1. 当程序启动时,核心控制器ActionSerlvet被容器实例化并初始化。读取子配置文件如:struts-config.xml等等,监听用户的请求,如.do的请求。
2. 当ActionSerlvet收到请求时,检查请求路径在<action-mappings>是否有匹配,没有会报路径错误如404。
3. 根据匹配的<action>的name属性在<form-beans>中查找ActionForm,如果有匹配就从scope(默认取值为request)指定的范围,取出ActionForm,将请求的参数封装到ActionForm中,否则自动新建ActionForm的实例。
4. 如果<action>的validate为true,择自动调用ActionForm的validate()方法进行验证。如果validate()返回值 !=null 或 length != 0时, 则验证失败转发到input指定的视图。
5. 将请求转发给type所指定的action处理,默认调用execute()方法,如果parameter="method",并且请求路径包含方法名,则调用此action的路径中指定的方法。
6. action中方法返回ActionForward对象,ActionForward指定视图组件,常见3种方式:
1. return mapping.findForward("forwardName");在<action-mappings> - <action> - <forward >中匹配页面,未找到返回空白页。如果<forward >配置了
2. return new ActionForward("/target.jsp");直接指定视图,未找到返回HTTP Status 404 - ………
3. return methodName(mapping,form,request,response); 进入action的其他方法体,视图由其他方法决定。
三. ActionSerlvet
1. ActionSerlvet是一个普通的servlet,继承HttpServlet,所以生命周期同样为初始化、执行、销毁。
2. ActionSerlvet接收所有请求,用户首次请求时加载ActionSerlvet类,执行初始化init()方法,此方法只运行1次。
3. init()初始化了struts资源文件如系统日志、警告、通知和错误等,加载了ActionServlet参数如config、debug和convertNull等,验证web.xml和struts配置文件的语法并解析,加载初始化插件等等,所以开发时修改配置文件后必须重启才生效。
4. doGet、doPost(HttpServletRequest request, HttpServletResponse response)方法都会调用process(),process()匹配或新建RequestProcessor实例,然后调用RequestProcessor的process(),process()中调用了10多个其他方法完成工作。
5. ActionSerlvet只有一个,但根据不同的请求匹配不同的子模块信息,会实例化多个RequestProcessor实例,既每个子模块有一个RequestProcessor。
6. 当服务器停止destroy()销毁。
四. 扩展struts1
1. 控制层
1. 扩展ActionSerlvet, 继承ActionServlet
1. 重写init()方法:
public class MyActionServlet extends ActionServlet {
public void init() throws ServletException {
super.init();
// 做自己的事情
……
}
}
2. 重写process()方法:
protected void process(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
request.setCharacterEncoding("UTF-8");// 设置解码方式
super.process();
}
注意:必须调用源方法,再在源方法或前或后加了一些自己的操作,这种扩展方式很简单,但适用广泛。
配置:
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>改为<servlet-class>packagename.MyActionServlet</servlet-class>
2. 扩展RequestProcessor,继承RequestProcessor:
1. 重写processPreprocess()方法:比如用于验证用户是否已登录
processPreprocess()为process()中调用的第6个方法,该方法不作任何操作,只返回true。
public class MyRequestProcessor extends RequestProcessor{
protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) {
// 做自己的事情
return true;
}
}
2. 重写重写processPreprocess()方法:比如用于验证用户是否有访问action的权限
3. 重写重写processContent()方法:比如用于设置响应类型
配置:
<controller>
<set-property property="processorClass" value="packagename.MyRequestProcessor" />
<set-property property="contentType" value="text/html; charset=utf-8" />
<set-property property="nocache" value="true"/>
</controller>或
<controller nocache="true" inputForward="true" maxFileSize="2M" contentType="text/html;charset=UTF-8"
processorClass="packagename.MyRequestProcessor"/>
3. 扩展Action时,一般是继承Action的子类如DispatchAction,因为Action的子类扩展了源Action,从而提高了代码的可重用性,减少冗余。
2. 视图层
一般是引用外部标签库:如jstl
1. 将jstl.tld文件拷贝到/WEB-INF/目录下,多个建文件夹如:/WEB-INF/tlds/
2. 在web.xml中配置,
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/tlds/jstl.tld</taglib-location>
</taglib>
3. 视图中导入<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
使用方法:${XX}、
<c:forEach var="fuwa" items="${XX}" begin="3" end="4" step="1" varStatus="s"><c:out value="${s.index}" /></c:forEach>
3. 插件机制
待续……