Spring @RestController自定义JSON反序列化器

时间:2014-12-18 15:42:40

标签: java spring rest jackson spring-boot

我想为某些类使用自定义JSON反序列化器(角色在这里),但我无法使其正常工作。自定义反序列化器不会被调用。

我使用Spring Boot 1.2。

解串器:

public class ModelDeserializer extends JsonDeserializer<Role> {

    @Override
    public Role deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        return null; // this is what should be called but it isn't
    }
}

控制器:

@RestController
public class RoleController {

    @RequestMapping(value = "/role", method = RequestMethod.POST)
    public Object createRole(Role role) {
        // ... this is called
    }
}
    关于角色的
  1. @JsonDeserialize

    @JsonDeserialize(using = ModelDeserializer.class)
    public class Role extends Model {
    
    }
    
  2. Java配置中的
  3. Jackson2ObjectMapperBuilder bean

    @Bean
    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.deserializerByType(Role.class, new ModelDeserializer());
        return builder;
    }
    
  4. 我做错了什么?

    编辑这可能是由@RestController引起的,因为它适用于@Controller ...

2 个答案:

答案 0 :(得分:22)

首先,您不需要重写Jackson2ObjectMapperBuilder来添加自定义反序列化程序。如果无法添加@JsonDeserialize注释,则应使用此方法。您应该使用@JsonDeserialize或覆盖Jackson2ObjectMapperBuilder

错过的是@RequestBody注释:

@RestController
public class JacksonCustomDesRestEndpoint {

    @RequestMapping(value = "/role", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Object createRole(@RequestBody Role role) {
        return role;
    }
}

@JsonDeserialize(using = RoleDeserializer.class)
public class Role {
    // ......
}

public class RoleDeserializer extends JsonDeserializer<Role> {
    @Override
    public Role deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        // .................
        return something;
    }
}

答案 1 :(得分:0)

还有另一个非常有趣的解决方案,如果您想在调用默认反序列化器之前修改JSON主体,可能会有所帮助。让我们想象你需要使用一些额外的bean(使用@Autowire机制)

让我们的图像情况,你有以下控制器:

@RequestMapping(value = "/order/product", method = POST)
public <T extends OrderProductInterface> RestGenericResponse orderProduct(@RequestBody @Valid T data) {
    orderService.orderProduct(data);
    return generateResponse();
}

OrderProductInterface的位置:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = NON_EMPTY)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, visible = true, property = "providerType")
@JsonSubTypes({
              @JsonSubTypes.Type(value = OrderProductForARequestData.class, name = "A")
          })
public interface OrderProductInterface{}

上面的代码将根据提交的providerType提供动态反序列化,并根据具体实现进行验证。为了更好地掌握,请考虑OrderProductForARequestData可以是这样的:

public class OrderProductForARequestData implements OrderProductInterface {

    @NotBlank(message = "is mandatory field.")
    @Getter @Setter
    private String providerId;

    @NotBlank(message = "is mandatory field.")
    @Getter @Setter
    private String providerType;

    @NotBlank(message = "is mandatory field.")
    @Getter @Setter
    private String productToOrder;

}

现在让我们想象一下,我们想以某种方式初始化providerType(丰富输入),然后才会执行默认的反序列化。所以根据{{{}中的规则对对象进行反序列化1}}。 为此,您可以通过以下方式修改OrderProductInterface课程:

@Configuration