首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在运行时指定asyncRabbitTemplate.convertSendAndReceiveAsType()的返回类型?

如何在运行时指定asyncRabbitTemplate.convertSendAndReceiveAsType()的返回类型?
EN

Stack Overflow用户
提问于 2021-09-23 11:26:28
回答 1查看 70关注 0票数 0

我一直在努力使用下面的代码。并且不确定如何反序列化它,甚至在运行时传递正确的类型。

代码是:

代码语言:javascript
运行
复制
 @Override
    public <T, R> R sendAsync(T payload, String routingKey, String exchangeName) {
       
        ListenableFuture<R> listenableFuture =
                asyncRabbitTemplate.convertSendAndReceiveAsType(
                        exchangeName,
                        routingKey,
                        payload,
                        new ParameterizedTypeReference<>() {
                        }
                );

        try {

            return listenableFuture.get();

        } catch (InterruptedException | ExecutionException e) {
            LOGGER.error(" [x] Cannot get response.", e);
            return null;
        }
    }

假设我只是像下面这样调用该方法

代码语言:javascript
运行
复制
SaveImageResponse response = backendClient.sendAsync( new SaveImageRequest(createQRRequest.getOwner(), qr), RabbitConstants.CREATE_QR_IMAGE_KEY, RabbitConstants.CDN_EXCHANGE);

而pojo如下所示:

代码语言:javascript
运行
复制
public class SaveImageResponse {
    private String id;
    private String message;

    public SaveImageResponse() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "SaveImageResponse{" +
                "id='" + id + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}

当前代码抛出以下错误:

代码语言:javascript
运行
复制
Caused by: java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class dev.yafatek.qr.api.responses.SaveImageResponse (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; dev.yafatek.qr.api.responses.SaveImageResponse is in unnamed module of loader 'app')

提前感谢

解决方案:

因此,我最终使用了以下内容:

代码语言:javascript
运行
复制
@Override
    public <T, R> R sendAsync(T payload, String routingKey, String exchangeName, Class<R> clazz) {

        ListenableFuture<R> listenableFuture =
                asyncRabbitTemplate.convertSendAndReceiveAsType(
                        exchangeName,
                        routingKey,
                        payload,
                        new ParameterizedTypeReference<>() {
                        }
                );

        try {
            return objectMapper.convertValue(listenableFuture.get(), clazz);
        } catch (InterruptedException | ExecutionException e) {
            LOGGER.error(" [x] Cannot get response.", e);
            return null;
        }
    }

通过使用对象映射器并在使用

代码语言:javascript
运行
复制
Class<POJO> clazz

要使用上面的代码:

代码语言:javascript
运行
复制
WebsiteInfoResponse websiteInfoResponse = backendClient.sendAsync(new GetWebsiteInfoReq(createBusinessDetailsRequest.getWebsiteUrlId()), RabbitConstants.GET_WEBSITE_INFO_KEY, RabbitConstants.QR_EXCHANGE, WebsiteInfoResponse.class);
EN

回答 1

Stack Overflow用户

发布于 2021-09-23 16:38:33

你不能这么做。

使用ParameterizedTypeReference<Foo>的全部原因是告诉转换器您需要一个Foo;这必须在方法的编译时解决;您不能调用sendAsync()来接收不同的类型。

不提供泛型类型意味着它将转换为Object (通常是一个映射)。

即使是new ParameterizedTypeReference<R>() { }也无法工作,因为( sendAsync()方法的)泛型类型在编译时不能解析R

您必须自己进行转换。

代码语言:javascript
运行
复制
@SpringBootApplication
public class So69299112Application {

    public static void main(String[] args) {
        SpringApplication.run(So69299112Application.class, args);
    }

    @Bean
    MessageConverter converter() {
        return new Jackson2JsonMessageConverter();
    }

    ObjectMapper mapper = new ObjectMapper();

    @Bean
    AsyncRabbitTemplate template(RabbitTemplate template) {
        template.setMessageConverter(new SimpleMessageConverter());
        return new AsyncRabbitTemplate(template);
    }

    @Bean
    ApplicationRunner runner(Service service) {
        return args -> {
            byte[] response = service.sendAsync("bar", "foo", "");
            Foo foo = this.mapper.readerFor(Foo.class).readValue(response);
            System.out.println(foo);
        };
    }

    @RabbitListener(queues = "foo")
    public Foo listen(String in) {
        return new Foo(in);
    }

    public static class Foo {

        String foo;

        public Foo() {
        }

        public Foo(String foo) {
            this.foo = foo;
        }

        public String getFoo() {
            return this.foo;
        }

        public void setFoo(String foo) {
            this.foo = foo;
        }

        @Override
        public String toString() {
            return "Foo [foo=" + this.foo + "]";
        }

    }

}

@Component
class Service {

    private static final Logger LOGGER = LoggerFactory.getLogger(Service.class);

    AsyncRabbitTemplate asyncRabbitTemplate;

    public Service(AsyncRabbitTemplate asyncRabbitTemplate) {
        this.asyncRabbitTemplate = asyncRabbitTemplate;
    }

    public byte[] sendAsync(Object payload, String routingKey, String exchangeName) {

        ListenableFuture<byte[]> listenableFuture = asyncRabbitTemplate.convertSendAndReceive(
                exchangeName,
                routingKey,
                payload);

        try {

            return listenableFuture.get();

        }
        catch (InterruptedException | ExecutionException e) {
            LOGGER.error(" [x] Cannot get response.", e);
            return null;
        }
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69299112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档