2015-09-01 1 views
1

У меня есть интеграционный маршрут весны в xml, который сделает вызов веб-службы (multipart/formdata) и должен вернуть ответ в формате JSON. Проблема в том, что я не нахожу хороший образец маршрута SI, который выполняет множественный запрос с ответом. Любая помощь действительно ценится.Весна Интеграция Многостраничная форма Загружает маршрут с ответом JSON не работает

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 
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/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd 
    http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd"> 

<bean id="byteArrayHttpMessageConverter" 
    class="org.springframework.http.converter.ByteArrayHttpMessageConverter"> 
</bean> 

<bean id="formHttpMessageConverter" 
    class="org.springframework.http.converter.FormHttpMessageConverter"> 
</bean> 

<bean id="multipartResolver" 
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> 

<bean id="headerMapper" 
    class="org.springframework.integration.http.support.DefaultHttpHeaderMapper"> 
    <property name="inboundHeaderNames" value="*" /> 
    <property name="outboundHeaderNames" value="*" /> 
    <property name="userDefinedHeaderPrefix" value="" /> 
</bean> 


<int:channel id="http.request.submit.withfiles" /> 
<int:channel id="http.response.submit.withfiles" /> 

<int:channel id="http.router.route1.process.submit.withfiles" /> 
<int:channel id="http.router.route2.process.submit.withfiles" /> 

<int-http:inbound-gateway id="http.gateway.inbound.submit.withfiles" 
    supported-methods="POST" header-mapper="headerMapper" 
    request-channel="http.request.submit.withfiles" 
    reply-channel="http.response.submit.withfiles" path="/v1.0/file"> 
    <int-http:request-mapping consumes="multipart/form-data" 
     produces="application/json" /> 
    <int-http:header name="routingCode" expression="headers['routingCode']" /> 

</int-http:inbound-gateway> 

<int:header-value-router input-channel="http.request.submit.withfiles" 
    header-name="routingCode" default-output-channel="http.router.route2.process.submit.withfiles"> 
    <int:mapping value="AB" 
     channel="http.router.route1.process.submit.withfiles" /> 
    <int:mapping value="AC" 
     channel="http.router.route2.process.submit.withfiles" /> 
    <int:mapping value="AD" 
     channel="http.router.route2.process.submit.withfiles" /> 
    <int:mapping value="AE" 
     channel="http.router.route2.process.submit.withfiles" /> 
    <int:mapping value="AF" 
     channel="http.router.route2.process.submit.withfiles" /> 
</int:header-value-router> 

<int-http:outbound-gateway 
    id="http.gateway.outbound.route1.submit.withfiles" header-mapper="headerMapper" 
    request-channel="http.router.route1.process.submit.withfiles" 
    reply-channel="http.response.submit.withfiles" 
    url="http://localhost:8080/myapplication1/file" 
    http-method-expression="headers.http_requestMethod" 
    expected-response-type="java.lang.String" charset="UTF-8" 
    reply-timeout="50000" /> 

<int-http:outbound-gateway 
    id="http.gateway.outbound.route2.submit.withfiles" header-mapper="headerMapper" 
    request-channel="http.router.route2.process.submit.withfiles" 
    reply-channel="http.response.submit.withfiles" 
    url="http://localhost:8081/myapplication2/file" 
    http-method="POST" charset="UTF-8" expected-response-type="java.lang.String" 
    reply-timeout="50000"> 
</int-http:outbound-gateway> 

Сообщение об ошибке:

02-Sep-2015 13:36:07.300 SEVERE [http-nio-8080-exec-13] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [springServlet] in context with path [/my-switcher] threw exception [Request processing failed; nested exception is org.springframework.messaging.MessageHandlingException: HTTP request execution failed for URI [http://localhost:8081/myapplication2/file]; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)) (through reference chain: org.springframework.integration.http.multipart.UploadedMultipartFile["inputStream"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)) (through reference chain: org.springframework.integration.http.multipart.UploadedMultipartFile["inputStream"])] with root cause 
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)) (through reference chain: org.springframework.integration.http.multipart.UploadedMultipartFile["inputStream"]) 
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59) 
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:26) 
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575) 
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666) 
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) 
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:129) 
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2240) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:231) 
    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208) 
    at org.springframework.http.converter.FormHttpMessageConverter.writePart(FormHttpMessageConverter.java:331) 
    at org.springframework.http.converter.FormHttpMessageConverter.writeParts(FormHttpMessageConverter.java:311) 
    at org.springframework.http.converter.FormHttpMessageConverter.writeMultipart(FormHttpMessageConverter.java:301) 
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:240) 
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:87) 
    at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:774) 
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:567) 
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:545) 
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:466) 
    at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.handleRequestMessage(HttpRequestExecutingMessageHandler.java:422) 
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99) 
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97) 
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:286) 
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:245) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45) 
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:95) 
    at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:188) 
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78) 
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116) 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101) 
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97) 
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) 
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:286) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:150) 
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:45) 
    at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:42) 
    at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:331) 
    at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:302) 
    at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.actualDoHandleRequest(HttpRequestHandlingEndpointSupport.java:492) 
    at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:389) 
    at org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:103) 
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) 
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1517) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1474) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 

Подробнее:

Фактический вебсервис (http://localhost:8081/myapplication2/file) сделать многослойную форму загрузки и возвращает сообщение JSon обратно к вызывающему приложению. Итак, что я ожидаю от этого маршрута SI, HTTP-исходящий шлюз вызовет вышеупомянутый веб-сервис и сделает postupload и вернет ответ json.

Также я передаю запрос через почтальона, как это. enter image description here

+0

Вопросы, которые просто говорят: «(x) не работает», как правило, здесь не уделяется особого внимания. Вам нужно объяснить, что вы пробовали, и что именно вы подразумеваете под «нерабочим», путем добавления журналов, следов стека и т. Д. В качестве доказательств. См. Http://stackoverflow.com/help/how-to-ask –

+0

Отредактировано с ошибкой Сообщение и данные – user3121011

+0

По какой-то причине исходящий 'RestTemplate' пытается преобразовать' UploadedMultipartFile' в JSON (который не будет работать). Мне нужно провести некоторое экспериментирование. –

ответ

0

Thanks Gary.

На данный момент я решил эту проблему, заменив «исходящий путь http» на «активатор службы» и вызвал веб-сервис через шаблон REST внутри класса, который указан в активаторе службы.

<int:service-activator id="serviceactivator"   
    input-channel="http.router.process.submit.withfiles" 
    output-channel="http.response.submit.withfiles"  
    ref="multipartReceiver" method="receive" 
    requires-reply="true" > 
</int:service-activator> 
2

Proxying a multipart/form-data Запрос, подобный этому, в настоящее время не поддерживается.

Проблема заключается в том, что Spring MVC преобразует необработанные данные формы в MultipartHttpInputMessage; который далее преобразуется входящим шлюзом в MultiValueMap, где файловая часть (ы) имеет (есть) UploadedMultipartFile экземпляров.

Исходящий шлюз не знает, как обрабатывать этот объект; для этого нет конвертера.

Вы можете попробовать добавить трансформатор, чтобы преобразовать UploadedMultiPartFile элемент (ы) в полезной нагрузке для Resource (ов), или написать пользовательскую MessageConverter и ввести его в исходящий шлюз.

Мы видим все больше и больше этих HTTP-прокси-сценариев, поэтому, пожалуйста, откройте «новую функцию» JIRA issue.

Еще лучше, рассмотрите contributing решение!

EDIT:

Вот еще одну работу вокруг - и это более эффективно. Фактически мы хотим отключить многокомпонентное декодирование во входящем шлюзе и передать запрос с несколькими частями без изменений к исходящему.

Вот как это сделать ...

Удалить многосекционный распознаватель боб

Добавить обычай «PASS-через» многочастный преобразователь к входящему шлюзу ...

public class PassThroughMultiPartConverter implements HttpMessageConverter<byte[]> { 

    @Override 
    public boolean canRead(Class<?> clazz, MediaType mediaType) { 
     if (!(byte[].class.isAssignableFrom(clazz))) { 
      return false; 
     } 
     if (mediaType != null) { 
      return MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType) 
        || MediaType.MULTIPART_FORM_DATA.includes(mediaType); 
     } 
     else { 
      return false; 
     } 
    } 

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

    @Override 
    public List<MediaType> getSupportedMediaTypes() { 
     return Collections.singletonList(MediaType.MULTIPART_FORM_DATA); 
    } 

    @Override 
    public byte[] read(Class<? extends byte[]> clazz, HttpInputMessage inputMessage) 
      throws IOException, HttpMessageNotReadableException { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     FileCopyUtils.copy(inputMessage.getBody(), baos); 
     return baos.toByteArray(); 
    } 

    @Override 
    public void write(byte[] t, MediaType contentType, HttpOutputMessage outputMessage) 
      throws IOException, HttpMessageNotWritableException { 
     throw new UnsupportedOperationException(); 
    } 

} 

.

<int-http:inbound-gateway 
    ... 
            request-payload-type="byte[]" 
            message-converters="converter" 
            merge-with-default-converters="false" /> 

<bean id="converter" class="foo.PassThroughMultiPartConverter" /> 
+0

Я думаю, что у меня может быть другая работа - следите за обновлениями ... –

+0

См. Редактирование для другого решения. –

+0

Поддержка будет добавлена ​​в [предстоящий выпуск 4.2] (https://jira.spring.io/browse/INT-3818). –

Смежные вопросы