我用 Scalatra 写了一个小服务,它做了两件事:
- 提供 JSON 数据
- 提供与 Excel 工作表相同的数据
JSON 使用 spray-json、Excel 完成 - 使用 apache POI
基本上,我在 ScalatraServlet 实现中编写了两个方法:
def serveJson[T: JsonWriter](data: T) = {
contentType = "text/json"
data.toJson.prettyPrint
}
def serveExcel[T: ExcelWriter](data: T) = {
contentType = "application/excel"
data.toExcel.getBytes
}
这里toJson是用spray-json实现的,所以我只是提供了一个JsonWriter隐式转换。所以我决定写一个类似toExcel的转换。
// ExcelWriter.scala
package com.example.app.excel
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import annotation.implicitNotFound
@implicitNotFound(msg = "Cannot find ExcelWriter type class for ${T}")
trait ExcelWriter[T] {
def write(obj: T): HSSFWorkbook
}
object ExcelWriter {
implicit def func2Writer[T](f: T => HSSFWorkbook): ExcelWriter[T] = new ExcelWriter[T] {
def write(obj: T) = f(obj)
}
}
// Imports.scala
package com.example.app.excel
import org.apache.poi.hssf.usermodel.HSSFWorkbook
object Imports {
type ExcelWriter[T] = com.example.app.excel.ExcelWriter[T]
implicit def pimpAny[T](any: T) = new AnyExcelPimp(any)
private[excel] class AnyExcelPimp[T](any: T) {
def toExcel(implicit writer: ExcelWriter[T]): HSSFWorkbook = writer.write(any)
}
}
现在,问题是:
如果我 import import cc.spray.json._
,则import excel.Imports._
scalac 会抛出错误serveJson
(值 toJson 不是类型参数 T 的成员)
如果我导入import excel.Imports._
,则import cc.spray.json._
scalac 会引发类似的错误serveExcel
(toExcel 的值不是类型参数 T 的成员)
令人惊讶的是,如果我只使用其中一个导入,一切都可以编译并正常工作(好吧,一半,因为我注释掉了一半,它使用了删除的导入)。
我的实施有什么问题?
链接到 spray-json 源,我用作参考:https ://github.com/spray/spray-json/tree/master/src/main/scala/cc/spray/json
斯卡拉版本 - 2.9.2