动态方法调用.docx
Struts1框架提供了DispatchAction,从而允许一个Action内包含多个处理逻辑。
Struts2同样提供了这种处理多个请求的Action
比如:在一个页面上有登录和注册两个按钮,两个按钮都是提交到同一个Action进行业务处理。但处理的逻辑又完全不一样,这个时候我们就需要动态的改变URL来实现
首先我们要在JSP页面做点手脚,
先看JSP页面的代码:
<%@ page language="java" contentType ="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>注册页面</title> <style> .errorMessage{color:red} </style> <script type="text/javascript"> function loginsubmit() { targetFrom = document.forms[0]; targetFrom.action = "login!login.action?model=login"; targetFrom.submit(); } </script> </head> <body style="text-align: center" > <h1>欢迎注册</h1> <hr /> <div align="center" > <s:form action ="login.action?model=regist" > <s:textfield name = "username" label = "用户名" /> <s:textfield name = "password" label = "密码"/> <s:submit value = "注册"/> <tr> <td colspan="2"> <div align="right"> <input type = "button" value = "登录" onclick="loginsubmit()"/> </div> </td> </tr> </s:form> <a href = "userList.action">查看会员信息</a> </div> </body> </html> |
在登录按钮上点击的时候触发JS函数loginsubmit()
在loginsubmit函数中 我们将form的提交路径改为了 login!login.action?model=login
详细说明下:
第一个login也就是感叹号前面的login代表的是Action的名字,既是struts.xml中定义的action
第二个login也就是感叹号后面的login代表的是Action中的login函数
.action 是action的后缀。
model=login 是带到action中的参数 在action中如果定义了变量model并且定义了model的get set 方法,就能直接取到URL中带过去的值
我们看action的代码:
package action;
import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import java.util.Map.Entry;
import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport;
import entity.User;
public class LoginAction extends ActionSupport implements ServletResponseAware {
private String username ; private String password ; private String model;// 模式判断是登录还是注册
public String getModel() { return model; }
public void setModel(String model) { this.model = model; }
public HttpServletResponse getResponse() { return response; }
public void setResponse(HttpServletResponse response) { this.response = response; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public String login() { // 取到request对象 ActionContext cxt = ActionContext.getContext(); // 全局会话对象Application 即ServletContext Map<String, Object> application = cxt.getApplication(); // HttpSession对象 Map<String, Object> session = cxt.getSession(); //先取得用户列表 TreeMap<String, User> userList = (TreeMap<String, User>) application.get("userList"); User user = findUser(userList,this.username,this.password);
cxt.put("msg", "欢迎回来,<br />" + user.getUsername()); if (null == user) { return "input"; }else { session.put("user", user); return "ok"; }
}
public String execute() { // 取到request对象 ActionContext cxt = ActionContext.getContext(); // 全局会话对象Application 即ServletContext Map<String, Object> application = cxt.getApplication(); // HttpSession对象 Map<String, Object> session = cxt.getSession();
// 在全局对象中查找 idx Integer idx = (Integer) application.get("idx"); // 如果全局对象中没有idx 初始为1 否则自加 if (idx == null) { idx = 1; } else { idx++; } // 将idx写入全局对象 application.put("idx", idx); User user = new User(); user.setUserid(flushRight('0', 15, idx.toString())); user.setUsername(this.username); user.setPassword(this.password);
TreeMap<String, User> userList = (TreeMap<String, User>) application.get("userList"); if (userList == null) { userList = new TreeMap<String, User>(); } userList.put(user.getUserid(), user); // 将当前注册者的信息添加到全局会话对象的集合中 application.put("userList", userList); // cxt.put("userList", userList); // 将当前注册者的信息写入session会话对象中 session.put("user", user);
cxt.put("msg", "恭喜!注册成功,<br />您的ID是:" + user.getUserid()); //通过实现 ServletResponseAware接口来获得response 将用户的信息写入Cookie中 String value = ""; try { value = URLEncoder.encode(getUsername(), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Cookie c = new Cookie("user", value); c.setMaxAge(60 * 60); response.addCookie(c); return "ok"; }
// 增加数据校验 public void validate() { System.out.println("校验模式:"+model); TreeMap<String, User> userList = (TreeMap<String, User>) ActionContext.getContext().getApplication().get("userList"); if (model.equals("login")) { // 登录时判断用户名和密码是否正确 if ( null == userList || null == findUser(userList, this.username, this.password)) { addFieldError("username", "用户名或密码错误"); addFieldError("password", "用户名或密码错误"); return; }
} else { // 注册时判断用户是否存在 if (userList != null && userList.containsKey(getUsername())) { addFieldError("username", "用户名" + getUsername() + "已经存在"); return; } } if (getUsername() == null || getUsername().trim().equals("")) { addFieldError("username", "用户名不能为空"); } if (getPassword() == null || getPassword().trim().equals("")) { addFieldError("password", "密码不能为空"); }
}
public User findUser(TreeMap userList, String name, String pwd) { if (null ==userList) { return null; } Iterator<Entry<String, User>> ite = userList.entrySet().iterator(); while (ite.hasNext()) { Map.Entry<String, User> entry = (Map.Entry<String, User>) ite.next(); User u = entry.getValue(); System.out.println(null != this.username); if (null != this.username && this.username.equals(u.getUsername()) && this.password != null && this.password.equals(u.getPassword())) { return u; } } return null; }
/* * c 要填充的字符 length 填充后字符串的总长度 content 要格式化的字符串格式化字符串,左对齐 */ public String flushRight(char c, long length, String content) { String str = ""; long cl = 0; String cs = ""; if (content.length() > length) { str = content; } else { for (int i = 0; i < length - content.length(); i++) { cs = c + cs; } } str = cs + content; return str; }
private HttpServletResponse response;
public void setServletResponse(HttpServletResponse response) { this.response = response; }
} |
在Login Action中有两个特别的函数
public String login()
当请求路径为login.action!login时 会调用改方法 并获取返回的字符串作为视图索引
public String execute()
当请求路径为login.action时默认调用改函数
这样我们就能动态的调用Action中的方法了。
这时在当前的这个例子中 我们在校验数据的时候就发生了变化,在注册的时候,我们要判断用户名必须不存在,而在登录的时候我们需要判断用户名和密码必须存在并且相同,这可怎么办好呢?
所以,我们就需要将URL中在做点手脚,带一个参数过来告诉Action是什么模式,因此在URL中加入了:xxxx.action?model=login 或者xxxx.action?model=regist
参数传过来后,
我们在Action中定义了
private String model;// 模式判断是登录还是注册 public String getModel() { return model; }
public void setModel(String model) { this.model = model; } |
这样Action就能为我们自动充填model的值,在判断时就能使用
if (model.equals("login")){}
if (model.equals("regist")){}
去修改下你的action和JSP试试看吧!
另外:在本例中 用到了Map接口中的TreeMap.
TreeMap和HashMap在多数方法上都基本一直,都是Key-Value 方式存储的,他们最大的区别就在于TreeMap是有序的 而HashMap是无序的。在使用过程中,如果对保存的顺序上没有特别要求的话,建议使用HashMap
当然的当然,这种需求也可以使用在Struts.xml中实现。
做法是:在Struts中定义两个Action,name不同,class相同,并为action配置method属性
看这段xml
<action name="findAll"class="action.Bom3000cAction" method="findAll"> <result>/Bom3000c/Main.jsp</result> </action> <action name="findById" class="action.Bom3000cAction" method="findById"> <result>/Bom3000c/View.jsp</result> </action> |
这样在访问findAll.action时会执行Bom3000cAction.findAll()函数
而访问findById.action时会执行Bom3000cAction. findById ()函数
以上所用到的两种方式在今后都会频繁使用,希望能多加练习