Struts2 ajax的应用及其异常捕获缺点

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结合,无论采用 .post .ajax都捕获不到服务器产生的错误,这点struts2内部设计的不是很好
但是$.ajax捕获错误在servlet能做到。因为
所以所有的struts2的错误都会走该模板页面
* 因为在ajax请求时,action会把当前请求action类中所有 getXxx(){return xx}的方法进行{xxx:’aaa’} 形式的返回.当get方法返回的不是一个数据而是一个对象(尤其是一个代理对象时,往往会导致一些莫名的异常),此时在方法上加@JSON(serialize=false)就可以忽略该方法


对上述语句详细解释

①可能有人不理解 .post() .ajax()有什么区别.
这里写图片描述


$.ajax的回调函数种类

回调函数

如果要处理$.ajax()得到的数据,则需要使用回调函数。beforeSend、error、dataFilter、success、complete。

  • beforeSend 在发送请求之前调用,并且传入一个XMLHttpRequest作为参数。
  • error 在请求出错时调用。传入XMLHttpRequest对象,描述错误类型的字符串以及一个异常对象(如果有的话)
  • dataFilter 在请求成功之后调用。传入返回的数据以及”dataType”参数的值。并且必须返回新的数据(可能是处理过的)传递给success回调函数。
  • success 当请求之后调用。传入返回后的数据,以及包含成功代码的字符串。
  • complete 当请求完成之后调用这个函数,无论成功或失败。传入XMLHttpRequest对象,以及一个包含成功或错误代码的字符串。

即:假如 后台中发生了 int = 1/0 的运行时错误.
如果是用 servlet 编写的后台处理 , servlet底层捕获了这个异常并将这个异常编写了错误代码号(如果没有记错应该是405),这样在 .ajax()error. .post()方法不会做出任何行为.
如果是用 action编写的后台处理 , action底层在dispatcher阶段同样捕获了相关异常(除了servlet容器异常),并导入到一个固定的模板页面,可是struts2却没有设置相应的错误代码号,因此 .ajax() .post()都捕获不到相关异常.action强制的输出了错误模板,回调data永远可以接受到模板数据.


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);
        }
    }
发布了30 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wsl9420/article/details/53556600