Struts2自定义返回Json类型result

本来Struts2有自己的json类型的返回结果,并提供了插件,但是它有一个问题,那就是它会将所有序列化的字段都返回,如果想要制定返回Action的某一个属性,则需要在配置result时,配置参数(这里只是举个例子):

<param name="root">responseMap</param>  

配置了这个参数,返回结果就会从Action中的responseMap为根进行返回。

 

但是如果自定义结果类型,就可以自己控制了,而且不需要struts2-json-result插件,以下是配置信息:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.objectFactory" value="spring" />
    <constant name="struts.i18n.encoding" value="utf-8" />
    <constant name="struts.enable.SlashesInActionNames" value="true" />
    <package name="default" extends="struts-default" namespace="/login">
        <result-types>
            <result-type name="jsonResult" class="com.lxl.student.mng.base.JSONResult" />
        </result-types>
        
        <action name="*/*" class="{1}" method="{2}">
            <result type="jsonResult" name="success">
                <param name="resultName">responseData</param>
            </result>
        </action>
    </package>

</struts>

 

com.lxl.erp.base.JSONResult为我们自己需要实现的返回类型的实现类:
package com.lxl.student.mng.base;

import java.io.PrintWriter;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.StrutsResultSupport;

import com.lxl.student.mng.common.HttpConstant;
import com.lxl.student.mng.common.ResourceLanguage;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.ExceptionHolder;
import com.opensymphony.xwork2.util.ValueStack;

import net.sf.json.JSONObject;

public final class JSONResult extends StrutsResultSupport {
    private static final long serialVersionUID = 1L;

    private String resultName;

    public void setResultName(String resultName) {
        this.resultName = resultName;
    }

    @Override
    protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
        BaseAction bas = (BaseAction) invocation.getAction();
        bas.clearErrorsAndMessages();

        HttpServletResponse response = (HttpServletResponse) invocation.getInvocationContext().get(HTTP_RESPONSE);
        response.setContentType(HttpConstant.RESPONSE_CONTENT_TYPE);

        @SuppressWarnings("unchecked")
        Map<String, Object> responseMap = (Map<String, Object>) invocation.getStack().findValue(resultName);

        if (responseMap == null) {
            responseMap = new HashMap<String, Object>(3);
        } else if (responseMap.get(HttpConstant.RETCODE) == null) {
            ValueStack s = invocation.getStack();
            for (int i = s.size(); i > 0; i--) {
                Object obj = s.pop();
                if (obj instanceof ExceptionHolder) {
                    responseMap.put(HttpConstant.RETCODE, HttpConstant.ERROR_CODE);
                    responseMap.put(HttpConstant.RETMSG, HttpConstant.UNKNOWNERROR);

                    Object o = ((ExceptionHolder) obj).getException();

                    if (o instanceof ServiceException) {
                        String accept_language = ServletActionContext.getRequest()
                                .getHeader(HttpConstant.REQUEST_HEADER_LANG);
                        String language = accept_language.split(",")[0];
                        Locale locale = Locale.getDefault();
                        if (language.toLowerCase().indexOf(ResourceLanguage.CHINESE) > -1) {
                            locale = Locale.CHINA;
                        } else if (language.toLowerCase().indexOf(ResourceLanguage.ENGLISH) > -1) {
                            locale = Locale.US;
                        }
                        ResourceBundle bundle = ResourceBundle.getBundle(ResourceLanguage.SOURCELOCATION, locale);

                        ServiceException exception = (ServiceException) o;

                        responseMap.put(HttpConstant.RETMSG, exception.getErrorMsg(bundle));
                    } else if (o instanceof Exception) {
                        Exception exception = (Exception) o;
                        responseMap.put(HttpConstant.RETMSG, exception.getCause().getMessage());
                    } else if (o instanceof UndeclaredThrowableException) {
                        o = ((UndeclaredThrowableException) o).getUndeclaredThrowable();
                    }
                    break;
                }
            }
        }

        PrintWriter pw = response.getWriter();
        pw.write(JSONObject.fromObject(responseMap).toString());

        System.out.println(JSONObject.fromObject(responseMap));

        return;
    }
}

这样,只要在Action中添加一个属性responseMap存储要返回的数据,通过

(Map<String, Object>) invocation.getStack().findValue(resultName)

在值栈中获取返回的数据(resultName是在struts.xml中配置的,struts会将值压入到值栈中,通过这个配置的名字就可以找到)。

这样Action请求处理函数中,将要返回的请求数据结果放到responseMap中,然后返回SUCCESS就可以了,前台就可以通过ajax请求访问了。

注:

HttpConstant.RESPONSE_CONTENT_TYPE="text/plain; charset=UTF-8"
posted @ 2016-01-24 10:42  烈日1990  阅读(688)  评论(0编辑  收藏  举报