2

I've read all the questions related with this problem but no solution worked for me...

I have a simple upload form. The controller, i't a controller i've used a lot of times (never for a file upload though).

@Controller
public class FileUploadController {
    @Autowired
    private HttpServletRequest request;

    @RequestMapping(value={"/upload"}, method=  RequestMethod.GET)
    public String getUploadForm() {

        return "/upload";

    }

    @RequestMapping(value={"/upload"}, method=RequestMethod.POST)
    public @ResponseBody String uploadedFile(@RequestParam("uploadedFile") UploadedFile uploadedFile, BindingResult result, ModelMap model,
                                RedirectAttributes redirectAttributes) {

        if (result.hasErrors()) {
            return "/upload";

        } 
            InputStream is = null;
            OutputStream os = null;
            MultipartFile file = uploadedFile.getFile();
            String fileName = file.getOriginalFilename();
            String imagepath = request.getSession().getServletContext().getRealPath("/resources/images");
            try {
                is = file.getInputStream();
                File newFile = new File(imagepath+"/"+fileName);

                if(!newFile.exists()){
                    newFile.createNewFile();
                }
                os = new FileOutputStream(newFile);
                int read=0;
                byte[] bytes = new byte[1024];
                while((read = is.read(bytes)) != -1){
                    os.write(bytes, 0, read);
                }
                redirectAttributes.addFlashAttribute("css", "success");
                redirectAttributes.addFlashAttribute("msg", "File "+fileName+ "aggiunto correttamente");
                model.addAttribute("fileName", fileName);


            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        return "redirect:/floors";

    }

}

Then I have the upload form, cleaned form all the css part:

<form:form method="POST" enctype="multipart/form-data" modelAttribute="uploadedFile">

         <input type="hidden"
             name="${_csrf.parameterName}"
             value="${_csrf.token}" />
        <form:errors path="*" cssClass="alert alert-danger alert-dismissible"
            element="div" />


            <label class="control-label col-sm-2">Carica
                immagine</label>

                <input type="file" name="file">
                <form:errors path="file" class="control-label" />


        <button id="singlebutton" name="singlebutton"
                        class="btn btn-primary" type="submit">Carica</button>

        </div>
    </form:form>

I don't know if it's useful, but this is UploadedFile.java, really simple

import org.springframework.web.multipart.MultipartFile;

public class UploadedFile{

    MultipartFile file;


    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file = file;
    }

}

The form in HTML has:

<form id="uploadedFile" class="form-horizontal" action="/smartpark/upload" method="POST" enctype="multipart/form-data">

Where is the problem? I cannot even understand at which point che POST request goes wrong...

I'm adding the debug: Spring debug says:

2015-12-22 18:52:13 DEBUG FilterChainProxy:324 - /upload at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-12-22 18:52:13 DEBUG FilterChainProxy:324 - /upload at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-12-22 18:52:13 DEBUG HttpSessionSecurityContextRepository:192 - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@468e6d7e: Authentication: org.springframework.security.authentication.RememberMeAuthenticationToken@468e6d7e: Principal: org.springframework.security.core.userdetails.User@62dd304: Username: mario; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@7798: RemoteIpAddress: 192.168.3.38; SessionId: null; Granted Authorities: ROLE_ADMIN'
2015-12-22 18:52:13 DEBUG FilterChainProxy:324 - /upload at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2015-12-22 18:52:13 DEBUG HstsHeaderWriter:128 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@26ee04e5
2015-12-22 18:52:13 DEBUG FilterChainProxy:324 - /upload at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2015-12-22 18:52:13 DEBUG CsrfFilter:106 - Invalid CSRF token found for http://192.168.3.240:8080/smartpark/upload
2015-12-22 18:52:13 DEBUG DispatcherServlet:861 - DispatcherServlet with name 'dispatcher' processing POST request for [/smartpark/Access_Denied]
2015-12-22 18:52:13 DEBUG RequestMappingHandlerMapping:306 - Looking up handler method for path /Access_Denied
2015-12-22 18:52:13 DEBUG ExceptionHandlerExceptionResolver:133 - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
2015-12-22 18:52:13 DEBUG ResponseStatusExceptionResolver:133 - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
2015-12-22 18:52:13 DEBUG DefaultHandlerExceptionResolver:133 - Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
2015-12-22 18:52:13 WARN  PageNotFound:208 - Request method 'POST' not supported
2015-12-22 18:52:13 DEBUG DispatcherServlet:1034 - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
2015-12-22 18:52:13 DEBUG DispatcherServlet:1000 - Successfully completed request
2015-12-22 18:52:13 DEBUG HttpSessionSecurityContextRepository$SaveToSessionResponseWrapper:211 - Skip invoking on
2015-12-22 18:52:13 DEBUG SecurityContextPersistenceFilter:105 - SecurityContextHolder now cleared, as request processing completed

Browser network logs don't say anything, just that the POST resource is not accomplished

Thanks

5
  • 2
    On a side note. You can use the requestmapping annotation over your class @Controller @RequestMapping("floors") public class... That way you don't have to have a redundant constant over every method Commented Dec 22, 2015 at 17:13
  • Turn on your debug logs, check what Spring is registering as handler methods. Turn on your browser's network logs and check what is sent in your request. Post all of that. Commented Dec 22, 2015 at 17:44
  • 1
    Something in your security stack is forwarding the request to /smartpark/Access_Denied. Commented Dec 22, 2015 at 18:00
  • 1
    mmmm... maybe it's because of DEBUG CsrfFilter:106 - Invalid CSRF token found even if I pass it with the form... Commented Dec 22, 2015 at 18:03
  • 1
    I would recommend re-coding it from scratch using the guide: spring.io/guides/gs/uploading-files . Might be faster than trying to figure out where you went wrong. Start with something super simple , then expand on it without breaking it. Commented Dec 22, 2015 at 18:03

4 Answers 4

1

Things to Consider:

Check your request header and see if it's submitting to floors/upload. if not try to add action="floors/upload" property in your form tag.

Try to change your controller to (without the path)

 @RequestMapping(value="upload", method=RequestMethod.POST)
Sign up to request clarification or add additional context in comments.

6 Comments

I used the advice from @shinjw, but i got the same error, the HTML of the form goes to <form id="uploadedFile" class="form-horizontal" action="/smartpark/floors/upload/" method="POST" enctype="multipart/form-data">so it looks it goes to the right position...
Yes i did, I updated the question to reflect his advice
I already did it, thanks. I put everything at root level, now the mapping it's pointing to /upload directly
What is the line if (result.hasErrors()) ? maybe this causes the method to skip the uploading stuff
You mean that was the issue?
|
1

I found the problem. Following this link I saw that multipart file upload with spring and CSRF must be handled with care.

So I first disabled the CSRF to see if everything went well. After it, I added

@Override protected void beforeSpringSecurityFilterChain(ServletContext servletContext) { insertFilters(servletContext, new MultipartFilter()); }

to my SecurityWebApplicationInitializer.java so to not need the authentication to upload file on the server, but only to move them to their final destination.

Than I had to configure the filterMultipartResolver and everything went good.

Thank you all

Comments

0

Look into spring's PathVariables.

@RequestMapping(value = " /upload/{pathName}", method=RequestMethod.POST)
public String getOrder(@PathVariable String pathName){
 // do what you need
}

Comments

0

IntelliJ suggested I use <form:form, which uses gave

<html xmlns:form="http://www.w3.org/1999/xhtml">

at the top of my .html file. I changed to just <form in my body and then my POST request worked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.