2017-08-11 1 views
0

J'ai une passerelle http entrante dont le message entrant est transmis à une passerelle http sortante (en utilisant l'intégration java dsl). Lorsque la réponse de la passerelle sortante a le statut http 200, la réponse sortante revient à l'appelant de la passerelle entrante comme prévu.Intégration de ressort: préserver le code d'erreur http et le corps en réponse

Toutefois, lorsque la passerelle sortante répond avec des erreurs client spécifiques telles que 423 verrouillé ou 403 interdit, l'appelant de la passerelle entrante reçoit 500 et un message de corps contenant une exception en tant que chaîne. Je comprends que c'est parce que SI gère les erreurs http sortantes comme des exceptions. Mais dans mon cas, je dois passer par le statut d'erreur et le corps de la réponse qui vient avec la réponse sortante à l'appelant de la passerelle entrante, pour les codes d'erreur spécifiques. Comment je fais ça?

+0

S'il vous plaît, trace la part de pile que vous voyez là avant erreur pour votre service, que 500 –

Répondre

1

Nous appelons ce scénario comme proxy HTTP et avoir un test de cas sur la question: https://github.com/spring-projects/spring-integration/blob/master/spring-integration-http/src/test/java/org/springframework/integration/http/dsl/HttpDslTests.java

Je viens de faire une enquête et voici ce que vous avez besoin:

IntegrationFlows 
    .from(Http.inboundGateway("/service") 
      .requestMapping(r -> r.params("name")) 
      .errorChannel("httpProxyErrorFlow.input")) 
... 

@Bean 
public IntegrationFlow httpProxyErrorFlow() { 
    return f -> f 
      .transform(Throwable::getCause) 
      .<HttpClientErrorException>handle((p, h) -> 
        MessageBuilder.withPayload(p.getResponseBodyAsString()) 
          .setHeader(HttpHeaders.STATUS_CODE, p.getStatusCode()) 
          .build()); 
} 

Nous devons gérer les erreurs en aval sur le niveau de la passerelle entrante. Pour cela, Spring Integration suggère la fonctionnalité errorChannel.

Cette httpProxyErrorFlow fournit une certaine logique à ce sujet. Tout d'abord nous savons que le message pour le errorChannel est ErrorMessage et son payload est MessagingException - à la suite de l'emballage HttpClientErrorException dans le HttpRequestExecutingMessageHandler. Donc, avec le .transform() nous descendons à l'exception désirée et dans le .handle() nous construisons un nouveau message basé sur le contenu HttpClientErrorException.

Le HttpRequestHandlingMessagingGateway est en mesure de traiter un tel message correctement et définir un code d'état souhaité à la réponse:

protected final Object setupResponseAndConvertReply(ServletServerHttpResponse response, Message<?> replyMessage) { 
    getHeaderMapper().fromHeaders(replyMessage.getHeaders(), response.getHeaders()); 
    HttpStatus httpStatus = this.resolveHttpStatusFromHeaders(replyMessage.getHeaders()); 
    if (httpStatus != null) { 
     response.setStatusCode(httpStatus); 
    } 

http://docs.spring.io/spring-integration/docs/4.3.11.RELEASE/reference/html/http.html#http-response-statuscode