10
votes

I'm trying to upload file via JSP and controller but I always get

HTTP Status 405 - Request method 'POST' not supported

type Status report

message Request method 'POST' not supported

description The specified HTTP method is not allowed for the requested resource.

This is my form (only part of all JSP page):

<form method="POST" enctype="multipart/form-data" action="product.file.add">
    <input name="productId" type="hidden" />
    <tr>
        <th>Foto: </th>
        <td><input type="file" name="file" /></td>
    </tr>
    <tr>
        <td class="bt" ><input type="submit" value="Add image" /></td>
        <td class="bt" ><input type="submit" value="Continue without image" /></td>
    </tr>
</form>

My part of controller (only looged file name now):

@RequestMapping(value = "/admin/product.file.add", method = RequestMethod.POST)
    public String productFileUpload(@RequestParam("file") MultipartFile file,
            @RequestParam("productId") int productId) {
        logger.info(file.getName());
        return "redirect:/admin/product";
}

And part of servlet-context.xml

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

But always I get:

HTTP Status 405 - Request method 'POST' not supported

Could you please help me someone? :(


My controller without all method:

@Controller
public class ProductController {

    @Autowired
    private ProductDao productDao;

    @Autowired
    private ProducerDao producerDao;

    @Autowired
    private SectionDao sectionDao;

    @Autowired
    private TasteDao tasteDao;

    @Autowired
    private CategoryDao categoryDao;

    private static final Logger logger = LoggerFactory
            .getLogger(ProductController.class);


    @RequestMapping(value = "/admin/productfileadd", method = RequestMethod.POST)
    public String productFileUpload(@RequestParam("file") MultipartFile file,
            @RequestParam("productId") int productId) {
        logger.info(file.getName());
        return "redirect:/admin/product";
    }       


}

My application run on:

http://localhost:8080/prosvaly/

I'm using in all for the same "action style" and it works. In this form when I clik on the button. It redirects me on the right way. I tried to change my action on

action="/prosvaly/admin/productfileadd

But still same error. And when I change method type from POST to GET, I get another error:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: The current request is not a multipart request

So I think that problem is not in action, because GET method can find the same URL

4
Dots in @RequestMappings have a special meaning, if you don't really need them try to execute the action without them e.g. @RequestMapping(value = "/admin/productfileadd", method = RequestMethod.POST) and <form method="POST" enctype="multipart/form-data" action="productfileadd"> - Andreas
I tried it without dots and I got same error :( - user1604064
Could you lookup where you are posting to e.g. with Fiddler, maybe you are not calling the right action and it should be action="/admin/productfileadd". - Andreas
The error means that Spring MVC is not able to find a suitable controller for the POST request. Post your full controller code and also URL mapping config. - Pat
btw, just to clarify this has nothing to do with your file upload code. Something is inherently wrong in the way you have configured Spring MVC - not specific to upload function. - Pat

4 Answers

14
votes

The main problem was in spring security. I resolved this problem. Sprinf security blocks my URL but I don't know why.

I resolved this problem, I added ?${_csrf.parameterName}=${_csrf.token} to end of my form action

<form method="POST" action="uploadOneFile**?${_csrf.parameterName}=${_csrf.token}**" enctype="multipart/form-data">

Now it works!

0
votes

value of @RequestMapping is "/admin/product.file.add", and the action of form is action="product.file.add". I think the should be action="/admin/product.file.add"

Or you can try with <form method="POST" enctype="multipart/form-data" action="/product.file.add">

0
votes

I had the same issue and my solution was different. In my case I am using annotations based configurations I annotated my class with @Controller but I never told the configuration class to scan my package where the controllers was and the way to do this is to annotation your configuration class with

@ComponentScan(basePackages = "com.controllers.location.package") 
0
votes

Spring MVC is configured by default to prevent Cross-Site Request Forgery (CSRF) attacks by requiring a server generated CSRF token to be returned as part of POST requests.

Including the CSRF token as part of your form template is simple as an input:

<input type="hidden"
  th:name="${_csrf.parameterName}"
  th:value="${_csrf.token}">

You can disable CSRF protection on a per-route basis like:

@Override
protected void configure(HttpSecurity http) throws Exception {
  http.csrf().disable();
}

Both of these examples come from the Spring documentation about CSRF.

The dangers of disabling CSRF request validation should be weighed before deciding to do so - it opens your users up to action hijacking in some contexts.

Here are a couple more helpful articles on the topic: https://www.baeldung.com/spring-security-csrf https://www.baeldung.com/csrf-thymeleaf-with-spring-security