Affects: \5.2.2
we usually inject an array use comma like this:
key=A,B,C
@Value("${key}")
String[] keys;
but can't inject an array like below
origin=http://domainA.com,http://domainB.com
only key have one element, below SpEL can work fine, if key have more than 2 elements, it won't work
@CrossOrigin(value = "${origin}")
Or
@CrossOrigin(value = "#{'${origin}'.split(',')}")
Can provide any advice?
Comment From: sbrannen
Yes, it is possible to inject an array into a field or constructor/method argument using @Value
, but it is not possible to use a SpEL expression that evaluates to an array in a single String
supplied to @CrossOrigin
.
The reason for the latter is that each individual String
configured via @CrossOrigin(value = { ... })
is processed as follows for Spring MVC (the same holds true for WebFlux).
https://github.com/spring-projects/spring-framework/blob/0a9c768b812e7e1208c76429bb7c3f700fdc1446/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java#L463-L471
org.springframework.util.StringValueResolver.resolveStringValue(String)
resolves the supplied SpEL expression, which in the provided @CrossOrigin(value = "#{'${origin}'.split(',')}")
example results in a String[]
.
The concrete implementation org.springframework.beans.factory.config.EmbeddedValueResolver.resolveStringValue(String)
then invokes toString()
on that array. Thus, the elements of the array are lost.
Now, if you knew exactly how many elements were in the array -- for example always two -- you could do something like the following.
@CrossOrigin({"#{'${myOrigins}'.split(',')[0]}", "#{'${myOrigins}'.split(',')[1]}"})
But that is obviously not a robust solution.
Similarly, with the @CrossOrigin(value = "${origin}")
example, if the origin
property contains a comma-separated list of URLs, the property does not get automatically split, and the entire string is treated as a single URL which does not achieve the desired goal.
In summary, it is not currently possible to supply a SpEL expression via CrossOrigin.value
that evaluates to anything other than a single String
representing the URL.
Comment From: rstoyanchev
As of 5.3 we support origin patterns and I'm wondering if that helps in this case. If not, I think we should be able to treat the input as a "," separated string.
Comment From: Ikki-Dai
thanks, will try new version in the future
Comment From: arunsai271
I'm facing the same issue that am not able to inject a list of strings into origins parameter of @CrossOrigin. Can anyone help me how to inject list of allowed hosts from application.properties ?
Comment From: rstoyanchev
I'll close this as superseded by #27606. Any further discussion can go on there.