servlet 代码中的类型信息丢失 [英] Loss of type info in servlet code

查看:34
本文介绍了servlet 代码中的类型信息丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆