Java Spring集成流响应HTTP 400

Java Spring集成流响应HTTP 400,java,spring,spring-integration,Java,Spring,Spring Integration,我有一个spring集成流,它需要一个“routingkey”消息头。如果这不存在,我希望将HTTP 400响应发送回客户端。我该怎么做?下面您将看到determinateRoutingKey方法,在这里我可以确定路由密钥是否作为头传递 @Bean public IntegrationFlow webToRabbit(RabbitTemplate amqpTemplate) { return IntegrationFlows .from (

我有一个spring集成流,它需要一个“routingkey”消息头。如果这不存在,我希望将HTTP 400响应发送回客户端。我该怎么做?下面您将看到determinateRoutingKey方法,在这里我可以确定路由密钥是否作为头传递

@Bean
public IntegrationFlow webToRabbit(RabbitTemplate amqpTemplate)
{
    return IntegrationFlows
            .from
            (
                Http.inboundGateway("/tunnel")
                    .replyTimeout(Integer.valueOf(timeout))
                    .mappedRequestHeaders("*")
                    .mappedResponseHeaders("*")
            )
            .log()
            .handle
            (
                Amqp.outboundGateway(amqpTemplate)
                    .exchangeName(exchangeName)
                    .routingKeyFunction(f->determineRoutingKey(f))
                    .mappedRequestHeaders("*")
                    .mappedReplyHeaders("*")
            )
            .log()
            .bridge(null)
            .get();
}

private String determineRoutingKey(Message<?> message) 
{
    MessageHeaders headers = message.getHeaders();
    if(headers.containsKey(HEADER_ROUTINGKEY))
    {
        String routingKey = Objects.toString(headers.get(HEADER_ROUTINGKEY));
        log.debug("Using routing key: " + routingKey);
        return routingKey;
    }
    else
    {
        log.error("Headers found: " + Objects.toString(headers));

        //Here I get an exception stating that MessageHeaaders is immutable
        message.getHeaders().put(HttpHeaders.STATUS_CODE, HttpStatus.BAD_REQUEST);
        return null;
    }
}
@Bean
公共集成流webToRabbit(RabbitTemplate amqpTemplate)
{
返回积分流
从…起
(
Http.inboundGateway(“/tunnel”)
.replyTimeout(整型.valueOf(超时))
.mappedRequestHeaders(“*”)
.mappedResponseHeaders(“*”)
)
.log()
手柄
(
Amqp.outboundGateway(amqpTemplate)
.exchangeName(exchangeName)
.routingKeyFunction(f->DeterminatorOutingKey(f))
.mappedRequestHeaders(“*”)
.mappedReplyHeaders(“*”)
)
.log()
.bridge(空)
.get();
}
私有字符串确定例程key(消息消息)
{
MessageHeaders=message.getHeaders();
if(headers.containsKey(HEADER\u ROUTINGKEY))
{
String routingKey=Objects.toString(headers.get(HEADER\u routingKey));
log.debug(“使用路由密钥:“+routingKey”);
返回路由键;
}
其他的
{
log.error(“找到的头文件:“+Objects.toString(头文件));
//这里我得到一个异常,声明MessageHeaaders是不可变的
message.getHeaders().put(HttpHeaders.STATUS\u代码,HttpStatus.BAD\u请求);
返回null;
}
}
提前感谢您的帮助。

有如下逻辑:

private HttpStatus resolveHttpStatusFromHeaders(MessageHeaders headers) {
    Object httpStatusFromHeader = headers.get(org.springframework.integration.http.HttpHeaders.STATUS_CODE);
    return buildHttpStatus(httpStatusFromHeader);
}
因此,您需要的只是常规(带有错误消息的字符串?)回复和适当的
HttpStatus.BAD_请求
作为
http_statusCode

在任何例外情况下都没有理由

更新

因为你在流的中间,它离回答还很远,你可以坚持那个异常方法。 要返回正确的400响应,您必须在

Http.inboundGateway()
上执行
errorChannel
,并使用一些简单的转换器返回带有适当
HttpHeaders的
消息。状态代码
头:

Http.inboundGateway("/tunnel")
    .errorChannel("httpErrorFlow.input")
...

@Bean
public IntegrationFlow httpErrorFlow() {
    return f -> f
            .<RuntimeException, Message<?>>transform(payload -> {
                if (payload.getCause() instanceof MyRoutingKeyException) {
                    return MessageBuilder.withPayload("Bad routing key")
                            .setHeader(HttpHeaders.STATUS_CODE, HttpStatus.BAD_REQUEST)
                            .build();
                }
                throw payload;
            });
}
Http.inboundGateway(“/tunnel”)
.errorChannel(“httpErrorFlow.input”)
...
@豆子
公共集成流httpErrorFlow(){
返回f->f
.有这样一种逻辑:

private HttpStatus resolveHttpStatusFromHeaders(MessageHeaders headers) {
    Object httpStatusFromHeader = headers.get(org.springframework.integration.http.HttpHeaders.STATUS_CODE);
    return buildHttpStatus(httpStatusFromHeader);
}
因此,您需要的只是常规(带有错误消息的字符串?)回复和适当的
HttpStatus.BAD_请求
作为
http_statusCode

在任何例外情况下都没有理由

更新

因为你在流的中间,它离回答还很远,你可以坚持那个异常方法。 要返回正确的400响应,您必须在

Http.inboundGateway()
上执行
errorChannel
,并使用一些简单的转换器返回带有适当
HttpHeaders的
消息。状态代码
头:

Http.inboundGateway("/tunnel")
    .errorChannel("httpErrorFlow.input")
...

@Bean
public IntegrationFlow httpErrorFlow() {
    return f -> f
            .<RuntimeException, Message<?>>transform(payload -> {
                if (payload.getCause() instanceof MyRoutingKeyException) {
                    return MessageBuilder.withPayload("Bad routing key")
                            .setHeader(HttpHeaders.STATUS_CODE, HttpStatus.BAD_REQUEST)
                            .build();
                }
                throw payload;
            });
}
Http.inboundGateway(“/tunnel”)
.errorChannel(“httpErrorFlow.input”)
...
@豆子
公共集成流httpErrorFlow(){
返回f->f

。很抱歉,我不理解您的答案。
HttpRequestHandlingEndpointSupport
可以正确解析标题中的状态代码,并使用reply
payload
作为响应主体。您不需要抛出任何异常。否则它只会
500
。您必须手动填充reply并添加
HttpHeaders.STAT在错误的情况下,将US_CODE添加到回复消息中。您可以抛出异常,但必须将errorChannel添加到Http.inboundGateway()中
使用
HttpHeaders.STATUS\u code
header for
HttpStatus.BAD\u REQUEST
值将该异常转换为正确的回复。如果我没有在此处抛出异常,那么在determineRoutingKey函数中没有返回路由键。此时我不知道如何路由消息。我不知道框架是如何运行的我只是用我认为你第一次建议的方法更新了我的代码。我试图在消息头中添加一个http状态码,但它说这些头是不可变的,并抛出一个500。错误通道路由看起来非常复杂,我不确定如果我我有一个自定义的错误通道。必须有一个处理这种简单情况的最佳实践。很抱歉,我不理解您的答案。
HttpRequestHandlingEndpointSupport
可以正确解析来自标题的状态代码,并使用reply
payload
作为响应主体。您不需要抛出任何异常。否则,它只是只有
500
。在错误的情况下,您必须手动填充reply并将
HttpHeaders.STATUS\u code
添加到回复消息中。您可以抛出异常,但必须将
errorChannel
添加到
Http.inboundGateway()中
使用
HttpHeaders.STATUS\u code
header for
HttpStatus.BAD\u REQUEST
值将该异常转换为正确的回复。如果我没有在此处抛出异常,那么在determineRoutingKey函数中没有返回路由键。此时我不知道如何路由消息。我不知道框架是如何运行的我只是用我认为你第一次建议的方法更新了我的代码。我试图在消息头中添加一个http状态码,但它说这些头是不可变的,并抛出一个500。错误通道路由看起来非常复杂,我不确定如果我我们有一个自定义错误通道。必须有一个处理这种简单情况的最佳实践。