反序列化的改造/杰克逊错误

Posted

技术标签:

【中文标题】反序列化的改造/杰克逊错误【英文标题】:Retrofit/Jackson error on deserializing 【发布时间】:2017-12-26 13:33:41 【问题描述】:

我正在尝试从我的 Web 服务获取 JSON 并反序列化为我的类 UserSync,但我收到以下错误:

无法从字符串值 ('') 实例化类型 [简单类型,com.example.breno.teste.model.User] 类型的值;没有单字符串构造函数/工厂方法 在 [来源:okhttp3.ResponseBody$BomAwareReader@fbf814f;行:1,列:86](通过引用链:com.example.breno.teste.dto.UserSync["user"])

我读过一些帖子说我需要在 UserSync 中声明我的用户类静态,但是当我这样做时,杰克逊找不到任何用户属性,即使使用 JsonDescription。另一个帖子说我可能需要声明一个默认构造函数,所以我做了。

这是 UserSync 类:

@JsonIgnoreProperties(ignoreUnknown = true)
public class UserSync 
    @JsonProperty("status")
    private String Status;
    @JsonProperty("currentDate")
    private String CurrentDate;
    @JsonProperty("message")
    private String Message;
    @JsonProperty("user")
    private static User NewUser;

    public UserSync() 
    

    public String getStatus() 
        return Status;
    

    public String getCurrentDate() 
        return CurrentDate;
    

    public String getMessage() 
        return Message;
    

    public static User getNewUser() 
        return NewUser;
    

用户类:

public class User implements Serializable 
    @JsonProperty("userKey")
    private UUID UserKey;
    @JsonProperty("userPassword")
    private String UserPassword;
    @JsonProperty("userGroupKey")
    private UUID UserGroupKey;
    @JsonProperty("signInDate")
    private String SignInDate;
    @JsonProperty("active")
    private boolean Active;
    @JsonProperty("profilePicturePath")
    private String ProfilePic;
    @JsonProperty("completeName")
    private String UserCompleteName;
    @JsonProperty("email")
    private String UserEmail;
    @JsonProperty("isLogged")
    private boolean IsLogged;

    public User() 
    

    public boolean getIsLogged() 
        return IsLogged;
    

    public void setIsLogged(boolean isLogged) 
        IsLogged = isLogged;
    

    public String getUserEmail() 
        return UserEmail;
    

    public void setUserEmail(String userEmail) 
        UserEmail = userEmail;
    

    public UUID getUserKey() 
        return UserKey;
    

    public void setUserKey(UUID userKey) 
        UserKey = userKey;
    

    public String getUserPassword() 
        return UserPassword;
    

    public void setUserPassword(String userPassword) 
        UserPassword = userPassword;
    

    public UUID getUserGroupKey() 
        return UserGroupKey;
    

    public void setUserGroupKey(UUID userGroupKey) 
        UserGroupKey = userGroupKey;
    

    public String getSignInDate() 
        return SignInDate;
    

    public void setSignInDate(String signInDate) 
        SignInDate = signInDate;
    

    public boolean getActive() 
        return Active;
    

    public void setActive(boolean active) 
        Active = active;
    

    public String getProfilePic() 
        return ProfilePic;
    

    public void setProfilePic(String profilePic) 
        ProfilePic = profilePic;
    

    public String getUserCompleteName() 
        return UserCompleteName;
    

    public void setUserCompleteName(String userCompleteName) 
        UserCompleteName = userCompleteName;
        

我的服务类(现在使用 postNewUser):

public interface UserService 
@GET("Login/LoginUser?")
Call<UserSync> login(@Query("email") String email, @Query("password") String password);

//region NewUser Services
@GET("Login/VerifyNewUser?")
Call<UserSync> validateNewUser(@Query("email") String email);

@POST("Login/PostNewUser")
Call<UserSync> postNewUser(@Body User user);
//endregion

最后是 JSON:


  "status": "OK",
  "currentDate": "20/07/2017 11:59:02",
  "message": "teste",
  "user": 
    "userKey": "8e2f0d2d-3522-472d-be1d-28791367f4ee",
    "email": "teste_teste@hotmail.com",
    "userPassword": "123456",
    "profilePicturePath": "teste",
    "completeName": "Jorge",
    "userGroupKey": null,
    "signInDate": "2017-07-07T16:26:06.097",
    "active": true,
    "isLogged": true
  

有人可以帮帮我吗?

编辑 1 - 这是我用来进行改造调用的方法:

public void register(User user) 
        Call<UserSync> postCall = new RetrofitInitializator().getUserService().postNewUser(user);
        postCall.enqueue(getRegisterCallback());
    

@NonNull
    private Callback<UserSync> getRegisterCallback() 
        return new Callback<UserSync>() 
            @Override
            public void onResponse(Call<UserSync> call, Response<UserSync> response) 
                User user = response.body().getNewUser();
            
            @Override
            public void onFailure(Call<UserSync> call, Throwable t) 
                Log.e("Register - onFailure", t.getMessage());
            
        ;
    

EDIT 2 - 改造初始化器类:

public class RetrofitInitializator 
    private final Retrofit retrofit;

    public RetrofitInitializator() 
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient.Builder builder = new OkHttpClient
                .Builder();
        builder.addInterceptor(interceptor);

        retrofit = new Retrofit.Builder()
                .baseUrl("http://192.168.15.6:7071/api/")
                .addConverterFactory(JacksonConverterFactory.create())
                .client(builder.build())
                .build();
    

    public UserService getUserService() 
        return retrofit.create(UserService.class);
    

【问题讨论】:

向我们展示您如何创建改造服务类 (UserService) @MatiasElorriaga 在通话中添加了编辑 1。 请添加RetrofitInitializator代码..我想看看你是否添加杰克逊转换器 @MatiasElorriaga,有。 我认为您需要在 User 中添加一个构造函数,它将一个字符串作为参数,并将该字符串解析为一个 User 对象。 【参考方案1】:

我设法解决了将 User 类型切换为 JsonNode 并在此之后进行转换的问题。

@JsonProperty("status")
    private String Status;
    @JsonProperty("currentDate")
    private String CurrentDate;
    @JsonProperty("message")
    private String Message;
    @JsonProperty("user")
    private JsonNode NewUser;

和转换:

private User getUserFromUserAsync(UserSync userSync) throws JsonProcessingException 
        ObjectMapper mapper = new ObjectMapper();
        return mapper.treeToValue(userSync.getNewUser(), User.class);
    

【讨论】:

以上是关于反序列化的改造/杰克逊错误的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试反序列化对象列表时,杰克逊抛出错误映射异常

杰克逊未能将字符串反序列化为 Joda-Time

Spring框架中的Jackson反序列化错误处理

杰克逊:地图的反序列化

有啥方法可以防止杰克逊中的字段反序列化?

JSON杰克逊序列化反序列化列表列表