struts2 Action跳转到另外一个Action 再跳转到一个界面_百度知道
struts2 Action跳转到另外一个Action 再跳转到一个界面
jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink"><img class="ikqb_img" src="http.hiphotos://c.jpg" esrc="http.baidu:在返回后./zhidao/wh%3D600%2C800/sign=07f13ba357baa294fc6a7efce1b591a3ab8ad51f3deb48f658b.baidu。本人是菜鸟.com/zhidao/pic/item/91ef76c6a7efce1b591a3ab8ad51f3deb48f658b://a.com/zhidao/wh%3D450%2C600/sign=cc774bf3cbe060637ebe6e/c8ea15ce36d3d53924a8fcbab02f.baidu.hiphotos。另外在程序执行中.jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink"><a href="http1:在登录界面
提问者采纳
无法显示要跳转的界面是什么意思啊,你是用什么方式请求的,ajax吗
就是界面一直停留在LOGIN 界面,没有跳转到我需要的界面,但是通过FIREBUG我发现,在HTTP返回信息里,是所有的信息以及返回了,但是没有显示。。。
你可以贴下你的源码吗。。就是login界面的源码。。
应该没问题的。。。你加我,我看看。。一七五八二一五七零五
提问者评价
大哥是个热心人,非常感谢!
其他类似问题
为您推荐:
struts2的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁1.method标签
格式:&s:submit name="method:方法名" value="按钮名"&
其实很简单,举个例子说明:
(1)action类,用来处理用户请求。methodPrefixAction.java
1 package com. 2
3 public class MethodPrefixAction { 4
public String execute1(){ 5
System.out.println("execute1()....."); 6
return null; 7
public String execute2(){ 9
System.out.println("execute2().....");10
return null;11
在一个类中有两个函数,分别针对用户请求调用。
(2)struts.xml配置
1 &?xml version="1.0" encoding="GB2312" ?& 2 &!DOCTYPE struts PUBLIC 3
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 4
"http://struts.apache.org/dtds/struts-2.0.dtd"& 5
7 &struts& 8
&package name="com.action" extends="struts-default"& 9
&action name="methodAction" class="com.action.MethodPrefixAction"&10
&/action&11
&/package&12 13 &/struts&
(3)jsp文件,即用户界面层。method.jsp
1 &%@ page language="java" import="java.util.*" pageEncoding="utf-8" contentType="text/ charset=utf-8"%& 2 &%@ taglib prefix="s" uri="/struts-tags"%& 3
4 &!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"& 5 &html& 6
&title&method.jsp&/title& 8
&s:form action="methodAction"&13
&s:submit name="method:execute1" value="提交"&&/s:submit&14
&s:submit name="method:execute2" value="提交"&&/s:submit&15
&/s:form&16
&/body&17 &/html&
第13、14行是关键,根据method标签后面的方法名去调用相应的方法。
2.action标签
格式:&s:action name="actionname" executeResult="true"&
(1)ActionPrefixedAction.java
1 package com. 2
3 import org.apache.struts2.ServletActionC 4
5 public class ActionPrefixAction { 6
private S 7
public String execute()throws Exception { 8
ServletActionContext.getRequest().setAttribute("ActionString", "这是default默认返回值,假设是welcome"); 9
return "success";10
public String getMsg(){12
public void setMsg(String msg){15
this.msg =16
(2)struts.xml
1 &?xml version="1.0" encoding="GB2312" ?& 2 &!DOCTYPE struts PUBLIC 3
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 4
"http://struts.apache.org/dtds/struts-2.0.dtd"&
7 &struts& 8
&package name="com.action" extends="struts-default"& 9
&action name="actionAction1" class="com.action.ActionPrefixAction"&10
&result name="success"&success.jsp&/result&11
&/action&12
&action name="actionAction2" class="com.action.ActionPrefixAction" method="default"&13
&result name="success"&success.jsp&/result&14
&/action&15
&/package&16 17 &/struts&
(3)success.jsp用来显示结果界面
1 &%@ page language="java" import="java.util.*" pageEncoding="utf-8" contentType="text/ charset=utf-8"%& 2 &%@ taglib prefix="s" uri="/struts-tags" %& 3 &!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"& 4 &html& 5
&title&action.jsp&/title& 7
&h3&Action返回的效果-success.jsp页面&/h3&11
&s:property value="msg"/&12
&s:property value="#attr.ActionString"/&13
&/body&14 &/html&
(4)action.jsp 用户交互界面,但是这里代码比较简单,action标签相当于提交了表单,所以无需用户输入
1 &%@ page language="java" import="java.util.*" pageEncoding="utf-8" contentType="text/ charset=utf-8"%& 2 &%@ taglib prefix="s" uri="/struts-tags" %& 3 &!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"& 4 &html& 5
&title&action.jsp&/title& 7
&div&下面的action标签将会显示结果的返回界面:::&/div&11
&s:action name="actionAction1" executeResult="true"&&/s:action&13
===========================================================15
&div&下面的action标签将会显示dodefault方法的结果界面:::&/div&16
&s:action name="actionAction2" executeResult="true" ignoreContextParams="true"/&17
===========================================================19
&div&使用Action标签,但是executeResult为false,则不会显示结果界面:::&/div&20
&s:action name="actionAction2" executeResult="false"&&/s:action&21
&/body&22 &/html&
最后,配置编译后,输入 &其中Struts2Proj 是工程名。
显示结果如下:
&3.Redirect标签和Redirect-action标签
这两个标签分别用于将请求重定向到URL或Action.
格式:&s:submit name="redirect:url" value="buttonname"/&
格式:&s:submit name="redirect-action:action-name" value="buttonname"&
重定向到URL,点击按钮后,页面会重定向到指定网页,但是action按钮则重定向到指定的action,不过Redirect-action标签并不提交表单域数据。
阅读(...) 评论() 系统不会严格区分Actino里面的那个属性是用来封装请求参数的属性,那个事用来封装结果的属性,对于系统来说,封装请求参数和封装处理结果的属性石完全平等的.如果用户的HTTP请求里面包含了tip的请求参数,系统就会调用Action的void setTip(String tip)方法,通过这种方式,名为tip的请求参数就可以传给Action实例,如果Action类里面没有包含对应的方法,那么名字为tip的请求参数也就无法传入该Action. 同样,在JSP页面中输出的Action属性的时候,它也不会区分该属性是用来封装请求参数的还是用于封装处理结果的属性,所以说,使用Struts2的标签既可以输出Action的处理结果,也可以输出Http请求参数值. 从上面的代码可以看到,需要在JSP页面中输出的处理结果是一个非常简单的字符串,可以使用标签来控制输出.实际上,Action类里面可以封装非常复杂的属性,包括其他用户自己定义的属性,数组,集合对象和Map对象等等.对于这些复杂类型的输出,一样可以通过Struts2的标签来完成. 为了让用户开发的Action来更加的规范,Struts2提供了一个Action接口,这个接口定义了Struts2的Action处理类应该实现的规范,下面是Action接口的代码: public interface Action {
public static final String SUCCESS="success";
public static final String ERROR="error";
public static final String INPUT="input";
public static final String LOGIN="login";
public static final String NONE="none";
public String execute()throws E } 上面的Action接口里面只定义了一个execute方法,该接口的规范规定了Action类应该包含一个execute方法,该方法的作用是返回一个字符串,除此之外,该接口还定义了5个字符串常量,他们的作用是统一execute方法的返回值. 比如说,当Action处理完用户的请求成功之后,有人喜欢返回welcome这种字符串,有的人喜欢返回success字符串…这样不利于项目的统一管理.Struts2的Action定义上面的5个字符串:error,none,input,longin和success等等分别代表了特定的含义,当然,如果开发者依然希望使用特定的字符串做为逻辑视图的名字,开发者依然可以返回自己的视图. 另外,Struts2还提供了Action类的一个实现类:ActionSupport,下面是Action类的代码: package com.opensymphony.xwork2; import com.opensymphony.xwork2.util.ValueS import com.opensymphony.xwork2.util.logging.L import com.opensymphony.xwork2.util.logging.LoggerF import java.io.S import java.util.*; /** * Provides a default implementation for the most common actions. */ //系统提供的ActionSupport类 public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class); private final transient TextProvider textProvider = new TextProviderFactory().createInstance(getClass(), this);
private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
//收集校验错误的方法
public void setActionErrors(Collection errorMessages) {
validationAware.setActionErrors(errorMessages);
//返回校验错误的方法
public Collection getActionErrors() {
return validationAware.getActionErrors();
}
public void setActionMessages(Collection messages) {
validationAware.setActionMessages(messages);
}
public Collection getActionMessages() {
return validationAware.getActionMessages();
}
/**
* @deprecated Use {@link #getActionErrors()}.
*/
@Deprecated public Collection getErrorMessages() {
return getActionErrors();
}
/**
* @deprecated Use {@link #getFieldErrors()}.
*/
@Deprecated public Map<String, List> getErrors() {
return getFieldErrors();
//设置表单域校验错误信息
public void setFieldErrors(Map<String, List> errorMap) {
validationAware.setFieldErrors(errorMap);
//返回表单域校验错误信息
public Map<String, List> getFieldErrors() {
return validationAware.getFieldErrors();
//控制locale的相关信息
public Locale getLocale() {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
return ctx.getLocale();
} else {
LOG.debug("Action context not initialized");
}
public boolean hasKey(String key) {
return textProvider.hasKey(key);
//返回国际化信息的方法
public String getText(String aTextName) {
return textProvider.getText(aTextName);
}
public String getText(String aTextName, String defaultValue) {
return textProvider.getText(aTextName, defaultValue);
}
public String getText(String aTextName, String defaultValue, String obj) {
return textProvider.getText(aTextName, defaultValue, obj);
}
public String getText(String aTextName, List args) {
return textProvider.getText(aTextName, args);
}
public String getText(String key, String[] args) {
return textProvider.getText(key, args);
}
public String getText(String aTextName, String defaultValue, List args) {
return textProvider.getText(aTextName, defaultValue, args);
}
public String getText(String key, String defaultValue, String[] args) {
return textProvider.getText(key, defaultValue, args);
}
public String getText(String key, String defaultValue, List args, ValueStack stack) {
return textProvider.getText(key, defaultValue, args, stack);
}
public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
return textProvider.getText(key, defaultValue, args, stack);
}
public ResourceBundle getTexts() {
return textProvider.getTexts();
}
public ResourceBundle getTexts(String aBundleName) {
return textProvider.getTexts(aBundleName);
}
public void addActionError(String anErrorMessage) {
validationAware.addActionError(anErrorMessage);
}
public void addActionMessage(String aMessage) {
validationAware.addActionMessage(aMessage);
}
public void addFieldError(String fieldName, String errorMessage) {
validationAware.addFieldError(fieldName, errorMessage);
}
public String input() throws Exception {
return INPUT;
}
public String doDefault() throws Exception {
return SUCCESS;
}
/**
* A default implementation that does nothing an returns "success".
*
* Subclasses should override this method to provide their business logic.
*
* See also {@link com.opensymphony.xwork2.Action#execute()}.
* @return returns {@link #SUCCESS}
* @throws Exception can be thrown by subclasses.
*/ //默认的处理用户请求的方法,直接返回success字符串
public String execute() throws Exception {
return SUCCESS;
}
public boolean hasActionErrors() {
return validationAware.hasActionErrors();
}
public boolean hasActionMessages() {
return validationAware.hasActionMessages();
}
public boolean hasErrors() {
return validationAware.hasErrors();
}
public boolean hasFieldErrors() {
return validationAware.hasFieldErrors();
}
/**
* Clears field errors. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearFieldErrors() {
validationAware.clearFieldErrors();
}
/**
* Clears action errors. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearActionErrors() {
validationAware.clearActionErrors();
}
/**
* Clears messages. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearMessages() {
validationAware.clearMessages();
}
/**
* Clears all errors. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearErrors() {
validationAware.clearErrors();
}
/**
* Clears all errors and messages. Useful for Continuations and other situations
* where you might want to clear parts of the state on the same action.
*/
public void clearErrorsAndMessages() {
validationAware.clearErrorsAndMessages();
}
/**
* A default implementation that validates nothing.
* Subclasses should override this method to provide validations.
*/
//包含空的输入校验方法
public void validate() {
}
@Override public Object clone() throws CloneNotSupportedException {
return super.clone(); }
public void pause(String result) {
} } 正如上面的代码看到的,该Action是一个默认的Action类,该类里面已经提供了很多默认的方法,这些默认的方法包括获取国际化信息的方法,数据校验的方法,默认的处理用户请求的方法等等,实际上,ActionSupport类是Struts2默认的Action处理类,如果让开发者的Action类继承该ActionSupport来,就会大大的简化Action的开发. (当用户配置的Action类没有指定class属性的时候,系统会自动使用ActionSupport类作为默认的Action处理类) 2)
Action访问Servlet API Struts2的Action并没有直接和任何的Servlet API进行耦合,这是Struts2的一个改良之处,因为Action类不再和Servlet API耦合,就可以更加轻松的去测试该Action,就不用mock去模拟数据测试了. 但是对于web应用的控制器而言,不访问Servlet API几乎是不可能的,比如说跟踪HTTP Session的状态等等.Struts2框架提供了一种更加轻松的方式来访问Servlet API,Web应用中通常需要访问的Servlet API就是HttpServletRequest,HttpSession和HttpContext,这三个类分别代表JSP内置对象里面的request,session和application. Struts2提供了一个ActionContext类,Struts2的Action可以通过该类来访问Servlet API,下面是ActionContext类中包含的几个常用的方法: l
Object get(Object key):该方法类似于调用HttpServletRequest的getAttribute(String name)方法. l
Map getApplication():返回一个Map对象,该对象模拟了该应用的ServletContext实例. l
static ActionContext getContext():静态方法,获取系统的ActionContext实例. l
Map getParameters():获取所有的请求参数,类似于调用HttpServletRequest对象的getParameterMap方法. l
Map getSession():返回一个Map对象,这个Map对象模拟了HttpSession实例. l
void setApplication(Map application):直接传入一个Map实例,将该Map实例里面的key-value对转换成application的属性名属性值. l
void setSession(Map session):直接传入一个Map实例,将该Map实例里面的key-value对转换成session的属性名和属性值. 下面的一个应用将在Action类中通过ActionContext访问ServletAPI: ①
系统提交请求到LoginAction,LoginAction的代码如下: package com.supermos.app.A import com.opensymphony.xwork2.A import com.opensymphony.xwork2.ActionC public class LoginAction implements Action{
private S
private S
public String getUsername() {
public void setUsername(String username) {
this.username =
public String getPassword() {
public void setPassword(String password) {
this.password =
public String execute(){
//获取ActionContext实例,通过该实例访问Servlet API
ActionContext ctx=ActionContext.getContext();
//获取ServletContext里面的counter属性
Integer counter=(Integer)ctx.getApplication().get("counter");
//如果counter的属性为空,就设置该counter的属性为1
if(counter==null){
counter=1;
//否则,将counter加1
else{
counter=counter+1;
//将增加1之后的counter的值设置为counter属性
ctx.getApplication().put("counter", counter);
//将登陆用的username属性设置为一个HttpSession属性
ctx.getSession().put("user",this.getUsername());
if("supermos".equalsIgnoreCase(this.getUsername())&&"ziwen".equalsIgnoreCase(this.getPassword())){
//直接设置HttpServletRequest属性,下面的代码的作用类似于设置HttpServletRequest属性
//request.setAttribute("tip","服务器提示,您已经成功登陆");
ctx.put("tip", "服务器提示,您已经成功登陆");
return this.SUCCESS;
}else{
//直接设置HttpServletRequest属性
ctx.put("tip","服务器提示,您登陆失败,请检查您的用户名和密码");
return this.ERROR;
} } ②
上面的Action访问了HttpServletRequest的属性,也访问了HttpSession的属性,还让问了HttpContext的属性,将该Action配置在struts.xml文件中,struts.xml文件的代码如下:
本站的访问次数为:${applicationScope.counter}
${sessionScope.user },您已经登录!
${requestScope.tip }
</body> 显然,相比Struts1中直接访问ServletAPI,Strut2通过ActionContext访问ServletAPI更加的优雅,让Action彻底从ServletAPI中分离出来,从而可以允许该Action脱离web容器.最大的好处就是可以脱离web容器测试Action. 3)
Action直接访问ServletAPI 虽然Struts2提供了ActionContext来访问ServletAPI,但是这种方式毕竟不能够直接获得ServletAPI的实例,为了在Action中直接访问ServletAPI,Struts2还提供了如下的几个接口: l
ServletContextAware:实现该接口的Action可以直接访问Web应用的ServletContext实例.(aware[əˈwɛə]意识到的,知道的) l
ServletRequestAware:实现该接口的Action可以直接访问服务器相应的HttpServletRequest实例 l
ServletResponseAware:实现该接口的Action可以直接访问服务器相应的HttpServletResponse实例. 下面以ServletResponseAware为例子,介绍如何在Action中访问HttpServletResponse对象,本应用通过HttpServletResponse为系统添加Cookie对象.下面是该上面例子的Action的修改: package com.supermos.app.A import javax.servlet.http.C import javax.servlet.http.HttpServletR import org.apache.struts2.interceptor.ServletResponseA import com.opensymphony.xwork2.A import com.opensymphony.xwork2.ActionC public class LoginAction implements Action,ServletResponseAware{
//需要访问的HttpServletResponse对象
private HttpServletR
private S
private S
public String getUsername() {
public void setUsername(String username) {
this.username =
public String getPassword() {
public void setPassword(String password) {
this.password =
//实现ServletResponseAware接口所必须要实现的一个方法
public void setServletResponse(HttpServletResponse response) {
//在该方法内就可以访问web应用对客户的响应对象
this.response =
public String execute(){
//获取ActionContext实例,通过该实例访问Servlet API
ActionContext ctx=ActionContext.getContext();
//获取ServletContext里面的counter属性
Integer counter=(Integer)ctx.getApplication().get("counter");
//如果counter的属性为空,就设置该counter的属性为1
if(counter==null){
counter=1;
//否则,将counter加1
else{
counter=counter+1;
//将增加1之后的counter的值设置为counter属性
ctx.getApplication().put("counter", counter);
//将登陆用的username属性设置为一个HttpSession属性
ctx.getSession().put("user",this.getUsername());
if("supermos".equalsIgnoreCase(this.getUsername())&&"ziwen".equalsIgnoreCase(this.getPassword())){
//直接设置HttpServletRequest属性,下面的代码的作用类似于设置HttpServletRequest属性
//request.setAttribute("tip","服务器提示,您已经成功登陆");
ctx.put("tip", "服务器提示,您已经成功登陆");
//创建一个user对象
Cookie c=new Cookie("user",this.getUsername());
//设置cookie对象的最大的生存时间
c.setMaxAge(60*60);
//使用HttpServletResponse来添加Cookie对象
response.addCookie(c);
return this.SUCCESS;
}else{
//直接设置HttpServletRequest属性
ctx.put("tip","服务器提示,您登陆失败,请检查您的用户名和密码");
return this.ERROR;
} } 通过查看Struts2的API的相关文档,发现,实现ServletResponseAware,仅仅需要实现如下的方法: public void setServletResponse(HttpServletResponse response) 实现了上面的方法的时候,该方法内有一个HttpServletResponse参数,该参数就代表了web应用中对客户端的一个相应对象,并将该对象设置成Action的成员属性,从而允许在execute方法中访问该HttpServletResponse对象. 于此类似的是,如果一个Action实现了ServletRequestAware接口,就必须要实现如下的方法: public void setServletRequest(HttpServletRequest request) 通过实现上面的方法,从而允许Action直接访问HttpServletRequest对象. 为了直接访问ServletAPI,Struts2提供了一个ServletActionContext,这个类包含了以下几个静态的方法: l
static PageContext getPageContext():取得Web应用的PageContext对象. l
static HttpServletRequest gettRequest():取得Web应用的HttpServletRequest对象 l
static HttpServletResponse getResponse():取得Web应用的HttpServletResponse对象. l
static ServletContext getServletContext():取得Web应用的ServletContext对象 借助于ServletActionContext这个类的帮助,开发者也可以直接在Action中直接访问ServletAPI,却可以避免Action类需要实现XXXAware接口-虽然如此,但该Action却依然需要与ServletAPI直接耦合,一样不利于程序的解耦. (可以通过ServletActionContext类的帮助,从而以更加简单的方式来直接的访问ServletAPI) 当该Action处理完用户的请求之后,web应用就向客户机中添加了一个Cookie对象下面的JSP页面通过表达式来访问Cookie的值,该JSP页面的代码如下:
本站的访问次数为:${applicationScope.counter}
${sessionScope.user },您已经登录!
${requestScope.tip }
============传说中的分割线,以下为了验证Cookie===============
从系统中读取的Cookie值:${cookie.user.value}
</body> 必须应该指出的问题是,虽然可以在Action中获取HttpServletResponse,但是如果希望HttpServletResponse来生成服务器相应是不可能的,因为Action只是控制器,也就是说,如果在Action中书写如下的代码response.getWriter().println(“Helloworld”);上面的代码在标准的Servlet中会生成对客户端的输出,但是在Struts2的Action中,就没有任何的实际意义了. (提示:即使我们在Struts2的Action类中获得了HttpServletResponse的对象,也不要尝试直接在Action中生成对客户端的输出.!!!!) 4) 配置Action 一旦提供了Action的实现类之后,我们就可以在struts.xml当中对该Action进行配置,配置Action就是让Struts2容器知道该Action的存在,并且可以调用该Action来处理用户的请求,因此,我们认为,Action是Struts2的基本”程序单位”. Struts2使用包来组织Action,因此将Action定义是放在包定义下面来完成的,定义Action通过使用package下的action子元素来完成,定义Action的时候,至少需要制定该Action的name属性,该name属性既是该Action的名字,也是该Action需要处理的URL的前半部分. (Struts2的Action名字就是它所要处理的URL的前半部分,与Struts1不同,Struts1中Action配置中的name属性指定的是该Action关联的ActionForm,而path属性才是该Action要处理的URL,可以理解,Struts2中的Action的name属性就等同于Struts1中Action的path属性) 除此之外,通常还要为action指定一个class属性,其中class属性指定了改Action的实现类. (该class属性并不是必需的,如果我们不为元素指定class属性,系统就会默认使用系统的ActionSupport类来进行处理) 因此,一个Action的配置片段如下:
Action只是一个控制器,它并不直接对浏览者产生任何的响应,因此Action处理完用户的请求之后,Action需要将制定的视图资源呈现给用户.因此配置Action的时候,应该配置逻辑视图和物理视图资源之间的映射. 配置逻辑视图和物理视图之间的映射关系是通过元素来定义的,每个元素定义逻辑视图和物理视图之间的一次映射关系. 完整的Action配置定义如下: action=”ActionName!methodName.action” 单机”注册”按钮的时候将会激发regist函数,该函数的代码如下: function regist(){
//获取JSP页面中一个表单元素
targetForm=document.forms[0];
//东该修改目标表单的action属性
targetForm.action=”Login!regist.action”;
//提交表单 targetForm.submit(); } 上面JavaScript代码的核心在于动态的修改表单元素的Action属性,修改之后action属性为Login!regist.action,其实质就是将该表单提交给loginAction的regist方法进行处理. LoginAction的代码如下: package com.supermos.app.A import javax.servlet.http.C import javax.servlet.http.HttpServletR import org.apache.struts2.interceptor.ServletResponseA import com.opensymphony.xwork2.A import com.opensymphony.xwork2.ActionC public class LoginAction implements Action,ServletResponseAware{
//需要访问的HttpServletResponse对象
private HttpServletR
private S
private S
private S
public HttpServletResponse getResponse() {
public void setResponse(HttpServletResponse response) {
this.response =
public String getTip() {
public void setTip(String tip) {
this.tip =
public String getUsername() {
public void setUsername(String username) {
this.username =
public String getPassword() {
public void setPassword(String password) {
this.password =
//实现ServletResponseAware接口所必须要实现的一个方法
public void setServletResponse(HttpServletResponse response) {
//在该方法内就可以访问web应用对客户的响应对象
this.response =
public String regist(){
ActionContext.getContext().getSession().put("user", this.getUsername());
this.setTip("恭喜您"+this.getUsername()+",您注册成功了");
return this.SUCCESS;
public String execute(){
//获取ActionContext实例,通过该实例访问Servlet API
ActionContext ctx=ActionContext.getContext();
//获取ServletContext里面的counter属性
Integer counter=(Integer)ctx.getApplication().get("counter");
//如果counter的属性为空,就设置该counter的属性为1
if(counter==null){
counter=1;
//否则,将counter加1
else{
counter=counter+1;
//将增加1之后的counter的值设置为counter属性
ctx.getApplication().put("counter", counter);
//将登陆用的username属性设置为一个HttpSession属性
ctx.getSession().put("user",this.getUsername());
if("supermos".equalsIgnoreCase(this.getUsername())&&"ziwen".equalsIgnoreCase(this.getPassword())){
//直接设置HttpServletRequest属性,下面的代码的作用类似于设置HttpServletRequest属性
//request.setAttribute("tip","服务器提示,您已经成功登陆");
ctx.put("tip", "服务器提示,您已经成功登陆");
//创建一个user对象
Cookie c=new Cookie("user",this.getUsername());
//设置cookie对象的最大的生存时间
c.setMaxAge(60*60);
//使用HttpServletResponse来添加Cookie对象
response.addCookie(c);
return this.SUCCESS;
}else{
//直接设置HttpServletRequest属性
ctx.put("tip","服务器提示,您登陆失败,请检查您的用户名和密码");
return this.ERROR;
} } 当浏览者点击”注册”按钮的时候,系统将提交给login Action的regist方法处理.通过这种方式,我们可以再一个Action中包含多个处理逻辑,并可以通过为表单元素指定不同的action属性来提交给Action的不同的方法. 对于使用动态方法调用的方法,比如说regist方法,该方法的方法声明与系统默认的execute方法的方法声明只有方法名字不相同,其他的比如方法的参数,返回值的类型都应该绝对的相同. (使用动态方法调用前必须设置Struts2允许动态方法调用,开启系统的动态方法调用是通过设置struts.enable.DynamicMethodInvocation常量来完成的,设置该常量的值为true将开启动态方法调用,否者将关闭动态方法调用) 6) 为action元素指定method属性 对于一个表单中有含有两个不同的按钮,分别提交给不同的处理逻辑的情况下,Struts2还提供了一种另外的方法,即将一个Action处理类定义成多个逻辑Action.如果在配置元素的时候,指定action的method属性,则可以让Action类调用指定方法,而不是execute方法来处理用户的请求. 比如说,我们可以有如下的配置片段:
/success.jsp
/error.jsp
/login.jsp
(代码中是name=”*Action”不要写成了”*Action.action”…..日) 上面的不是定义了一个普通的Action,而是定义了一系列的逻辑Action—只要用户请求的URL是*Action.action的模式,都可以通过该Action类来进行处理.配置该action元素的时候,还制定method属性(method属性用于指定处理用户请求的方法),但该method属性使用了一个表达式{0},该表达式的值就是name属性值中第一个*的值.例如,如果用户请求的URL为loginAction.action,则调用com.supermos.app.Action.LoginAction的login方法,如果请求URL为registAction.action,这调用的是com.supermos.app.Action.LoginAction的regist方法. 下面是本应用的LoginAction类的代码: package com.supermos.app.A import javax.servlet.http.C import javax.servlet.http.HttpServletR import org.apache.struts2.interceptor.ServletResponseA import com.opensymphony.xwork2.A import com.opensymphony.xwork2.ActionC public class LoginAction implements Action,ServletResponseAware{
//需要访问的HttpServletResponse对象
private HttpServletR
private S
private S
private S
public HttpServletResponse getResponse() {
public void setResponse(HttpServletResponse response) {
this.response =
public String getTip() {
public void setTip(String tip) {
this.tip =
public String getUsername() {
public void setUsername(String username) {
this.username =
public String getPassword() {
public void setPassword(String password) {
this.password =
//实现ServletResponseAware接口所必须要实现的一个方法
public void setServletResponse(HttpServletResponse response) {
//在该方法内就可以访问web应用对客户的响应对象
this.response =
public String regist(){
ActionContext.getContext().getSession().put("user", this.getUsername());
this.setTip("恭喜您"+this.getUsername()+",您注册成功了");
return this.SUCCESS;
public String login(){
//获取ActionContext实例,通过该实例访问Servlet API
ActionContext ctx=ActionContext.getContext();
//获取ServletContext里面的counter属性
Integer counter=(Integer)ctx.getApplication().get("counter");
//如果counter的属性为空,就设置该counter的属性为1
if(counter==null){
counter=1;
//否则,将counter加1
else{
counter=counter+1;
//将增加1之后的counter的值设置为counter属性
ctx.getApplication().put("counter", counter);
//将登陆用的username属性设置为一个HttpSession属性
ctx.getSession().put("user",this.getUsername());
if("supermos".equalsIgnoreCase(this.getUsername())&&"ziwen".equalsIgnoreCase(this.getPassword())){
//直接设置HttpServletRequest属性,下面的代码的作用类似于设置HttpServletRequest属性
//request.setAttribute("tip","服务器提示,您已经成功登陆");
ctx.put("tip", "服务器提示,您已经成功登陆");
//创建一个user对象
Cookie c=new Cookie("user",this.getUsername());
//设置cookie对象的最大的生存时间
c.setMaxAge(60*60);
//使用HttpServletResponse来添加Cookie对象
response.addCookie(c);
return this.SUCCESS;
}else{
//直接设置HttpServletRequest属性
ctx.put("tip","服务器提示,您登陆失败,请检查您的用户名和密码");
return this.ERROR;
} } 上面的Action类不再包含默认的execute方法,而是包含了regist和login两个方法,这两个方法与execute方法除了方法名字不相同之外,其他的完全相同. 我们修改JavaScript中regist函数的代码为如下的形式:
<script type="text/javascript">
function regist(){
//获取页面中的第一个表单元素
var form=document.forms[0];
//动态修改表单的action属性
form.action="registAction.action";
//提交表单
form.submit();
</script> 在上面的方法中看到,当浏览者单击”注册”按钮的时候,动态修改表单的action属性为registAction.action,该请求匹配了*Action的形式,将交给Action处理:registAction匹配*Action模式的时候.*的值为regist,则调用regist方法来处理用户的请求. 除此之外,表达式也可以出现在元素的class属性当中,也就是Struts2允许将一系列的Action配置成一个元素. 看下面的struts.xml配置文件的片段: 上面的定义片段定义了一个模式为*_*的Action,也就是说,只要匹配该模式的请求,都可以被该Action处理.如果有URL为Book_save.action的请求,因为匹配了*_*的模式,并且第一个*的值为Book,第二个*的值为save,就意味着可以调用Book处理类的save方法来处理用户的请求. 实际上Struts2不仅允许在class属性,name属性中使用表达式,还可以在元素的result子元素中使用表达式,下面提供了一个通用Action,该Action可以配置成如下的形式:
/{1}.jsp
在上面的Action的定义中,Action的名字是一个*,它可以匹配任意的Action.所有的用户请求都可以通过该Action来进行处理,因为没有为该Action指定class属性,也就是说该Action使用ActionSupport来作为处理类,而且因为该ActionSupport类的execute方法返回success字符串,即该Action总是直接返回result中指定的JSP资源,JSP资源使用了表达式来生成资源名,上面的Action定义的含义是: 如果请求a.action,则进入a.jsp,如果请求b.action则进入b.jsp页面,以此类推. 现在的问题是,当用户请求的URL同时匹配多个Action的时候,究竟由哪个Action来进行处理? 不如说,现在有URL为abcAction.action的请求,在Struts.xml文件中配置了如下的三个Action,他们的Action name的值分别为abcAction,*Action还有*,则这个请求名将被abcAction的Action进行处理. 如果有URL为defAction.action的请求,struts.xml文件中同样配置了abcAction,*Action和*的一个Action,defAction.action的请求显然不会被name为abcAction的Action处理,到底是被name为*Action处理还是被*的Action来处理呢? 如果有URL为abcAction.action的请求,如果struts.xml文件中没有名为abcAction的Action,则一定由该Action来处理用户请求:如果struts.xml文件中没有名为abcAction的Action,则搜寻name属性值匹配abcAction的Action,例如name为*Action或者*,*Action并不会比*更加优先匹配abcAction的请求,而是先找到那个Action,就先有那个Action来处理用户的请求. (因为除非请求的URL与Action name属性绝对相同,否则将按照先后顺序来决定哪个Action来处理用户的请求,因此,我们在写配置文件的时候,要尽量将*的Action配置到最后,否者Struts2将使用该Action来处理所有希望使用模式匹配的请求) 8) 默认的Action 在某些情况下,用户请求非常简单,不需要系统过多的处理,或者这些请求只是一个简单的转发作用. (提示: 对于使用Struts2框架的应用而言,尽量不要让超级链接直接连接到某个视图资源,因为这种方式增加了额外的风险,推荐将所有的请求都发送给Struts2框架,让该框架来处理用户的请求,哪怕是只是简单的超级链接). 对于只是简单的超级链接的请求,可以通过定义name为*的Action(该Action应该放在最后定义)实现,除此之外,Struts2还允许在容器中定义一个默认的Action,当用户的请求的URL在容器中找不到对应的Action的时候,系统将使用默认的Action来处理用户的请求. 配置默认的Action通过元素完成,每个元素配置一个默认Action下面的struts.xml配置片段配置了一个默认的Action.
从上面的配置文件就可以看到,配置默认的Action只需要配置元素就可以了,配置该元素的时候需要指定一个name属性,该name属性指向容器中另外一个有效的Action,该Action将成为该容器中默认的Action. 分类: |