2

我正在使用Unfiltered 0.6.8(使用 Jetty 连接器)并且遇到了一个奇怪的行为:路径段没有 URL 解码。

以下代码是我的最小测试用例:

import unfiltered.request._
import unfiltered.response._

object Test extends App with unfiltered.filter.Plan {
  def intent = {

    case reg @ Path(Seg(test :: Nil)) =>
      println(test)
      ResponseString(test)
  }

  unfiltered.jetty.Http.local(8080).filter(Test).run()
}

查询会在客户端和服务器端http://localhost:8080/some_string产生预期的结果: 。some_string

另一方面,客户端和服务器都http://localhost:8080/some%20string产生some%20string了收益,而不是some string我所期望的。

解决这个问题是微不足道的(java.net.URLDecoder#decode(String, String)),但我想知道:

  • 我忘记了一些微不足道的事情并自欺欺人。
  • unfiltered 有一个工具包可以自动处理这些麻烦。
  • 如果以上都不是,这种行为是否有特殊原因,或者我应该提交错误报告?

作为旁注,unfiltered标签不存在,我没有足够的声誉来创建它,这就是我默认使用scala.

4

1 回答 1

7

奇怪,我也看到了这种行为。在Seg拆分路径段之前,对象中没有任何内容可以进行任何类型的 url 解码,而且我在框架中也看不到任何其他内容。我遇到了一篇文章,其中详细介绍了使用自定义提取器的解决方案,如下所示:

object Decode {
  import java.net.URLDecoder
  import java.nio.charset.Charset

  trait Extract {
    def charset: Charset
    def unapply(raw: String) = 
      Try(URLDecoder.decode(raw, charset.name())).toOption
  }

  object utf8 extends Extract {
    val charset = Charset.forName("utf8")
  }
}

然后你可以像这样使用它:

case reg @ Path(Seg(Decode.utf8(test) :: Nil)) =>
  println(test)
  ResponseString(test)

或者如果你想解码整个路径,就像这样:

case reg @ Path(Decode.utf8(Seg(test :: Nil))) =>
  println(test)
  ResponseString(test)

值得庆幸的是,该框架是灵活的,并且可以像这样进行扩展,因此您当然可以选择。

于 2013-08-06T17:35:09.283 回答