1.访问web元素,可以取得Map类型的request,session,application,真实类型为HttpServletRequest,HttpSession,ServletContext的引用。Map类型的request,session,application是依赖于Struts2容器,并只用控制反转IOC这种,而后面三个真实类型,虽然也是依赖于Struts2,可以使用获得原类型,还可以使用获取原类型加上控制反转,接下来分别介绍四种方法来访问web元素。
2.首先,新建一个struts2项目,取名为WebAttr,项目结构图如下:
然后打开index.jsp页面,修改编码格式,开始编写该页面的代码,代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form name="f" action="" method="post">
用户名:<input type="text" name="user.username">
密码:<input type="password" name="user.password"><br/>
<input type="button" value="submit1" onclick="javascript:document.f.action='login1';document.f.submit();">
<input type="button" value="submit2" onclick="javascript:document.f.action='login2';document.f.submit();">
<input type="button" value="submit3" onclick="javascript:document.f.action='login3';document.f.submit();">
<input type="button" value="submit4" onclick="javascript:document.f.action='login4';document.f.submit();">
</form>
</body>
</html>
其中我们新建一个表单,并提供两个文本输入框,用来输入用户名和密码,在action类那里进行验证是否正确,表单里有4个提交按钮,onclick属性是JavaScript代码,点击第一个提交到login1的action里去,其它的类似。
对应的struts.xml配置文件代码如下,通过不同的方式获取web元素配置也是一样,即下面介绍的四种方法的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>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.devMode" value="true"></constant>
<package name="login" namespace="/" extends="struts-default">
<action name="login*" class="com.gk.login.LoginAction{1}">
<result name="success">/user_login_success.jsp</result>
<result name="error">/user_login_error.jsp</result>
</action>
</package>
</struts>
在这个小项目中,还有一个java类User类,即JavaBean,里面提供了用户名和密码属性,和相应的Getter()和Setter()方法,放在src下的tom.xg.bean下,代码如下:
package tom.xg.bean;
public class User {
private String username;
private String password;
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;
}
}
以上的index.jsp,struts.xml以及User.java文件都是下面四种方式我们所需要的,其实还有提交成功后跳转的页面以及提交失败后跳转的页面也是一样的,在方式一中介绍。
方法一:ActionContext方式:
3.接下来介绍第一种方法,就是使用ActionContext方式,即Action上下文环境的方式,一般在Action类的构造方法,或execute()方法中获取。依赖于容器。
新建一个LoginAction1类,放在com.gk.login包下,代码如下:
package com.gk.login;
import java.util.Map;
import tom.xg.bean.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction1 extends ActionSupport {
private User user;//声明User类的对象user
//声明Map类型的三个对象,request,session,application
private Map request;
private Map session;
private Map application;
/*
* 构造方法
*/
public LoginAction1() {
//主动获取的,知道request,session,application是怎么来的
request = (Map) ActionContext.getContext().get("request");
session = ActionContext.getContext().getSession();
application = ActionContext.getContext().getApplication();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() {
if (user.getUsername().trim().equals("abc")
&& user.getPassword().equals("123")) {
//利用键值对来存放数值进去request,session,application
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
return "success";
} else {
return "error";
}
}
}
如果用户名和密码输入正确的话,跳转到user_login.success.jsp页面,代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'user_login_success.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
登录成功!<br/>
<s:property value="#request.r1"/> | <%=request.getAttribute("r1") %><br/>
<s:property value="#session.s1"/> | <%=session.getAttribute("s1") %><br/>
<s:property value="#application.a1"/> | <%=application.getAttribute("a1") %><br/>
<s:property value="#attr.r1"/><br/>
<s:property value="#attr.s1"/><br/>
<s:property value="#attr.a1"/><br/>
<s:debug></s:debug>
</body>
</html>
注:因为request,session,application对象,在struts2中将它们放在ActionContext中,因此需要使用#key来访问这些对象,即取这些对象的键,便可以取得对应键的值。
如果输入用户名和密码失败的话,跳转到user_login_error.jsp页面,代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'user_login_error.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
登录失败,请重新登录! <br>
</body>
</html>
方法二:IOC,控制反转的方式,这个是经常使用的:
4.让Action类实现RequestAware,SessionAware,ApplicationAware接口,然后重写他们的set方法(setRequest,setSession,setApplication),通过依赖注入,控制反转(原来是自己控制,现在由别人来控制值)。
新建一个LoginAction2类,代码如下:
package com.gk.login;
import java.util.Map;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;
import tom.xg.bean.User;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction2 extends ActionSupport implements RequestAware,
SessionAware, ApplicationAware {
private User user;
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
@Override
public void setApplication(Map<String, Object> application) {
// TODO Auto-generated method stub
this.application = application;
}
@Override
public void setSession(Map<String, Object> session) {
// TODO Auto-generated method stub
this.session = session;
}
@Override
public void setRequest(Map<String, Object> request) {
// TODO Auto-generated method stub
this.request = request;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() {
if (user.getUsername().trim().equals("abc")
&& user.getPassword().equals("123")) {
//依赖注入,控制反转
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
return "success";
} else {
return "error";
}
}
}
跳转jsp视图和在视图中获取相关对象与方式一相同,这里就不说了。
方法三:获取原类型:
5.获取的分别为HttpServletRequest,HttpSession,ServletContext这三个对象,依赖于容器。
新建一个LoginAction3类,代码如下:
package com.gk.login;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import tom.xg.bean.User;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction3 extends ActionSupport {
private User user;
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
public LoginAction3() {
request = ServletActionContext.getRequest();
session = request.getSession();
application = session.getServletContext();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() {
if (user.getUsername().trim().equals("abc")
&& user.getPassword().equals("123")) {
request.setAttribute("r1", "r1");
session.setAttribute("s1", "s1");
application.setAttribute("a1", "a1");
return "success";
} else {
return "error";
}
}
}
跳转视图,在视图中获取方式同方式一。
方法四:获取原类型+控制反转:
6.首先需要Action类实现ServletRequestAware接口,并重写setServletRequest()方法,获取到HttpServletRequest对象,再通过HttpServletRequest对象取HttpSession和ServletContext对象,依赖于IOC(控制反转)。
新建一个LoginAction4类,代码如下:
package com.gk.login;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import tom.xg.bean.User;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction4 extends ActionSupport implements ServletRequestAware {
private User user;
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
this.request = request;
this.session = request.getSession();
this.application = session.getServletContext();
}
public String execute() {
if (user.getUsername().trim().equals("abc")
&& user.getPassword().equals("123")) {
request.setAttribute("r1", "r1");
session.setAttribute("s1", "s1");
application.setAttribute("a1", "a1");
return "success";
} else {
return "error";
}
}
}
7.接着我们部署该项目WebAttr到Tomcat服务器上,开启Tomcat服务器,运行后如下:
输入正确的用户名abc和密码123后,分别点击下列四个提交按钮,都会出现下图的效果:
用户名或密码输入错误,点击提交按钮的话,都会出现下图的效果:
在登录成功时,有个Debug按钮,我们点击之后可以查看值栈内容和栈的上下文环境,如下图所示:
上图中的request中有我们所付给的键值对,大家可以试下,session和application里面也该有的,这里就不说了。
8.工作原理(关于LoginAction2)
(1).Struts2接收来自客户端的请求,然后根据struts.xml文件的Action配置,先new一个LoginAction对象
(2).检查该LoginAction是否实现了RequestAware接口?
(3).若实现,则调用setRequest(Map<String,Object> request)方法从Filter中读取预先配置的request的,并映射给一个Map类型的request对象,则execute()即可直接调用得到的Map类型的request。
9.下面给出上面代码的地址:http://download.csdn.net/download/u012561176/8536213 希望对大家有用!
10.以上内容是我根据老师所教的所写的,仅供大家学习参考,如有错误,请指出,谢谢!
原文:http://blog.csdn.net/u012561176/article/details/44650887