如何实现自定义 Spring Http 消息转换器来编写类型化集合

问题描述 投票:0回答:2

我有一个返回

List<Person>
的 Spring Boot 控制器,我想实现一个自定义
HttpMessageConverter
,它可以编写
Person
类型的集合。

我看到

AbstractHttpMessageConverter
,但是
supports()
方法只接受一个类,所以我可以测试Collection,但没有办法(据我所知)测试Person类型的Collection。

我还看到

GenericHttpMessageConverter
AbstractGenericHttpMessageConverter
听起来很有希望,但我不知道如何正确实施。

java spring-boot spring-restcontroller spring-rest
2个回答
0
投票

我想我找到了解决方案。以下似乎有效...

@Component
static class PersonMessageConverter
    extends AbstractGenericHttpMessageConverter<Collection<Person>> {

  public PersonMessageConverter() {
    super(MediaType.APPLICATION_JSON);
  }

  @Override
  public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
    TypeToken<Collection<Person>> personCollectionType = new com.google.common.reflect.TypeToken<>() {};
    return canWrite(mediaType) && personCollectionType.isSupertypeOf(type);
  }

  @Override
  protected void writeInternal(Collection<Person> persons, Type type, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {
    // do write...
  }

  // continue with read methods here
}

0
投票
AbstractGenericHttpMessageConverter 的

canWrite 是在 ResourceRegionHttpMessageConverter 中的 springs 代码中实现的。我建议使用它作为参考实现。

在你的情况下是:

@Override
public boolean canWrite(@Nullable Type type, @Nullable Class<?> clazz, @Nullable MediaType mediaType) {
    if (!(type instanceof ParameterizedType parameterizedType)) {
        return (type instanceof Class<?> c && Person.class.isAssignableFrom(c));
    }
    if (!(parameterizedType.getRawType() instanceof Class<?> rawType)) {
        return false;
    }
    if (!(Collection.class.isAssignableFrom(rawType))) {
        return false;
    }
    if (parameterizedType.getActualTypeArguments().length != 1) {
        return false;
    }
    Type typeArgument = parameterizedType.getActualTypeArguments()[0];
    if (!(typeArgument instanceof Class<?> typeArgumentClass)) {
        return false;
    }
    return Person.class.isAssignableFrom(typeArgumentClass);
}

此解决方案不依赖于 guava 等其他第三方库。

© www.soinside.com 2019 - 2024. All rights reserved.