使用自定义JsonSerializer时没有找到转换器错误

时间:2016-02-16 16:04:24

标签: spring rest spring-mvc serialization jackson

在Spring应用程序中,我想将自己的JsonSerializer与RestController一起使用。我的JsonSerializer在Jackson2ObjectMapperBuilder中注册。到目前为止一切都那么好,但是当我用@JsonSerialize注释相应的字段时,Spring MVC抱怨我的课程没有找到转换器。这是代码:

public class DurationAsHourSerializer extends JsonSerializer<Duration>{
    @Override
    public void serialize(Duration value, JsonGenerator gen, SerializerProvider serializers)
            throws IOException, JsonProcessingException {
            gen.writeNumber(value.toHours());

    }
}

@Configuration
@EnableWebMvc
public class AppConfig {
    @Bean
    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Duration.class, new DurationAsHourSerializer());
        b.modulesToInstall(module);
        return b;
    }
}

@EqualsAndHashCode
@ToString
public class Order {
    @Getter
    @Setter
    private String id;

    @Getter
    @Setter
    @NotNull
    private String customerId;

    @Getter
    @Setter
    private ZonedDateTime validFrom;

    @Getter
    @Setter
    private ZonedDateTime validTo;

    @Getter
    @Setter
    @JsonSerialize(as=DurationAsHourSerializer.class)
    private Duration maxDuration;

    @Getter
    @Setter
    @JsonSerialize(as=DurationAsHourSerializer.class)
    private Duration actDuration;
}

@RestController
@RequestMapping("order")
public class OrderController {

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<?> createOrder(@RequestBody @Valid Order order) {
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest().path("/" + order.getId()).build().toUri());
        return new ResponseEntity<>(null, headers, HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.GET)
    public Order getExample() {
        Order order = new Order();
        order.setMaxDuration(Duration.ofHours(10));
        return order;
    }
}

当我向getExample()发送请求时,出现以下错误:

  

java.lang.IllegalArgumentException:找不到返回的转换器   type的类:class com.sap.sptutorial.rest.Order at   org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:178)   〜[弹簧webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]

为什么转换器不能使用我的串行器,或者为什么我的串行器会使现有的转换器不可用?

PS:这是对How do I use a custom Serializer with Jackson?的跟进,在那里我尝试使用Field Formatter进行相同的工作,并了解到Formatters不用于Jackson序列化。

2 个答案:

答案 0 :(得分:0)

这背后的原因可能是,因为已经有另外一个由Spring构建的Jackson2ObjectMapperBuilder对象,它仍在使用它。

你需要确保将这个@Bean作为spring使用的默认值,或者使用@PostConstruct而不是@Bean来修改由Spring初始化的相同的Jackson2ObjectMapperBuilder实例

@Autowired
private Jackson2ObjectMapperBuilder builder;
............

@PostConstruct
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
    SimpleModule module = new SimpleModule();
    module.addSerializer(Duration.class, new DurationAsHourSerializer());
    b.modulesToInstall(module);
    return b;
}

答案 1 :(得分:0)

错误是我在@JsonSerialize注释中使用了错误的属性。而不是@JsonSerialize(as=DurationAsHourSerializer.class),您必须声明序列化程序与@JsonSerialize(using=DurationAsHourSerializer.class)

一起使用