做了一个小测试 struts2,spring,mybatis的框架,所需jar包如下:
新增result type:json
JsonResult.java
package com.test.xiaobc.login.server.util;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import com.test.xiaobc.base.action.AbstractAction;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.inject.Inject;
public class JsonResult implements Result{
/** 继承ActionSupport中的属性 */
protected static final Set<String> FIELDS = new HashSet<String>();
private static final long serialVersionUID = 8840245761025613454L;
private String defaultEncoding = "UTF-8";
private Log log = LogFactory.getLog(getClass());
private String includeProperties;
private Set<String> includePropertiesSet;
/**
* <action name="findAll" class="orderBillAction" method="findAll">
* <result name='success' type='json'>
* <param name="contentType">text/html</param>
* </result>
* </action>
*/
private String contentType;
/** 序列化属性,默认为null替换为空字符串 */
private JsonFeature feature = JsonFeature.getDefaultJsonFeature();
/**
* 调用js函数名称
*/
private String callbackParameter;
static {
FIELDS.add("actionErrors");
FIELDS.add("actionMessages");
FIELDS.add("class");
FIELDS.add("errorMessages");
FIELDS.add("errors");
FIELDS.add("locale");
FIELDS.add("fieldErrors");
FIELDS.add("texts");
FIELDS.add("success");
FIELDS.add("isException");
}
@Inject("struts.i18n.encoding")
public void setDefaultEncoding(String val) {
this.defaultEncoding = val;
}
/**
*
* <p>设置编码格式utf-8</p>
* @date 2013-4-3 上午9:35:08
* @return
* @see
*/
protected String getEncoding() {
String encoding = this.defaultEncoding;
if (encoding == null) {
encoding = System.getProperty("file.encoding");
}
if (encoding == null) {
encoding = "UTF-8";
}
return encoding;
}
public String getIncludeProperties() {
return includeProperties;
}
/**
*
* <p>拆分包含属性文件</p>
* @date 2013-4-3 上午9:35:39
* @param includeProperties
* @see
*/
public void setIncludeProperties(String includeProperties) {
if (includeProperties == null) {
return;
}
this.includeProperties = includeProperties;
String[] properties = this.includeProperties.split(",");
includePropertiesSet = new HashSet<String>();
for (String property : properties) {
includePropertiesSet.add(property);
}
this.setIncludePropertiesList(includePropertiesSet);
}
public Set<String> getIncludePropertiesList() {
return includePropertiesSet;
}
public void setIncludePropertiesList(Set<String> includePropertiesList) {
this.includePropertiesSet = includePropertiesList;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getFeature() {
return feature.getFeature();
}
public void setFeature(String feature) {
if(StringUtils.isNotBlank(feature) && !this.feature.getFeature().equals(feature)) {
this.feature = new JsonFeature(feature);
}
}
/**
* 序列化对象成JSON
*
* @param val
* @param sb
* @throws JsonGenerationException
* @throws JsonMappingException
* @throws IOException
*/
private void serialize(Object val, StringBuilder sb)
throws JsonGenerationException, JsonMappingException, IOException {
if (val == null) {
sb.append(feature.doFeature()).append(",");
} else if (val instanceof Number || val instanceof Boolean) {
sb.append(val.toString()).append(",");
} else if (val instanceof Date) {
sb.append((Long) ((Date) val).getTime()).append(",");
} else if (val instanceof Calendar) {
sb.append((Long) ((Calendar) val).getTime().getTime()).append(",");
} else {
sb.append(feature.doFeature(
JsonHelps.toString(val)
)).append(",");
}
}
/**
*
* <p>向叶面输入json</p>
* @date 2013-4-3 上午9:37:10
* @param invocation
* @throws Exception
* @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
*/
public void execute(ActionInvocation invocation) throws Exception {
if (log.isDebugEnabled()) {
log.debug("begin JSONResult");
}
HttpServletRequest request= ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
if (getContentType() != null) {
response.setContentType(this.getContentType());
} else {
response.setContentType("application/json");
}
response.setCharacterEncoding(defaultEncoding);
StringBuilder sb = new StringBuilder();
sb.append("{");
Object obj = invocation.getAction();
BeanInfo ip = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] pros = ip.getPropertyDescriptors();
// 对success、isException属性特别处理
if (obj instanceof AbstractAction) {//此处是自己创建的父类action(AbstractAction)
PropertyDescriptor spd = new PropertyDescriptor("success",
obj.getClass());
Method smd = spd.getReadMethod();
Object success = smd.invoke(obj);
//返回的success属性名的前后都加上双引号
sb.append("\"success\"").append(":");
serialize(success, sb);
PropertyDescriptor epd = new PropertyDescriptor("exception",
obj.getClass());
Method emd = epd.getReadMethod();
Object isException = emd.invoke(obj);
//返回的isException属性名的前后都加上双引号
sb.append("\"isException\"").append(":");
serialize(isException, sb);
}
for (PropertyDescriptor pro : pros) {
if (includePropertiesSet != null && !includePropertiesSet.contains(pro.getDisplayName())) {
continue;
}
Method method = pro.getReadMethod();
if (method != null) {
Object val = method.invoke(obj, new Object[0]);
String proName = pro.getDisplayName();
if (FIELDS.contains(proName)) {
continue;
}
//返回的请求类的所有属性名的前后都加上双引号
sb.append("\"");
sb.append(pro.getDisplayName());
sb.append("\"");
sb.append(":");
serialize(val, sb);
}
}
String result = "";
if (sb.length() > 1) {
result = sb.substring(0, sb.length() - 1);
}
result = result.concat("}");
result = addCallbackIfApplicable(request, result);
OutputStream out = response.getOutputStream();
out.write(result.getBytes(defaultEncoding));
out.flush();
out.close();
}
/**
* 增加js方法调用
* @date 2012-12-5 下午3:35:43
* @param request
* @param json
* @return
* @see
*/
private String addCallbackIfApplicable(HttpServletRequest request, String json) {
if ((callbackParameter != null) && (callbackParameter.length() > 0)) {
String callbackName = request.getParameter(callbackParameter);
if ((callbackName != null) && (callbackName.length() > 0)) {
json = callbackName + "(" + json + ")";
}
}
return json;
}
public void setCallbackParameter(String callbackParameter) {
this.callbackParameter = callbackParameter;
}
public String getCallbackParameter() {
return callbackParameter;
}
}
class JsonFeature {
public static final String ALLOW_NULL_REPLACED_EMPTY = "ALLOW_NULL_REPLACED_EMPTY";
public static final String ALLOW_NULL = "ALLOW_NULL";
public static final String REGEX_NULL = "['\"]*null['\"]*";
public static final String EMPTY_STRING = "\"\"";
public static final String NULL_STRING = "null";
static final JsonFeature defaultJsonFeature = new JsonFeature(ALLOW_NULL);
private String feature;
public JsonFeature(String feature) {
this.feature = feature;
}
public static JsonFeature getDefaultJsonFeature() {
return defaultJsonFeature;
}
public String getFeature() {
return feature;
}
/**
* 根据特性返回对应的字符串
*
* @return 字符串
*/
public String doFeature() {
if (feature.equalsIgnoreCase(ALLOW_NULL_REPLACED_EMPTY)) {
return EMPTY_STRING;
} else {
return NULL_STRING;
}
}
/**
* 根据特性替换字符串并返回替换后的字符串
*
* @param str 被替换的目标
* @return 替换后的字符串
*/
public String doFeature(String str) {
if (feature.equalsIgnoreCase(ALLOW_NULL_REPLACED_EMPTY)) {
return str.replaceAll(REGEX_NULL, EMPTY_STRING);
} else {
return str;
}
}
}
<!-- 定义一个resultType -->
<result-types>
<result-type name="json" class="com.test.xiaobc.login.server.util.JsonResult"></result-type>
</result-types>
上面JsonResult.java用到一个工具类 JsonHelps.java:
package com.test.xiaobc.login.server.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
/**
* json工具类
* <p style="display:none">modifyRecord</p>
* @since
*/
public abstract class JsonHelps {
/**
* Object序列化为json字符串
* @param obj
* @return
*/
public static final String toString(Object obj) {
return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.DisableCircularReferenceDetect);
}
}
最后配置 action的返回类型:
<action name="menu" class = "loginAction" method = "menu">
<result name="success" type="json"/>
<result name="error"/>
</action>
action中有相应的成员变量,并且有get,set方法:
然后请求后前台返回字符串: