Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encoded Comma in URL is read as List in Spring

I have a REST Component in Spring. Simplified, it looks like this:

@RequestMapping(value = "/route", method = RequestMethod.GET)
public Object thisIsTheMethod(@RequestParam(value = "value", required = false) List<String> values) {
    return OtherClass.doTheThing(values);
}

This is used to consume a list of Strings of arbitrary length. You could do it a number of ways:

localhost:8080/route?value=this&value=that

OR

localhost:8080/route?value=this,that

Now let's say I want to pass in one string which contains a comma: value,1. How would I go about doing that? Replacing the comma with %2C results in a list of 2 values ("value", "1"). Putting anything in quotes, or escaped quotes, has similar problems. It looks like it works when I have multiple parameters and use the multiple-values pattern, though not when I use the comma-separated pattern.

like image 583
DrGodCarl Avatar asked May 05 '16 19:05

DrGodCarl


1 Answers

EDIT: I'm not sure why I bothered creating a domain object and going through the trouble of encoding and decoding the whole list. It's just as well that you can simply Base64 encode each parameter, and decide each parameter when read in.

As per my comment above, I was able to implement a solution. I am not particularly satisfied with the implementation, but it gets the job done. I would like to reiterate that there is almost certainly a better solution that can follow a more explicit approach with regards to the domain objects and the marshalling and unmarshalling of the values.

Assuming the list of values is formatted as a JSON list of value objects such as:

[{"value":"test,1"},{"value": "test,2"}]

The Base64 encoding is:

W3sidmFsdWUiOiJ0ZXN0LDEifSx7InZhbHVlIjogInRlc3QsMiJ9XQ==

My Controller is setup as:

@RequestMapping(value = "/test", method = RequestMethod.GET)
@ResponseBody
public String test(@RequestParam(value = "values", required = true) String values) throws JsonParseException, JsonMappingException, IOException{

    byte[] bValues = Base64.getDecoder().decode(values.getBytes());
    String json = new String(bValues);
    ObjectMapper mapper = new ObjectMapper();
    List<Value> myObjects = mapper.readValue(json, new TypeReference<List<Value>>(){});
    StringBuilder result = new StringBuilder();

    int i = 1;
    for (Value value : myObjects){
        result.append("value ");
        result.append(" ");
        result.append(i++);
        result.append(": ");
        result.append(value.getValue());
        result.append("<br>");
    }

    result.setLength(result.length() - 1);
    return result.length() > 0 ? result.toString() : "Test";
}

public static void main(String[] args) {
    SpringApplication.run(UatproxyApplication.class, args);
}

The Value class is:

public class Value implements Serializable{

private static final long serialVersionUID = -7342446805363029057L;

private String value;

public Value(){

}

public String getValue() {
    return value;
}

public void setValue(String value) {
    this.value = value;
}

}

The request is:

/test?values=W3sidmFsdWUiOiJ0ZXN0LDEifSx7InZhbHVlIjogInRlc3QsMiJ9XQ==

And the response is:

value 1: test,1
value 2: test,2
like image 89
Andonaeus Avatar answered Oct 25 '22 21:10

Andonaeus