`
lianxiangbus
  • 浏览: 526106 次
文章分类
社区版块
存档分类
最新评论

自己编写的一个Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加载对象[修订081217]

 
阅读更多

最后更新:09-02-08
bug fix:支持了Hibernate one-to-many映射到List的处理


由于Json自己的String转换有问题,无法正确的转换中文为uxxxx的字符,因此改用DWR包内的JavascriptUtil处理String类型。可以直接引用,还可以拆离出来,因为仅是一个转换工具类,跟DWR的没有依赖关系。这样就可以采用ISO-8859-1编码来传递所有UNICODE了。

代码:

  1. packagecom.aherp.framework.util;
  2. importorg.json.JSONString;
  3. publicclassJSONStringObjectimplementsJSONString{
  4. privateStringjsonString=null;
  5. publicJSONStringObject(StringjsonString){
  6. this.jsonString=jsonString;
  7. }
  8. @Override
  9. publicStringtoString(){
  10. returnjsonString;
  11. }
  12. publicStringtoJSONString(){
  13. returnjsonString;
  14. }
  15. }

  1. packagecom.aherp.framework.util;
  2. importjava.lang.reflect.Array;
  3. importjava.lang.reflect.Method;
  4. importjava.util.Calendar;
  5. importjava.util.Date;
  6. importjava.util.Map;
  7. importjava.util.Map.Entry;
  8. importorg.json.JSONArray;
  9. importorg.json.JSONException;
  10. importorg.json.JSONObject;
  11. importorg.json.JSONString;
  12. /**
  13. *JSON工具类,反射的方式转换整个对象
  14. *@authorJimWu
  15. *
  16. */
  17. publicclassJSONUtil{
  18. privatestaticJSONUtilinstance=null;
  19. publicJSONUtil(){}
  20. /**
  21. *代理类是否输出的检查,返回true则允许继续转换
  22. *@parambean
  23. *@return是否允许继续转换
  24. */
  25. protectedbooleancanProxyOutput(Objectbean){
  26. returntrue;
  27. }
  28. /**
  29. *代理类时做的检查.返回应该检查的对象.
  30. *@parambean
  31. *@return实际获取的对象
  32. */
  33. protectedObjectproxyConvert(Objectbean){
  34. returnbean;
  35. }
  36. staticpublicStringtoJSONString(Objectobj)throwsJSONException{
  37. returntoJSONString(obj,false);
  38. }
  39. staticpublicStringtoJSONString(Objectobj,booleanuseClassConvert)throwsJSONException{
  40. if(instance==null)
  41. instance=newJSONUtil();
  42. returninstance.getJSONObject(obj,useClassConvert).toString();
  43. }
  44. @SuppressWarnings("unchecked")
  45. privateStringgetJSONArray(ObjectarrayObj,booleanuseClassConvert)throwsJSONException{
  46. if(arrayObj==null)
  47. return"null";
  48. arrayObj=proxyConvert(arrayObj);
  49. JSONArrayjSONArray=newJSONArray();
  50. if(arrayObjinstanceofIterable){
  51. for(ObjectrowObj:((Iterable)arrayObj)){
  52. if(canProxyOutput(rowObj)){
  53. if(rowObj==null)
  54. jSONArray.put(newJSONStringObject(null));
  55. elseif(rowObj.getClass().isArray()||rowObjinstanceofIterable)
  56. jSONArray.put(getJSONArray(rowObj,useClassConvert));
  57. else
  58. jSONArray.put(getJSONObject(rowObj,useClassConvert));
  59. }
  60. }
  61. }
  62. if(arrayObj.getClass().isArray()){
  63. intarrayLength=Array.getLength(arrayObj);
  64. for(inti=0;i<arrayLength;i++){
  65. ObjectrowObj=Array.get(arrayObj,i);
  66. if(canProxyOutput(rowObj)){
  67. if(rowObj==null)
  68. jSONArray.put(newJSONStringObject(null));
  69. elseif(rowObj.getClass().isArray()||rowObjinstanceofIterable)
  70. jSONArray.put(getJSONArray(rowObj,useClassConvert));
  71. else
  72. jSONArray.put(getJSONObject(rowObj,useClassConvert));
  73. }
  74. }
  75. }
  76. returnjSONArray.toString();
  77. }
  78. @SuppressWarnings("unchecked")
  79. JSONStringObjectgetJSONObject(Objectvalue,booleanuseClassConvert)throwsJSONException{
  80. //处理原始类型
  81. if(value==null){
  82. returnnewJSONStringObject("null");
  83. }
  84. value=proxyConvert(value);
  85. if(valueinstanceofJSONString){
  86. Objecto;
  87. try{
  88. o=((JSONString)value).toJSONString();
  89. }catch(Exceptione){
  90. thrownewJSONException(e);
  91. }
  92. thrownewJSONException("BadvaluefromtoJSONString:"+o);
  93. }
  94. if(valueinstanceofNumber){
  95. returnnewJSONStringObject(JSONObject.numberToString((Number)value));
  96. }
  97. if(valueinstanceofBoolean||valueinstanceofJSONObject||
  98. valueinstanceofJSONArray){
  99. returnnewJSONStringObject(value.toString());
  100. }
  101. if(valueinstanceofString)
  102. returnnewJSONStringObject('"'+JavascriptUtil.escapeJavaScript(value.toString())+'"');
  103. if(valueinstanceofMap){
  104. JSONObjectjSONObject=newJSONObject();
  105. for(ObjectrowObj:((Map)value).entrySet()){
  106. Entryentry=(Entry)rowObj;
  107. ObjectvalueObj=entry.getValue();
  108. if(canProxyOutput(valueObj))
  109. jSONObject.put(entry.getKey().toString(),getJSONObject(valueObj,useClassConvert));
  110. }
  111. returnnewJSONStringObject(jSONObject.toString());
  112. }
  113. if(valueinstanceofDate){
  114. Calendarcalendar=Calendar.getInstance();
  115. calendar.setTime(calendar.getTime());
  116. StringBuildersb=newStringBuilder("newDate(");
  117. sb.append(calendar.get(Calendar.YEAR));
  118. sb.append(",");
  119. sb.append(calendar.get(Calendar.MONTH));
  120. sb.append(",");
  121. sb.append(calendar.get(Calendar.DAY_OF_MONTH));
  122. sb.append(",");
  123. sb.append(calendar.get(Calendar.HOUR_OF_DAY));
  124. sb.append(",");
  125. sb.append(calendar.get(Calendar.MINUTE));
  126. sb.append(",");
  127. sb.append(calendar.get(Calendar.SECOND));
  128. sb.append(")");
  129. returnnewJSONStringObject(sb.toString());
  130. }
  131. //class
  132. if(valueinstanceofClass)
  133. returnnewJSONStringObject(JavascriptUtil.escapeJavaScript(((Class)value).getSimpleName()));
  134. //数组
  135. if(valueinstanceofIterable||value.getClass().isArray()){
  136. returnnewJSONStringObject(getJSONArray(proxyConvert(value),useClassConvert));
  137. }
  138. returnreflectObject(value,useClassConvert);
  139. }
  140. @SuppressWarnings("unchecked")
  141. privateJSONStringObjectreflectObject(Objectbean,booleanuseClassConvert){
  142. JSONObjectjSONObject=newJSONObject();
  143. Classklass=bean.getClass();
  144. for(Methodmethod:klass.getMethods()){
  145. try{
  146. Stringname=method.getName();
  147. Stringkey="";
  148. if(name.startsWith("get")){
  149. key=name.substring(3);
  150. }elseif(name.startsWith("is")){
  151. key=name.substring(2);
  152. }
  153. if(key.length()>0&
  154. Character.isUpperCase(key.charAt(0))&
  155. method.getParameterTypes().length==0){
  156. if(key.length()==1){
  157. key=key.toLowerCase();
  158. }elseif(!Character.isUpperCase(key.charAt(1))){
  159. key=key.substring(0,1).toLowerCase()+
  160. key.substring(1);
  161. }
  162. ObjectelementObj=method.invoke(bean);
  163. if(!useClassConvert&&elementObjinstanceofClass)
  164. continue;
  165. if(canProxyOutput(elementObj))
  166. jSONObject.put(key,getJSONObject(elementObj,useClassConvert));
  167. }
  168. }catch(Exceptione){
  169. /*forgetaboutit*/
  170. }
  171. }
  172. returnnewJSONStringObject(jSONObject.toString());
  173. }
  174. }

调用测试程序

importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;


publicclassAObj...{
privateintii=7;
privatebooleanbb=true;
privateStringss="你好";
privateListaList=newArrayList();

publicAObj()...{
aList.add(
"hello");
aList.add(
false);
aList.add(
newBObj());
aList.add(
newHashMap());
}


publicbooleanisBb()...{
returnbb;
}

publicvoidsetBb(booleanbb)...{
this.bb=bb;
}

publicintgetIi()...{
returnii;
}

publicvoidsetIi(intii)...{
this.ii=ii;
}

publicStringgetSs()...{
returnss;
}

publicvoidsetSs(Stringss)...{
this.ss=ss;
}

publicListgetAList()...{
returnaList;
}

publicvoidsetAList(Listlist)...{
aList
=list;
}

}

importjava.math.BigDecimal;
importjava.util.HashMap;


publicclassBObj...{

privateHashMapinnerhm=newHashMap();

publicBObj()...{
doubledd=7.4354;
innerhm.put(
"gigi","高兴");
innerhm.put(
"sina",newBigDecimal(dd));
}


publicHashMapgetInnerhm()...{
returninnerhm;
}


publicvoidsetInnerhm(HashMapinnerhm)...{
this.innerhm=innerhm;
}

}


publicclassCObjextendsAObj...{

privateObject[]oarray=newObject[]...{352,false,"kick"};

publicObject[]getOarray()...{
returnoarray;
}


publicvoidsetOarray(Object[]oarray)...{
this.oarray=oarray;
}

}

importorg.json.JSONException;

importcom.aherp.framework.util.JSONUtil;

publicclassTest...{
publicstaticvoidmain(String[]args)throwsJSONException...{
CObjcObj
=newCObj();
System.out.println(JSONUtil.toJSONString(cObj));
}

}




输出:
{"AList":["hello",false,{"innerhm":{"gigi":"/u9AD8/u5174","sina":7.4353999999999995651478457148186862468719482421875}},{}],"ii":7,"oarray":[352,false,"kick"],"ss":"/u4F60/u597D","bb":true}

如果需要支持Hibernate,那么必须弄清其机制。Hibernate采用CGLIB对VO对象进行字节码增加,实际机制就是使用一个原类型的proxy子类,其子类实现了HibernateProxy接口。其接口有一个isUninitialized的判断方法,用来判断该代理类是否已经初始化(还记得在事务外使用延迟加载的对象会抛no Session的错误吗,正是由于实际使用的对象已经变成原来类的子类proxy了)。而对于one-to-many映射时,很难判断对象只加载一次,因此为了避免递归调用死循环,忽略了Hibernate的one-to-many集合的递归反射。其原理和many-to-one一样,也是一个子类化的proxy,具有PersistentSet的接口。

因此,支持Hibernate的JSONUtil如下:


  1. packagecom.aherp.framework.util;
  2. importorg.hibernate.collection.PersistentSet;
  3. importorg.hibernate.proxy.HibernateProxy;
  4. importorg.hibernate.proxy.LazyInitializer;
  5. importorg.json.JSONException;
  6. /**
  7. *支持Hibernate的JSONUtil.
  8. *自动检测是否已经代理加载,如果未加载,则将对象仅加载为OID
  9. *@authorJimWu
  10. *
  11. */
  12. publicclassHiJSONUtilextendsJSONUtil{
  13. privatestaticHiJSONUtilinstance=null;
  14. staticpublicStringtoJSONString(Objectobj)throwsJSONException{
  15. returntoJSONString(obj,false);
  16. }
  17. staticpublicStringtoJSONString(Objectobj,booleanuseClassConvert)throwsJSONException{
  18. if(instance==null)
  19. instance=newHiJSONUtil();
  20. returninstance.getJSONObject(obj,useClassConvert).toString();
  21. }
  22. @Override
  23. protectedObjectproxyConvert(Objectbean){
  24. if(beaninstanceofHibernateProxy){
  25. LazyInitializerlazyInitializer=((HibernateProxy)bean).getHibernateLazyInitializer();
  26. if(lazyInitializer.isUninitialized()){
  27. returnlazyInitializer.getIdentifier();
  28. }else
  29. returnlazyInitializer.getImplementation();
  30. }
  31. if(beaninstanceofPersistentSet || bean instanceof PersistentList){
  32. returnnewString[]{};//忽略hibernateone-to-many
  33. }
  34. returnbean;
  35. }
  36. @Override
  37. protectedbooleancanProxyOutput(Objectbean){
  38. return!(bean!=null&&(beaninstanceofPersistentSet || bean instanceof PersistentList));
  39. }
  40. }
  41. ;

但是这样还是有个问题,当one-to-one具备双向映射关系时,会陷入调用递归死循环。因此避免这样的情况。

将本人修改过的JavaScriptUtil也附上

  1. /*
  2. *Copyright2005JoeWalker
  3. *
  4. *LicensedundertheApacheLicense,Version2.0(the"License");
  5. *youmaynotusethisfileexceptincompliancewiththeLicense.
  6. *YoumayobtainacopyoftheLicenseat
  7. *
  8. *http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. *Unlessrequiredbyapplicablelaworagreedtoinwriting,software
  11. *distributedundertheLicenseisdistributedonan"ASIS"BASIS,
  12. *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
  13. *SeetheLicenseforthespecificlanguagegoverningpermissionsand
  14. *limitationsundertheLicense.
  15. */
  16. packagecom.aherp.framework.util;
  17. importjava.io.BufferedReader;
  18. importjava.io.IOException;
  19. importjava.io.StringReader;
  20. importjava.util.Arrays;
  21. importjava.util.Locale;
  22. importjava.util.SortedSet;
  23. importjava.util.TreeSet;
  24. importorg.apache.commons.logging.Log;
  25. importorg.apache.commons.logging.LogFactory;
  26. /**
  27. *VariousJavascriptcodeutilities.
  28. *Theescapeclassesweretakenfromjakarta-commons-langwhichinturnborrowed
  29. *fromTurbineandotherprojects.Thelistofauthorsbelowisalmostcertainly
  30. *fartoolong,butI'mnotsurewhoreallywrotethesemethods.
  31. *@authorJoeWalker[joeatgetaheaddotltddotuk]
  32. *@authorApacheJakartaTurbine
  33. *@authorGenerationJavaCorelibrary
  34. *@authorPurpleTechnology
  35. *@author<ahref="mailto:bayard@generationjava.com">HenriYandell</a>
  36. *@author<ahref="mailto:alex@purpletech.com">AlexanderDayChaffee</a>
  37. *@author<ahref="mailto:cybertiger@cyberiantiger.org">AntonyRiley</a>
  38. *@authorHelgeTesgaard
  39. *@author<ahref="sean@boohai.com">SeanBrown</a>
  40. *@author<ahref="mailto:ggregory@seagullsw.com">GaryGregory</a>
  41. *@authorPhilSteitz
  42. *@authorPeteGieser
  43. */
  44. @SuppressWarnings("unchecked")
  45. publicclassJavascriptUtil
  46. {
  47. /**
  48. *Flagforuseinjavascriptcompression:Removesinglelinecomments.
  49. *ForeaseofuseyoumaywishtouseoneoftheLEVEL_*compressionlevels.
  50. *@noinspectionPointlessBitwiseExpression
  51. */
  52. publicstaticfinalintCOMPRESS_STRIP_SL_COMMENTS=1<<0;
  53. /**
  54. *Flagforuseinjavascriptcompression:Removemultilinecomments.
  55. *ForeaseofuseyoumaywishtouseoneoftheLEVEL_*compressionlevels.
  56. */
  57. publicstaticfinalintCOMPRESS_STRIP_ML_COMMENTS=1<<1;
  58. /**
  59. *Flagforuseinjavascriptcompression:Removewhitespaceatthestartandendofaline.
  60. *ForeaseofuseyoumaywishtouseoneoftheLEVEL_*compressionlevels.
  61. */
  62. publicstaticfinalintCOMPRESS_TRIM_LINES=1<<2;
  63. /**
  64. *Flagforuseinjavascriptcompression:Removeblanklines.
  65. *Thisoptionwillmakethejavascripthardertodebugbecauselinenumberreferences
  66. *arelikelybealtered.
  67. *ForeaseofuseyoumaywishtouseoneoftheLEVEL_*compressionlevels.
  68. */
  69. publicstaticfinalintCOMPRESS_STRIP_BLANKLINES=1<<3;
  70. /**
  71. *Flagforuseinjavascriptcompression:Shrinkvariablenames.
  72. *Thisoptioniscurrentlyun-implemented.
  73. *ForeaseofuseyoumaywishtouseoneoftheLEVEL_*compressionlevels.
  74. */
  75. publicstaticfinalintCOMPRESS_SHRINK_VARS=1<<4;
  76. /**
  77. *Flagforuseinjavascriptcompression:Removealllinesendings.
  78. *Warning:Javascriptcanaddsemi-colonsinforyou.Ifyoumakeuseofthisfeature
  79. *thenremovingnewlinesmaywellbreak.
  80. *ForeaseofuseyoumaywishtouseoneoftheLEVEL_*compressionlevels.
  81. */
  82. publicstaticfinalintCOMPRESS_REMOVE_NEWLINES=1<<5;
  83. /**
  84. *Compressionlevelthatleavesthesourceun-touched.
  85. */
  86. publicstaticfinalintLEVEL_NONE=0;
  87. /**
  88. *Basiccompressionthatleavesthesourcefullydebuggable.
  89. *Thisincludesremovingallcommentsandextraneouswhitespace.
  90. */
  91. publicstaticfinalintLEVEL_DEBUGGABLE=COMPRESS_STRIP_SL_COMMENTS|COMPRESS_STRIP_ML_COMMENTS|COMPRESS_TRIM_LINES;
  92. /**
  93. *Normalcompressionmakesallchangesthatwillworkforgenericjavascript.
  94. *Thisaddsvariablenamecompressionandblanklineremovalinadditiontothe
  95. *compressionsdonebyLEVEL_DEBUGGABLE.
  96. */
  97. publicstaticfinalintLEVEL_NORMAL=LEVEL_DEBUGGABLE|COMPRESS_STRIP_BLANKLINES|COMPRESS_SHRINK_VARS;
  98. /**
  99. *LEVEL_ULTRAperformsadditionalcompressionthatmakessomeassumptionsaboutthe
  100. *styleofjavascript.
  101. *Specificallyitassumesthatyouarenotusingjavascriptsabilitytoinferwherethe;
  102. *shouldgo.
  103. */
  104. publicstaticfinalintLEVEL_ULTRA=LEVEL_NORMAL|COMPRESS_REMOVE_NEWLINES;
  105. /**
  106. *Compressthesourcecodebyremovingjavastylecommentsandremoving
  107. *leadingandtrailingspaces.
  108. *@paramtextThejavascript(orjava)programtocompress
  109. *@paramlevelThecompressionlevel-seeLEVEL_*andCOMPRESS_*constants.
  110. *@returnThecompressedversion
  111. */
  112. publicstaticStringcompress(Stringtext,intlevel)
  113. {
  114. Stringreply=text;
  115. //Firstwestripmultilinecomments.Ithinkthisisimportant:
  116. if((level&COMPRESS_STRIP_ML_COMMENTS)!=0)
  117. {
  118. reply=stripMultiLineComments(text);
  119. }
  120. if((level&COMPRESS_STRIP_SL_COMMENTS)!=0)
  121. {
  122. reply=stripSingleLineComments(reply);
  123. }
  124. if((level&COMPRESS_TRIM_LINES)!=0)
  125. {
  126. reply=trimLines(reply);
  127. }
  128. if((level&COMPRESS_STRIP_BLANKLINES)!=0)
  129. {
  130. reply=stripBlankLines(reply);
  131. }
  132. if((level&COMPRESS_SHRINK_VARS)!=0)
  133. {
  134. reply=shrinkVariableNames(reply);
  135. }
  136. if((level&COMPRESS_REMOVE_NEWLINES)!=0)
  137. {
  138. reply=stripNewlines(reply);
  139. }
  140. returnreply;
  141. }
  142. /**
  143. *Removeanyleadingortrailingspacesfromalineofcode.
  144. *Thisfunctioncouldbeimprovedbymakingitstripunnecessarydouble
  145. *spaces,butsincewewouldneedtoleavedoublespacesinsidestrings
  146. *thisisnotsimpleandsincethebenefitissmall,we'llleaveitfornow
  147. *@paramtextThejavascriptprogramtostripspacesfrom.
  148. *@returnThestrippedprogram
  149. */
  150. publicstaticStringtrimLines(Stringtext)
  151. {
  152. if(text==null)
  153. {
  154. returnnull;
  155. }
  156. try
  157. {
  158. StringBufferoutput=newStringBuffer();
  159. //Firstwestripmultilinecomments.Ithinkthisisimportant:
  160. BufferedReaderin=newBufferedReader(newStringReader(text));
  161. while(true)
  162. {
  163. Stringline=in.readLine();
  164. if(line==null)
  165. {
  166. break;
  167. }
  168. output.append(line.trim());
  169. output.append('/n');
  170. }
  171. returnoutput.toString();
  172. }
  173. catch(IOExceptionex)
  174. {
  175. log.error("IOExecptionunexpected.",ex);
  176. thrownewIllegalArgumentException("IOExecptionunexpected.");
  177. }
  178. }
  179. /**
  180. *Removeallthesingle-linecommentsfromablockoftext
  181. *@paramtextThetexttoremovesingle-linecommentsfrom
  182. *@returnThesingle-linecommentfreetext
  183. */
  184. publicstaticStringstripSingleLineComments(Stringtext)
  185. {
  186. if(text==null)
  187. {
  188. returnnull;
  189. }
  190. try
  191. {
  192. StringBufferoutput=newStringBuffer();
  193. BufferedReaderin=newBufferedReader(newStringReader(text));
  194. while(true)
  195. {
  196. Stringline=in.readLine();
  197. if(line==null)
  198. {
  199. break;
  200. }
  201. //Skip@DWRcomments
  202. if(line.indexOf(COMMENT_RETAIN)==-1)
  203. {
  204. intcstart=line.indexOf(COMMENT_SL_START);
  205. if(cstart>=0)
  206. {
  207. line=line.substring(0,cstart);
  208. }
  209. }
  210. output.append(line);
  211. output.append('/n');
  212. }
  213. returnoutput.toString();
  214. }
  215. catch(IOExceptionex)
  216. {
  217. log.error("IOExecptionunexpected.",ex);
  218. thrownewIllegalArgumentException("IOExecptionunexpected.");
  219. }
  220. }
  221. /**
  222. *Removeallthemulti-linecommentsfromablockoftext
  223. *@paramtextThetexttoremovemulti-linecommentsfrom
  224. *@returnThemulti-linecommentfreetext
  225. */
  226. publicstaticStringstripMultiLineComments(Stringtext)
  227. {
  228. if(text==null)
  229. {
  230. returnnull;
  231. }
  232. try
  233. {
  234. StringBufferoutput=newStringBuffer();
  235. //Commentrules:
  236. /*/Thisisstillacomment
  237. /*/**///Commentsdonotnest
  238. ///**/Thisisinacomment
  239. /*//*///Thesecond//isneededtomakethisacomment.
  240. //Firstwestripmultilinecomments.Ithinkthisisimportant:
  241. booleaninMultiLine=false;
  242. BufferedReaderin=newBufferedReader(newStringReader(text));
  243. while(true)
  244. {
  245. Stringline=in.readLine();
  246. if(line==null)
  247. {
  248. break;
  249. }
  250. if(!inMultiLine)
  251. {
  252. //Wearenotinamulti-linecomment,checkforastart
  253. intcstart=line.indexOf(COMMENT_ML_START);
  254. if(cstart>=0)
  255. {
  256. //ThiscouldbeaMLCononeline...
  257. intcend=line.indexOf(COMMENT_ML_END,cstart+COMMENT_ML_START.length());
  258. if(cend>=0)
  259. {
  260. //Acommentthatstartsandendsononeline
  261. //BUG:youcanhavemorethan1multi-linecommentonaline
  262. line=line.substring(0,cstart)+SPACE+line.substring(cend+COMMENT_ML_END.length());
  263. }
  264. else
  265. {
  266. //Arealmulti-linecomment
  267. inMultiLine=true;
  268. line=line.substring(0,cstart)+SPACE;
  269. }
  270. }
  271. else
  272. {
  273. //Wearenotinamultilinecommentandwehavn't
  274. //startedonesowearegoingtoignoreclosing
  275. //commentseveniftheyexist.
  276. }
  277. }
  278. else
  279. {
  280. //Weareinamulti-linecomment,checkfortheend
  281. intcend=line.indexOf(COMMENT_ML_END);
  282. if(cend>=0)
  283. {
  284. //Endofcomment
  285. line=line.substring(cend+COMMENT_ML_END.length());
  286. inMultiLine=false;
  287. }
  288. else
  289. {
  290. //Thecommentcontinues
  291. line=SPACE;
  292. }
  293. }
  294. output.append(line);
  295. output.append('/n');
  296. }
  297. returnoutput.toString();
  298. }
  299. catch(IOExceptionex)
  300. {
  301. log.error("IOExecptionunexpected.",ex);
  302. thrownewIllegalArgumentException("IOExecptionunexpected.");
  303. }
  304. }
  305. /**
  306. *Removeallblanklinesfromastring.
  307. *Ablanklineisdefinedtobealinewheretheonlycharactersarewhitespace.
  308. *Wealwaysensurethatthelinecontainsanewlineattheend.
  309. *@paramtextThestringtostripblanklinesfrom
  310. *@returnTheblanklinestrippedreply
  311. */
  312. publicstaticStringstripBlankLines(Stringtext)
  313. {
  314. if(text==null)
  315. {
  316. returnnull;
  317. }
  318. try
  319. {
  320. StringBufferoutput=newStringBuffer();
  321. BufferedReaderin=newBufferedReader(newStringReader(text));
  322. booleandoneOneLine=false;
  323. while(true)
  324. {
  325. Stringline=in.readLine();
  326. if(line==null)
  327. {
  328. break;
  329. }
  330. if(line.trim().length()>0)
  331. {
  332. output.append(line);
  333. output.append('/n');
  334. doneOneLine=true;
  335. }
  336. }
  337. if(!doneOneLine)
  338. {
  339. output.append('/n');
  340. }
  341. returnoutput.toString();
  342. }
  343. catch(IOExceptionex)
  344. {
  345. log.error("IOExecptionunexpected.",ex);
  346. thrownewIllegalArgumentException("IOExecptionunexpected.");
  347. }
  348. }
  349. /**
  350. *Removeallnewlinecharactersfromastring.
  351. *@paramtextThestringtostripnewlinecharactersfrom
  352. *@returnThestrippedreply
  353. */
  354. publicstaticStringstripNewlines(Stringtext)
  355. {
  356. if(text==null)
  357. {
  358. returnnull;
  359. }
  360. try
  361. {
  362. StringBufferoutput=newStringBuffer();
  363. BufferedReaderin=newBufferedReader(newStringReader(text));
  364. while(true)
  365. {
  366. Stringline=in.readLine();
  367. if(line==null)
  368. {
  369. break;
  370. }
  371. output.append(line);
  372. output.append(SPACE);
  373. }
  374. output.append('/n');
  375. returnoutput.toString();
  376. }
  377. catch(IOExceptionex)
  378. {
  379. log.error("IOExecptionunexpected.",ex);
  380. thrownewIllegalArgumentException("IOExecptionunexpected.");
  381. }
  382. }
  383. /**
  384. *Shrinkvariablenamestoaminimum.
  385. *@paramtextThejavascriptprogramtoshrinkthevariablenamesin.
  386. *@returnTheshrunkversionofthejavascriptprogram.
  387. */
  388. publicstaticStringshrinkVariableNames(Stringtext)
  389. {
  390. if(text==null)
  391. {
  392. returnnull;
  393. }
  394. thrownewUnsupportedOperationException("Variablenameshrinkingisnotsupported");
  395. }
  396. /**
  397. *<p>Escapesthecharactersina<code>String</code>usingJavaScriptStringrules.</p>
  398. *<p>EscapesanyvaluesitfindsintotheirJavaScriptStringform.
  399. *Dealscorrectlywithquotesandcontrol-chars(tab,backslash,cr,ff,etc.)</p>
  400. *
  401. *<p>Soatabbecomesthecharacters<code>'//'</code>and
  402. *<code>'t'</code>.</p>
  403. *
  404. *<p>TheonlydifferencebetweenJavastringsandJavaScriptstrings
  405. *isthatinJavaScript,asinglequotemustbeescaped.</p>
  406. *
  407. *<p>Example:
  408. *<pre>
  409. *inputstring:Hedidn'tsay,"Stop!"
  410. *outputstring:Hedidn/'tsay,/"Stop!/"
  411. *</pre>
  412. *</p>
  413. *
  414. *@paramstrStringtoescapevaluesin,maybenull
  415. *@returnStringwithescapedvalues,<code>null</code>ifnullstringinput
  416. */
  417. publicstaticStringescapeJavaScript(Stringstr)
  418. {
  419. if(str==null)
  420. {
  421. returnnull;
  422. }
  423. StringBufferwriter=newStringBuffer(str.length()*2);
  424. intsz=str.length();
  425. for(inti=0;i<sz;i++)
  426. {
  427. charch=str.charAt(i);
  428. //handleunicode
  429. if(ch>0xfff)
  430. {
  431. writer.append("//u");
  432. writer.append(hex(ch));
  433. }
  434. elseif(ch>0xff)
  435. {
  436. writer.append("//u0");
  437. writer.append(hex(ch));
  438. }
  439. elseif(ch>0x7f)
  440. {
  441. writer.append("//u00");
  442. writer.append(hex(ch));
  443. }
  444. elseif(ch<32)
  445. {
  446. switch(ch)
  447. {
  448. case'/b':
  449. writer.append('//');
  450. writer.append('b');
  451. break;
  452. case'/n':
  453. writer.append('//');
  454. writer.append('n');
  455. break;
  456. case'/t':
  457. writer.append('//');
  458. writer.append('t');
  459. break;
  460. case'/f':
  461. writer.append('//');
  462. writer.append('f');
  463. break;
  464. case'/r':
  465. writer.append('//');
  466. writer.append('r');
  467. break;
  468. default:
  469. if(ch>0xf)
  470. {
  471. writer.append("//u00");
  472. writer.append(hex(ch));
  473. }
  474. else
  475. {
  476. writer.append("//u000");
  477. writer.append(hex(ch));
  478. }
  479. break;
  480. }
  481. }
  482. else
  483. {
  484. switch(ch)
  485. {
  486. case'/'':
  487. //IfwewantedtoescapeforJavastringsthenwewould
  488. //notneedthisnextline.
  489. writer.append('//');
  490. writer.append('/'');
  491. break;
  492. case'"':
  493. writer.append('//');
  494. writer.append('"');
  495. break;
  496. case'//':
  497. writer.append('//');
  498. writer.append('//');
  499. break;
  500. case'<':
  501. writer.append("//u003c");
  502. break;
  503. case'>':
  504. writer.append("//u003e");
  505. break;
  506. default:
  507. writer.append(ch);
  508. break;
  509. }
  510. }
  511. }
  512. returnwriter.toString();
  513. }
  514. /**
  515. *<p>Returnsanuppercasehexadecimal<code>String</code>forthegiven
  516. *character.</p>
  517. *@paramchThecharactertoconvert.
  518. *@returnAnuppercasehexadecimal<code>String</code>
  519. */
  520. privatestaticStringhex(charch)
  521. {
  522. returnInteger.toHexString(ch).toUpperCase(Locale.ENGLISH);
  523. }
  524. /**
  525. *<p>UnescapesanyJavaScriptliteralsfoundinthe<code>String</code>.</p>
  526. *<p>Forexample,itwillturnasequenceof<code>'/'</code>and<code>'n'</code>
  527. *intoanewlinecharacter,unlessthe<code>'/'</code>isprecededbyanother
  528. *<code>'/'</code>.</p>
  529. *@paramstrthe<code>String</code>tounescape,maybenull
  530. *@returnAnewunescaped<code>String</code>,<code>null</code>ifnullstringinput
  531. */
  532. publicstaticStringunescapeJavaScript(Stringstr)
  533. {
  534. if(str==null)
  535. {
  536. returnnull;
  537. }
  538. StringBufferwriter=newStringBuffer(str.length());
  539. intsz=str.length();
  540. StringBufferunicode=newStringBuffer(4);
  541. booleanhadSlash=false;
  542. booleaninUnicode=false;
  543. for(inti=0;i<sz;i++)
  544. {
  545. charch=str.charAt(i);
  546. if(inUnicode)
  547. {
  548. //ifinunicode,thenwe'rereadingunicode
  549. //valuesinsomehow
  550. unicode.append(ch);
  551. if(unicode.length()==4)
  552. {
  553. //unicodenowcontainsthefourhexdigits
  554. //whichrepresentsourunicodechacater
  555. try
  556. {
  557. intvalue=Integer.parseInt(unicode.toString(),16);
  558. writer.append((char)value);
  559. unicode.setLength(0);
  560. inUnicode=false;
  561. hadSlash=false;
  562. }
  563. catch(NumberFormatExceptionnfe)
  564. {
  565. thrownewIllegalArgumentException("Unabletoparseunicodevalue:"+unicode+"cause:"+nfe);
  566. }
  567. }
  568. continue;
  569. }
  570. if(hadSlash)
  571. {
  572. //handleanescapedvalue
  573. hadSlash=false;
  574. switch(ch)
  575. {
  576. case'//':
  577. writer.append('//');
  578. break;
  579. case'/'':
  580. writer.append('/'');
  581. break;
  582. case'/"':
  583. writer.append('"');
  584. break;
  585. case'r':
  586. writer.append('/r');
  587. break;
  588. case'f':
  589. writer.append('/f');
  590. break;
  591. case't':
  592. writer.append('/t');
  593. break;
  594. case'n':
  595. writer.append('/n');
  596. break;
  597. case'b':
  598. writer.append('/b');
  599. break;
  600. case'u':
  601. //uh-oh,we'reinunicodecountry....
  602. inUnicode=true;
  603. break;
  604. default:
  605. writer.append(ch);
  606. break;
  607. }
  608. continue;
  609. }
  610. elseif(ch=='//')
  611. {
  612. hadSlash=true;
  613. continue;
  614. }
  615. writer.append(ch);
  616. }
  617. if(hadSlash)
  618. {
  619. //thenwe'reintheweirdcaseofa/attheendofthe
  620. //string,let'soutputitanyway.
  621. writer.append('//');
  622. }
  623. returnwriter.toString();
  624. }
  625. /**
  626. *Checktoseeifthegivenwordisreservedorabadideainanyknown
  627. *versionofJavaScript.
  628. *@paramnameThewordtocheck
  629. *@returnfalseifthewordisnotreserved
  630. */
  631. publicstaticbooleanisReservedWord(Stringname)
  632. {
  633. returnreserved.contains(name);
  634. }
  635. /**
  636. *Thearrayofjavascriptreservedwords
  637. */
  638. privatestaticfinalString[]RESERVED_ARRAY=newString[]
  639. {
  640. //ReservedandusedatECMAScript4
  641. "as",
  642. "break",
  643. "case",
  644. "catch",
  645. "class",
  646. "const",
  647. "continue",
  648. "default",
  649. "delete",
  650. "do",
  651. "else",
  652. "export",
  653. "extends",
  654. "false",
  655. "finally",
  656. "for",
  657. "function",
  658. "if",
  659. "import",
  660. "in",
  661. "instanceof",
  662. "is",
  663. "namespace",
  664. "new",
  665. "null",
  666. "package",
  667. "private",
  668. "public",
  669. "return",
  670. "super",
  671. "switch",
  672. "this",
  673. "throw",
  674. "true",
  675. "try",
  676. "typeof",
  677. "use",
  678. "var",
  679. "void",
  680. "while",
  681. "with",
  682. //ReservedforfutureuseatECMAScript4
  683. "abstract",
  684. "debugger",
  685. "enum",
  686. "goto",
  687. "implements",
  688. "interface",
  689. "native",
  690. "protected",
  691. "synchronized",
  692. "throws",
  693. "transient",
  694. "volatile",
  695. //ReservedinECMAScript3,unreservedat4besttoavoidanyway
  696. "boolean",
  697. "byte",
  698. "char",
  699. "double",
  700. "final",
  701. "float",
  702. "int",
  703. "long",
  704. "short",
  705. "static",
  706. //Ihaveseenthefolowinglistas'bestavoidedforfunctionnames'
  707. //butitseemswaytoallencompassing,soI'mnotgoingtoincludeit
  708. /*
  709. "alert","anchor","area","arguments","array","assign","blur",
  710. "boolean","button","callee","caller","captureevents","checkbox",
  711. "clearinterval","cleartimeout","close","closed","confirm",
  712. "constructor","date","defaultstatus","document","element","escape",
  713. "eval","fileupload","find","focus","form","frame","frames",
  714. "getclass","hidden","history","home","image","infinity",
  715. "innerheight","isfinite","innerwidth","isnan","java","javaarray",
  716. "javaclass","javaobject","javapackage","length","link","location",
  717. "locationbar","math","menubar","mimetype","moveby","moveto",
  718. "name","nan","navigate","navigator","netscape","number","object",
  719. "onblur","onerror","onfocus","onload","onunload","open","opener",
  720. "option","outerheight","outerwidth","packages","pagexoffset",
  721. "pageyoffset","parent","parsefloat","parseint","password",
  722. "personalbar","plugin","print","prompt","prototype","radio","ref",
  723. "regexp","releaseevents","reset","resizeby","resizeto",
  724. "routeevent","scroll","scrollbars","scrollby","scrollto","select",
  725. "self","setinterval","settimeout","status","statusbar","stop",
  726. "string","submit","sun","taint","text","textarea","toolbar",
  727. "top","tostring","unescape","untaint","unwatch","valueof","watch",
  728. "window",
  729. */
  730. };
  731. privatestaticSortedSetreserved=newTreeSet();
  732. /**
  733. *Foreasyaccess...
  734. */
  735. static
  736. {
  737. //TheJavascriptreservedwordsarraysowedon'tgenerateillegaljavascript
  738. reserved.addAll(Arrays.asList(RESERVED_ARRAY));
  739. }
  740. privatestaticfinalStringSPACE="";
  741. /**
  742. *Howdoesamultilinecommentstart?
  743. */
  744. privatestaticfinalStringCOMMENT_ML_START="/*";
  745. /**
  746. *Howdoesamultilinecommentend?
  747. */
  748. privatestaticfinalStringCOMMENT_ML_END="*/";
  749. /**
  750. *Howdoesasinglelinecommentstart?
  751. */
  752. privatestaticfinalStringCOMMENT_SL_START="//";
  753. /**
  754. *Sometimesweneedtoretainthecommentbecauseithasspecialmeaning
  755. */
  756. privatestaticfinalStringCOMMENT_RETAIN="#DWR";
  757. /**
  758. *Thelogstream
  759. */
  760. privatestaticfinalLoglog=LogFactory.getLog(JavascriptUtil.class);
  761. }


    需要的JSON类我已经放到共享,你可以从
    http://download.csdn.net/source/879579

    下载
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics