3

我通过 Java 将 JAXB 对象发送到 Rabbit MQ。

JAXBContext jaxbContext = JAXBContext.newInstance(MyDTO.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

    // output pretty printed
    jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
     java.io.StringWriter sw = new StringWriter();
     jaxbMarshaller.marshal(deliveryrequest, sw);

    ConnectionFactory factory = new ConnectionFactory() ;

    //TODO change the hardcoding to the properties file
    factory.setHost("rabbitmq.host.net");
    factory.setUsername("user");
    factory.setPassword("pass");
    Channel channel ;
    Connection connection;

    Map<String, Object> args = new HashMap<String, Object>(); 
    String haPolicyValue = "all"; 
    args.put("x-ha-policy", haPolicyValue); 


    connection = factory.newConnection();
    channel = connection.createChannel();
    //TODO change the hardcoding to the properties file
    channel.queueDeclare("upload.com.some.queue", true, false, false, args);
    //TODO change the hardcoding to the properties file
    channel.basicPublish("com.some.exchange", "someroutingKey", 
            new AMQP.BasicProperties.Builder().contentType("text/plain")
            .deliveryMode(2).priority(1).userId("guest").build(),
            sw.toString().getBytes());

我在不同的应用程序中使用 Camel 来阅读这个。

    <camel:route id="myRoute">
        <camel:from uri="RabbitMQEndpoint" />
        <camel:to uri="bean:MyHandler" />
    </camel:route>

处理程序在骆驼端使用 Jaxb 对象重做

 @Handler
 public void handleRequest(MyDTO dto) throws ParseException {

我收到了我没想到的错误。

Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: byte[] to the required type: com.mycompany.MyDTO with value [B@1b8d3e42
at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:181)
at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:99)

解决方案表示赞赏。

4

3 回答 3

3

您来自 rabbit 的消息正文类型是一个 byte[],并且您想调用一个作为 MyDTO 类型的 bean。你有一个类型不匹配。而且 Camel 找不到可以将消息正文从 byte[] 转换为您的 MyDTO 类型的类型转换器。

来自 Rabbit 的 byte[] 数据是 XML 格式的吗?您是否在 MyDTO 类上有 JAXB 注释,因此您可以使用 JAXB 将其从 xml 编组为 Java ?

于 2013-10-04T07:04:02.297 回答
1

它是 Jaxb 对象。我的印象是,如果我也移动出版商骆驼。事情会解决的。

我将发布者更改为以下内容。

    @EndpointInject(context = "myContext" , uri = "direct:myRoute")
    private ProducerTemplate sendAMyContext;

在我调用的方法中

     @Override
public MyResponse putMyCall(
        MyRequest myrequest) {

        sendMyContext.sendBody(myrequest);

我的骆驼路线很简单

    <camel:camelContext id="MyContext" autoStartup="true" xmlns="http://camel.apache.org/schema/spring">


    <camel:endpoint id="myQueue" uri="${my.queue.1}" />

        <camel:route>
        <camel:from uri="direct:myRoute"/>
        <camel:to uri="bean:mySendHandler"/>
        <camel:convertBodyTo type="String"></camel:convertBodyTo>
        <camel:to uri="ref:myQueue" />
    </camel:route>

</camel:camelContext>

我添加了将 Jaxb 对象转换为字符串的处理程序(因为错误)

public class MySendHandler {



 @Handler
 public String myDelivery( MyRequest myRequest) throws ParseException, JAXBException {


         JAXBContext jaxbContext = JAXBContext.newInstance(MyRequest.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

        // output pretty printed
        jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
        java.io.StringWriter sw = new StringWriter();
        jaxbMarshaller.marshal(attributedDeliveryRequest, sw);

     return sw.toString();

  }

还是一样的错误

 [SpringAMQPConsumer.SpringAMQPExecutor-1] WARN  org.springframework.amqp.support.converter.JsonMessageConverter (JsonMessageConverter.java:111) - Could not convert incoming message with content-type [text/plain]
SpringAMQPConsumer.SpringAMQPExecutor-1] ERROR org.apache.camel.processor.DefaultErrorHandler (MarkerIgnoringBase.java:161) - Failed delivery for (MessageId: ID-Con ExchangeId: ID-65455-1380873539452-3-2). 
Exhausted after delivery attempt: 1 caught: org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[Message: <XML>]
org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[Message: <xml>
    .....
Caused by: org.apache.camel.InvalidPayloadException: No body available of type: MyDTO but has value: [B@7da255c of type: byte[] on: Message: <xml>
. Caused by: [org.apache.camel.NoTypeConversionAvailableException - No type converter available to convert from type: byte[] to the required type: MyDeliveryDTO with value [B@7da255c]
    at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:101)
    at org.apache.camel.builder.ExpressionBuilder$38.evaluate(ExpressionBuilder.java:934)
    ... 74 more
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: byte[] to the required type: MyDTO with value [B@7da255c
    at org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:181)
    at org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:99)
    ... 75 more

我的接收骆驼路线如下

<camel:route id="processVDelivery">
            <camel:from uri="aVEndpoint" />
            <camel:to uri="bean:myDataHandler" />
        </camel:route>

我添加了

    <camel:convertBodyTo type="String"></camel:convertBodyTo>

给它,它给了我错误,它不能将它从字符串转换为对象

添加这个

    <camel:unmarshal></camel:unmarshal>



-------------------------

问题的答案将是您的所有 mashaller 都必须是类路径的一部分

---------------------------------


    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>${jackson.version}</version>
    </dependency>

------- 您也可以使用数据格式自定义编组器

<camel:dataFormats>

                   <camel:jaxb id="name" contextPath="com.something"/>

    </camel:dataFormats

确保将 jaxb.in​​dex 文件保存在具有根级别 Jaxb 对象名称的 com.something 包中

于 2013-10-04T08:15:37.643 回答
0

在 Spring Boot 中使用 Camel Rest

 rest("/authenticate")
                .post()
                .route()
                .setHeader("Content-Type", constant("application/json"))
                .setHeader("Accept", constant("application/json"))
                .setHeader(Exchange.HTTP_METHOD, constant("POST"))
                  .process(exchange -> {
        org.apache.camel.TypeConverter tc = exchange.getContext().getTypeConverter();
String str_value = tc.convertTo(String.class, exchange.getIn().getBody());
             System.err.println(str_value);
              exchange.getOut().setBody(str_value);
      })
                //.removeHeader(Exchange.HTTP_URI)
                .to("http://localhost:8082/authenticate?bridgeEndpoint=true")
                  //.convertBodyTo(DTO.class)
                .log("Boo!")
                .end()
                .endRest();
         
于 2021-12-16T18:36:51.277 回答