import java.io.OutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Field; import com.opensymphony.webwork.ServletActionContext; import com.opensymphony.xwork.ActionContext; import com.opensymphony.xwork.ActionInvocation; import com.opensymphony.xwork.Result; import org.json.JSONObject; /** * 支持自动组装JSONObject的JSONResult,支持encoding编码。 * * @author WUZHENZHONG * @data 2012-07-02 */ public class JSONResult implements Result { /** * */ private static final long serialVersionUID = 9010804483391553391L; private static final Log log = LogFactory.getLog(JSONResult.class); // action中的json对象的名词 private String jsonObjectProperty = "jsonObject"; private String contentType = "application/json"; private String encoding = "utf-8"; @Override public void execute(ActionInvocation invocation) throws Exception { if (log.isDebugEnabled()) { log.debug("executing JSONResult"); } // 通过xwork的invocation从webwork的action中获得JSONObject对象 JSONObject jsonObject = getJSONObject(invocation); if (jsonObject != null) { String json = jsonObject.toString(); HttpServletResponse response = getServletResponse(invocation); response.setContentType(getContentType()); // encoding byte[] bs = json.getBytes(this.encoding); response.setContentLength(bs.length); OutputStream os = response.getOutputStream(); os.write(bs); os.flush(); if (log.isDebugEnabled()) { log.debug("written [" + json + "] to HttpServletResponse outputstream"); } } } protected JSONObject getJSONObject(ActionInvocation invocation) throws Exception { ActionContext actionContext = invocation.getInvocationContext(); // 从xwork配置中获得JSON对象名词 Object obj = actionContext.getValueStack().findValue(jsonObjectProperty); if (obj == null) { log.error("property [" + jsonObjectProperty + "] returns null, please check xwork.xml file"); return null; } // 如果Action中的对象是JSONObject,那么就不需要反射动态转换为JSONObject // 如果Action中的对象就是POJO,那么这里自动组装JSONObject if (!JSONObject.class.isInstance(obj)) { log.debug("build json object by reflection."); JSONObject jsonObj = new JSONObject(); for (Field field : obj.getClass().getDeclaredFields()) { String getter = "get" + Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1); jsonObj.append(field.getName(), obj .getClass() .getDeclaredMethod(getter) .invoke(obj)); } return jsonObj; } return (JSONObject) obj; } protected HttpServletResponse getServletResponse(ActionInvocation invocation) { return (HttpServletResponse) invocation .getInvocationContext() .getContextMap() .get(ServletActionContext.HTTP_RESPONSE); } public void setEncoding(String encoding) { this.encoding = encoding; } public String getEncoding() { return encoding; } public void setJsonObjectProperty(String jsonObjectProperty) { this.jsonObjectProperty = jsonObjectProperty; } public String getJsonObjectProperty() { return jsonObjectProperty; } public void setContentType(String contentType) { this.contentType = contentType; } public String getContentType() { return contentType; } }
配置文件:
<xwork> <package name="system-default" extends="webwork-default"> <result-types> <result-type name="json" class="com.guagua.chat.search.JSONResult" /> </result-types> <action name="search" class="com.guagua.chat.search.SearchAction"> <result name="cjcategory" type="json"> <param name="jsonObjectProperty">cjroomcategory</param> </result> </action> </package> </xwork>
类例子:
import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import com.guagua.base.AuthFactory; import com.guagua.base.AuthToken; import com.guagua.base.UnauthorizedException; import com.guagua.vas.constants.CacheConstants; import com.guagua.vas.redis.RedIsService; import com.opensymphony.webwork.ServletActionContext; public class SearchAction { private static Logger logger = Logger.getLogger(SearchAction.class.getName()); public CjRoomCategoryVo cjroomcategory = new CjRoomCategoryVo(); /** * 获取房间分类接口 * @return JSON * @throws Exception */ @SuppressWarnings("unchecked") public String getcjcategory() throws Exception { Map<String,String> catemap = RedIsService.getJedisByKey(CacheConstants.CJ_ROOM_CATEGORY); String returnstr = ""; if(catemap==null || catemap.size()<=0){ catemap.put("cj_room_category_101_0", "{'category_id':101,'name':'桂林','parent_id':0}"); catemap.put("cj_room_category_1011_101", "{'category_id':1011,'name':'桂林s','parent_id':101}"); catemap.put("cj_room_category_1012_101", "{'category_id':1012,'name':'桂林sf','parent_id':101}"); catemap.put("cj_room_category_102_0", "{'category_id':102,'name':'桂林1','parent_id':0}"); catemap.put("cj_room_category_1013_102", "{'category_id':1013,'name':'桂林sf','parent_id':102}"); } List arrayList = new ArrayList(catemap.entrySet()); Collections.sort(arrayList, new TariffMapComparator()); for(Iterator it = arrayList.iterator();it.hasNext();){ Map.Entry<String,String> entry = (Map.Entry<String,String>)it.next(); if(entry.getKey().endsWith("_0")){ String tempstr = "'category':"+entry.getValue(); String[] tp = entry.getKey().split("_"); StringBuffer subtempstr = new StringBuffer(""); for(Iterator subit = arrayList.iterator();subit.hasNext();){ Map.Entry<String,String> subentry = (Map.Entry<String,String>)subit.next(); if(subentry.getKey().endsWith("_"+tp[3])){ subtempstr.append(subentry.getValue()+","); } } String tempsubstr = subtempstr.toString(); if(tempsubstr.length()>0){ tempsubstr = tempsubstr.substring(0, tempsubstr.length()-1); } tempsubstr = "'subcategory':["+tempsubstr+"]"; String tempcountstr = "{"+tempstr+","+tempsubstr+"}"; returnstr = returnstr + tempcountstr+","; } } returnstr = "["+returnstr.substring(0, returnstr.length()-1)+"]"; cjroomcategory.setJsonstr(returnstr); return "cjcategory"; } public CjRoomCategoryVo getCjroomcategory() { return cjroomcategory; } public void setCjroomcategory(CjRoomCategoryVo cjroomcategory) { this.cjroomcategory = cjroomcategory; } /** * 分类排序 * @author WUZHENZHONG * */ @SuppressWarnings({"unused", "unchecked"}) private class TariffMapComparator implements Comparator{ public int compare(Object o1, Object o2) { Map.Entry<String,String> obj1 = (Map.Entry<String,String>)o1; Map.Entry<String,String> obj2 = (Map.Entry<String,String>)o2; return obj1.getKey().toString().compareTo(obj2.getKey().toString()); } } }