如何验证 spring 集成 http 入站适配器中的传入 json 和 return Json 响应
How to validate incoming json in spring integration http inbound adaptor and return a Json response
我正在尝试设置一个只接受 json 的 http:inbound-gateway
。我的 xml 配置看起来像。
<int-http:inbound-gateway id="inboundGateway"
supported-methods="POST"
request-payload-type="eu.model.MyRequest"
request-channel="inputChannel"
mapped-response-headers="Return-Status, Return-Status-Msg, HTTP_RESPONSE_HEADERS"
path="/myService"
reply-timeout="50000"
message-converters="converters"
merge-with-default-converters="false"
validator="myValidator">
<int-http:request-mapping consumes="application/json"/>
</int-http:inbound-gateway>
<util:list id="converters">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</util:list>
我看到从 5.2 版本开始可以使用验证器在发送到通道之前检查有效负载,但我似乎找不到示例。添加 validator="myValidator"
似乎验证了 myRequest。
然而,尽管 <int-http:request-mapping consumes="application/json"/>
将内容限制为有效 json 并且验证器发出 HTTP Status 400 – Bad Request
错误是 returned in html?
如何将其覆盖为 return 自定义 json 响应?
编辑 1
这是我的完整 xml 配置
<int-http:inbound-gateway id="inboundGateway"
supported-methods="POST"
request-payload-type="eu.neurocom.wind.msdp.cis.model.MyRequest"
request-channel="inputChannel"
reply-channel="responseChannel"
error-channel="errorChannel"
mapped-response-headers="Return-Status, Return-Status-Msg, HTTP_RESPONSE_HEADERS"
path="/myservice"
reply-timeout="50000"
message-converters="converters"
merge-with-default-converters="false"
validator="myValidator">
<int-http:request-mapping consumes="application/json" produces="application/json" />
</int-http:inbound-gateway>
<util:list id="converters">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</util:list>
<int:service-activator
input-channel="errorChannel"
output-channel="responseChannel"
ref="globalExceptionHandler"
method="handleError"
/>
<int:service-activator ref="incomingActivator" input-channel="inputChannel" output-channel="responseChannel" method="handle"></int:service-activator>
我的端点激活器方法看起来像
public Message<MyResponse> handle(Message<MyRequest> message) {
logger.info("Received {}", message);
...}
如果在激活器中抛出错误,错误通道 return 是我的自定义 json 响应,否则在记录消息之前,我在 text/html 中得到以下响应;.
<body>
<h1>HTTP Status 400 – Bad Request</h1>
<hr class="line" />
<p><b>Type</b> Status Report</p>
<p><b>Message</b> Validation failure</p>
<p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a
client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
</p>
<hr class="line" />
<h3>Apache Tomcat/8.5.58</h3>
编辑 2
波纹管是我的验证器 class looger 被调用,如果 msidsn 不存在触发器
public class MyRequestValidator implements Validator {
private static final Logger logger = LoggerFactory.getLogger(MyRequestValidator.class);
@Override
public boolean supports(Class<?> clazz) {
return CisRequest.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
logger.debug("validatorCalled");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "msisdn", "msisdn.required");
}
}
我的web.xml
<servlet>
<servlet-name>inboundGateway</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>\WEB-INF\classes\spring-integration-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Note: All <servlet> elements MUST be grouped together and
placed IN FRONT of the <servlet-mapping> elements -->
<servlet-mapping>
<servlet-name>inboundGateway</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
那个组件的逻辑是这样的:
message = prepareRequestMessage(servletRequest, httpEntity, headers, payload);
}
catch (Exception ex) {
MessageConversionException conversionException =
new MessageConversionException("Cannot create request message", ex);
MessageChannel errorChannel = getErrorChannel();
if (errorChannel != null) {
ErrorMessage errorMessage = buildErrorMessage(null, conversionException);
if (expectReply) {
return this.messagingTemplate.sendAndReceive(errorChannel, errorMessage);
}
else {
this.messagingTemplate.send(errorChannel, errorMessage);
return null;
}
}
else {
throw conversionException;
}
}
因此,如果您为 <int-http:inbound-gateway>
配置了 error-channel
,您可以处理抛出的 IntegrationWebExchangeBindException
并根据需要生成自定义回复。
注意:我们可能需要在文档中提及这种方法。目前它仅指向标准 Spring MVC 方式来处理验证错误:https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/http.html#http-validation。欢迎提出 GH 问题!
我正在尝试设置一个只接受 json 的 http:inbound-gateway
。我的 xml 配置看起来像。
<int-http:inbound-gateway id="inboundGateway"
supported-methods="POST"
request-payload-type="eu.model.MyRequest"
request-channel="inputChannel"
mapped-response-headers="Return-Status, Return-Status-Msg, HTTP_RESPONSE_HEADERS"
path="/myService"
reply-timeout="50000"
message-converters="converters"
merge-with-default-converters="false"
validator="myValidator">
<int-http:request-mapping consumes="application/json"/>
</int-http:inbound-gateway>
<util:list id="converters">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</util:list>
我看到从 5.2 版本开始可以使用验证器在发送到通道之前检查有效负载,但我似乎找不到示例。添加 validator="myValidator"
似乎验证了 myRequest。
然而,尽管 <int-http:request-mapping consumes="application/json"/>
将内容限制为有效 json 并且验证器发出 HTTP Status 400 – Bad Request
错误是 returned in html?
如何将其覆盖为 return 自定义 json 响应?
编辑 1 这是我的完整 xml 配置
<int-http:inbound-gateway id="inboundGateway"
supported-methods="POST"
request-payload-type="eu.neurocom.wind.msdp.cis.model.MyRequest"
request-channel="inputChannel"
reply-channel="responseChannel"
error-channel="errorChannel"
mapped-response-headers="Return-Status, Return-Status-Msg, HTTP_RESPONSE_HEADERS"
path="/myservice"
reply-timeout="50000"
message-converters="converters"
merge-with-default-converters="false"
validator="myValidator">
<int-http:request-mapping consumes="application/json" produces="application/json" />
</int-http:inbound-gateway>
<util:list id="converters">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</util:list>
<int:service-activator
input-channel="errorChannel"
output-channel="responseChannel"
ref="globalExceptionHandler"
method="handleError"
/>
<int:service-activator ref="incomingActivator" input-channel="inputChannel" output-channel="responseChannel" method="handle"></int:service-activator>
我的端点激活器方法看起来像
public Message<MyResponse> handle(Message<MyRequest> message) {
logger.info("Received {}", message);
...}
如果在激活器中抛出错误,错误通道 return 是我的自定义 json 响应,否则在记录消息之前,我在 text/html 中得到以下响应;.
<body>
<h1>HTTP Status 400 – Bad Request</h1>
<hr class="line" />
<p><b>Type</b> Status Report</p>
<p><b>Message</b> Validation failure</p>
<p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a
client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
</p>
<hr class="line" />
<h3>Apache Tomcat/8.5.58</h3>
编辑 2 波纹管是我的验证器 class looger 被调用,如果 msidsn 不存在触发器
public class MyRequestValidator implements Validator {
private static final Logger logger = LoggerFactory.getLogger(MyRequestValidator.class);
@Override
public boolean supports(Class<?> clazz) {
return CisRequest.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
logger.debug("validatorCalled");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "msisdn", "msisdn.required");
}
}
我的web.xml
<servlet>
<servlet-name>inboundGateway</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>\WEB-INF\classes\spring-integration-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Note: All <servlet> elements MUST be grouped together and
placed IN FRONT of the <servlet-mapping> elements -->
<servlet-mapping>
<servlet-name>inboundGateway</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
那个组件的逻辑是这样的:
message = prepareRequestMessage(servletRequest, httpEntity, headers, payload);
}
catch (Exception ex) {
MessageConversionException conversionException =
new MessageConversionException("Cannot create request message", ex);
MessageChannel errorChannel = getErrorChannel();
if (errorChannel != null) {
ErrorMessage errorMessage = buildErrorMessage(null, conversionException);
if (expectReply) {
return this.messagingTemplate.sendAndReceive(errorChannel, errorMessage);
}
else {
this.messagingTemplate.send(errorChannel, errorMessage);
return null;
}
}
else {
throw conversionException;
}
}
因此,如果您为 <int-http:inbound-gateway>
配置了 error-channel
,您可以处理抛出的 IntegrationWebExchangeBindException
并根据需要生成自定义回复。
注意:我们可能需要在文档中提及这种方法。目前它仅指向标准 Spring MVC 方式来处理验证错误:https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/http.html#http-validation。欢迎提出 GH 问题!