2

I have following code:

@Controller
public class FileUploadController {

@Autowired
private AttachmentsToSendJDBCTemplate attachmentsToSendJDBCTemplate;

@RequestMapping(value = "/upload", method = RequestMethod.GET)
public String showUploadForm(HttpServletRequest request) {
    return "upload";
}

@RequestMapping(value = "/doUpload", method = RequestMethod.POST)
public String handleFileUpload(HttpServletRequest request,
@RequestParam CommonsMultipartFile[] fileUpload) throws Exception { 
int a = 5; //breakpoint is here;

upload.jsp:

<form method="post" action="doUpload" enctype="multipart/form-data">
    <table border="0">
        <tr>
            <td><input type="file" name="fileUpload" size="50" /></td>
        </tr>           
        <tr>
            <td colspan="2" align="center"><input type="submit" value="Upload" /></td>
        </tr>
    </table>
</form>

web.xml:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/application-context.xml,
            /WEB-INF/spring-database.xml,
            /WEB-INF/spring-security.xml,
            /WEB-INF/spring-web-config.xml,
            /WEB-INF/mail-service.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/application-context.xml,
        /WEB-INF/spring-database.xml,
        /WEB-INF/spring-security.xml,
        /WEB-INF/spring-web-config.xml,
        /WEB-INF/mail-service.xml
    </param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

spring-web-config.xml:

<context:component-scan base-package="com.github.fedorchuck.morshinska" />

<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/" />
    <property name="suffix" value=".jsp" />
</bean>

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

<mvc:resources mapping="/resources/**" location="/resources/" cache-period="31556926"/>

<mvc:annotation-driven />

application-context.xml:

<bean id="springSecurityFilterChain" class="org.springframework.web.filter.DelegatingFilterProxy"/>

<bean id="userDetailsService" class="com.github.fedorchuck.morshinska.service.account.AccountDetailsServiceImpl"/>

<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>

<bean id="emailJDBCTemplate" class="com.github.fedorchuck.morshinska.dao.impl.EmailJDBCTemplate">
    <property name="dataSource"  ref="dataSource" />
</bean>

<bean id="usersJDBCTemplate" class="com.github.fedorchuck.morshinska.dao.impl.UsersJDBCTemplate">
    <property name="dataSource"  ref="dataSource" />
</bean>

<bean id="attachmentsToSendJDBCTemplate" class="com.github.fedorchuck.morshinska.dao.impl.AttachmentsToSendJDBCTemplate">
    <property name="dataSource"  ref="dataSource" />
</bean>

and log:

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/upload],methods=[GET]}" onto public java.lang.String com.github.fedorchuck.morshinska.web.controller.FileUploadController.showUploadForm(javax.servlet.http.HttpServletRequest)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/doUpload],methods=[POST]}" onto public java.lang.String com.github.fedorchuck.morshinska.web.controller.FileUploadController.handleFileUpload(javax.servlet.http.HttpServletRequest,org.springframework.web.multipart.commons.CommonsMultipartFile[]) throws java.lang.Exception
...
org.springframework.web.servlet.PageNotFound handleHttpRequestMethodNotSupported
  WARNING: Request method 'POST' not supported
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver logException
  WARNING: Handler execution resulted in exception: Request method 'POST' not supported

Method GET working correct in contradistinction to POST (HTTP Status 405 - Request method 'POST' not supported). I'm sure - something wrong with configuration. So, where is my mistake. Please help.

5 Answers5

3

The question is solved. It was CSRF token. More precisely:

<form method="POST" 
      enctype="multipart/form-data" 
      action="doUpload?${_csrf.parameterName}=${_csrf.token}">
      ...
      <input type="hidden" 
             name="${_csrf.parameterName}" 
             value="${_csrf.token}" />
</form>

For more information chapter in docs.spring.io

2

Can give following a try? This is how I have the method setup on my controller.

@RequestMapping(value = "/doUpload", method = RequestMethod.POST)
public String handleFileUpload(MultipartFile uploadedFile, HttpServletRequest request) throws Exception { 
int a = 5; //breakpoint is 

I am not sure what CommonsMultipartFile does. I don't think you need @RequestParam.

I hope it helped.

Update - I think the problem is the 'value' attr on the button. There is no matching controller that accepts the param 'Upload'.

exe
  • 317
  • 1
  • 10
2

You're submitting a value from the button, but not accepting it on the controller method.

rhinobear
  • 21
  • 1
  • 2
0

Give a try - use @RequestBody in place of @RequestParam.

Moni
  • 433
  • 3
  • 9
0

I had this issue, spent hours, and got an answer. Here are all the steps you need to check if you get 405(Request method 'POST' not supported) while uploading the Multipart file!

  1. Chek _csrf and enctype value in .jsp file in html form label Check this short answer.
  2. Make sure you have multipartResolver bean in your spring-servlet.xml:
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/, if you get an exception while creating this bean, add this dependency to your pom.
  3. Check your controller's method's annotation which handles the request, it should be something like this:
    @RequestMapping(value = "/requestpath", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    and this if you have additional fields
    @RequestMapping(method = RequestMethod.POST, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_FORM_URLENCODED_VALUE})

To sum up: _csrf and enctype in .jsp, bean in spring-servlet.xml, request consumer in the controller.