Struts2 基础笔记

来源:互联网 发布:淘宝产品推广 编辑:程序博客网 时间:2024/05/18 00:16

简介:

  

    最近学习了一下Struts2,我又是一个不愿意背的人,所以写点东西留下来,方便以后自己用到时回忆。


    因为我比较喜欢在代码中对程序进行注视,所以乍一看代码感觉会多。

    注视当中有容易出错的地方的提醒,也有函数解释,所以会显得很罗嗦。

    为了让例子以后也可以正常运行,所以没有做DB操作.好吧,我承认我是因为懒得意


    涉及到的内容有:

  1. 通过xml配置文件来实现
  2. 数据校验validation
  3. 注解方式的实现
  4. 响应流程


    失败的地方:

              jsp 传 list 类型的数据到 action 的方法没有实现。


需要的lib有:

struts2版本:struts-2.3.1.2



源代码:

  1. 在 web.xml 中添加如下代码。作用是当url地址改变时就扫描struts.xml。

<filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class><!-- 这里会调用默认地址:/WEB-INF/classes下的struts.xml --></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping>


       2.   在WEB-INF/classes/struts.xml中

<?xml version="1.0" encoding="UTF-8" ?>  <!DOCTYPE struts PUBLIC      "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"      "http://struts.apache.org/dtds/struts-2.0.dtd"><struts><!--1. package name: 名字可以随便起2. namespace: 可删除。在这里jsp的action为"/Login/*.action"。添加原因为区分action如果删除了的话,那么action为"*.action"即可3. extends: 继承的父package名称4. action name:acntio的名字(2.中写的jsp的action中的*部分)5. class:执行该action的class文件路径6. result name:action的class返回的结果。根据返回结果跳到不同页面更加相信内容请看:http://hi.baidu.com/ehols/blog/item/1f15aa444a8fa481b3b7dcec.html --><package name="ASD" namespace="/Login" extends="struts-default"><action name="login" class="com.action.LoginAction"><result name="success">/WEB-INF/main.jsp</result><result name="fail">/fail.jsp</result><!-- input为Struts2自带表单验证validate(本例子中为LoginAction-validation.xml)验证失败后返回值 --><result name="input">/index.jsp</result></action></package></struts>


关于这个部分更详细的解释可以看:点击打开链接


       3.   index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%><%@ taglib prefix="s" uri="/struts-tags"%><html><head><title>登陆界面</title><!-- 定义CSS,使错误信息以红色进行显示 --><style type="text/css">.label {font-style: italic;}.errorLabel {font-style: italic;color: red;}.errorMessage {font-weight: bold;color: red;}</style></head><body>请输入以下信息:<br /><!-- 在这里不要写成 <s:form action="/Login/login" >  这样写运行时将会报一大堆警告 --><s:form name="loginForm" action="login" namespace="/Login" method="post"><s:textfield name="id" label="用户名" /><s:password name="pwd" label="密码" /><s:submit value="登陆" /><s:reset name="重置"></s:reset></s:form></body></html>



       4.   在com.action.LoginAction中

package com.action;  import java.util.ArrayList;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import com.entity.User;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.Preparable;  public class LoginAction extends ActionSupport implements Preparable{private static final long serialVersionUID = 8740491047560899431L;private String id;  //对应页面中的s:textfield nameprivate String pwd; //对应页面中的s:textfield nameArrayList<User> userList; //所有的用户信息//该Action的业务的执行函数    public String execute() throws Exception    {    HttpServletRequest request = ServletActionContext.getRequest();           if(id.equals("mizhiwu") &&    pwd.equals("123")){        String str = "2012-2-20";    request.setAttribute("date", str);    return "success";    }    else{    return "fail";    }    }        //自定义的特殊校验类在validate.xml中写不了的话就在这写,自动加载    //validate.xml讲解请看下面        public void validate(){    if(!id.equals("mizhiwu")){    this.addFieldError("id","用户名请输入 mizhiwu");    }    if(!pwd.equals("123")){    this.addFieldError("pwd","密码请输入 123");    }    }        //在表单验证(validate)中需要用到get方法public String getId() {return id;}public String getPwd() {return pwd;}//jsp页面跳到这里后,set方法首先自动调用,加载jsp页面的值    //即使标签为<input type="text" name="id" >标签的也可以通过这样获得public void setId(String id) {this.id = id;}public void setPwd(String pwd) {this.pwd = pwd;}//可以使该Action跳转后的页面可以通过<s:iterator value="userList" var="var">直接获得public ArrayList<User> getUserList() {return userList;}public void setUserList(ArrayList<User> userList) {this.userList = userList;}//继承Preparable后必须实现的函数//prepare函数先于validate实现//实现理由是:保存原数据,有益于用户体验//不适用的后果:如果validation验证失败,那么返回登陆页面时,//      之前的用户名,密码等数据将全部丢失,用户必须重新填写//函数内要做的内容:首先get数据,并重新set一下。并把页面加载时都要做的事放在该函数中public void prepare() throws Exception {//该页面加载时总是要做的事--获得所有用户信息(模拟)ArrayList<User> userList = new ArrayList<User>();User user1 = new User("id1","123");User user2 = new User("id2","123");userList.add(user1);userList.add(user2);setUserList(userList);//get数据String tempId = getId();//set数据,以免validation返回时数据丢失setId(tempId);}}

       5.   在com.action下,也就是与LoginAction同一个位置中,新建LoginAction-validation.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN""http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"><validators><!-- 详细部分请看:http://hi.baidu.com/cnkarl/blog/item/389d5a176c9e2412962b43a5.html --><field name="id"><field-validator type="requiredstring"><param name="trim">true</param><message>请填写用户名</message></field-validator><field-validator type="stringlength"><param name="minLength">4</param><param name="maxLength">10</param><message>用户名长度应在4到10个字符间</message></field-validator></field><field name="pwd"><field-validator type="requiredstring"><message>请填写密码</message></field-validator><field-validator type="stringlength"><param name="minLength">2</param><param name="maxLength">10</param><message>为了您账号的安全,请设置2个字母以上的密码(最长可设置10个字母)</message></field-validator></field></validators>

这是Struts2自带的validation.起好名字后将会自动调用。

正确的位置是:需要验证的Action类同一个位置。

正确的名字是:Action名字-validation.xml。

更详细的看:点击打开链接


错误提示效果:




       6.   WEB-INF/main.jsp中


<%@ page language="java" import="java.util.*" pageEncoding="GBK"%><%@ taglib prefix="s" uri="/struts-tags"%><html><head><title>主界面</title><style type="text/css">.label {font-style: italic;}.errorLabel {font-style: italic;color: red;}.errorMessage {font-weight: bold;color: red;}</style></head><body><!-- 在跳到该页面前的action(LoginAction)中,有get,set方法,就可以以"${变量名}"形式获得 -->Hello ${id}<br><br>输出所有用户(用 s:iterator):<br><!-- 获得action传来的值并利用s:iterator来输出 --><s:iterator value="userList" var="var"><li>用户名:<s:property value="#var.id" /></li><li>密码:<s:property value="#var.pwd" /></li><br></s:iterator><s:form name="mainList" action="addOneUser" namespace="/AboutUser"method="post"><!-- 下面这样是错误的! --><!-- <s:hidden name="hidUserList" value="%{userList}"></s:hidden> --><!-- 通过hidden的传值  --><s:hidden name="hidID" value="%{id}"></s:hidden><s:textfield name="nowTime" label="当前时间" value="%{#request.date}" />当前登录用户:<input type="text" name="test1"value='<s:property value="id" />' /><s:submit value="添加用户" /></s:form></body></html>


OK,如果只是想简单了解一下的话,那么到这里就可以了。你可以尝试着运行了。

到这里我们实现了最基础的部分(用户登陆以及显示主页面信息操作。其中包括传值,跳转),而且附带个页面验证功能。


到这部分,我们需要注意的一点就是validation验证失败后返回的部分。

也就是LoginAction-validation.xml验证失败后会返回登陆页面,但默认情况下,我们之前输入的用户名等数据将全部丢失。

换句话说用户一旦输入不符合规范,那么倒霉的用户就需要重新全部填写信息,重新登陆。

如果登陆不恐怖的话,想想如果这是一个申请页面,就因为身份证号少输入一位,你就要重新填写一大堆的数据,重新申请发火

为了避免这种情况,所以我们在LoginAction中实现Preparable接口的prepare函数,在该函数中把我们想要保存的值get,set一下。


也许是我刚学习的原因吧,感觉Struts2的validation很鸡肋。在这里只是学习一下。

实际应用中觉得还是使用ajax会更好更容易一些。ajax部分我会在Spring MVC 部分进行说明。


接下来我们通过annotation(注解)的方式来实现数据校验和Action管理。抛弃繁琐的xml设置。


       7.  在com.action.AddUserAction中

package com.action;import java.util.ArrayList;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import org.apache.struts2.convention.annotation.Action;import org.apache.struts2.convention.annotation.Namespace;import org.apache.struts2.convention.annotation.Result;import com.entity.User;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.Preparable;import com.opensymphony.xwork2.validator.annotations.Validations;import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;import com.opensymphony.xwork2.validator.annotations.ValidatorType;//注解方式的数据校验@Validations(requiredStrings ={@RequiredStringValidator(type = ValidatorType.FIELD,fieldName = "nowTime", message = "当前时间不能为空")})//@InterceptorRefs({//    @InterceptorRef("prepare"),//    //@InterceptorRefs("defaultStack")//})@Namespace("/AboutUser")     //指定名称空间public class AddUserAction extends ActionSupport implements Preparable{private static final long serialVersionUID = -3354842689160304136L;private String nowTime;private String hidID;ArrayList<User> userList; //所有的用户信息HttpServletRequest request = ServletActionContext.getRequest();  //注解方式的Action@Action(value = "/addOneUser", results = {@Result(name = "success", location = "/WEB-INF/addUser.jsp"),@Result(name = "fail", location = "../../fail.jsp"),@Result(name = "input",location = "../main.jsp")})public String execute()    {System.out.println("******************");System.out.println(hidID);System.out.println("******************");    return "success";    }public String getHidID() {return hidID;}public void setHidID(String hidID) {this.hidID = hidID;}public String getNowTime() {return nowTime;}public void setNowTime(String nowTime) {this.nowTime = nowTime;}public ArrayList<User> getUserList() {return userList;}public void setUserList(ArrayList<User> userList) {this.userList = userList;}public void prepare() throws Exception {//无奈的办法。。。。。不然不填写当前日期的话,validation验证失败后,main.jsp页面将没有所有用户信息。ArrayList<User> userList = new ArrayList<User>();User user1 = new User("id1","123");User user2 = new User("id2","123");userList.add(user1);userList.add(user2);setUserList(userList);}}

如果想验证一下这个注解方式的数据校验的话,只需要将当前时间框的数据去掉就可以了。


       8.  在WEB-INF/addUser.jsp中

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%><%@ taglib prefix="s" uri="/struts-tags"%><html><head><title>这是注解方式实现的</title></head><body>这是注解方式实现的<br></body></html>


至此,所有代码全部完成。

在这里可以看出,如果我们通过注解的方式来编写代码的话,我们可以不用写struts.xml,不用写validation.xml。非常的方便。


快哭了美中不足的是我在这里没有实现当添加用户时校验失败,返回到main.jsp的话,我唯一的办法就是再一次的连接数据库(模拟),

然后取出所有用户信息,进行显示。否则main.jsp显示所有用户信息界面中,将没有任何数据。

正常的话应该是AddUserAction中的prepare()函数获得main.jsp页面中的userList后重新set一下。

可是我无法实现jsp传list属性值到action当中。

可怜如果有哪位能告诉我解决方法的话在下将感激不尽。


值得说明的是,在Struts2中页面间传值通常用<s:hidden>标签传递数据。


源程序的话大家可以到: 点击打开链接  下载。

导入该程序的用户需要重新导入servlet-api包(在Tomcat的安装路径下的lib文件夹下面有)。



呼~,下面说一下响应流程。与其说是响应流程,不如说是java怎么找到的正确代码执行方式。反正我也不知道叫什么才确切。


响应流程:

  1. 首先是Index.jsp页面。并当点击登录按钮时发送“/Login/login”地址。
  2. 这时首先启动的是web.xml
  3. web.xml通过<filter-name>struts2</filter-name> 找到了/WEB-INF/classes下的struts.xml
  4. struts.xml中在第17行中找到了"/Login",在第18行找到了"login",并且找到了处理该Action的class地址“com.action.LoginAction”。
  5. LoginAction.class中执行了prepare()函数和validation校验。如果没有问题执行了execute()函数,执行业务逻辑部分。
  6. 之后LoginAction.class返回结果(如"success")。
  7. 返回到struts.xml中,在19行找到了对应的返回结果对应的页面(/WEB-INF/main.jsp).
  8. 显示/WEB-INF/main.jsp页面。


大功告成~~~~



原创粉丝点击