来自:http://blog.csdn.net/yuchen2008/archive/ 2007/04/14 /1564742.aspx
Struts(一)
基本概念:
1.什么是MVC?有什么用?
2.控制器的结构
3.什么是Struts?有什么用?
4.Struts的内容与环境配置
什么是MVC?有什么用?
MVC是一种设计框架,程序流程清晰,便于维护
表现层 中间层 持久层
(web) (业务层service) (data)
CV M
我们重点看一下web层:
用户请求---C:做两件事情,第一,得到url(v1),第二,查看url对应得动作action---action
Action访问中间层M层得到结果,查看这个结果对应得url(v2)---C---v2
Jsp---javabena模式的缺点在于流程非常复杂,所以mvc解决了这个问题,所有的流程在C,中心控制器,但是,如果我们需要再添加或修改一些动作的话,还是要修改C中心控制器的,这样不大方便,那么Struts框架解决了这个问题
控制器的结构:
C(中心控制器)也叫前端控制器:所有的请求和返回都要通过它
C后面是多个action,它帮助C和M进行交流的
什么是Struts?有什么用?
MVC的实现,实现了C中心控制器,我们看一下Struts框架的MVC
V1---C(ActionServlet)---xml(struts_config.xml):通过这个文件得到url(v1)对应的action---action---xml通过这个文件得到和结果对应的url(v2)---action---C---v2
这样,所有的流程在这个xml文件中,那么要添加或者修改action的时候,我们不需要修改C,这个C是servlet类,只要修改Strust_config.xml就可以了
Struts的内容与环境配置
1.版本问题:Struts和Tomcat里面的包要保持一致,我们可以先将一个空的Struts环境备份好
位置:struts/参考资料/lib/ struts-blank.zip
2.Struts环境:
将struts-blank.zip解压到tomcat的webapps下
WEB-INF/web.xml struts_config.xml and tld
WEB-INF/lib:struts and app 所需要的包
WEB-INF/classes/ resources:资源文件,做国际化的
Struts_config.xml:这个文件就是实现了控制器的流程
web.xml:
<load-on-startup>2</load-on-startup>:当Tomcat启动的时候,马上加载这个servlet类到内存中
*.do拦截方式叫做单点接触
Struts_config.xml:
<action-mappings>:这里面都是action,url的映射
<action path=”url” type=”action”>
<forward name=”action return rst” path=”rst url”>
</action>
Struts的工作流程:
web应用启动,便会加载ActionServlet类,这个类常驻内存的,当用户发送请求的时候,ActionServlet读取Struts_config.xml,将得到的信息保存到相应的对象中,例如,将url对应的action保存到ActionMapping对象中
ActionServlet的工作流程:
当接到请求后,调用process()方法,将请求交给RequestProcessor的实例来处理,在struts1.1后,请求的处理者变成了RequestProcessor
RequestProcessor的工作流程:
1.什么是RequestProcessor?有什么用?
这个类接收来自servlet的每一个请求,我们可以自己定制请求的处理功能,需要继承这个类,并且在struts_config.xml中改写<controller>标签
2.工作流程:
processMutipart():在这个方法中,Struts将会读取request来检查request的contentType是否是multipart/form-data。如果是的话,将会解析request并且将之包装到HttpServletRequest中。当你创建了一个HTML FORM用来提交数据,那么request的contentType默认就是application/x-www-form-urlencoded。但是如果你的form使用了file类型的input控件允许用户上传文件的话,你就必须将contentType改为multipart/form-data。如果是这样的情况,你就不能再通过getParameter()来获取用户提交的数据;你必须将request作为一个InputStream来读取,并且自己解析它来获得参数值
processPath():String path = processPath(request, response);得到url
processLocale():确定客户端的位置,做国际化的,再一个调用这个方法会创建一个HttpSession,如果不想被创建,可以在struts_config.xml中设置不调用这个方法,<controller>
<set-property property="locale" value="false"/>
</controller>
processContent():通过调用response.setContentType()来为response设置contentType。这个方法首先会尝试从struts-config.xml配置中得到contentType。缺省情况下使用text/html。如果想覆盖它,可以象如下这样:
<controller>
<set-property property="contentType" value="text/plain"/>
</controller>
processNoCache():可以解决输出的时候出现缓存response的问题
如果配置是no-cache,Struts将会为每个response设置下面三个headers:
requested in struts config.xml
response.setHeader("Pragma", "No-cache";
response.setHeader("Cache-Control", "no-cache";
response.setDateHeader("Expires", 1);
如果你想设置no-cache header,在struts-config.xml中加入下面信息:
<controller>
<set-property property="noCache" value="true"/>
</controller>
processPreprocess():回调方法,里面的内容为return true;返回为true,控制器继续执行,否则停止,我们可以重写这个方法来控制中心控制器是否继续执行(这个方法为预处理提供一个hook(钩子),可以在子类中覆盖它。它的缺省实现没有作任何事情,总是返回true。返回false的话将会终止当前请求的处理)
processMapping():
ActionMapping mapping = processMapping(request, response, path);
if(mapping == null) {
return;
}
通过url得到ActionMapping对象,这个对象存放的是url-action,rst-url映射的信息
这个方法将会用路径信息得到一个ActionMapping对象。也就是struts-config.xml文件中的<action>元素:
<action path="/newcontact" type="com.sample.NewContactAction"
name="newContactForm" scope="request">
<forward name="sucess" path="/sucessPage.do"/>
<forward name="failure" path="/failurePage.do"/>
</action>
ActionMapping元素包含了Action类的名称和处理请求使用的ActionForm等等信息。它还包含当前ActionMapping配置的ActionForwards信息
processRoles():struts的安全机制
Struts web应用提供了一个授权方案。也就是说,一旦一个用户登入了容器,struts的processRoles()方法将会通过调用request.isUserInRole(),来检查他是否有必须的角色来运行一个给定的ActionMapping。
<action path="/addUser" roles="administrator"/>
假设你有一个AddUserAction并且你只想让administrator能够增加新的user。你所要做的就是给你的AddUserAction元素增加一个role属性,这个属性的值为administrator。这样,在运行AddUserAction之前,这个方法会确保用户拥有administraotr的角色
processActionForm():ActionForm就是一个javabean,这个类是用来存储并处理表单数据的,首先会去request scope中找这个对象,如果没有,创建一个,有得话就从里面拿出来直接用,每一个ActionMapping都一个相应的ActionForm类。当Struts处理一个ActionMapping的时候,它将会从<action>元素的name属性中找出对应的ActionForm类的名称。
<form-bean name="newContactForm"
type="org.apache.struts.action.DynaActionForm">
<form-property name="firstName"
type="java.lang.String"/>
<form-property name="lastName"
type="java.lang.String"/>
</form-bean>
processPopulate():这个方法就是将表单的参数封装到ActionForm对象
processValidate():表单验证,Struts将会调用你的ActionForm类的validate方法。如果你从validate()返回ActionErrors,它将会将user重定向到<action>元素的input属性指定的页面
processForward():检查mapping中有没有使用流转标签,找到后使用,功能相当于RequestDispatcher.forward(),流转到指定的url
processInclude():检查mapping中有没有使用包含标签,找到后使用,功能相当于RequestDispatcher.include(),将一个指定的url包含
如果上面两个方法都设置了,只会调用forward()
processActionCreate():这个方法从<action>标签中的type里得到action类,创建这个类的实例
processActionPerform():这个方法调用action的execute()方法,execute()这个方法一般写业务逻辑的,我们在写action的时候,会继承action类,实现execute()这个方法
processForwardConfig():通过上面的步骤,requestProcessor为我们创建了一个ActionForward的实例,也就是execute的返回值,在这个对象中有nextUrl,也就是action得到的rst对应的path,这个path就是nextUrl,然后创建这个url的RequestDispathcher对象,再调用这个对象的RequestDispathcher.forward()方法
以下是RequestProcessor的部分源代码:
public void process(HttpServletRequest request,HttpServletResponse response)
throws IOException, ServletException {
// Wrap multipart requests with a special wrapper
request = processMultipart(request);
// Identify the path component we will
// use to select a mapping
String path = processPath(request, response);
if (path == null) {
return;
}
if (log.isDebugEnabled()) {
log.debug("Processing a '" + request.getMethod() +
"' for path '" + path + "'";
}
// Select a Locale for the current user if requested
processLocale(request, response);
// Set the content type and no-caching headers
// if requested
processContent(request, response);
processNoCache(request, response);
// General purpose preprocessing hook
if (!processPreprocess(request, response)) {
return;
}
// Identify the mapping for this request
ActionMapping mapping =
processMapping(request, response, path);
if (mapping == null) {
return;
}
// Check for any role required to perform this action
if (!processRoles(request, response, mapping)) {
return;
}
// Process any ActionForm bean related to this request
ActionForm form =
processActionForm(request, response, mapping);
processPopulate(request, response, form, mapping);
if (!processValidate(request, response, form, mapping)) {
return;
}
// Process a forward or include specified by this mapping
if (!processForward(request, response, mapping)) {
return;
}
if (!processInclude(request, response, mapping)) {
return;
}
// Create or acquire the Action instance to
// process this request
Action action =
processActionCreate(request, response, mapping);
if (action == null) {
return;
}
// Call the Action instance itself
ActionForward forward =
processActionPerform(request, response,
action, form, mapping);
// Process the returned ActionForward instance
processForwardConfig(request, response, forward);
}
第一个Struts应用:
1.配置环境
2.开发步骤
配置环境:
1.将模版拷贝到tomcat webapps目录下
2.配置需要的lib:如数据库的包
开发步骤:
1.需求分析 程序目标 程序逻辑
2.写jsp页面
3.写struts_config.xml文件,配置流程
4.写action
5.写M层
环境配置:
web项目根目录:first_struts
/first_struts
/first_struts/JS
/first_struts/pages login.jsp success.jsp
/first_struts/pice
/first_struts/WEB-INF : web.xml struts_config.xml
/WEB-INF/classes
/WEB-INF/lib
/WEB-INF/src
/src/yuchen.first.LoginAction.java
程序目标:
测试struts应用,用户进入登陆页面,当提交数据的时候,显示登陆成功页面
Jsp:
Login.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W 3C //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>
<form action="/first-struts/login.do" method="post">
userName: <input type="text" name="user"/><br>
password: <input type="password" name="pwd" /><br>
<input type="submit" />
</form>
</body>
</html>
success.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W 3C //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>
<h1>success!</h1>
</body>
</html>
LoginAction.java:
package yuchen.first;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class LoginAction extends Action{
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response
)throws java.lang.Exception
{
//通过从mapping中找forward标签中的值为success的name所对应的nextUrl
//生成ActionForward对象,里面有nextUrl
return mapping.findForward("success");
}
}
struts_config.xml:
添加这段代码
<action
path="/login"
type="yuchen.first.LoginAction">
<forward name="success" path="/pages/success.jsp"/>
</action>