1

Yesterday I had a similar problem where Ajax POST method returned 405 error which was caused by csrf token. Someone helped mi with this, but now I'm powerless what is happening.

I have an Ajax POST request:

$(document).ready(function(){
    var mic, recorder, soundFile;
    setup();
})


function setup() {
  mic = new p5.AudioIn();
  mic.start();
  recorder = new p5.SoundRecorder();
  recorder.setInput(mic);
  soundFile = new p5.SoundFile();
}

function toggleRecording(e) {
    if (e.classList.contains("recording")) {
        recorder.stop();    
        e.classList.remove("recording"); 
        sendAudioToServer(soundFile)
    } else {
        e.classList.add("recording");
        recorder.record(soundFile);
    }
}

function sendAudioToServer(soundFile)
{
    var data = new FormData();
    data.append('file', soundFile);
    $.ajax({
        method: 'POST',
        enctype: 'multipart/form-data',
        url: '/recognizeCommand',
        data: data,
        processData: false,
        contentType: false,
        success: function(data) {
          alert("works!");
        },    
        error: function(xhr, ajaxOptions, thrownError) {
            alert(xhr.status);
            alert(thrownError);
        }
    })
}

soundFile is an object from p5.js library which contain audio. I also try with simple String but there is the same error

And a controller in Spring MVC:

@RequestMapping(value = "/recognizeCommand", method = RequestMethod.POST)
    public @ResponseBody String recognizeCommand(@RequestParam("file") MultipartFile multipartFile) {
        try {
            SpeechRecognitionApplication.logger.info("BEFORE: " + multipartFile);
            byte[] bytes = multipartFile.getBytes();
            SpeechRecognitionApplication.logger.info(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "finish";
    }

When I send this Ajax request it throws error 400 and there is exception in Spring:

org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
    at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:199) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:112) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]

What is important that when I tested endpoint with postman and send some file as parameter it works correctly.

I know there are similar posts on this forum but seriously I checked each of them, try every solution and nothing can help. I believe that some of you will have any idea how to solve this problem.

EDIT Added this 3 lines before ajax post method:

data.append('file', "example");
console.log("file: " + data.get("file"));
console.log(data);

returns:

enter image description here

8
  • I believe your problem lies within contentType = false; Commented Jun 21, 2018 at 19:15
  • When I delete it there is status 500: org.springframework.web.multipart.MultipartException: Current request is not a multipart request Commented Jun 21, 2018 at 19:17
  • I tried every combination with ajax arguments and nothing works. Commented Jun 21, 2018 at 19:19
  • what is the Type of Sound file. Commented Jun 21, 2018 at 20:51
  • p5.SoundFile(); Commented Jun 21, 2018 at 20:51

2 Answers 2

2

I guess problem is not with spring controller, but the way the file is passed to request. To ensure that file is passed, you can log into browser to check if file is present :

console.log("file" + data.get("file"));

Could you show the code you use to get file from input ?

EDIT: Could you tes your endpoint with this simle file upload form ?

<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>

        function handleFileSelect() {
            var data = new FormData();
            input = document.getElementById('fileinput');
            data.append('file', input.files[0]);
            console.log("file" + data.get("file"));
            $.ajax({
                method: 'POST',
                enctype: 'multipart/form-data',
                url: 'http://localhost:8080/test/recognizeCommand',
                data: data,
                processData: false,
                contentType: false,
                success: function (data) {
                    alert("works!");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert(xhr.status);
                    alert(thrownError);
                }
            });
        }
    </script>
</head>
<body>

<input type="file" id="fileinput"/>
<input type='button' id='btnLoad' value='Test' onclick='handleFileSelect();'>

</body>
</html>

Sign up to request clarification or add additional context in comments.

4 Comments

It returns: file[object Object]
please test it with my edited answer. Replace url with yours
so the problem is with p5.SoundFile(), it might not be valid mutipart file. Your backend works correctly
Well, so I have to find some other library or check deeply documentation to find solution
1

You are getting this exception

org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present

and if you look this part of yor code

public @ResponseBody String recognizeCommand(@RequestParam("file") MultipartFile multipartFile)

You are using @RequestParam, so you have to change your code to

@RequestMapping(value = "/recognizeCommand", method = RequestMethod.POST, consumes = { "multipart/form-data" })
public @ResponseBody String recognizeCommand(@RequestPart("file") MultipartFile multipartFile) {

and it should work

4 Comments

Maybe soundFile is not a valid MultipartFile, try with an other file
If I pass simple String to FormData it's the same problem
Still the same problem
You cannot pass a simple String in multipart, you have to use something like this... formData.append('test', new Blob(["HELLO!!!"], { type: "text/plain" })); .... I think your file is not a valid MultipartFile

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.