给Ajax请求加上".do"
来源:互联网 发布:矩阵中diag什么意思 编辑:程序博客网 时间:2024/05/17 21:59
场景:一个基于Ajax技术的Web应用,采用的是多页面方式 ,每个页面内部使用Ajax实现复杂业务逻辑之间的无刷新切换,使用了Struts来实现MVC。
问题:Ajax的请求对象是Servlet。如果一个Ajax请求对应一个Servlet服务,那么就需要创建很多个Servlet,然后还要在web.xml中添加很多的Servlet定义。我想看到的是一个比较干净的web.xml文件,就像Struts那样,只保留一个ActionServlet的配置是多么令人愉快的事情啊!
分析:Struts使用struts-config.xml文件来定义请求的Servlet的路径(不妨将Action看成是Servlet的包装)。由哪个具体的Action去执行客户端的请求,则是由org.apache.struts.action.RequestProcessor的processActionCreate()方法来决定的。具体而言,则是根据struts-config.xml文件中action的配置属性type来决定。
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
...
<action-mappings>
<action
path="/A1"
type="my.test.action.A1Action">
<forward name="SUCCESS" path="/search/A1.jsp" />
</action>
</action-mappings>
...
</struts-config>
参照Struts的源代码:
* <p>Return an <code>Action</code> instance that will be used to process
* the current request, creating a new one if necessary.</p>
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param mapping The mapping we are using
* @return An <code>Action</code> instance that will be used to process
* the current request.
* @throws IOException if an input/output error occurs
*/
protected Action processActionCreate(HttpServletRequest request,
HttpServletResponse response, ActionMapping mapping)
throws IOException {
// Acquire the Action instance we will be using (if there is one)
String className = mapping.getType(); //这里就是获取action的type属性
if (log.isDebugEnabled()) {
log.debug(" Looking for Action instance for class " + className);
}
// If there were a mapping property indicating whether
// an Action were a singleton or not ([true]),
// could we just instantiate and return a new instance here?
Action instance;
synchronized (actions) {
// Return any existing Action instance of this class
instance = (Action) actions.get(className);//根据属性选择相应的Action对象
if (instance != null) {
if (log.isTraceEnabled()) {
log.trace(" Returning existing Action instance");
}
return (instance);
}
// Create and return a new Action instance
if (log.isTraceEnabled()) {
log.trace(" Creating new Action instance");
}
try {
instance = (Action) RequestUtils.applicationInstance(className);
// Maybe we should propagate this exception
// instead of returning null.
} catch (Exception e) ...
actions.put(className, instance);
}
if (instance.getServlet() == null) {
instance.setServlet(this.servlet);
}
return (instance);
}
从Action中可以获取ActionServlet(javax.servlet.http.HttpServlet的子类)。其实,程序执行时所需的客户端参数是从Request中获取的。从Action基类给出的抽象方法execute()的参数列表可以看出:
ActionMapping mapping,
ActionForm actionForm,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
。。。
}
继承此方法可以获取到足够的信息来处理客户端的请求。
为Ajax服务的Servlet与Action的处理流程不同之处在于,前者会直接将处理的结果数据以一定的方式(比如xml或JSON格式的数据流)发送给客户端;后者会返回一个ActionForward对象,根据Action配置的forward列表来决定向客户端发送哪一个页面。因此,如果用Action来为Ajax提供服务,那么在逻辑处理结束发送结果数据的时候,应该直接通过Response将数据发送出去,而不是返回到Action的基类。Rqeuest对象可以很容易得到,因此,创建一个称为AjaxAction的类,它是Action的子类,但不返回ActionForward,而是直接输出数据流:
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForward;
public abstract class CommonAjaxAction extends Action {
public final ActionForward execute(
ActionMapping mapping,
ActionForm actionForm,
HttpServletRequest request,
HttpServletResponse response)throws Exception {
try {
//对请求的逻辑处理,获得返回数据
String data = "";
data = ajaxExecute(request);
//直接输出数据流
response.setContentType("application/x-javascript; charset=utf-8");
response.getWriter().write(data);
return null;
} finally {
...
}
}
/**
* Ajax逻辑处理
*
* 由子类执行
*
* @param request
* @throws IOException
*/
protected abstract String ajaxExecute(HttpServletRequest request) throws IOException;
}
使用实例:
创建一个名为A1AjaxAction的Action,它是CommonAjaxAction的子类:
public String ajaxExecute(HttpServletRequest request) throws IOException {
//执行业务逻辑,返回处理结果数据
A1Service service = new A1ServiceImpl();
return service.getXxx();
}
}
由于不返回ActionForward对象,因此struts-config.xml中相应的Action的forward部分就不需要了:
<action
path="/A1Ajax"
type="my.test.ajax.A1AjaxAction">
</action>
....
相应地,页面中的Ajax请求看起来就和Struts的请求一致了:
var data = ...
var url = "A1Ajax.do";
var async = true; //异步
var method = "GET";
var oj = createHttpRequest();
...
oj.open(method, url, async);
oj.send(data);
现在想想要添加一个Ajax的服务是多么简单!只要继承CommonAjaxAction类并实现ajaxExecute方法,返回你想给客户端的数据就行了。但别忘记在struts-config.xml中添加对应的action定义!再看看web.xml是多么的干净整洁 ^_^
结论:通过继承Struts的Action并作小小改造,不返回ActionForward,而直接将处理结果直接输出,形式上统一了Ajax请求和页面提交(两者都是".do"形式的请求),并且还简化了Servlet的配置。
- 给Ajax请求加上".do"
- ajax请求加上loading遮罩
- jquery给get请求加上时间戳
- 通用Servlet Ajax请求 /do 处理所有请求,反射机制
- Ajax 校验 加jQuery 给Ajax发请求完整版
- Trip: 给Requests加上协程,一百份网络请求一份时间
- 给图片加上水印
- 给图片加上水印
- 给工具栏加上背景图片
- 给xml加上头
- 给Listview加上进度条
- 给菜单加上图片
- 给figure加上title
- 给UIView加上背景图
- 给图片加上倒影
- 给程序加上皮肤
- 给ThemeButton加上图标
- 给表单加上验证
- 对JAVA学习和JAVA程序员找工作的看法
- 我修改/收藏的CSDN知识.(asp.net JavaScript)( 随时更新)
- 如何去除flash防导入密码【本站原创】
- 在C#.net中如何操作XML
- Asp.net2.0页面执行顺序
- 给Ajax请求加上".do"
- 浅析Asp.net中的Web.config文件(转载)
- IT从业人员必看的10个论坛
- 周末出动:广州石室圣心天主教堂
- 日志和时间函数设计
- 有效编写软件的75条建议
- C语言测试:想成为嵌入式程序员应知道的0x10个基本问题
- VC调用存储过程的通用方法(SQLServer篇)
- The First Day In ITS