ajax相关原理
整合
* 导入jar包
struts2-json-plugin-2.1.8.1.jar
说明:
在该jar包中有struts-plugin.xml文件
<struts><package name="json-default" extends="struts-default"> <result-types> <result-type name="json" class="org.apache.struts2.json.JSONResult"/></result-types><interceptors><interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/></interceptors></package></struts>
从上述配置中可以看到
* 有一个package”json-default”,有一个自定义的结果集,该结果集处理哪些数据应该返回客户端
* 在struts的配置文件中:
所有的package应该继承json-default,result的类型应该是”json”,result没有文本值
* 在action中,所有的get方法,例如
getXxx 将会已这样的形式返回{xxx:’aaa’}
* 针对struts2与ajax结合,无论采用
但是$.ajax捕获错误在servlet能做到。因为
所以所有的struts2的错误都会走该模板页面
* 因为在ajax请求时,action会把当前请求action类中所有 getXxx(){return xx}的方法进行{xxx:’aaa’} 形式的返回.当get方法返回的不是一个数据而是一个对象(尤其是一个代理对象时,往往会导致一些莫名的异常),此时在方法上加@JSON(serialize=false)就可以忽略该方法
对上述语句详细解释
①可能有人不理解
$.ajax的回调函数种类
回调函数
如果要处理$.ajax()得到的数据,则需要使用回调函数。beforeSend、error、dataFilter、success、complete。
- beforeSend 在发送请求之前调用,并且传入一个XMLHttpRequest作为参数。
- error 在请求出错时调用。传入XMLHttpRequest对象,描述错误类型的字符串以及一个异常对象(如果有的话)
- dataFilter 在请求成功之后调用。传入返回的数据以及”dataType”参数的值。并且必须返回新的数据(可能是处理过的)传递给success回调函数。
- success 当请求之后调用。传入返回后的数据,以及包含成功代码的字符串。
- complete 当请求完成之后调用这个函数,无论成功或失败。传入XMLHttpRequest对象,以及一个包含成功或错误代码的字符串。
即:假如 后台中发生了 int = 1/0 的运行时错误.
如果是用 servlet 编写的后台处理 , servlet底层捕获了这个异常并将这个异常编写了错误代码号(如果没有记错应该是405),这样在
如果是用 action编写的后台处理 , action底层在dispatcher阶段同样捕获了相关异常(除了servlet容器异常),并导入到一个固定的模板页面,可是struts2却没有设置相应的错误代码号,因此
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException { Map<String, Object> extraContext = createContextMap(request, response, mapping, context); // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY); boolean nullStack = stack == null; if (nullStack) { ActionContext ctx = ActionContext.getContext(); if (ctx != null) { stack = ctx.getValueStack(); } } if (stack != null) { extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack)); } String timerKey = "Handling request from Dispatcher"; try { UtilTimerStack.push(timerKey); String namespace = mapping.getNamespace(); String name = mapping.getName(); String method = mapping.getMethod(); Configuration config = configurationManager.getConfiguration(); ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy( namespace, name, method, extraContext, true, false); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack()); // if the ActionMapping says to go straight to a result, do it! if (mapping.getResult() != null) { Result result = mapping.getResult(); result.execute(proxy.getInvocation()); } else { proxy.execute(); } // If there was a previous value stack then set it back onto the request if (!nullStack) { request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); } } catch (ConfigurationException e) { // WW-2874 Only log error if in devMode if(devMode) { String reqStr = request.getRequestURI(); if (request.getQueryString() != null) { reqStr = reqStr + "?" + request.getQueryString(); } LOG.error("Could not find action or result/n" + reqStr, e); } else { if (LOG.isWarnEnabled()) { LOG.warn("Could not find action or result", e); } } sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);//产生错误的模板页面,并返回到客户端 } catch (Exception e) { sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);//产生错误的模板页面,并返回到客户端 } finally { UtilTimerStack.pop(timerKey); } }