文章目录
1 Struts 1.x简介
Struts是由Apache在2002年推广的一个开源项目,主要是进行MVC实现的开发框架。但是为什么需要为MVC设计一个框架呢?为了更好的解释下面做个对比:
(1)考虑一:如果使用标准的开发技术(JSP+Servlet+JavaBean),如果没有进行任何的设计会发现代码重复量惊人。
|——验证操作需要重复编写;
|——用户需要自己手工接收参数,手工进行数据的转型,而后设置到VO对象里面;
|——所有的跳转路径都统一定义在了程序之中,后期维护困难;
|——文件上传操作需要自己手工处理。
(2)考虑二:应该进行更加合理的设计(开发了一个DispatcherServlet),它提供有如下好处:
|——自动进行数据的接收以及VO类对象的转换,将VO类的概念进一步提升;
|——可以定义专门的资源文件进行各种信息以及跳转路径的保存;
|——上传的操作对用户而言几乎隐藏,用户接收参数的时候也不再需要区分到底是否有封装还是没有封装;
|——提供统一的验证操作形式,保证服务器端的验证简化;
|——利用反射机制的操作进行一个控制器的多业务处理。
利用了自己的设计来解决开发的重复性操作固然是一件非常兴奋的事情,但是事实上这样的开发操作如果用于直接的项目设计之中,那么要想实现一个几乎完美的DispatcherServlet实在是太难了。而且如果你真的开发完成了,并且希望在你的项目中实际使用,那么至少应该将代码变为接近于90%
的完美无缺才可以。
所以在后来使用JSP、Servlet进行MVC标准开发的过程之中,就特别需要有一家组织可以帮助所有的公司提供这样一个近乎完美的开发的一组类库,那么就可以为我们的开发与设计节约大量的时间,在这样的背景下产生了最早的Struts技术。随后随着版本的提升,Struts又产生了1.1、1.2、1.3(并且永恒定格在了1.3版本)。
在Struts 1.x中“完美”的实现MVC设计模式的体现,在这里面用户可以使用统一的风格进行数据的验证,用户也可以使用第三方验证框架(极其不好用,没有任何一个开发框架的验证框架好用)、支持FileUpload进行上传并且支持多业务处理等等优势,所以在最初的时候Struts 1.x被大量的采用。
被Struts 2.x所替代主要是因为Struts 1.x有一些天然的劣势(初期的设计问题),而在Struts 2.x支持了拦截器的操作,到了今天所有的新的项目已经很难见到Struts 1.x身影。
在最初的几年里面,只要你从事Java开发,如果不会Struts那么基本上就不叫Java开发。
面试题:请解释MVC与Struts的区别?
答:MVC是一个标准的设计模式,重点在于控制层、显示层、模型层彼此独立。而Struts只是MVC的一种实现,如果把MVC当做接口来看,那么Struts就是这个接口的实现子类。
Struts 1.x也就出现在维护项目的可能性居多,而在新项目开发之中最次也要使用Struts 2.x。
2 开发第一个Struts 1.x程序(开发配置)
下面将实现一个最简单的用户登录程序,本次的操作主要是在表单中输入用户名和密码西南西,而后要求判断用户名和密码是否有内容(服务器端验证),随后验证的信息是“lks/19990821”,如果成功则显示欢迎信息,否则显示失败的信息。
1、MyEclipse已经默认支持了Struts 1.x和Struts 2.x的开发,那么下面按照步骤进行:
(1)建立一个新的项目:Struts1Project;
(2)在Struts 1.x的时代里面还没有所谓的Annotation配置支持,所以此处如果要想使用Struts 1.x建议生成web.xml。
2、所谓的开发框架就是一组开发程序的jar包,那么在MyEclipse里面可以直接为项目配置这些jar包。
(1)选择项目,而后点右键,选择MyEclipse的项目支持。
3、进入Struts 1.x配置页面;
(1)本次使用1.3版本。
随后的界面里面需要定义一些配置信息,这些配置信息包含有如下内容:
|——Servlet的处理路径:Struts 1.x中的Servlet路径是一个经典的*.do
;
|——随后要求输入项目的程序包org.lks;
|————这个时候会发现自动创建有一个文件“ApplicationResources”,保存文本资源;
|——随后会询问所需要的Struts开发包。
项目建立完成之后会自动在项目中出现以下内容:
(1)会自动的将Struts 1.x的开发包配置到CLASSPATH之中;
(2)在WEB-INF目录下会自动创建有一个struts-config.xml文件,这个是Struts的核心配置文件;
(3)在src目录下(最终会输出到WEB-INF/classes下)存在有一个ApplicationResource.properties;
3 开发第一个Struts 1.x程序(程序编写)
1、建立一个login.jsp页面:
(1)在建立这个页面的时候稍微有一些不同,将使用Struts 1.x提供的标签完成。
范例:程序代码
此时发现在定义表单的时候所使用的形式不太一样了,因为它使用了标签处理(为了方便回填):
|——<form>
:<html:form action="" method="post" focus="login">
|——<input type="text">
:<html:text property="username" />
|——<input type="password">
:<html:password property="password" />
|——<input type="submit">
:<html:password property="password" />
|——<input type="reset">
:<html:reset value="reset"/>
在输入组件中定义的properties实际上在最后页面运行的时候会自动生成id与name两个属性,如果定义了以下内容:<html:text property="username"
,那么就会生成的<input type="text" name="username">
,除此之外,还可以生成与程序中的的接收属性进行对应。
2、配置错误信息,修改ApplicationResource.properties文件
# 这些验证的错误信息是给ActionForm准备的
username.input.null=<li>登录用户名不允许为空!</li>
password.input.null=<li>登录密码不允许为空!</li>
# 这些登录结果信息是给Action准备的
login.success=用户登陆成功,欢迎光临!
login.failure=用户登陆失败,请重新登录!
3、编写处理程序,但是Struts 1.x的处理程序是分为两种类型:Action(负责跳转,与Servlet功能相似)、ActionForm(进行数据验证使用的)。
随后会首先进入到创建ActionForm操作对话框,在这里面输入以下的内容:
(1)Use case:表示本次操作的模块名称,输入“mylogin”;
(2)随后会自动出现一个name的数据“myloginForm”,它是在struts-config.xml文件里面出现的;
(3)让这个ActionForm继承org.apache.struts.action.ActionForm
类;
(4)设置属性,在JSP里面写了两个属性:username
、password
。
随后下一步进入到Action的配置。
(1)首先在这里面最需要配置的是一个访问路径,也就是表单提交路径/mylogin
;
(2)此Action类继承org.apache.struts.action.Action
父类;
(3)随后设置input Source
。
4、首先在MyloginActionForm中编写如下代码:
(1)首先可以发现建立的属性都会自动生成setter、getter对应的方法;
(2)数据验证的代码操作要求写在validate方法里面;
package org.lks.struts.form;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
@SuppressWarnings("serial")
public class MyloginForm extends ActionForm {
private String password;
private String username;
/**
* 此方法主要进行用户输入数据的验证,如果现在输入的数据有错误,则将错误信息保存在ActionMessage类对象里面
* 并且将所有的ActionMessage类对象可以统一保存在ActionErrors,如果在返回的时候返回的是null或者ActionErrors返回的内容没有包含任何的错误信息
* 那么会将请求继续交给Action进行处理,否则会返回到一个错误路径(input Source)。
* @param mapping 表示所有映射信息,此类一般不使用
* @param request 可以接收用户的请求参数
* @return ActionErrors 如果返回null或者里面保存的错误信息为0,那么表示正确
*/
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
// TODO Auto-generated method stub
ActionErrors errors = new ActionErrors(); //保存错误信息
//当用户发送请求后所有的输入的参数都会自动调用setter赋值,当执行到此方法时,一定是已经处理完参数了
if( this.username == null || "".equals(this.username)){
//输入的username参数内容为空
//add()方法有两个参数,第一个参数表示的是提交参数的名字
//第二个参数表示读取的错误的key,错误的信息利用ActionMessage读取
errors.add("username", new ActionMessage("username.input.null"));
}
if( this.password == null || "".equals(this.password)){
//输入的password参数内容为空
errors.add("password", new ActionMessage("password.input.null"));
}
return errors;
}
public void reset(ActionMapping mapping, HttpServletRequest request) {
// TODO Auto-generated method stub
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
5、开发Action程序,一旦代码执行到Action之后,那么就表示数据验证通过,一定是符合要求的数据。
(1)在struts-config.xml中配置跳转的路径,现在假设成功或者失败都跳转到login.jsp页面:
<action attribute="myloginForm" input="/login.jsp" name="myloginForm"
path="/mylogin" scope="request" type="org.lks.struts.action.MyloginAction"
cancellable="true">
<forward name="success" path="login.jsp"></forward>
<forward name="failure" path="login.jsp"></forward>
</action>
(2)随后编写MyloginAction程序类:
package org.lks.struts.action;
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;
import org.lks.struts.form.MyloginForm;
public class MyloginAction extends Action {
/**
* 此操作主要是进行用户的请求处理,类似于doGet()或者是doPost()方法功能
* @param mapping 此类主要负责读取struts-config.xml文件配置
* @param form 表示要操作的ActionForm,使用它的目的是为了能够接收参数
* @param request 用户的请求
* @param response 用户回应
* @return ActionForward 表示返回路径信息,通过配置文件取出映射的key
*/
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
MyloginForm myloginForm = (MyloginForm) form;// TODO Auto-generated method stub
System.out.println();
if ("lks".equals(myloginForm.getUsername()) && "19990821".equals(myloginForm.getPassword())) {