Boa tarde,
Estou usando um gateway de saída para chamar um serviço que pode consumir XML (não SOAP) e produzir XML (não SOAP). Posso empacotar a classe JAXB para solicitar XML, mas não consigo descompactar a resposta XML de volta para as classes JAXB, o corpo da carga útil é nulo.
O fluxo é o seguinte
.subFlowMapping("SomeRequestType", subflow -> subflow
.transform(someRequestTransformer)
.enrichHeaders(header -> header.header("Content-Type","application/xml"))
.handle(someServiceOutboundGateway)
.transform(someResponseTransformer)
)
DesomeServiceOutboundGateway
@Bean
public HttpMessageConverter m() {
MarshallingHttpMessageConverter c = new MarshallingHttpMessageConverter();
c.setMarshaller(someMarshaller());
c.setUnmarshaller(someUnMarshaller());
return c;
}
@Bean(name="someServiceOutboundGateway")
public MessageHandler someOutboundGateway() {
return Http.outboundGateway(someUrl, lnquiHttp())
.httpMethod(HttpMethod.POST)
.expectedResponseType(Response.class)
.get();
}
@Bean
public RestTemplate lnquiHttp() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(connections);
connectionManager.setDefaultMaxPerRoute(maxConnectionsPerRoute);
RequestConfig requestConfig = RequestConfig
.custom()
.setConnectionRequestTimeout(timeout) // timeout to get connection from pool
.setSocketTimeout(timeout) // standard connection timeout
.setConnectTimeout(timeout) // standard connection timeout
.build();
HttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig).build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder();
RestTemplate restTemplate = restTemplateBuilder
.requestFactory(requestFactory)
.basicAuthorization(userName, password)
.messageConverters(m())
.build();
return restTemplate;
}
@Bean
public Marshaller someMarshaller() {
final Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(CONTEXTPATH_REQUEST);
marshaller.setSchema(responseSchema);
marshaller.setSupportJaxbElementClass(Boolean.TRUE);
return marshaller;
}
@Bean
public Unmarshaller someUnMarshaller() {
final Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
unmarshaller.setContextPath(CONTEXTPATH_RESPONSE);
unmarshaller.setSchema(responseSchema);
unmarshaller.setSupportJaxbElementClass(Boolean.TRUE);
return unmarshaller;
}
@Bean(name = "someJAXBContext")
public JAXBContext someJAXBContext() throws JAXBException {
return JAXBContext.newInstance(Response.class);
}
desomeResponseTransformer
@Component
public class SomeResponseTransformer implements GenericHandler<Object> {
@Override
public Object handle(final Object payload, final Map<String, Object> headers) {
ResponseEntity responseEntity = (ResponseEntity)payload;
Object body = responseEntity.getBody();
Response lnqiResponse = (Response)body;
... = buildHeader(lnqiResponse.getHeader());
Quando estou tentando obter o cabeçalho ( lnqiResponse.getHeader()
), recebo um NullPointerException.
Alguma ideia, por favor, de como descompactar a resposta para o Response
? Qualquer ajuda seria apreciada! Obrigado!
Depois de desempacotar, a carga útil de entrada para o seu
SomeResponseTransformer.handle()
método não será umResponseEntity
, mas sim aquele.expectedResponseType(Response.class)
.Não tenho certeza do que é
CONTEXTPATH_RESPONSE
, mas geralmente prefiro usarsetClassesToBeBound()
. Além disso, oJaxb2Marshaller
padrão espera de nós que um@XmlRootElement
na classe seja vinculado.Então, quando a resposta chegar do servidor, você precisa ter certeza de que
Content-Type
o cabeçalho é o que é suportado por issoMarshallingHttpMessageConverter
:Pode ser melhor a partir daqui começar a depurar suas chamadas e ver o que
RestTemplate
acontecedoExecute()
ao redorrequestCallback.doWithRequest(request);
eresponseExtractor.extractData(response)
.