[英]Scala enumeration serialization in jersey/jackson is not working for me
我已经阅读了有关枚举处理的jackson-module-scala页面( https://github.com/FasterXML/jackson-module-scala/wiki/Enumerations )。 我仍然无法正常工作。 基本代码如下所示:
@Path("/v1/admin")
@Produces(Array(MediaType.APPLICATION_JSON + ";charset=utf-8"))
@Consumes(Array(MediaType.APPLICATION_JSON + ";charset=utf-8"))
class RestService {
@POST
@Path("{type}/abort")
def abortUpload(@PathParam("type") typeName: ResourceTypeHolder) {
...
}
}
object ResourceType extends Enumeration {
type ResourceType = Value
val ssr, roadsegments, tmc, gab, tne = Value
}
class ResourceTypeType extends TypeReference[ResourceType.type]
case class ResourceTypeHolder(
@JsonScalaEnumeration(classOf[ResourceTypeType])
resourceType:ResourceType.ResourceType
)
这应该是这样工作的,对吗? 我仍然收到这些错误:
Following issues have been detected:
WARNING: No injection source found for a parameter of type public void no.tull.RestService.abortUpload(no.tull.ResourceTypeHolder) at index 0.
unavailable
org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public void no.tull.RestService.abortUpload(no.tull.ResourceTypeHolder) at index 0.; source='ResourceMethod{httpMethod=POST, consumedTypes=[application/json; charset=utf-8], producedTypes=[application/json; charset=utf-8], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class no.tull.RestService, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@7ffe609f]}, definitionMethod=public void no.tull.RestService.abortUpload(no.tull.ResourceTypeHolder), parameters=[Parameter [type=class no.tull.ResourceTypeHolder, source=type, defaultValue=null]], responseType=void}, nameBindings=[]}']
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:467)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:163)
at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:323)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
我还组装了一个很小的可运行项目(同时尝试消除任何其他复杂性)来说明问题: project.tgz
更新:创建了一个sbt文件来查看gradle是否正在构建一个奇怪的版本。 得到了相同的结果,但这是build.sbt :
name := "project"
version := "1.0"
scalaVersion := "2.10.4"
val jacksonVersion = "2.4.1"
val jerseyVersion = "2.13"
libraryDependencies ++= Seq(
"com.fasterxml.jackson.core" % "jackson-annotations" % jacksonVersion,
"com.fasterxml.jackson.core" % "jackson-databind" % jacksonVersion,
"com.fasterxml.jackson.jaxrs" % "jackson-jaxrs-json-provider" % jacksonVersion,
"com.fasterxml.jackson.jaxrs" % "jackson-jaxrs-base" % jacksonVersion,
"com.fasterxml.jackson.module" % "jackson-module-scala_2.10" % jacksonVersion,
"org.glassfish.jersey.containers" % "jersey-container-servlet-core" % jerseyVersion
)
seq(webSettings :_*)
libraryDependencies ++= Seq(
"org.eclipse.jetty" % "jetty-webapp" % "9.1.0.v20131115" % "container",
"org.eclipse.jetty" % "jetty-plus" % "9.1.0.v20131115" % "container"
)
...这是project / plugins.sbt :
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "0.9.0")
您的tarball似乎有一些问题。
您需要向Jackson添加一些Scala模块,才能使用任何Scala功能。 可以这样做:
val jsonObjectMapper = new ObjectMapper()
jsonObjectMapper.registerModule(DefaultScalaModule)
val jsonProvider: JacksonJsonProvider = new JacksonJsonProvider(jsonObjectMapper)
根据这个工作中的泽克-杰克逊的例子 。 您还需要将org.glassfish.jersey.jackson.JacksonFeature
注入到Jersey jersey-media-json-jackson
找到的Jersey中。 我的RestApplication.scala
像这样出来
import javax.ws.rs.core.Application
import javax.ws.rs.ext.{ContextResolver, Provider}
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.google.common.collect.ImmutableSet
import org.glassfish.jersey.jackson.JacksonFeature
@Provider
class ObjectMapperProvider extends ContextResolver[ObjectMapper] {
val defaultObjectMapper = {
val jsonObjectMapper = new ObjectMapper()
jsonObjectMapper.registerModule(DefaultScalaModule)
jsonObjectMapper
}
override def getContext(typ: Class[_]): ObjectMapper = {
defaultObjectMapper
}
}
class RestApplication extends Application {
override def getSingletons: java.util.Set[AnyRef] = {
ImmutableSet.of(
new RestService,
new ObjectMapperProvider,
new JacksonFeature
)
}
}
但是,真正的问题是@PathParam
批注。 此代码路径根本不会调用Jackson。 但是,有趣的是,Jersey似乎普遍支持解析为具有单个字符串的构造函数的任何类型。 因此,如果您修改ResourceTypeHolder
,则毕竟可以获得所需的功能。
case class ResourceTypeHolder(@JsonScalaEnumeration(classOf[ResourceTypeType]) resourceType:ResourceType.ResourceType) {
def this(name: String) = this(ResourceType.withName(name))
}
您也许可以将注射枚举支持者的枚举持有者的通用支持添加到Jersey。 但是,dropwizard-scala并没有实现这一目标,该项目也将遭受与使用Jersey相同的命运。 因此,我想这是不可能的,或者仅仅是对于任何人完成这项工作而言不够普遍。 当涉及到枚举时,我倾向于保留Java语言。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.