Scala.Option的Spring RequestParam格式化程序

时间:2015-11-18 03:48:14

标签: java spring scala spring-mvc

我们在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)。

1 个答案:

答案 0 :(得分:0)

我们设法通过创建AnyRefOption[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))
    )
  }
}