简体   繁体   English

Spring HTTP出站网关希望使用PollableChannel而不是DirectChannel

[英]Spring http outbound gateway wants to use PollableChannel instead of DirectChannel

I identified a configuration issue in my application which should try to send a request to a thirdparty service and should wait for the response. 我在应用程序中发现一个配置问题,该问题应尝试向第三方服务发送请求,并应等待响应。 The content type of the request and response is json. 请求和响应的内容类型为json。

The problem what I found is within the MessagingGatewaySupport class where I found an expectation for the reply channel which should be PollableChannel, but I need to use DirectChannel instead of Pollable: 我发现的问题是在MessagingGatewaySupport类中,在该类中我对回复通道的期望值应该是PollableChannel,但是我需要使用DirectChannel而不是Pollable:

protected Object receive() {
this.initializeIfNecessary();
MessageChannel replyChannel = getReplyChannel();
Assert.state(replyChannel != null && (replyChannel instanceof PollableChannel),
        "receive is not supported, because no pollable reply channel has been configured");
return this.messagingTemplate.receiveAndConvert(replyChannel, null);
}

I really think that I have a mistake in my configuration which is the following: 我真的认为我的配置有以下错误:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-http="http://www.springframework.org/schema/integration/http" xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http-4.3.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.3.xsd">

<jee:jndi-lookup id="repositoryUrl" jndi-name="repositoryUrl"/>
<jee:jndi-lookup id="wsMaxTotalConnections" jndi-name="wsMaxTotalConnections" default-value="50"/>
<jee:jndi-lookup id="wsMaxPerRoute" jndi-name="wsDefaultMaxPerRoute" default-value="50"/>
<jee:jndi-lookup id="wsConnectionTimeout" jndi-name="wsDefaultConnectionTimeout" default-value="10000"/>
<jee:jndi-lookup id="wsReadTimeout" jndi-name="wsDefaultReadTimeout" default-value="5000"/>

<int:gateway id="requestGateway" service-interface="com.example.Repository" default-request-channel="requestChannel" 
    default-reply-channel="responseChannel"/>

<int:channel id="requestChannel"/>
<int:channel id="responseChannel"/>

<int-http:outbound-gateway request-channel="requestChannel" url="#{repositoryUrl}" http-method="POST" expected-response-type="java.lang.String"
    request-factory="httpComponentsClientHttpRequestFactory" message-converters="jsonMessageConverter"/>

<bean id="jsonMessageConverter" class="com.example.JsonMessageConverter">
    <constructor-arg>
        <bean class="com.example.DataType"/>
    </constructor-arg>
</bean>

<bean id="httpComponentsClientHttpRequestFactory" class="com.example.ApplicationHttpComponentsClientHttpRequestFactory">
    <property name="maxTotalConnections" ref="wsMaxTotalConnections"/>
    <property name="defaultMaxPerRoute" ref="wsMaxPerRoute"/>
    <property name="connectionTimeout" ref="wsConnectionTimeout"/>
    <property name="readTimeout" ref="wsReadTimeout"/>
</bean>

JsonMessageConverter class: JsonMessageConverter类:

public class JsonMessageConverter implements HttpMessageConverter<Object> {
private static final Logger logger = LoggerFactory.getLogger(JsonMessageConverter.class);

private Object clazz;

private List<MediaType> supportedMediaTypes = Collections.emptyList();

public Object getClazz()
{
    return clazz;
}

public void setClazz(Object clazz)
{
    this.clazz = clazz;
}

public JsonMessageConverter(Object clazz)
{
    this.clazz = clazz;
}

@Override
public boolean canRead(Class<?> clazz, MediaType mediaType)
{
    return this.clazz.getClass().equals(clazz);
}

@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType)
{
    return false;
}

@Override
public List<MediaType> getSupportedMediaTypes()
{
    return supportedMediaTypes;
}

@Override
public Object read(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException
{
    Object response = new Object();

    logger.trace("Received message in :{} ", inputMessage.getBody().toString());

    try
    {
        Gson gson = new Gson();
        String inputStreamString = inputMessage.getBody().toString();

        response = gson.fromJson(inputStreamString, this.clazz.getClass());
    }
    catch (Exception e)
    {
        throw new HttpMessageConversionException("Failed to convert response to: " + clazz, e);
    }

    logger.trace("Received message out :{} ", response);

    return response;

}

@Override
public void write(Object t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException
{
    Gson gson = new Gson();

    logger.trace("Sent message in :{} ", t);

    String json = gson.toJson(t);

    outputMessage.getBody().write(json.getBytes());

    logger.trace("Sent message out :{} ", json);
}

} }

The related part of the exception: 异常的相关部分:

java.lang.IllegalStateException: receive is not supported, because no pollable reply channel has been configured
at org.springframework.util.Assert.state(Assert.java:392)
at org.springframework.integration.gateway.MessagingGatewaySupport.receive(MessagingGatewaySupport.java:391)
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:468)
at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:429)
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:420)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy28.getSoccerSeasons(Unknown Source)
at com.example.ServiceImpl.getData(ServiceImpl.java:26)

The version of Spring Integration is 4.3.6. Spring Integration的版本为4.3.6。 Can somebody help me? 有人可以帮我吗? I tried many example, but I have not find any which has worked fine. 我尝试了许多示例,但没有找到任何能正常工作的示例。

Thanks in advance for your help. 在此先感谢您的帮助。

You need to show your com.example.Repository interface. 您需要显示com.example.Repository接口。

It looks like the method you are calling has no parameters. 您正在调用的方法似乎没有参数。 You need to send something in order to receive a reply. 您需要发送一些东西才能收到回复。

See the documentation about gateway methods with no parameters . 请参阅有关没有参数的网关方法的文档

When invoking methods on a Gateway interface that do not have any arguments, the default behavior is to receive a Message from a PollableChannel. 在网关接口上调用不带任何参数的方法时,默认行为是从PollableChannel接收消息。

At times however, you may want to trigger no-argument methods so that you can in fact interact with other components downstream that do not require user-provided parameters, eg triggering no-argument SQL calls or Stored Procedures. 但是,有时您可能希望触发无参数方法,以便实际上可以与不需要用户提供参数的其他下游组件进行交互,例如,触发无参数SQL调用或存储过程。

In order to achieve send-and-receive semantics, you must provide a payload. 为了实现发送和接收语义,您必须提供有效负载。 In order to generate a payload, ... 为了生成有效载荷,...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM