主要是解决JSON因Hibernate映射生成的集合的转化出现的死循环问题。
这个方法很重要
1 public String ajaxJsonByObjectDirecdt(Object obj, String[] filterNames){ 2 JsonConfig jsonConfig = new JsonConfig(); 3 jsonConfig.setIgnoreDefaultExcludes(false); 4 jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT); //防止自包含 5 6 if(filterNames != null){ 7 //这里是核心,过滤掉不想使用的属性 8 jsonConfig .setExcludes(filterNames) ; 9 }10 JSONObject jsonObj = JSONObject.fromObject(obj, jsonConfig);11 //ajax()方法主要功能是将数据通过输出流输出到Client12 return ajax(jsonObj.toString(), "text/html");13 14 }
对于参数,String[] filterNames,这个字符串数组中存放的是变量的名字(句柄),而不是变量的类型。
1 public String getUserLoginInfo(){ 2 User user = (User)getSession().getAttribute(USER); 3 //要过滤的属性集合 4 String[] filterNames = 5 new String[]{"role", "operatingHistories", "helpInfoBoards", "replyInfos", 6 "helpInfos", "credits", "users", "user", 7 "helpInfoBoard"}; 8 9 return ajaxJsonByObjectDirecdt(user, filterNames);10 }
其中User类含有以下属性:
1 public class User implements java.io.Serializable { 2 3 // Fields 4 5 private String id; 6 private Role role; 7 private String username; 8 private String studentNum; 9 private String address;10 private Integer age;11 private String nickname;12 private String sex;13 private String qq;14 private String phonenumber;15 private String fixedTelephone;16 private String password;17 private Timestamp registerDate;18 private String imgUrl;19 private String email;20 private String question;21 private String answer;22 private Timestamp totalOnlineDate;23 private SetoperatingHistories = new HashSet (24 0);25 private Set helpInfoBoards = new HashSet (0);26 private Set replyInfos = new HashSet (0);27 private Set helpInfos = new HashSet (0);28 private Set credits = new HashSet (0);29 30 31 //more methods. 32 }
两端代码参照下,就知道怎么使用了。
后台异常信息:
1 INFO com.opensymphony.xwork2.config.ConfigurationManager 2 Detected container provider org.apache.struts2.convention.ClasspathConfigurationProvider@67b0eb2c needs to be reloaded. Reloading all providers. 3 INFO com.opensymphony.xwork2.config.ConfigurationManager 4 Detected package provider org.apache.struts2.convention.ClasspathConfigurationProvider@67b0eb2c needs to be reloaded. Reloading all providers. 5 INFO com.opensymphony.xwork2.config.ConfigurationManager 6 Detected package provider org.apache.struts2.convention.ClasspathConfigurationProvider@31af5c3 needs to be reloaded. Reloading all providers. 7 INFO com.opensymphony.xwork2.config.ConfigurationManager 8 Detected package provider org.apache.struts2.convention.ClasspathPackageProvider@5efcd6cc needs to be reloaded. Reloading all providers. 9 INFO com.opensymphony.xwork2.config.providers.XmlConfigurationProvider 10 Parsing configuration file [struts-default.xml] 11 INFO com.opensymphony.xwork2.config.providers.XmlConfigurationProvider 12 Parsing configuration file [struts-plugin.xml] 13 INFO com.opensymphony.xwork2.config.providers.XmlConfigurationProvider 14 Parsing configuration file [struts.xml] 15 INFO com.opensymphony.xwork2.config.impl.DefaultConfiguration 16 Overriding property struts.i18n.reload - old value: false new value: true 17 INFO com.opensymphony.xwork2.config.impl.DefaultConfiguration 18 Overriding property struts.configuration.xml.reload - old value: false new value: true 19 INFO org.apache.struts2.config.BeanSelectionProvider 20 Loading global messages from i18n 21 INFO org.apache.struts2.spring.StrutsSpringObjectFactory 22 Initializing Struts-Spring integration... 23 INFO com.opensymphony.xwork2.spring.SpringObjectFactory 24 Setting autowire strategy to name 25 INFO org.apache.struts2.spring.StrutsSpringObjectFactory 26 ... initialized Struts-Spring integration successfully 27 2014-06-03 01:07:12 Test: Reloading class 'student.life.support.platform.action.BaseAction'. 28 hql:from student.life.support.platform.model.User as model where model.username = ? 29 Hibernate: 30 select 31 user0_.id as id62_, 32 user0_.address as address62_, 33 user0_.age as age62_, 34 user0_.answer as answer62_, 35 user0_.email as email62_, 36 user0_.fixed_telephone as fixed6_62_, 37 user0_.img_url as img7_62_, 38 user0_.nickname as nickname62_, 39 user0_.password as password62_, 40 user0_.phonenumber as phonenu10_62_, 41 user0_.qq as qq62_, 42 user0_.question as question62_, 43 user0_.register_date as register13_62_, 44 user0_.role_id as role18_62_, 45 user0_.sex as sex62_, 46 user0_.student_num as student15_62_, 47 user0_.total_online_date as total16_62_, 48 user0_.username as username62_ 49 from 50 studentlifesupportplatform.user user0_ 51 where 52 user0_.username=? 53 WARN net.sf.json.JSONObject 54 Property 'handler' has no read method. SKIPPED 55 Hibernate: 56 select 57 role0_.id as id61_0_, 58 role0_.role_permissions as role2_61_0_, 59 role0_.role_type as role3_61_0_ 60 from 61 studentlifesupportplatform.role role0_ 62 where 63 role0_.id=? 64 Hibernate: 65 select 66 users0_.role_id as role18_1_, 67 users0_.id as id1_, 68 users0_.id as id62_0_, 69 users0_.address as address62_0_, 70 users0_.age as age62_0_, 71 users0_.answer as answer62_0_, 72 users0_.email as email62_0_, 73 users0_.fixed_telephone as fixed6_62_0_, 74 users0_.img_url as img7_62_0_, 75 users0_.nickname as nickname62_0_, 76 users0_.password as password62_0_, 77 users0_.phonenumber as phonenu10_62_0_, 78 users0_.qq as qq62_0_, 79 users0_.question as question62_0_, 80 users0_.register_date as register13_62_0_, 81 users0_.role_id as role18_62_0_, 82 users0_.sex as sex62_0_, 83 users0_.student_num as student15_62_0_, 84 users0_.total_online_date as total16_62_0_, 85 users0_.username as username62_0_ 86 from 87 studentlifesupportplatform.user users0_ 88 where 89 users0_.role_id=? 90 WARN net.sf.json.JSONObject 91 Property 'transactionTimeout' has no read method. SKIPPED 92 WARN net.sf.json.JSONObject 93 Property 'URL' has no read method. SKIPPED 94 WARN net.sf.json.JSONObject 95 Property 'array' has no read method. SKIPPED 96 WARN net.sf.json.JSONObject 97 Property 'asciiStream' has no read method. SKIPPED 98 WARN net.sf.json.JSONObject 99 Property 'bigDecimal' has no read method. SKIPPED100 WARN net.sf.json.JSONObject101 Property 'binaryStream' has no read method. SKIPPED102 WARN net.sf.json.JSONObject103 Property 'blob' has no read method. SKIPPED104 WARN net.sf.json.JSONObject105 Property 'boolean' has no read method. SKIPPED106 WARN net.sf.json.JSONObject107 Property 'byte' has no read method. SKIPPED108 WARN net.sf.json.JSONObject109 Property 'bytes' has no read method. SKIPPED110 WARN net.sf.json.JSONObject111 Property 'characterStream' has no read method. SKIPPED112 WARN net.sf.json.JSONObject113 Property 'clob' has no read method. SKIPPED114 ERROR freemarker.runtime115 Method public java.lang.String org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int) threw an exception when invoked on net.sf.json.JSONException: java.lang.reflect.InvocationTargetException116 Method public java.lang.String org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int) threw an exception when invoked on net.sf.json.JSONException: java.lang.reflect.InvocationTargetException117 The problematic instruction:118 ----------119 ==> ${msg[0]} [on line 68, column 29 in org/apache/struts2/dispatcher/error.ftl]120 ----------121 122 Java backtrace for programmers:123 ----------124 freemarker.template.TemplateModelException: Method public java.lang.String org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int) threw an exception when invoked on net.sf.json.JSONException: java.lang.reflect.InvocationTargetException125 at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)126 at freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)127 at freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)128 at freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)129 at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)130 at freemarker.core.Expression.getStringValue(Expression.java:93)131 at freemarker.core.DollarVariable.accept(DollarVariable.java:76)132 at freemarker.core.Environment.visit(Environment.java:210)133 at freemarker.core.MixedContent.accept(MixedContent.java:92)134 at freemarker.core.Environment.visit(Environment.java:210)135 at freemarker.core.IfBlock.accept(IfBlock.java:82)136 at freemarker.core.Environment.visit(Environment.java:210)137 at freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:179)138 at freemarker.core.Environment.visit(Environment.java:417)139 at freemarker.core.IteratorBlock.accept(IteratorBlock.java:102)140 at freemarker.core.Environment.visit(Environment.java:210)141 at freemarker.core.MixedContent.accept(MixedContent.java:92)142 at freemarker.core.Environment.visit(Environment.java:210)143 at freemarker.core.IfBlock.accept(IfBlock.java:82)144 at freemarker.core.Environment.visit(Environment.java:210)145 at freemarker.core.MixedContent.accept(MixedContent.java:92)146 at freemarker.core.Environment.visit(Environment.java:210)147 at freemarker.core.Environment.process(Environment.java:190)148 at freemarker.template.Template.process(Template.java:237)149 at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)150 at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)151 at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)152 at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)153 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)154 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)155 at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)156 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)157 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)158 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)159 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)160 at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)161 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)162 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)163 at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171)164 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)165 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)166 at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)167 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)168 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)169 at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)170 at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)171 at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)172 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)173 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)174 at java.lang.Thread.run(Thread.java:662)175 Caused by: java.lang.NullPointerException176 at freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)177 at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)178 ... 49 more179 2014-6-3 1:07:12 org.apache.catalina.core.StandardWrapperValve invoke180 严重: Servlet.service() for servlet [default] in context with path [/StudentLifeSupportPlatformSystem] threw exception181 java.lang.IllegalStateException: Cannot call sendError() after the response has been committed182 at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:451)183 at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:801)184 at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)185 at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)186 at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)187 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)188 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)189 at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)190 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)191 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)192 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)193 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)194 at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)195 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)196 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)197 at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171)198 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)199 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)200 at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)201 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)202 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)203 at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)204 at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)205 at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)206 at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)207 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)208 at java.lang.Thread.run(Thread.java:662)
欢迎讨论交流,
我的邮箱:zone.technology.exchange@gmail.com