[摘要]本文是对JAVA对象转化JSON出现死循环问题的讲解,对学习Java编程技术有所帮助,与大家分享。
主要是解决JSON因Hibernate映射生成的集合的转化出现的死循环问题。
这个方法很重要
public String ajaxJsonByObjectDirecdt(Object obj, String[] filterNames){ JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setIgnoreDefaultExcludes(false); jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT); //防止自包含 if(filterNames != null){ //这里是核心,过滤掉不想使用的属性 jsonConfig .setExcludes(filterNames) ; } JSONObject jsonObj = JSONObject.fromObject(obj, jsonConfig); //ajax()方法主要功能是将数据通过输出流输出到Client return ajax(jsonObj.toString(), "text/html"); }对于参数,String[] filterNames,这个字符串数组中存放的是变量的名字(句柄),而不是变量的类型。public String getUserLoginInfo(){ User user = (User)getSession().getAttribute(USER); //要过滤的属性集合 String[] filterNames = new String[]{"role", "operatingHistories", "helpInfoBoards", "replyInfos", "helpInfos", "credits", "users", "user", "helpInfoBoard"}; return ajaxJsonByObjectDirecdt(user, filterNames); }
其中User类含有以下属性:
public class User implements java.io.Serializable { // Fields private String id; private Role role; private String username; private String studentNum; private String address; private Integer age; private String nickname; private String sex; private String qq; private String phonenumber; private String fixedTelephone; private String password; private Timestamp registerDate; private String imgUrl; private String email; private String question; private String answer; private Timestamp totalOnlineDate; private Set<OperatingHistory> operatingHistories = new HashSet<OperatingHistory>( 0); private Set<HelpInfoBoard> helpInfoBoards = new HashSet<HelpInfoBoard>(0); private Set<ReplyInfo> replyInfos = new HashSet<ReplyInfo>(0); private Set<HelpInfo> helpInfos = new HashSet<HelpInfo>(0); private Set<Credit> credits = new HashSet<Credit>(0); //more methods. }两端代码参照下,就知道怎么使用了。后台异常信息:
INFO com.opensymphony.xwork2.config.ConfigurationManager Detected container provider org.apache.struts2.convention.ClasspathConfigurationProvider@67b0eb2c needs to be reloaded. Reloading all providers. INFO com.opensymphony.xwork2.config.ConfigurationManager Detected package provider org.apache.struts2.convention.ClasspathConfigurationProvider@67b0eb2c needs to be reloaded. Reloading all providers. INFO com.opensymphony.xwork2.config.ConfigurationManager Detected package provider org.apache.struts2.convention.ClasspathConfigurationProvider@31af5c3 needs to be reloaded. Reloading all providers. INFO com.opensymphony.xwork2.config.ConfigurationManager Detected package provider org.apache.struts2.convention.ClasspathPackageProvider@5efcd6cc needs to be reloaded. Reloading all providers. INFO com.opensymphony.xwork2.config.providers.XmlConfigurationProvider Parsing configuration file [struts-default.xml] INFO com.opensymphony.xwork2.config.providers.XmlConfigurationProvider Parsing configuration file [struts-plugin.xml] INFO com.opensymphony.xwork2.config.providers.XmlConfigurationProvider Parsing configuration file [struts.xml] INFO com.opensymphony.xwork2.config.impl.DefaultConfiguration Overriding property struts.i18n.reload - old value: false new value: true INFO com.opensymphony.xwork2.config.impl.DefaultConfiguration Overriding property struts.configuration.xml.reload - old value: false new value: true INFO org.apache.struts2.config.BeanSelectionProvider Loading global messages from i18n INFO org.apache.struts2.spring.StrutsSpringObjectFactory Initializing Struts-Spring integration... INFO com.opensymphony.xwork2.spring.SpringObjectFactory Setting autowire strategy to name INFO org.apache.struts2.spring.StrutsSpringObjectFactory ... initialized Struts-Spring integration successfully 2014-06-03 01:07:12 Test: Reloading class 'student.life.support.platform.action.BaseAction'. hql:from student.life.support.platform.model.User as model where model.username = ? Hibernate: select user0_.id as id62_, user0_.address as address62_, user0_.age as age62_, user0_.answer as answer62_, user0_.email as email62_, user0_.fixed_telephone as fixed6_62_, user0_.img_url as img7_62_, user0_.nickname as nickname62_, user0_.password as password62_, user0_.phonenumber as phonenu10_62_, user0_.qq as qq62_, user0_.question as question62_, user0_.register_date as register13_62_, user0_.role_id as role18_62_, user0_.sex as sex62_, user0_.student_num as student15_62_, user0_.total_online_date as total16_62_, user0_.username as username62_ from studentlifesupportplatform.user user0_ where user0_.username=? WARN net.sf.json.JSONObject Property 'handler' has no read method. SKIPPED Hibernate: select role0_.id as id61_0_, role0_.role_permissions as role2_61_0_, role0_.role_type as role3_61_0_ from studentlifesupportplatform.role role0_ where role0_.id=? Hibernate: select users0_.role_id as role18_1_, users0_.id as id1_, users0_.id as id62_0_, users0_.address as address62_0_, users0_.age as age62_0_, users0_.answer as answer62_0_, users0_.email as email62_0_, users0_.fixed_telephone as fixed6_62_0_, users0_.img_url as img7_62_0_, users0_.nickname as nickname62_0_, users0_.password as password62_0_, users0_.phonenumber as phonenu10_62_0_, users0_.qq as qq62_0_, users0_.question as question62_0_, users0_.register_date as register13_62_0_, users0_.role_id as role18_62_0_, users0_.sex as sex62_0_, users0_.student_num as student15_62_0_, users0_.total_online_date as total16_62_0_, users0_.username as username62_0_ from studentlifesupportplatform.user users0_ where users0_.role_id=? WARN net.sf.json.JSONObject Property 'transactionTimeout' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'URL' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'array' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'asciiStream' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'bigDecimal' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'binaryStream' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'blob' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'boolean' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'byte' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'bytes' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'characterStream' has no read method. SKIPPED WARN net.sf.json.JSONObject Property 'clob' has no read method. SKIPPED ERROR freemarker.runtime 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.InvocationTargetException 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.InvocationTargetException The problematic instruction: ---------- ==> ${msg[0]} [on line 68, column 29 in org/apache/struts2/dispatcher/error.ftl] ---------- Java backtrace for programmers: ---------- 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.InvocationTargetException at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130) at freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138) at freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111) at freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90) at freemarker.core.Expression.getAsTemplateModel(Expression.java:89) at freemarker.core.Expression.getStringValue(Expression.java:93) at freemarker.core.DollarVariable.accept(DollarVariable.java:76) at freemarker.core.Environment.visit(Environment.java:210) at freemarker.core.MixedContent.accept(MixedContent.java:92) at freemarker.core.Environment.visit(Environment.java:210) at freemarker.core.IfBlock.accept(IfBlock.java:82) at freemarker.core.Environment.visit(Environment.java:210) at freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:179) at freemarker.core.Environment.visit(Environment.java:417) at freemarker.core.IteratorBlock.accept(IteratorBlock.java:102) at freemarker.core.Environment.visit(Environment.java:210) at freemarker.core.MixedContent.accept(MixedContent.java:92) at freemarker.core.Environment.visit(Environment.java:210) at freemarker.core.IfBlock.accept(IfBlock.java:82) at freemarker.core.Environment.visit(Environment.java:210) at freemarker.core.MixedContent.accept(MixedContent.java:92) at freemarker.core.Environment.visit(Environment.java:210) at freemarker.core.Environment.process(Environment.java:190) at freemarker.template.Template.process(Template.java:237) at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797) at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519) at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: java.lang.NullPointerException at freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85) at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106) ... 49 more 2014-6-3 1:07:12 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service() for servlet [default] in context with path [/StudentLifeSupportPlatformSystem] threw exception java.lang.IllegalStateException: Cannot call sendError() after the response has been committed at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:451) at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:801) at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519) at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662)