Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request parameters cannot bind to Optional<List<String>> [SPR-13418] #17997

Closed
spring-projects-issues opened this issue Sep 1, 2015 · 7 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Sep 1, 2015

Kazuki Shimizu opened SPR-13418 and commented

Request parameter cannot bind to Optional<List<String>> at the @RequestMapping method.

I define the following method as handler method(@RequestMapping method).

@RequestMapping(path="search")
public String search(@RequestParam(defaultValue="word1,word2,word3") Optional<List<String>> words, Model model) {
    List<String> searchWords = words.get();
    System.out.println(searchWords);
    //...
}

I submit a request to http://localhost:8080/myApp/search?words=aaa&words=bbb.
In this case, i was expected a printing as follow:

[aaa, bbb]

But actually, printed as follow:

[aaa]

In this case, request parameters can be bind to first element only.

In addition, i submit a request to http://localhost:8080/myApp/search. (without request parameters)
In this case, printed as follow:

[word1, word2, word3]

In this case,default value converted by conversion service was applied.

This behavior is bug or specification ?

I will submit a repro project at the later.


Affects: 4.2.1

Issue Links:

0 votes, 5 watchers

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

I've submit PR of repro project.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

It looks like when a request parameter has 2 values the ArrayToObjectConverter kicks in, which tries to convert the first value in the array to the target Object. Since ObjectToOptionalConverter can do just that, we end up with only the first request parameter value used. The case when the @RequestParam default value is used works because in that scenario the conversion is from a comma-separated String.

As a workaround in this case you can remove Optional. The use of defaultValue implies its optional and it will always have a value.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Juergen Hoeller, it seems that ObjectToOptionalConverter ought to be registered earlier, perhaps ahead of the collection converters?

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Rossen Stoyanchev, indeed, worth a try...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Kazuki Shimizu commented

Thanks for comments!!

As a workaround in this case you can remove Optional.

I know the workaround and tried it.
Actually, i want to use without defaultValue attribute as follow.
(in other words, i want to apply a default value that decided by programmatic)

e.g.)

@RequestMapping(path="search")
public String search(@RequestParam String type, @RequestParam Optional<List<String>> words, Model model) {
    model.addAttribute("words", String.valueOf(words.orElseGet(()->defaultValue(type))));
    // ...
}

private List<String> defaultValue(String type){
    // it is dummy code.
    return "1".equals(type) ?
            Arrays.asList("word1", "word2", "word3") :
            Arrays.asList("word4", "word5", "word6");
}

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Let's do this in a broader fashion for 4.3, making sure Optional declarations work for collections across the framework. In the end, we never really defined the semantics there.

For the time being, when not using defaultValue, you could also declare @RequestParam(required=false). Optional is effectively just a syntactic variation of that.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Tor Arne Kvaløy commented

As of version 4.3.2 I still only get the first element in the list.

@RequestParam(required = false) Optional<List<String>> locations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants