2

As far as I know, Spring Boot has two ways of passing arrays in request parameters:

  1. comma separated values, ex: numbers=1,2,3,4,5
  2. repeated parameter name, ex: numbers=1&numbers=2&numbers=3&numbers=4&numbers=5

In my example below, it first tries to convert an array using method 1. then after exception it successfully convert it using method 2.


My questions are:

is there any way to tell Spring Boot to use only method 2.?

Alternatively is there any way to escape commas in JSON string passed as request parameter of x-www-form-urlencoded content type?


DemoObject.class:

public class DemoObject {
    
    private String name;
    private String description;
    private Integer count;

    //Constructor, Getters and Setters

}

DemoController.class:

@RestController
public class DemoController {
    
    @PostMapping("test")
    String test(@RequestParam List<DemoObject> objects, @RequestParam Integer number) throws JsonProcessingException {
        return "["+number +"] " +om.writerWithDefaultPrettyPrinter().writeValueAsString(objects);
    }
    
}

DemoConverter.class:

@Component
public class DemoConverter implements GenericConverter {

    private final ObjectMapper om = new ObjectMapper();
    
    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        Set<ConvertiblePair> convertibles = new HashSet<>();
        convertibles.add(new ConvertiblePair(String.class, DemoObject.class));
        return convertibles;
    }

    @Override
    public Object convert(Object o, TypeDescriptor sourceType, TypeDescriptor targetType) {
        try {
            return om.readValue((String) o, targetType.getType());
        } catch (JsonProcessingException ex) {
            Logger.getLogger(DemoConverter.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException("Conversion failed");
        }
    }

}

Sample request 1.:

POST http://localhost:8080/test  
Body x-www-form-urlencoded  
objects:{"name":"test","description":"AAA"}
number:123

Spring Boot throws an exception:

com.fasterxml.jackson.core.io.JsonEOFException: 
Unexpected end-of-input: expected close marker for Object 
(start marker at [Source: (String)"{"name":"test""; line: 1, column: 1])

But result is correct with status 200 code.


Sample request 2.:

POST http://localhost:8080/test  
Body x-www-form-urlencoded  
objects:{"name":"test","description":"AAA"}  
objects:{"name":"test2","description":"BBB"}  
number:123

No exception, status 200, correct result.


Any help appreciated.

Gabriel's Messanger
  • 3,213
  • 17
  • 31
  • Hi mateusz-kowalski, so the RequestParam it is when you pass them in the URL like in the examples you did, but your actually request it is a POST sending in the body. So first thing, it is RequestBody the annotation you need for the Controller. Also, you don't need the converter. If you just send "[ {"name":"test","description":"AAA"} ]" it will be mapped as array to the controller with [ ] to show JSON that it is a array . – Brother Mar 22 '21 at 11:59
  • @Brother I updated example with another arg. I want to pass multiple args. https://stackoverflow.com/a/47457597/5970359 - here is smillar thread, about passing request params in POST, but any of them are not satisfactioning me. If i should not use RequestParam in POST, so what is proper annotation or method to do so without creating any data wraper or dealing with maps. – Mateusz Kowalski Mar 22 '21 at 12:13
  • Also i found this: https://stackoverflow.com/a/32980438/5970359 it seems that RequestParam with body of x-www-form-urlencoded is allowed. https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html – Mateusz Kowalski Mar 22 '21 at 12:38

0 Answers0