筑基Struts

废话少说,直接代码说话,这里用的是Struts1.2

首先是web.xml文件

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <!-- 它是用来管理所有动作的,在Struts框架中起控制器的作用 --> <!-- 它通过struts-config.xml配置来管理所有的action --> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <!-- 指定该servlet在启动过程中的一些初始化参数 --> <!-- 这里的<init-param>等初始化参数,完全可以全部删掉,它们都没什么用 --> <init-param> <!-- 指定Struts1.x配置文件的名字和路径 --> <!-- 由于struts-config.xml就是Struts1.x的缺省配置文件,所以这里也可以取消这个配置 --> <!-- 除非修改了//WebRoot//WEB-INF//struts-config.xml的名字,那么就需要在这里指明一下 --> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <!-- servlet日志的输出等级 --> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <!-- 解析struts-config.xml时采用的是apache的第三方组件 --> <!-- 所以detail参数就是设置apache的该第三方组件的日志的输出级别 --> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <!-- 当Web项目启动时,立即执行该Servlet中的内容 --> <!-- 换句话说,此时等于系统替我们做了一个servlet。当Web程序启动的时候,这段servlet就运行在了这个容器里 --> <!-- 该servlet是org.apache.struts.action.ActionServlet类,这个类来源于刚刚添加的Struts1.x的Jar包中 --> <load-on-startup>0</load-on-startup> </servlet> <!-- 若这里映射为为*.action,则页面应改为<form action="login.action" method="POST"> --> <!-- 而此时struts-config.xml中的<action path="/login">则无需更改 --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>

然后是前台登录界面login.jsp

<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%> <%-- 注意:需要将默认的struts-html.tld文件放置到WEB-INF目录下 --%> <h4> <font color="red">提示:</font>程序设定的用户名和密码分别为 <font color="blue"><strong>admin</strong></font>和 <font color="blue"><strong>jadyer</strong></font><br/> 当输入的用户名为jade时,会在uname后面显示错误信息 </h4> <html:form action="/login"> uname:<html:text property="uname" /><html:errors property="uname" /><br/> upass:<html:password property="upass" /><br/> <html:submit value="提交"/> </html:form> <%-- ======================================================================================================================== <html:form>标记的缺陷是:它的action的值必须对应一个存在的ActionForm 若使用普通<form>标签,可以写成<form action="login.do" method="POST"> ======================================================================================================================== 点击按钮时,首先将login.do的请求发送给web.xml中生成的总的控制器 然后总的控制器会将该请求转到struts-config.xml中与其相关的<action-mappings>里面的<action>标记的部分 这时会发现它有两个属性,即attribute和name。然后就会在LoginForm.java中发现setter和getter,接着便调用对应的setter 相应的setter方法会与该页面中传递的参数比对。如果传出去的input的name值为king,那么就会到LoginForm.java中查找setKing() 如果LoginForm.java中有setKing()的话,那么就会执行该方法。本例中input的name为uname,那么就会执行setUname()方法 【另外】若此次传递的uname值是stone,此时它保存在老用户的request对象中。当新用户再次访问该页面时,stone是不会保存的 ======================================================================================================================== 有一种情况,比如登录的信息都是错误的 这个时候,不转向到显示错误信息的页面,而是停留在原页面不动,并且仍然在输入域中显示输入的数据 此时便可使用${loginForm.uname}或者Struts1.x中的<html:text property="uname"/> 获取ActionForm中所保存的表单数据,然后将它显示在<input>的value值中 ======================================================================================================================== Struts中的<html>标签和Struts结合的非常紧密 它的<html>标签封装了所有HTML中的元素,它会自动读取ActionForm中的属性 在开发中,大部分会使用JSTL,很少使用到Struts的标签,只在国际化的时候,会用到几个Struts标签 除此外,在一般的情况下使用的都是JSTL ======================================================================================================================== 使用Struts开发的应用程序,仅能使用一个ActionServelt 换句话说,用Struts做出来的应用,就要求机器的性能应当是相当够快的了,因为它所有的东西都是从这个中心开始转的 设想:上千人在线,大家一起调用这个中心的时候,机器的承受能力可想而知,但是能够使用得起Struts项目的,机器也应该不会特别差 所以有种说法:普通的一个两、三万能搞定的项目,是不会用Struts的,就用Servlet加上JSP搞定 所以有种说法:而十多万的项目才可能会使用Struts框架 ======================================================================================================================== 【Struts的运行过程】 01..运行web.xml中有关ActionServlet的servlet的装载 02..运行struts-config.xml描述的<action> 03..运行ActionForm中的reset()方法 04..用户点击提交按钮 05..用户的提交动作被发送到web.xml中设置的ActionServelt 06..为*.do分配action 07..装载ActionForm 08..调用ActionForm中的setXxx()方法 09..调用ActionForm中的validate()方法 10..调用Action中的execute()方法 11..执行Action中的所有的业务操作。这是核心 12..执行Forward()转向 ======================================================================================================================== --%>

登录失败时显示的fail.jsp页面

<%@ page pageEncoding="UTF-8"%> <%=request.getAttribute("ErrorInfo")%>

登录成功时显示的success.jsp页面

<%@ page pageEncoding="UTF-8"%> <%@ page import="com.jadyer.struts.form.LoginForm"%> <% LoginForm lf = (LoginForm)request.getAttribute("loginForm"); %> <font color="blue"><%=lf.getUname()%></font>,登录成功

然后是struts1.x的核心配置文件struts-config.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"> <struts-config> <form-beans> <!-- 定义数据模型的名字为loginForm,它是由LoginForm类实现的 --> <!-- 配置ActionForm的标签必须在前面。这是由DTD决定的。这个DTD文件并不是在网站上的 --> <!-- 可以查看DTD:左侧项目列表展开struts.jar下的org.apache.struts.resources包 --> <!-- 然后就可以看到struts-config_1_2.dtd文件了 --> <form-bean name="loginForm" type="com.jadyer.struts.form.LoginForm" /> </form-beans> <!-- 全局转向可以被所有的action调用。局部转向只能被它所属的action调用 --> <!-- 这里,<forward/>还有一个className的属性,这个className是Struts提供的一个扩展性 --> <!-- 也就是说,如果我们觉得Struts的ActionForward做的不是很好,或者说满足不了我们的需求 --> <!-- 这时,我们也可以继承它,然后我们自定义一个转向类,来完成我们所需的转向 --> <!-- 当我们编写完自己的转向类之后,在className的值中把我们写的转向类填写进去 --> <!-- 它就会用我们的转向类来转向了,而不再使用Struts的转向类了 --> <!-- 所以说,这个className属性是提供了一种扩展性。并且,在很多的标签中都有该属性 --> <global-forwards > <forward name="fail" path="/fail.jsp" /> </global-forwards> <action-mappings> <action path="/login" attribute="loginForm" name="loginForm" input="/login.jsp" scope="request" type="com.jadyer.struts.action.LoginAction"> <!-- path:指明action的映射名,即前台表单的action属性值。它的值一定要以斜杠开头,即从根开始 --> <!-- type:指明当前的action所使用的具体的类 --> <!-- name:指定收集表单数据的ActionForm,它的值对应的是<from-bean>标签的name值 --> <!-- attribute:在页面中使用request.getAttribute("ActionForm名称");获取表单数据时 --> <!-- 它会先查找这里的attribute属性,次之才会去查找name属性,详见success.jsp页面代码 --> <!-- input:指明数据来源的页面 --> <!-- 当ActionForm中的validate()验证失败或不合法时,异常会自动转向到<action/>标签中input属性指向的页面 --> <!-- scope:Struts1.x的内部处理是这样的:在实例化ActionForm之后,它会把表单上的数据写到ActionForm上 --> <!-- 然后再把实例好的ActionForm对象放到scope内,scope属性可以取值为request或者session,默认为session --> <!-- validate:设置应用在运行时,是否执行ActionForm中的validate()方法。值为FALSE则不执行。缺省为TRUE,即执行 --> <!-- forward标签:转向分为转发和重定向。此时的转向是按照默认的转发。若增加redirect="true"设置,则是重定向 --> <forward name="success" path="/success.jsp" /> </action> </action-mappings> <message-resources parameter="com.jadyer.struts.ApplicationResources" /> </struts-config> <!-- ===================【关于attribute属性的补充】============================================================= --> <!-- 由于在struts-config.xml中设置的scope为request,name为loginForm --> <!-- 所以我们可以在该Action转向后的页面中通过request.getAttribute("loginForm")获取表单信息 --> <!-- 因为Struts框架在将ActionForm对象传送到Action中之前 --> <!-- 会将ActionForm对象保存在struts-config.xml中的<action/>标签里设置的Scope中,比如scope="request"配置 --> <!-- 它会让Struts调用request.setAttribute("ActionForm名称", ActionForm对象)方法,将ActionForm对象保存到request中 --> <!-- 其中ActionForm名称与struts-config.xml配置中的ActionForm名称一致 --> <!-- 但在取值时,需要注意<action/>中是否设置了attribute属性 --> <!-- 若struts-config.xml设置了attribute="testForm"的话,则须使用request.getAttribute("testForm")获取表单信息 --> <!-- 若使用request.getAttribute("loginForm")则会出现空指针错误,这是因为程序调用ActionForm时是先从attribute中开始查找的 --> <!-- 如果struts-config.xml中没有为<action>指定attribute属性,此时程序才会去使用name属性的值,来获取表单数据 --> <!-- ===================【关于forward属性和ForwardAction】====================================================== --> <!-- 示例代码:<action path="/toLogin" forward="/login.jsp"/> --> <!-- 这里的forward属性会自动将toLogin.do的请求转向到login.jsp页面中 --> <!-- forward和type属性之间是互斥的,只有一个会生效,但forward的优先级要高于type属性 --> <!-- 在使用Struts1.x框架的时候,一般的情况下要尽量避免自己做转向,所以的转向都交给Struts1.x处理 --> <!-- 另外也可以使用ForwardAction做转向,代码如下所示 --> <!-- <action path="/toLogin" type="org.apache.struts.actions.ForwardAction" parameter="/login.jsp"/> --> <!-- 使用ForwardAction的时候,还需要通过parameter属性来指定转向路径或具体页面 --> <!-- ForwardAction和Forward属性是一样的,都能够节省Action的数量 --> <!-- 参考Struts中的RequestProcessor.class源码可知,ForwardAction会执行完所有的流程 --> <!-- 而Forward执行到一半就不再执行了,而是去转向页面了。其实,具体使用时,直接使用Forward属性便可 --> <!-- ===================【关于unknown属性】==================================================================== --> <!-- 示例代码:<action path="/nonelogin" unknown="true" forward="/unknown.jsp" /> --> <!-- unknown属性默认值为FALSE。将其设为TRUE之后,假如前台页面发送了一个stone.do的请求 --> <!-- 它就会像平常一样,到struts-config.xml中查找stone.do的请求,结果自然没有找到 --> <!-- 此时它就会查找<action/>中配置了unknown属性为TRUE的<action/> --> <!-- 找到这个<action/>之后就转向到它的forward属性指定的页面,其实这是一种容错处理,且仅对do请求起作用 --> <!-- 注意:不要同时对两个<action/>都设置unknown属性 --> <!-- ======================================================================================================== -->

用到的struts1.x中的ActionForm类

package com.jadyer.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; /** * 该类只有继承了org.apache.struts.action.ActionForm之后 * 它才会自动把表单中的数据射进来。也就是说ActionForm是用来做数据收集的 * 而ActionForm的属性名必须和表单中输入域的名称一致 * 当它收集数据的时候,Struts1.x会自动为该类New对象 * 然后New出来的对象自动调用set()方法,把表单上的数据射进来 */ @SuppressWarnings("serial") public class LoginForm extends ActionForm { //ActionForm会自动将前台<input>中输入的字符串转换为这里定义的类型 //也就是说这里还可以根据实际需要把属性定义成int型,是不会报错的 private String uname; private String upass; //【注意】属性名可以任意写,但是setter方法名不可随意写 //在JavaBean规范当中,它是拿setter方法里面的名字与表单中<input>的name值做匹配的 //不止Struts1.x中是这样的,所有的JavaBean中都是这样的,这是JavaBean规范 public void setUname(String uname) { this.uname = uname; } public String getUname() { return uname; } public void setUpass(String upass) { this.upass = upass; } public String getUpass() { return upass; } /** * Struts的使用是基于多线程的。每一个用户提交的信息都不同,得到的结果自然不同 * 而reset()就是一个重置方法。即当每一个用户提交之后,它会把原有的值清空 * 但有时也使用该方法设定初值 * 所以reset()一般两种用途:设定初值、清空数据 */ public void reset(ActionMapping mapping, HttpServletRequest request) { //这里的uname对应的是<html:text property="uname"/>中的属性值 //这么做的好处是无论多少个用户在任何时刻访问该页面,所看到的uname文本框中显示都是这里设定的值 this.uname="请输入用户名"; } /** * 程序会首先执行reset()方法,然后再执行validate()方法 * 尽管在正常的开发中很少会用到这里的validate()来做验证,但我们还是应该对它有些了解 * validate()验证属于服务器端验证,在页面中使用JavaScript的方式属于客户端验证 * 关键性的应用应该在服务器端验证,因为客户端验证是可以跳过的 * 而ActionForm中的validate()原则上只做对表单的验证,它不应该访问数据库 * 应该把需要访问数据库的验证封装到应用的模型层中,然后在Action中对其调用 * 由于validate()属于表单级的验证。故只能判断【用户名或密码】长度是否合法等等 */ public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors error = null; if("jade".equals(this.uname)){ error = new ActionErrors(); //第一个参数:对应前台<html:errors property="uname"/>的属性值 //第二个参数:对应ApplicationResources.properties中的key属性 error.add("uname", new ActionMessage("ner")); } return error; //如果return null;则认为验证是正确的 } }

用到的struts1.x中的Action类

package com.jadyer.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 com.jadyer.struts.form.LoginForm; /** * 它需要继承org.apache.struts.action.Action类 * Action----------每一次请求,对应一个Action * ActionForward---转向信息 * ActionForm------收集数据 * ActionMapping---配置信息 * 一个ActionMapping实例对应了一个struts-config.xml中的<action-mappings>标签里的配置信息 * 所以,当发出请求的时候,假如请求的是login.do * 它就会到配置文件里把与login对应的<action/>配置信息放到ActionMapping实例中传到Action里 * 而这里的ActionForm就是struts-config.xml中<action/>标记的name和attribute部分,即<form-bean/>标记的部分 */ public class LoginAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { // Struts中提供的action和普通servlet的区别就是:它可自动装载一个form进来 // 它的action会自动装载struts-config.xml中设置的与之对应的ActionForm // 在Struts1.x中,它会自动实例化ActionForm,然后把表单上的数据射过去 // 射过去之后,ActionForm就收集好了数据。然后会调用Action中的execute()方法 // 会把收集好的ActionForm直接传过来。所以参数中的ActionForm就是LoginForm // 造型之后就可以使用了。这样,Action就从表单上拿到了数据 // 拿到数据之后,正常情况下在Action中就应该调用模型层 LoginForm loginForm = (LoginForm) form; // 或用request.getParameter("uname")取值 // 但不建议通过request.getParameter(arg0)的方式获取表单数据 // 推荐采用ActionForm获取数据。因为ActionForm能够自动类型转换 String uname=loginForm.getUname(); String upass=loginForm.getUpass(); if("admin".equals(uname) & "jadyer".equals(upass)){ return mapping.findForward("success"); }else{ request.setAttribute("ErrorInfo", "用户名或密码不正确,请重新输入!"); //在Struts中,如果返回ActionForward,那么Struts会自动转向 //但是在这里也可以不返回ActionForward,而是由我们自己来转向 //示例如下 //response.sendRedirect(request.getContextPath() + "/login.jsp"); //return null; ActionForward af = mapping.findForward("fail"); return af; } } } //====================【关于InputForward】========================================================================== //request.removeAttribute("loginForm"); //return mapping.getInputForward();//返回原页面。即得到的数据是从哪个页面输入的,就返回到哪个页面去 //即:首先移除loginForm属性,然后return mapping.getInputForward(); //这里的loginForm就是struts-config.xml中的<action>标记中的loginForm属性 //就好比是网站中的返回,返回到原来的页面,但不显示之前所输入的数据 //否则在【后退】的时候,信息仍然存在 //====================【关于DynaActionForward】===================================================================== //@Override //public ActionForward execute(ActionMapping mapping, ActionForm form, // HttpServletRequest request, HttpServletResponse response){ // String page = request.getParameter("page");//从前台页面获取的page参数 // ActionForward af = new ActionForward(); // af.setPath("/page" + page + ".jsp?name=Stone"); // af.setRedirect(true); // //或简写为ActionForward af = new ActionForward("/page" + page + ".jsp?name=Stone", true); // return af; //} //所谓的动态ActionForward就是自己New一个ActionForward,然后自己赋值 //动态ActionForward的一个好处就是:可无限制的添加参数。比如这里的【?name=Tom】 //所以说,动态ActionForward可以在运行期被修改,而静态ActionForward是不允许修改参数的 //通过本人实际测试得知:静态ActionForward确实是不允许传参的,否则会报告空指针错误 //以下两行是本人的测试代码 //return mapping.findForward("success"); //<forward name="success" path="/loginSuccess.jsp?sdf=sfsdf" redirect="true"/> //但是当所重定向的是一个*.do的请求时,是可以正常转过去的,不会报错,代码如下所示 //<forward name="success" path="/mustlogin.do?command=list&pageNo=1" redirect="true"/> //================================================================================================================

最后是用到的资源文件ApplicationResources.properties

#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net) # Resources for parameter 'com.jadyer.struts.ApplicationResources' # Project struts1_demo #ner = /u8F93/u5165/u6709/u8BEF ner = input is error

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值