Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC multipart response

I'm trying to write full multipart flow, from the client side sending multipart request using Spring restTemplate and from the server side auto resolve the different parts to objects (I'm using JAXB for objects marshaling) and send a response back in multipart.

I'm was able to implement almost all the flow but I'm unable to send a multipart response with jaxb objects from spring controller.

Here is the contorller code:

@RequestMapping(value="/putuser",method=RequestMethod.POST)
@ResponseBody
public MultiValueMap<String, Object> getUser(@RequestBody User user) throws IOException, JAXBException {
    }
    user.setName("new");
    MultiValueMap<String, Object> form = new LinkedMultiValueMap<String, Object>();  
    form.add("user", user);
    form.add("file", new FileSystemResource("/tmp/1.1")); 
    return form;
}

This is the exception that I'm getting in the server side:

java.lang.ClassCastException: org.springframework.core.io.FileSystemResource cannot be cast to java.lang.String
    at org.springframework.http.converter.FormHttpMessageConverter.writeForm(FormHttpMessageConverter.java:233)
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:197)
    at org.springframework.http.converter.FormHttpMessageConverter.write(FormHttpMessageConverter.java:73)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:148)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:189)
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:69)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:746)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)

It looks like Spring is trying to convert each part in the response to String instead of the correct content type (file/xml etc/) I tried to update my spring.xml file like this:

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.FormHttpMessageConverter">
                <property name="partConverters">
                    <list>
                        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
                        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
                        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
                        <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
                    </list>
                </property>
        </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

To try making he FormHttpMessageConverter to write the parts correctly but this did not helped

Is there any way making spring to send multipart responses correctly with different types of parts?

like image 692
Asaf Zinger Avatar asked Nov 24 '22 04:11

Asaf Zinger


1 Answers

You will need to set Content-Type header of your response to appropriate value. The FormHttpMessageConverter relies on Content-Type to identify if it needs to cast the response to String or some other type.

@RequestMapping(value="/putuser",method=RequestMethod.POST)
@ResponseBody
public MultiValueMap<String, Object> getUser(@RequestBody User user, HttpServletResponse httpResponse) throws IOException, JAXBException {
    }
    user.setName("new");
    MultiValueMap<String, Object> form = new LinkedMultiValueMap<String, Object>();  
    form.add("user", user);
    form.add("file", new FileSystemResource("/tmp/1.1")); 
    httpResponse.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); // <-- IMPORTANT
    return form;
}
like image 188
Chetan Gole Avatar answered Feb 28 '23 08:02

Chetan Gole