1

I am trying to upload a multipart form-data with an attached xml file to integration server.

I am using a HttpRequestHandlingMessagingGateway with a RequestMapping bean.

  @Bean("Inbound_GATEWAY_in")
    public MessageChannel Inbound_GATEWAY_in() { return new DirectChannel(); }
  @Bean
    public HttpRequestHandlingMessagingGateway selerixInboundRequest() {
        HttpRequestHandlingMessagingGateway gateway =
                new HttpRequestHandlingMessagingGateway(true);
        gateway.setRequestMapping(selerixMapping());
        gateway.setMessageConverters( messageConverter() );
        gateway.setMultipartResolver(multipartResolverBean());
        gateway.setRequestTimeout(3000); // 3s
        gateway.setReplyTimeout(5000); // 5s
        gateway.setRequestChannelName("Inbound_GATEWAY_in");
        gateway.setReplyChannelName("Outbound_GATEWAY_out");
        return gateway;
    }
    @Bean
    public RequestMapping selerixMapping() {
        RequestMapping requestMapping = new RequestMapping();
        requestMapping.setPathPatterns("/path");
        requestMapping.setMethods(HttpMethod.POST);
        requestMapping.setConsumes(MediaType.MULTIPART_FORM_DATA_VALUE);
        return requestMapping;
    }
@Bean
    public MultipartResolver multipartResolverBean(){
        return new CommonsMultipartResolver();
    }
@ServiceActivator(inputChannel = "Inbound_GATEWAY_in")
    public Message<?>  headerEnrich_Inbound_GATEWAY_in(Message<?> message){
         Message<?> outmessage = null;
    LOGGER.info("message ", message); // returns blank message

But when I am trying to upload the xml file the message is coming as blank.

How can I find the xml file in the Message<?> or how can I check the Request object ?

Santrupta Dash
  • 269
  • 2
  • 15
  • Is spring integration dead ? I do not see any new question or any samples using java. All the samples are only with xml or java DSL. Can anyone help me I am wasting time using spring integration ? – Santrupta Dash Feb 02 '23 at 14:53
  • How do you upload the file? What is your `messageConverter`? You can turn on DEBUG logging level for `org.springframework.integration` to see how your messages are traveling through the flow and with what content. – Artem Bilan Feb 02 '23 at 16:33

2 Answers2

1

Here is a simple test to demonstrate how we can upload the file using Spring Integration:

@SpringJUnitWebConfig
@DirtiesContext
public class FileUploadTests {

    @Autowired
    private WebApplicationContext wac;


    private MockMvc mockMvc;

    @BeforeEach
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    void commonsFileUploadValidation() throws Exception {
        MockPart mockPart1 = new MockPart("file", "file.text", "ABC".getBytes(StandardCharsets.UTF_8));
        mockPart1.getHeaders().setContentType(MediaType.TEXT_PLAIN);

        this.mockMvc.perform(multipart("/path").part(mockPart1))
                .andExpect(status().isOk())
                .andExpect(content().string("File uploaded: file.text with content: ABC"));
    }

    @Configuration
    @EnableIntegration
    public static class ContextConfiguration {

        @Bean("Inbound_GATEWAY_in")
        public MessageChannel Inbound_GATEWAY_in() {
            return new DirectChannel();
        }

        @Bean
        public HttpRequestHandlingMessagingGateway selerixInboundRequest() {
            HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway();
            RequestMapping requestMapping = new RequestMapping();
            requestMapping.setPathPatterns("/path");
            gateway.setRequestMapping(requestMapping);
            gateway.setRequestChannelName("Inbound_GATEWAY_in");
            return gateway;
        }

        @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
        public MultipartResolver multipartResolver() {
            return new StandardServletMultipartResolver();
        }

        @ServiceActivator(inputChannel = "Inbound_GATEWAY_in")
        public String headerEnrich_Inbound_GATEWAY_in(MultiValueMap<String, MultipartFile> payload) throws IOException {
            MultipartFile file = payload.getFirst("file");
            return "File uploaded: " + file.getOriginalFilename() + " with content: " + new String(file.getBytes());
        }

    }

}

Note: the CommonsMultipartResolver is deprecated for a while and was removed from latest Spring. Please, be sure that you use the latest versions of the frameworks: https://spring.io/projects/spring-integration#learn

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Thanks Artem. But I implemented using RestTemplate. RestTemplate provides cleaner documentation and easier implementation. However according to your expert views - Is RestTemplate advisable in a spring integration project? – Santrupta Dash Feb 11 '23 at 17:36
  • The `RestTemplate` is a client side API. Not sure why you talk about it in this question about the server side... Maybe different SO question if you have anything in mind? Although I believe that you need to start from some book, like Spring in Action. Since it feels like you flow a little bit with what you have in your hands. Spring Integration really uses the mentioned `RestTemplate` in its client side channel adapter implementation - `HttpRequestExecutingMessageHandler`. Sure! You can use a `RestTemplate` in the unit test as well, but there is indeed a reason in MockMVC. – Artem Bilan Feb 13 '23 at 12:58
  • Sorry My bad. It was not RestTemplate, It was a normal rest controller. I added that in a separate answer. below. Could you please advice if it is a correct way Or should I use the above way. – Santrupta Dash Feb 14 '23 at 13:26
  • 1
    Well, in the end it is up to you. Your question was about a `HttpRequestHandlingMessagingGateway` and I gave you a working answer. If you go a `@RestController`, then it is already a fully different story... – Artem Bilan Feb 14 '23 at 15:59
  • Thanks @Artem Bilan. For your response. I will definitely try to implement you answer as that is a bit more spring integration way. That's why I have marked your answer as accepted answer. Thanks again. – Santrupta Dash Feb 14 '23 at 16:56
1

What I did is I created an interface

@Configuration
@MessagingGateway
@EnableIntegration
public interface IntegrationGateway2 {

 @Gateway(requestChannel = "Inbound_CHANNEL_in", replyChannel = "Inbound_Channel_reply")
 public Message<?> sendAndReceive(Message<?> input);
}

and then created a normal rest controller and fetched the multipart file and then converted to a message.


@RestController
@EnableIntegration
@Configuration
public class SelerixController {
   
    @Bean("Inbound_CHANNEL_in")
    public MessageChannel Inbound_Channel_in() {
        return new DirectChannel();
    }
    @Bean("Inbound_Channel_reply")
    public MessageChannel Inbound_Channel_reply() {
        return new DirectChannel();
    }

    @Autowired
    IntegrationGateway integrationGateway;

    @PostMapping("/processFile")
    public ResponseEntity<String> fileUpload(@RequestParam String partner, @RequestParam("file") MultipartFile file ) throws IOException {
        Message reply = null;
        String xmlInputData = "";
        if (file != null) {
            InputStream is = file.getInputStream();
            xmlInputData = new BufferedReader(new InputStreamReader(is))
                    .lines().collect(Collectors.joining(""));
            MapConversionUtility mcu = new MapConversionUtility();
            String json = mcu.convertXmlToJSON(xmlInputData);

            Map<String, Object> header = new HashMap<String, Object>();
            header.put("uuid", UUID.randomUUID().toString());
            header.put("REAL_TIME_FLAG", "TRUE"); //QUERY_PARAM
            header.put("QUERY_PARAM", partner);
            Message<?> request = MessageBuilder
                    .withPayload(json)
                    .copyHeaders(header)
                    .build();
            reply = integrationGateway.sendAndReceive( request);
            LOGGER.info("getting reply final *************** {}",reply.getPayload());
        }
    }
}
Didil
  • 58
  • 5