java - 使用 Jackson 进行 json 序列化期间出现 JsonMappingError

标签 java json serialization jackson resteasy

从 org.codehaus.jackson 切换到较新的 com.fasterxml.jackson 后,我遇到了 JsonMappingError。这是我类(class)的代码:

@Entity
@Table(name = "users")
@XmlRootElement
@Indexed(index="User")
public class User extends Resource<ResourceType> {

...

private String sessionId;

@Column(unique = true)
@JsonProperty
@Field(store=Store.YES)
@XmlElement
private String login;

@NotNull
@NotEmpty
private String password;

@Type(type = "localeUserType")
@NotNull
@XmlTransient
private Locale locale;

@NotNull
@JsonProperty
private boolean enabled=true;

@NotNull
@JsonProperty
private boolean hidden;

@NotNull
@JsonProperty
private boolean editable=true;

@JsonProperty
@NotNull
private int idleTime = 0; //minutes for client to dissconnect

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="role_id")
@NotNull
@XmlIDREF
@XmlElement(name="roleId")
private Role role; 

@JsonProperty
private Long expirationTime;

@JsonProperty
private String company;

@JsonProperty
private String department;

@JsonProperty
private String jobTitle;

@JsonProperty
private String email;

@JsonProperty
private String cellPhone;

@JsonProperty
private String officePhone;

@JsonProperty
@NotNull
private boolean mustChangePassword;
...

}

资源类别:

public class Resource<T extends ResourceType> extends AbstractEntity{

@Version
@NotNull
@JsonProperty("entityVersion")
@XmlAttribute
private Integer entityVersion;

@NotNull
@NotEmpty
@JsonProperty
@Field(store=Store.YES)
@Index(name = "resourceNameIndex")
@XmlElement
private String name;

@ManyToOne(targetEntity=ResourceType.class, fetch=FetchType.EAGER)
@JoinColumn(name="resource_type_id")
@NotNull
private T type;

private Integer deleted = 0;

@JsonProperty("type")
public Integer getTypeId() {
    return type==null ? null : type.getId();
}

@JsonProperty("type")
public void setTypeId(int id) {
    if (type!=null)
        type.setId(id);
}

public Resource() {
    entityVersion=0;
}

public NGResource(Integer id, String name){
    this();
    setId(id);
    setName(name);
}

public Resource(String name){
    this();
    setName(name);
}

public Resource(Integer id) {
    super(id);
}

public Resource(String name,T type){
    this(name);
    setType(type);
}
...
}

和抽象实体:

@MappedSuperclass
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@SuppressWarnings("serial")
public abstract class AbstractEntity implements Serializable {

@Id
@GeneratedValue
@JsonProperty("_id")
private Integer id;

public AbstractEntity() {
}

public AbstractEntity(Integer id) {
    this.id = id;
}

public AbstractEntity(int id) {
    this.id = id;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

@XmlID
@XmlAttribute
public void setID(String id){
    this.id=((id==null)?null:Integer.valueOf(id));
}

public String getID() {
    return (id==null)?null:id.toString();
}

}

这是堆栈跟踪:

 com.fasterxml.jackson.databind.JsonMappingException: Invalid Object Id definition for org.domain.entity.User: can not find property with name 'id'
    at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1117)
    at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:471)
    at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:669)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:107)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:851)
    at org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.writeTo(ResteasyJackson2Provider.java:199)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:129)
    at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:62)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:118)
    at org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor.aroundWriteTo(GZIPEncodingInterceptor.java:100)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:122)
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:99)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:432)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:376)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.domain.filter.SeqNoHeaderFilter.doFilter(SeqNoHeaderFilter.java:29)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.domain.filter.CurrentUserFilter.doFilter(CurrentUserFilter.java:36)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.domain.filter.TraceFilter.doFilter(TraceFilter.java:32)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.domain.filter.NoCacheHeaderFilter.doFilter(NoCacheHeaderFilter.java:25)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.gomain.filter.RootFilter.doFilter(RootFilter.java:47)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

有人可以帮我找出我做错了什么吗?

最佳答案

就我而言,这是因为 spring-data-rest 中的默认 RepositoryRestConfigurerAdapter 没有序列化我的实体类的 id 属性。为了解决这个问题,我创建了以下 spring 配置类:

@Configuration
public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
    @Autowired
    private EntityManager entityManager;

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        // This fixes issue where id is not marshalled in get for an object.
        // See: http://stackoverflow.com/questions/24839760/spring-boot-responsebody-doesnt-serialize-entity-id
        config.exposeIdsFor(
                entityManager.getMetamodel().getEntities().stream()
                        .map(Type::getJavaType)
                        .toArray(Class[]::new));
    }    
}

关于java - 使用 Jackson 进行 json 序列化期间出现 JsonMappingError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28071095/

相关文章:

java - 我如何检查 Parse 数据类 Android 中是否已经存在一个值

javascript - 循环 json 数组时出现问题

javascript - 为什么 SoundCloud API 会导致循环以不同的顺序列出数据

c++ - 使用 C++ 将对象读写到二进制文件中?

python - 为什么 dill 比 numpy 数组的 pickle 更快更磁盘高效

java - 使用枚举代替字符串

java - 错误 : cannot find symbol IOUtils. 复制(输入,输出);

java - 什么是 R.layout.search?

c++ - 如何将 JSON 发布到 Web 服务器?

java - 序列化 - 使用 ObjectStreamField [] serialPersistentFields 有什么好处?