简体   繁体   中英

Json Jackson deserialize object without setters

I have class(for example. In real project I have JAXB generated class instead User):

public class User {
  private List<String> users;

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

When I get User user(with data) I can serialize it to String or byte[] with JacksonJson. But when I try deserialize it to User I get error:

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)

Because User has not setter. How can I deserialize it?

You can do it by implement custom deserializer class.

Try with this:

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);

Deserializer 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;
    }
}

For Spring-boot application :

add this bean to deserialize globally.

@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;
    }

If you prefer to use Apache CXF while creating JAXB objects, you can use xjc plugin to create setter-getter methods automatically during generated objects. This way may be very pratical for you.

I ran into the same problem and in this way, I solved the problem without making a code change.

You can add the following part to your pom file:

<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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM