Struts中虽然提供了10种内置的结果类型,但是对于多变的需求,往往还是不够用的,所幸的是Struts支持结果类型的自定制,这允许开发人员去拓展结果类型来完成自己需要的而Struts又完成不了的功能。在开始了解自定制结果类型之前,需要知道-Struts中的10种内置的结果类型都是直接或者间接地实现了Result接口。现在在很多的开发框架中,都不会让开发人员去直接实现一个接口,而是选择了为这个接口提供简单的实现,开发人员只需要继承这个简单实现,覆写里面特定的方法来完成自己需要的功能。Struts为Result接口提供了一个简单实现-StrutsResultSupport,因此,在开发自定制结果类型的时候,不需要直接去实现Result接口,只需要直接继承StrutsResultSupport接口来间接实现Result接口就可以了。当然,你也可自己去实现Result接口。
Result接口
这个接口的原型如下:
public abstract interface Result extends Serializable
{
public abstract void execute(ActionInvocation paramActionInvocation)
throws Exception;
}
ActionInvocation这个变量参数,你可以从中得到当前的Action对象实例和Result对象实例,以及当前的ActionContext对象。如果要对Action实例做点事情,建议还是从Interceptor拦截器那块儿去做,在这里只需要做动作成功执行后,结果负责返回什么样的视图。
StrutsResultSupport抽象类
如果你的结果继承这个抽象类,那么你的结果能够支持以下两个功能:
- 在配置文件中使用变量给location参数传值,Struts会自动帮助你计算出真正的location参数值
- 可以将传递的参数编码
这个类中的四个私有成员比较重要,它们分别如下:
location:String | 代表动作成功执行之后,跳转到一个url作为视图,此时url未经过转换 |
parse:boolean | 是否将location参数进行转换,默认值为true |
encode:boolean | 是否将参数进行编码,默认值为false;如果要对参数编码,必须同时设置parse=true |
lastFinalLocation:String | 代表转换过之后的location值 |
protected abstract void doExecute(String paramString, ActionInvocation paramActionInvocation)
throws Exception;
注册自己结果类型
在struts.xml文件中,某一个package元素下,注册自己的结果类型
<result-types>
<result-type name="resultName" class="resultClass"/>
</result-types>
注册完之后,就可以在自己的动作类中使用自己定制的结果类型了。
自定制结果类型的一个例子
下面是一个例子,返回的是视图是jpg格式的图片。
结果类MyResult
@SuppressWarnings("serial")
public class MyResult extends StrutsResultSupport {
@Override
protected void doExecute(String arg0, ActionInvocation arg1)
throws Exception {
// TODO Auto-generated method stub
ActionContext context = arg1.getInvocationContext();
HttpServletResponse response = (HttpServletResponse) context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
ServletContext servletContext = (ServletContext)context.get("com.opensymphony.xwork2.dispatcher.ServletContext");
response.setContentType("image/jpeg");
OutputStream os = response.getOutputStream();
InputStream is = servletContext.getResourceAsStream("/images/01.jpg");
byte[] buffer = new byte[1024];
int len = -1;
while((len = is.read(buffer)) != -1)
{
os.write(buffer, 0, len);
}
os.flush();
os.close();
}
}
要获取常用的HttpServletRequest、HttpServletResponse、HttpSession、ServletContext对象,从ActionContext中得到,调用ActionContext.get(String name)就可以得到。像我在上述的代码中一样,不过,还可以使用这些常量:HTTP_REQUEST、HTTP_RESPONSE、HTTP_SESSION、SERVLET_CONTEXT作为查找键。
在struts.xml中注册
<package name="default" namespace="/" extends="struts-default">
<result-types>
<result-type name="image" class="com.daniel.results.MyResult"/>
</result-types>
<action name="image" class="com.daniel.action.ImageAction">
<result type="image">/index.jsp</result>
</action>
</package>
总结
结果类型的自定制很少有讲解的例子,本人也不清楚其在项目中的具体使用,如果有熟悉的大牛,可以推荐给我一些资料。