首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

《Struts2深入详解》札记-第三章 由“登录开始”

2012-11-10 
《Struts2深入详解》笔记--第三章 由“登录开始”1、使用领域对象来接收用户输入【工程1:sx_ch0301】:User对象中

《Struts2深入详解》笔记--第三章 由“登录开始”
1、使用领域对象来接收用户输入

【工程1:sx_ch0301】:

User对象中包含两个字段:username和password,在Action中有一个User对象user,则在jsp中:

<input type="text" name="user.username"><input type="password" name="user.password">

?来进行数据绑定。

当Struts2尝试设置user对象的username属性时,将依次调用以下的方法:

action.getUser();action.setUser(new User());action.getUser().setUserName();

Struts2首先尝试获得User对象的引用,当它发现User对象为null时,它将使用User类的默认构造方法创建一个User实例,并调用action的setUser()方法设置这个实例。这样,Struts2就可以设置Usser对象的username字段了。

?

在Struts2中,自动实例化对象的特性对于任意层次的对象包含关系都是适用的。

?

例如, user.address.street这样的表达式会调用:

getUser().getAdderss().setStreet(...);

?Struts2会先创建User对象,接着创建Address对象,然后设置Address对象的street属性。

?

2、使用ModelDriver action
【工程2:sx_ch0302】:

LoginAction 类实现了 ModelDriven 接口:(注意要实例化 User 对象,否则在 getModel() 时会取不到对象。)

public class LoginAction implements Action, ModelDriven<User> {        private User user = new User();    @Override    public User getModel() {         return user;    }}

在login.jsp页面中,表单字段就不需要再使用“user.”前缀了:

<input type="text" name="username"><input type="password" name="password">

在sucess.jsp页面中,表单字段也不需要再使用“user.”前缀了:

<s:property value="username" />
3、使用action的属性接收用户输入【工程3:sx_ch0303】:

在 Struts2 中,可以直接使用 action 的属性来接收用户的输入。为LoginAction添加 username 和 password 属性,同时实现这两个属性的getter和setter方法(这样可以直接删除 User 类):

?

public class LoginAction implements Action {      private String username;private String password;public String execute() throws Exception {               // 这里直接和属性比对if ("zhangsan".equals(username) && "1234".equals(password)) {return SUCCESS;} else {return ERROR;}}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;}}    
4、访问request、session和application对象

4.1 与 Servlet API 解耦的访问方式

【工程4:sx_ch0304】:
// 获得action的执行上下文ActionContext context = ActionContext.getContext();// 得到三个对象Map request = (Map)context.get("request");Map session = context.getSession();Map application = context.getApplication();// 使用三个对象// 在请求中放置欢迎信息request.put("greeting", "欢迎光临");// 在Session中保存 User 对象session.put("user", user);// 统计用户访问量,在 application 中保存用户访问量数据Integer count = (Integer) application.get("counter");if (null == count) {count = 1;} else {count++;}application.put("counter", count);

使用JSP内置的表达式语言来访问request、session和application范围的数据:

${seesionScope.user.username},${requestScope.greeting}${applicationScope.counter}
【工程5:sx_ch0305】:

利用请求对象来传递数据还有一种方式,直接使用 ActionContext 类的put()方法将数据保存到 ActionContext 中:

ActionContext.getContext().put("greeting", "欢迎光临");


然后在页面中,从请求对象中取出 greeting 属性:

${requestScope.greeting}

或者:

<%=request.getAttribute("greeting")%>
【工程6:sx_ch0306】:

通过接口注入来获取request、session和application对象,

request:实现 RequestAware 接口,实现setRequset(Map request)方法session:实现 SessionAware 接口,实现setSession(Map session)方法application:实现 ApplicationAware 接口,实现setApplication(Map application)方法
public class LoginAction implements Action, RequestAware, SessionAware,ApplicationAware {private User user = new User();private Map request;private Map session;private Map application;public void setRequest(Map request) {this.request = request;}public void setSession(Map session) {this.session = session;}public void setApplication(Map application) {this.application = application;}@SuppressWarnings("unchecked")public String execute() throws Exception {if ("zhangsan".equals(user.getUsername())&& "1234".equals(user.getPassword())) {// 在请求中放置欢迎信息request.put("greeting", "欢迎光临");// 在Session中保存 User 对象session.put("user", user);// 统计用户访问量,在 application 中保存用户访问量数据Integer count = (Integer) application.get("counter");if (null == count) {count = 1;} else {count++;}application.put("counter", count);return SUCCESS;} else {return ERROR;}}public User getUser() {return user;}public void setUser(User user) {this.user = user;}}

?

4.2 与 Servlet API 耦合的访问方式

【工程7:sx_ch0307】:

通过ServletActionContext 类来获取HttpServletRequest和ServletContext对象

HttpServletRequest:public static HttpServletRequest getRequest()ServletContext:public static ServletContext getServletContext()

注:ServletActionContext 类并没有提供直接得到 HttpSession 对象的方法,此对象可通过 HttpServletRequest 对象的 getSession() 方法来得到。

import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;import com.coderdream.model.User;import com.opensymphony.xwork2.Action;public class LoginAction implements Action {private User user = new User();@SuppressWarnings("unchecked")public String execute() throws Exception {if ("zhangsan".equals(user.getUsername())&& "1234".equals(user.getPassword())) {HttpServletRequest request = ServletActionContext.getRequest();HttpSession session = request.getSession();ServletContext context = ServletActionContext.getServletContext();// 在请求中放置欢迎信息request.setAttribute("greeting", "欢迎光临");// 在Session中保存 User 对象session.setAttribute("user", user);// 统计用户访问量,在 application 中保存用户访问量数据Integer count = (Integer) context.getAttribute("counter");if (null == count) {count = 1;} else {count++;}context.setAttribute("counter", count);return SUCCESS;} else {return ERROR;}}public User getUser() {return user;}public void setUser(User user) {this.user = user;}}
【工程8:sx_ch0308】:

还可以通过 ActionContext 类的 get() 方法,传递 ServletActionContext.HTTP_REQUEST 和 ServletActionContext.SERVLET_CONTEXT 键值来获取HttpServletRequest和ServletContext对象,同样,通过 ServletActionContext.HTTP_RESPONSE 键值来得到 HttpServletResponse 对象

?

import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;import com.coderdream.model.User;import com.opensymphony.xwork2.Action;import com.opensymphony.xwork2.ActionContext;public class LoginAction implements Action {private User user = new User();@SuppressWarnings("unchecked")public String execute() throws Exception {if ("zhangsan".equals(user.getUsername())&& "1234".equals(user.getPassword())) {ActionContext ctx = ActionContext.getContext();                       // 通过键值获得对象HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);HttpSession session = request.getSession();ServletContext context = (ServletContext) ctx.get(ServletActionContext.SERVLET_CONTEXT);// 在请求中放置欢迎信息request.setAttribute("greeting", "欢迎光临");// 在Session中保存 User 对象session.setAttribute("user", user);// 统计用户访问量,在 application 中保存用户访问量数据Integer count = (Integer) context.getAttribute("counter");if (null == count) {count = 1;} else {count++;}context.setAttribute("counter", count);return SUCCESS;} else {return ERROR;}}public User getUser() {return user;}public void setUser(User user) {this.user = user;}}
【工程9:sx_ch0309】:

最后,还可以通过 Action 类实现 ServletRequestAware 和 ServletContextAware 接口,由 Struts2 框架向 Action 实例注入 HttpServletRequest 和 ServletContext 对象:

?

import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.struts2.util.ServletContextAware;import com.coderdream.model.User;import com.opensymphony.xwork2.Action;public class LoginAction implements Action, ServletRequestAware,ServletContextAware {private User user = new User();private HttpServletRequest request;private ServletContext context;@SuppressWarnings("unchecked")public String execute() throws Exception {if ("zhangsan".equals(user.getUsername())&& "1234".equals(user.getPassword())) {HttpSession session = request.getSession();// 在请求中放置欢迎信息request.setAttribute("greeting", "欢迎光临");// 在Session中保存 User 对象session.setAttribute("user", user);// 统计用户访问量,在 application 中保存用户访问量数据Integer count = (Integer) context.getAttribute("counter");if (null == count) {count = 1;} else {count++;}context.setAttribute("counter", count);return SUCCESS;} else {return ERROR;}}public User getUser() {return user;}public void setUser(User user) {this.user = user;}public void setServletRequest(HttpServletRequest request) {this.request = request;}public void setServletContext(ServletContext context) {this.context = context;}}

?

输出结果:


《Struts2深入详解》札记-第三章 由“登录开始”

?

1 楼 netfork 2008-12-02   大哥,发这个文有什么用啊?
孙鑫的书是不错,不过有个大错误。
就是第457页,关于radio中使用freemarker的hash的内容,是错误的。
我试验了,不行,下文是正解!
http://www.iteye.com/topic/281493 2 楼 CoderDream 2008-12-02   netfork 写道
大哥,发这个文有什么用啊?孙鑫的书是不错,不过有个大错误。就是第457页,关于radio中使用freemarker的hash的内容,是错误的。我试验了,不行,下文是正解!http://www.iteye.com/topic/281493

学习笔记,很多东西对用过Struts1的人来说都是新东西,所以记录一下。 3 楼 netfork 2008-12-02   哎,javaeye管理员可能就喜欢你这样的文章~有深度,有内涵! 4 楼 ray_linn 2008-12-03   在Struts2中,自动实例化对象的特性对于任意层次的对象包含关系都是适用的 --- 你试验下包含个HashSet对象看看。 5 楼 寄生虫 2008-12-03   netfork 写道大哥,发这个文有什么用啊?
孙鑫的书是不错,不过有个大错误。
就是第457页,关于radio中使用freemarker的hash的内容,是错误的。
我试验了,不行,下文是正解!
http://www.iteye.com/topic/281493


你试试这种写法#@java.util.HashMap@{'MAN':'男','WOMEN':'女'},应该可以解决问题,不必要改代码 6 楼 netfork 2008-12-03   寄生虫 写道netfork 写道大哥,发这个文有什么用啊?
孙鑫的书是不错,不过有个大错误。
就是第457页,关于radio中使用freemarker的hash的内容,是错误的。
我试验了,不行,下文是正解!
http://www.iteye.com/topic/281493


你试试这种写法#@java.util.HashMap@{'MAN':'男','WOMEN':'女'},应该可以解决问题,不必要改代码

你的代码太丑了,如果是直接用OGNL,根本没必要那样写。
这样写即可:
http://netfork.iteye.com/blog/240868
r'#{"true":"男", "false":"女"}'

建议把下面的文章看全了,再来思考我为什么要改struts2的代码。
http://www.iteye.com/topic/281493 7 楼 xuyao 2008-12-03   最后一段代码贴错了吧 8 楼 CoderDream 2009-05-27   netfork 写道哎,javaeye管理员可能就喜欢你这样的文章~有深度,有内涵!
这个只是学习笔记!
9 楼 CoderDream 2009-05-27   xuyao 写道最后一段代码贴错了吧
已经更正,谢谢!

热点排行