web-dev-qa-db-ja.com

JsonMappingException:JSON文字列から型[単純型、a.b.c.Company]の値をインスタンス化できません。単一文字列のコンストラクタ/ファクトリメソッドはありません

既存のSpring + BlazeDS + HibernateサーバーにREST apiを追加しました。データを取得してJSONとしてシリアル化するとすべてが動作するように見えますが、POST POJOにデシリアライズされるデータ例外が発生します。

私は、春の注釈とクラスパス内のジャクソン瓶の存在が必要なすべてであるという印象を受けていました、少なくともそれは、単純なパラメーターを持つリスト、取得、削除メソッドのためでした。

org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class com.twoh.dto.Company] from JSON String; no single-String constructor/factory method

呼び出されるメソッドは次のとおりです。

public abstract class BaseEntityService<T extends BaseEntity> implements IBaseEntityService<T> {

private IBaseEntityDAO<T> DAO;

@Autowired
private ValidationResultHelper validationResultHelper;

public void setDAO(IBaseEntityDAO<T> DAO) {
    this.DAO = DAO;
}

...
@Secured("ROLE_USER")
@RequestMapping(value="/create", method=RequestMethod.POST)
public @ResponseBody ValidationResult create(@RequestBody T entity) {
    ValidationResult result = null;
    try {
        result = DAO.persistEntity(entity);
    } catch(JDBCException e) {
        result = ExceptionHelper.getValidationResult(e);
    } catch(DataIntegrityViolationException e) {
        result = ExceptionHelper.getValidationResult(e);
    }
    validationResultHelper.log(DAO.getSession(), entity.getId(), entity.getClass(), result);
    return result;
}
}

ここに完全な例外があります:

org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class com.twoh.dto.Company] from JSON String; no single-String constructor/factory method
at org.codehaus.jackson.map.deser.std.StdValueInstantiator._createFromStringFallbacks(StdValueInstantiator.Java:379)
at org.codehaus.jackson.map.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.Java:268)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromString(BeanDeserializer.Java:759)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.Java:585)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.Java:2723)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.Java:1914)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.Java:135)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.Java:154)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.readWithMessageConverters(HandlerMethodInvoker.Java:633)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestBody(HandlerMethodInvoker.Java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.Java:346)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.Java:171)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.Java:436)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.Java:424)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:669)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.Java:585)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:717)
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:290)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
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:235)
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:311)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.Java:116)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.Java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.Java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.Java:101)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.Java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.Java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.Java:182)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:173)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.Java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.Java:167)
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:298)
at org.Apache.coyote.http11.Http11Processor.process(Http11Processor.Java:857)
at org.Apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.Java:588)
at org.Apache.Tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.Java:489)
at Java.lang.Thread.run(Unknown Source)

更新:会社DTOの定義を追加

@CheckDictionaryProperty.List({
    @CheckDictionaryProperty(propertyName="partyId", dictionaryName="Party")
})
@Unique.List({
    @Unique(properties = {"code"}, message = "UNIQUE_CODE"),
    @Unique(properties = {"name"}, message = "UNIQUE_NAME")
})
@Entity
@FXClass
@Table(name="edrcompany")
@JsonAutoDetect
public class Company extends BaseEntity {

    private static final long serialVersionUID = 1L;

    public Company(){}

    @NotBlank
    @Column
    private String name;
    public String getName(){ return this.name; }
    public void setName(String name){ this.name = name; }

    @Column
    private String code;
    public String getCode() { return this.code; }
    public void setCode(String code) { this.code = code; }

    @NotNull
    @Column(name="party_id")
    private Integer partyId;
    public Integer getPartyId() { return this.partyId; }
    public void setPartyId(Integer partyId) { this.partyId = ValueHelper.isNullOrZero(partyId) ? null : partyId; }

    @ElementCollection(targetClass=Integer.class, fetch=FetchType.EAGER)
    @Fetch(FetchMode.SUBSELECT)
    @CollectionTable(name="edrcompanyadminlink", joinColumns={@JoinColumn(name="company_id")})
    @Column(name="user_id")
    private Collection<Integer> adminUserIdList = new HashSet<Integer>();
    public Collection<Integer> getAdminUserIdList() { return this.adminUserIdList; }
    public void setAdminUserIdList (Collection<Integer> adminUserIdList) { this.adminUserIdList = adminUserIdList; }    


}


@MappedSuperclass
@FXClass
public abstract class BaseEntity implements Serializable  {

    private static final long serialVersionUID = 1L;

    public BaseEntity(){}

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = ValueHelper.isNullOrZero(id) ? null : id; }

    @Column(name="ENTITY_UID", unique=true, nullable=false, updatable=false, length=36)
    /* Assign a default whenever this class is instantiated Hibernate will 
     * overwrite it when retrieving an entity from the DB.
     */
    private String uid = UUID.randomUUID().toString();
    public String getUID() { return uid; };
    public void setUID(String uid) { this.uid = uid; }

    @Version
    @Column
    private Integer version;
    @FXIgnore
    public Integer getVersion() { return this.version; }
    public void setVersion(Integer version) { this.version = version; }

    // Fake property so that DTO2FX will put it in
    public String getClassName() { return this.getClass().getName(); }
    @JsonIgnore
    public void setClassName(String className) { throw new UnsupportedOperationException(); }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || !(o instanceof BaseEntity)) return false;

        BaseEntity other = (BaseEntity) o;

        // if the id is missing, return false
        if (uid == null) return false;

        // equivalence by uid
        return uid.equals(other.getUID());
    }

    @Override
    public int hashCode() {
        if (uid != null) {
            return uid.hashCode();
        } else {
            return super.hashCode();
        }
    }

    @Override
    public String toString() {
        return this.getClassName() + ": " + this.getId();
    }

}

更新 JacksonがCompany.adminUserIdListプロパティを無視するようにDTOを修正すると、レコードが正常に作成されます。

@JsonIgnore
public Collection<Integer> getAdminUserIdList() { return this.adminUserIdList; }
@JsonIgnore
public void setAdminUserIdList (Collection<Integer> adminUserIdList) { this.adminUserIdList = adminUserIdList; }    

更新 FireFox RESTClientを使用して/company/get/1メソッドによって返されるJsonは次のとおりです。

{
  "partyId":1,
  "adminUserIdList":[21],
  "name":"2H Mechanical LLC",
  "code":null,
  "uid":"fc5e15e7-a9a7-11e1-be90-7d08b05cbb96",
  "id":1,
  "className":"com.twoh.dto.Company",
  "version":0
}

/compamy/createヘッダーを使用したContent-type=application/json呼び出しに類似のパターン(「id」と異なる「uid」を使用)を使用していました

12
hairyone

サーバーに送信していたJSONを修正することで同じ問題を解決しました。無効でした。最後の属性の最後にある「、」文字を削除し、機能しました。私はそれが役立つことを願っています

13
Techky

私の場合、中括弧の開始と終了が欠落していました。

0
Nirmal Mangal

@Nirmalと同様に、二重引用符で囲まれたJSONを渡しました。

"{ "SomeJSON":"Value" }"

の代わりに

{ "SomeJSON":"Value" }

"sを削除すると、問題は解決しました。

0
DivDiff