400 (Bad Request) when sending array to Spring Controller using AJAX

Asked

Viewed 566 times

3

POST http://localhost:7001/app/workflow/execute/ 400 (Bad Request)

I’m getting this error when trying to send 2 array’s to my Spring controller, but I’m getting this error, tried some solutions I found on Soen but was not successful. The version of my Spring is the 3.0.2.

JS Code

var url = '/app/workflow/execute/';
$.ajax({
    url: url,
    type: 'POST',
    dataType: 'json',
    data: {
        processName : pName,
        argumentsNameArray : argumentsNameArr,
        argumentsValArray : argumentsValArr
    },
})
.done(function(data) {
    console.log(data);
});

Java code

@RequestMapping(value = "/workflow/execute/", method = RequestMethod.POST)
@ResponseBody
public WorkflowProcess executeWFProccess(
        @PathVariable("processName") String processName,
        @PathVariable("argumentsNameArray[]") String[] argumentsNameArray,
        @PathVariable("argumentsValArray[]") String[] argumentsValArray) {

    WorkflowProcess wfProcess = new WorkflowProcess();
    ArrayList<WFArgument> wfArguments = new ArrayList<WFArgument>();
    wfProcess.setProcessName(processName);

    for (int i = 0; i < argumentsNameArray.length; i++) {
        wfArguments.add( new WFArgument(argumentsNameArray[i], argumentsValArray[i]) );
    }
    wfProcess.setArguments(wfArguments);

    return wfProcess;
}

2 answers

1


First we have to understand how the request is made, how the values will arrive on the server. For this we just see in the documentation of jQuery and we will have there that the data of ajax is sent as URL parameters.

The second thing to understand is the difference between @PathVaviable and @RequestParam, that is, when each one should be used. From the documentation we can realize that @PathVaviable is used to recover values of variables in URI templates, as an example /workflow/execute/{processName}, then we’d have something like this:

@RequestMapping(value = "/workflow/execute/{processName}", method = RequestMethod.POST)
public WorkflowProcess executeWFProccess(@PathVaviable("processName") final String processName) {
    // faz alguma coisa
}

As we saw at the beginning your request puts the values as parameters and not as variables in the URL. So when we’re using parameters we have to use @RequestParam so that Spring can map the request parameters for our variables request Mapping.

In view of this, we just need to change @PathVaviable for @RequestParam in your example, thus staying:

@RestController
@RequestMapping(value = "/app")
public class WorkflowProcessWS {

    @RequestMapping(value = "/workflow/execute/", method = RequestMethod.POST)
    public WorkflowProcess executeWFProccess(@RequestParam("processName") final String processName,
            @RequestParam("argumentsNameArray[]") final String[] argumentsNameArray,
            @RequestParam("argumentsValArray[]") final String[] argumentsValArray) {
        final WorkflowProcess process = new WorkflowProcess();
        final List<WFArgument> wfArguments = new ArrayList<>();
        process.setProcessName(processName);
        for (int i = 0; i < argumentsNameArray.length; i++) {
            wfArguments.add(new WFArgument(argumentsNameArray[i], argumentsValArray[i]));
        }
        process.setArguments(wfArguments);
        return process;
    }

}

Just to test I made a call this way:

var url = '/app/workflow/execute/';
$.ajax({
    url : url,
    type : 'POST',
    dataType : 'json',
    data : {
        processName : "Nome do Processo",
        argumentsNameArray : ["Name1", "Name2", "Name3"],
        argumentsValArray : ["Val1", "Val2", "Val3"]
    },
}).done(function(data) {
    console.log(data);
    console.log("processName: " + data.processName);
    $.each(data.arguments, function(key, value) {
        console.log("key: " + key + " | value: " + value.val + " | name: " + value.name);
    });
});

And the return logged it(just a part, to get smaller here) on Chrome console:

Resultado da requisição

Finally, if necessary, you can recover all the parameters of the request by mapping them to a Multivaluemap, including something like this in your method:

@RequestParam final MultiValueMap<String, String> params
  • Thank you very much, @Bruno César! Using the @RequestParam worked properly.

0

Where comes argumentsNameArr and argumentsValArray in the Javascript part?

They need to be in a format like variavel[]=valor1, variavel[]=valor2 to be interpreted by Java as an Array

Try also to use

    @PathVariable("argumentsNameArray") String[] argumentsNameArray // repare na ausencia dos []
  • I mount the array by iterating the fields of my form: $('input[name="argumentName[]"]').each(function() {&#xA; argumentsNameArr.push( $(this).val() );&#xA;});

  • The mount is correct as I understand it. Only remains to debug if the controller is receiving the request correctly. You can try using @Requestparam(value = "argumentsNameArray") String[] argumentsNameArray instead of Pathvariable

Browser other questions tagged

You are not signed in. Login or sign up in order to post.