我们在Scala应用程序中使用Spring MVC,我想弄清楚如何解开Scala Option
,以便可以使用@RequestParam
正确转换它们。我认为解决方案可能与Formatter SPI有关,但我不确定如何使Option
可以包含任意数量的值(我想要Spring),这样可以很好地工作正常处理,好像转换后的值根本不是Option
。从本质上讲,我几乎想要在正常转换发生后对值Option
进行额外的转换。
例如,给出以下代码:
@RequestMapping(method = Array(GET), value = Array("/test"))
def test(@RequestParam("foo") foo: Option[String]): String
网址/test
应该会导致foo
参数的值为None
,而网址/test?foo=bar
会导致foo
参数获得值Some("bar")
(/test?foo
可能会导致空字符串或None
)。
答案 0 :(得分:0)
我们设法通过创建AnyRef
到Option[AnyRef]
转换器并将其添加到Spring MVC的ConversionService
来解决此问题:
import org.springframework.beans.factory.annotation.{Autowired, Qualifier}
import org.springframework.core.convert.converter.ConditionalGenericConverter
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair
import org.springframework.core.convert.{ConversionService, TypeDescriptor}
import org.springframework.stereotype.Component
import scala.collection.convert.WrapAsJava
/**
* Base functionality for option conversion.
*/
trait OptionConverter extends ConditionalGenericConverter with WrapAsJava {
@Autowired
@Qualifier("mvcConversionService")
var conversionService: ConversionService = _
}
/**
* Converts `AnyRef` to `Option[AnyRef]`.
* See implemented methods for descriptions.
*/
@Component
class AnyRefToOptionConverter extends OptionConverter {
override def convert(source: Any, sourceType: TypeDescriptor, targetType: TypeDescriptor): AnyRef = {
Option(source).map(s => conversionService.convert(s, sourceType, new Conversions.GenericTypeDescriptor(targetType)))
}
override def getConvertibleTypes: java.util.Set[ConvertiblePair] = Set(
new ConvertiblePair(classOf[AnyRef], classOf[Option[_]])
)
override def matches(sourceType: TypeDescriptor, targetType: TypeDescriptor): Boolean = {
Option(targetType.getResolvableType).forall(resolvableType =>
conversionService.canConvert(sourceType, new Conversions.GenericTypeDescriptor(targetType))
)
}
}