2016-12-19 1 views
1

Ich versuche, so zu einem json Struktur zu bereichern Nutzlast mit Tasten einigen Kopf- und konvertieren:Transform-Header und Nutzlast zu Json Knoten

{ 
"Header": { ["key" : "value", "key2": "value"]} 
"Payload": { "attribute" : "value" } 
} 

Mein Gateway wie folgt konfiguriert ist:

@MessagingGateway 
public static interface MailService { 
    @Gateway(requestChannel = "mail.input") 
    void sendMail(String body, @Headers Map<String,String> headers);   
} 

Hier ist mein Fluss:

@Bean 
public IntegrationFlow errorFlow(){ 
    return IntegrationFlows.from(recoveryChannel()) 
          .transform("payload.failedMessage")        
          .enrichHeaders(c -> c.header(FileHeaders.FILENAME, "emailErrors.json")) 
          .handle(this.fileOutboundAdapter()) 
          .get(); 
} 

Wie könnte ich dieses Problem lösen?

Danke.

Antwort

1

Um die gesamte Nachricht an den JSON zu konvertieren, sollten Sie etwas tun:

.handle((p, h) -> MessageBuilder.withPayload(new GenericMessage<>(p, h))) 
.transform(Transformers.toJson()) 

Der Trick wie Transformers.toJson() ist nicht zu Kopf- und wandelt nur payload schert. Also müssen wir es ein bisschen hacken, indem wir das ganze message auf die payload setzen.

Seit ServiceActivator (Erdgeschoss des .handle()) gibt message wie wenn das Ergebnis Message<?> ist, haben wir Wahl nicht, es sei denn MessageBuilder bieten und Transformers.toJson() haben alle Infos für Ihren Anwendungsfall.

+0

Das ist es, Artem ,, Ich bin sehr dankbar. Ist es möglich, die zwei Knoten umzukehren? Headers/Payload von Payload/Headers –

+0

??? Was ist der Sinn? Sie sind Geschwister im Ziel-JSON. Nicht sicher, dass wir diese Reihenfolge tauschen können ... –

+0

Sie würden einen kundenspezifischen Transformator benötigen, um die Nutzlast in eine Karte umzuwandeln; Wenn Sie eine 'LinkedHashMap' verwenden, würde Jackson wahrscheinlich in der Reihenfolge iterieren, in der Sie die Map erstellt haben (Sie können auch die Zeitstempel und ID-Header auf diese Weise vermeiden). Eine solche Reihenfolge ist jedoch nur für den "menschlichen" Konsum interessant. –

0
@SpringBootApplication 
public class So41223173Application { 

    public static void main(String[] args) { 
     ConfigurableApplicationContext context = SpringApplication.run(So41223173Application.class, args); 
     context.getBean("flow.input", MessageChannel.class) 
       .send(new ErrorMessage(new MessagingException(new GenericMessage<>(new Foo())))); 
     context.close(); 
    } 

    @Bean 
    public IntegrationFlow flow() { 
     return f -> f.transform("payload.failedMessage") 
       .enrichHeaders(c -> c.header("foo", "bar")) 
       .transform(toMap(), "transform") 
       .transform(Transformers.toJson()) 
       .handle(m -> System.out.println(m.getPayload())); 
    } 

    @Bean 
    public Transformer toMap() { 
     return new AbstractTransformer() { 

      @Override 
      protected Object doTransform(Message<?> message) throws Exception { 
       Map<String, Object> map = new LinkedHashMap<>(); 
       Map<String, Object> headers = new LinkedHashMap<>(message.getHeaders()); 
       headers.remove(MessageHeaders.ID); 
       headers.remove(MessageHeaders.TIMESTAMP); 
       map.put("headers", headers); 
       map.put("payload", message.getPayload()); 
       return map; 
      } 

     }; 

    } 

    public static class Foo { 

     String bar = "bar"; 

     public String getBar() { 
      return this.bar; 
     } 

     public void setBar(String bar) { 
      this.bar = bar; 
     } 

    } 

} 

Ergebnis

{"headers":{"foo":"bar"},"payload":{"bar":"bar"}} 
+0

Danke Gary. Das klingt sinnvoll! –

Verwandte Themen