我正在使用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()
}
Run Code Online (Sandbox Code Playgroud)
查询http://localhost:8080/some_string产生预期结果:some_string,在客户端和服务器端.
另一方面,客户端和服务器上的http://localhost:8080/some%20string产量some%20string,而不是some string我期待的.
解决这个问题很简单(java.net.URLDecoder#decode(String, String)),但我想知道是否:
作为旁注,unfiltered标签不存在,我没有足够的声誉来创建它,这就是我违约的原因scala.
奇怪,我也看到了这种行为.在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")
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
case reg @ Path(Seg(Decode.utf8(test) :: Nil)) =>
println(test)
ResponseString(test)
Run Code Online (Sandbox Code Playgroud)
或者像这样,如果你想要整个路径解码:
case reg @ Path(Decode.utf8(Seg(test :: Nil))) =>
println(test)
ResponseString(test)
Run Code Online (Sandbox Code Playgroud)
值得庆幸的是,该框架是灵活的,并且可以像这样扩展,因此您当然可以选择.