servlet 代码中的类型信息丢失 [英] Loss of type info in servlet code
问题描述
我有一个用于 Jersey 的简单 Flash 实现,如下所示:
@PostConstruct def before { flash.rotateIn }@PreDestroy def { flash.rotateOut }物体闪光{val KeyNow = "local.flash.now"val KeyNext = "local.flash.next"//case class Wrapper(wrapped: Map[String, Seq[String]])case class Wrapper(wrapped: String)定义旋转{为了 {会话 <- 选项(request.getSession(false))obj <- 选项(session.getAttribute(KeyNext))} {request.setAttribute(KeyNow, obj)session.removeAttribute(KeyNext)}}定义旋转输出{for (obj <- Option(request.getAttribute(KeyNext))) {request.getSession.setAttribute(KeyNext, obj)}}def now = Option(request.getAttribute(KeyNow)) 匹配 {case Some(x: Wrapper) =>x.wrappedcase Some(x) if x.isInstanceOf[Wrapper] =>什么"案例_ =>不"}定义下一个(值:字符串){request.setAttribute(KeyNext, Wrapper(value))}}
我在这里稍微简化了它,但它允许我使用 flash.next
设置 flash 的值,并使用 flash.now
读取当前的 flash 值.>
奇怪的是我的 now
值总是WHAT".如果我在 REPL 中做了类似的事情,我就不会遇到同样的问题:
val req = new org.springframework.mock.web.MockHttpServletRequestval res = req.getSessionres.setAttribute("foo", Wrapper("foo"))req.setAttribute("foo", res.getAttribute("foo"))//不是无Option(req.getAttribute("foo")).collect { case x: Wrapper =>X }
我是否遗漏了一些明显的东西?
编辑
我在 https://github.com/kardeiz/sc-issue-20160229.
我试过你的例子.查看我的回答以了解您的其他问题,了解模式匹配在这种情况下的工作原理.
简而言之,由于您的 Wrapper
是内部类,因此模式匹配也会检查外部类"引用.似乎取决于应用程序服务器的实现 Router.flash
可以为每个请求提供不同的实例,因此模式匹配失败.
对此的简单修复是将 Wrapper
设为顶级类,这样它就不会引用任何其他类.
I have a simple flash implementation for use with Jersey that looks like this:
@PostConstruct def before { flash.rotateIn }
@PreDestroy def after { flash.rotateOut }
object flash {
val KeyNow = "local.flash.now"
val KeyNext = "local.flash.next"
// case class Wrapper(wrapped: Map[String, Seq[String]])
case class Wrapper(wrapped: String)
def rotateIn {
for {
session <- Option(request.getSession(false))
obj <- Option(session.getAttribute(KeyNext))
} {
request.setAttribute(KeyNow, obj)
session.removeAttribute(KeyNext)
}
}
def rotateOut {
for (obj <- Option(request.getAttribute(KeyNext))) {
request.getSession.setAttribute(KeyNext, obj)
}
}
def now = Option(request.getAttribute(KeyNow)) match {
case Some(x: Wrapper) => x.wrapped
case Some(x) if x.isInstanceOf[Wrapper] => "WHAT"
case _ => "NOPE"
}
def next(value: String) {
request.setAttribute(KeyNext, Wrapper(value))
}
}
I have simplified it here somewhat, but it lets me set a value for flash with flash.next
and read the current flash value with flash.now
.
The weird thing is that my now
value is always "WHAT". If I do something similar in my REPL, I don't have the same issues:
val req = new org.springframework.mock.web.MockHttpServletRequest
val res = req.getSession
res.setAttribute("foo", Wrapper("foo"))
req.setAttribute("foo", res.getAttribute("foo"))
// Is not None
Option(req.getAttribute("foo")).collect { case x: Wrapper => x }
Am I missing something obvious?
EDIT
I've added a minimal example webapp replicating this issue at https://github.com/kardeiz/sc-issue-20160229.
I tried your example. Check my answer for your other question for details how pattern matching works in this case.
In short, as you Wrapper
is an inner class, patter matching also checks the "outer class" reference. It seems that depending on the application server implementation Router.flash
can be different instance for each request, so pattern matching fails.
Simple fix for that is to make Wrapper
top-level class, so it doesn't have reference to any other class.
这篇关于servlet 代码中的类型信息丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!