Struts2整合Json和MyBatis,懒加载对象无法被正确转化json的问题
项目采用Struts2,已经加入struts-json-plugin来整合Json,DAO层使用了MyBatis。
以下是相关信息:
struts.xml:
......
<package name="json" namespace="/" extends="json-default">
<action name="versions" class="com.hp.cmu.dbmanager.action.ProjectVersionAction">
<result name="json" type="json"/>
</action>
</package>
.......
Action:
public class ProjectVersionAction extends BaseAction {
private static final long serialVersionUID = -3683721108697436670L;
private ProjectVersionService projectVersionService;
private List<ProjectVersion> projectVersions;
private long projectId;
public String findVersionByProject() {
projectVersions = projectVersionService.findByProject(projectId);
return "json";
}
/*以提供所有的getter/setter*/
}
ProjectVersion类:
public class ProjectVersion implements Serializable {
private static final long serialVersionUID = 6222511923126470050L;
private Project project;
private long versionId;
private String version;
/*以提供getter/setter*/
}
Project类:
public class Project implements Serializable {
private static final long serialVersionUID = 947162450880795125L;
private long projectId;
private String projectName;
private String projectDesc;
private String activeFg;
/*以提供getter/setter*/
}
问题描述:
页面通过JQuery的ajax调用findVersionByProject方法,控制台报错如下:
10:32:58,780 DEBUG JSONWriter:72 - com.hp.cmu.dbmanager.model.ProjectVersion.getCallbacks()
java.lang.NoSuchMethodException: com.hp.cmu.dbmanager.model.ProjectVersion.getCallbacks()
at java.lang.Class.getMethod(Class.java:1605)
at org.apache.struts2.json.JSONWriter.findBaseAccessor(JSONWriter.java:266)
at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:194)
at org.apache.struts2.json.JSONWriter.processCustom(JSONWriter.java:171)
at org.apache.struts2.json.JSONWriter.process(JSONWriter.java:161)
at org.apache.struts2.json.JSONWriter.value(JSONWriter.java:127)
at org.apache.struts2.json.JSONWriter.array(JSONWriter.java:455)
at org.apache.struts2.json.JSONWriter.process(JSONWriter.java:151)
at org.apache.struts2.json.JSONWriter.value(JSONWriter.java:127)
at org.apache.struts2.json.JSONWriter.add(JSONWriter.java:363)
at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:223)
at org.apache.struts2.json.JSONWriter.processCustom(JSONWriter.java:171)
at org.apache.struts2.json.JSONWriter.process(JSONWriter.java:161)
at org.apache.struts2.json.JSONWriter.value(JSONWriter.java:127)
at org.apache.struts2.json.JSONWriter.write(JSONWriter.java:95)
at org.apache.struts2.json.JSONUtil.serialize(JSONUtil.java:116)
at org.apache.struts2.json.JSONResult.createJSONString(JSONResult.java:196)
at org.apache.struts2.json.JSONResult.execute(JSONResult.java:170)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:374)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:278)
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:176)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:211)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:211)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:190)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:90)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:243)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:176)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:192)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:511)
at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:432)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:102)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
经查是由于json-plugin在转换延迟加载对象时会出现问题,当把project对象从projectVersion中移除后,功能正常。所以现在的问题是要在struts.xml的里加上“excludeProperties”或"includeProperties"属性来过滤一些代理类产生的无效对象或属性,但我不知道具体怎么配置?从前做过类似的Hibernate项目,知道加如下配置可以解决此类问题:
<result type="json">
<param name="excludeProperties">.*hibernateLazyInitializer</param>
</result>
换成MyBatis就不知道了,望有这方面经历的朋友告诉我下,谢谢!
[解决办法]
对象里面的关联对象很容易造成这样的情况,最好用单纯的string之类的东西,需要什么取什么。不要建立关联关系。
[解决办法]
怎么知道json返回那个对象的。
是这样配置的吗?
<result name="json" type="json">
<param name="root">projectVersions</param>
</result>
一般情况定一个类专门存放json数据。
如:2个属性
String msg;//提示的信息
Object o;//返回的数据 是list/单个对象 都可以。
[解决办法]
action中不需要的属性中get方法上加上@JSON(serialize=false)注解。
service接口不注解掉,直接返回全部json数据会报错的