龙目岛+杰克逊=> MismatchedInputException

时间:2019-01-31 12:57:33

标签: java jackson lombok

我有一个PSQL表,其中一列包含jsonb数据:

CREATE TABLE IF NOT EXISTS user (
    user_name VARCHAR(255) NOT NULL,
    user_email VARCHAR(255) NOT NULL,
    user_address jsonb NOT NULL
)

为此,我有以下java object

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Builder;
import lombok.Value;

@Value
@Builder
public class User {
    private String userName;
    private String userEmail;
    private UserAddress address;

    @Value
    @Builder
    @JsonDeserialize(builder = UserAddress.UserAddressBuilder.class)
    public static class UserAddress {
        @JsonProperty("street")
        private String street;
        @JsonProperty("house_number")
        private String houseNumber;

        @JsonPOJOBuilder(withPrefix = "")
        public static class UserAddressBuilder {
            private String street = null;
            private String houseNumber = null;

            public UserAddressBuilder street(String street) {
               this.street = street;

               return this;
            }

            public UserAddressBuilder houseNumber(String houseNumber) {
                this.houseNumber = houseNumber;

                return this;
            }
        }
    }
}

当我现在从User构建ResultSet时:

return User.builder()
        .userName(rs.getString(SqlConstants.TableUser.USER_NAME))
        .userEmail(rs.getString(SqlConstants.TableUser.USER_EMAIL))
        .userAddress(mapper.convertValue(rs.getString(SqlConstants.TableUser.USER_ADDRESS), User.UserAddress.class))
        .build();

我总是例外:

  

原因:com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造my.package.model.User$UserAddress$UserAddressBuilder的实例(尽管存在至少一个Creator):没有要从String值反序列化的String参数自变量/工厂方法( '“ {\” street \“:\” Some Street \“,\” house_number \“:\” Some House Number \“}'”

由于字段匹配,我找不到此问题的根源吗? 我还尝试了不使用@Builder的方法,而是使用了@Data@AllArgsConstructor@NoArgsConstructor

使用readValue而不是convertValue时得到相同的结果

1 个答案:

答案 0 :(得分:1)

如在使用

的评论中所述
.userAddress(mapper.readValue(rs.getString(SqlConstants.TableUser.USER_ADDRESS), 
                                              User.UserAddress.class))

应该只是罚款至少它为我。但是,更改之后,您可能会遇到:

  

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段 “house_number” ...

(代替原来的误差),这将通过小的变化而固定到UserAddressBuilder

@JsonProperty("house_number") // this is also needed to map correctly
public UserAddressBuilder houseNumber(String houseNumber) { ...

来自Javadoc

  

public T convertValue(Object fromValue,Class toValueType)
                 抛出:IllegalArgumentException -

     

从给定值到给定值类型的实例进行两步转换的便捷方法。的这是等同的功能的第一串行化给定值到JSON,然后结合JSON数据到给定类型的值,但可在不完全序列化为JSON来执行。相同的转换器(序列化器,反序列化器)将用于数据绑定,这意味着相同的对象映射器配置有效

readValue用于从字符串,流,读取器读取到对象值。使用convertValue(..),您可能需要定义转换器,但在您的情况下则不需要。