Json Jackson десериализует объект без сеттеров

У меня есть класс (например, в реальном проекте у меня есть JAXB сгенерированный класс вместо User):

public class User {
  private List<String> users;

  public List<String> getUsers() {
    return users;
  }
}

Когда я получаю пользовательский пользователь (с данными), я могу сериализовать его в String или byte [ ] с Джексоном. Но когда я пытаюсь десериализовать его на User, я получаю сообщение об ошибке:

Cannot construct instance of `javax.xml.bind.JAXBElement` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

Поскольку пользователь не настроил. Как можно десериализовать его?

0
задан 13 August 2018 в 13:47

2 ответа

Если вы предпочитаете использовать Apache CXF при создании объектов JAXB, вы можете использовать плагин xjc для автоматического создания методов setter-getter во время сгенерированных объектов.

Я столкнулся с одной и той же проблемой, и таким образом я решил проблему без изменения кода.

Вы можете добавить следующую часть к вашему файлу pom:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-codegen-plugin</artifactId>
            <version>${version.apache.cxf}</version>
            <executions>
                <execution>
                    <id>generate-sources</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <sourceRoot>${basedir}/src/main/java</sourceRoot>
                        <wsdlOptions>
                            <wsdlOption>
                                <wsdl>${basedir}/src/main/resources/wsdl/sample.wsdl</wsdl>
                                <wsdlLocation>classpath:wsdl/sample.wsdl</wsdlLocation>
                                <extraargs>
                                    <extraarg>-xjc-Xbg</extraarg>
                                    <extraarg>-xjc-Xcollection-setter-injector</extraarg>
                                </extraargs>
                            </wsdlOption>
                        </wsdlOptions>
                    </configuration>
                    <goals>
                        <goal>wsdl2java</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.apache.cxf.xjcplugins</groupId>
                    <artifactId>cxf-xjc-boolean</artifactId>
                    <version>3.0.3</version>
                </dependency>
                <dependency>
                    <groupId>org.andromda.thirdparty.jaxb2_commons</groupId>
                    <artifactId>collection-setter-injector</artifactId>
                    <version>1.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
1
ответ дан 15 August 2018 в 17:04

Вы можете сделать это, выполнив собственный класс десериализатора.

Попробуйте с этим:

String json = null;//your request json
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(User.class,new UserDeserialzer());
User user = objectMapper.registerModule(module).readValue(json,User.class);

Класс десериализатора:

public class UserDeserialzer extends JsonDeserializer<User>{
    @Override
    public User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode value = new ObjectMapper().readTree(p.getText());
        User user = new User();
        try {
            Field field = user.getClass().getDeclaredField("users");
            field.setAccessible(true);
            field.set(user,value.get("users"));
        }catch (Exception ex){
        }
        return user;
    }
}

Загрузите приложение:

добавьте этот компонент для десериализации по всему миру.

@Bean
    public Jackson2ObjectMapperBuilder configureObjectMapper() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(User.class,new UserDeserialzer());
        objectMapper.registerModule(module);
        builder.configure(objectMapper);
        return builder;
    }
0
ответ дан 15 August 2018 в 17:04
  • 1
    Я сказал, что класс автогенерируется. Я не могу его изменить – ip696 13 August 2018 в 14:01
  • 2
    реализовать класс десериализатора. затем установить значение путем отражения – sajib 13 August 2018 в 14:01
  • 3
    попробуйте с этим. если вы используете Spring / Spring-Boot, то можете добавить класс конфигурации для глобальной десериализации для пользователя. – sajib 13 August 2018 в 14:33

Другие вопросы по тегам:

Похожие вопросы: