如何从嵌入式 Jetty URL 中删除尾部斜杠?
How to remove trailing slash from embedded Jetty URLs?
我使用的是Scala的嵌入式Jetty 9.3.8.v20160314(这里Scala是附带的,这是一个纯Jetty的问题),配置如下:
val loginService = new RepoLoginService(usersRepository, signInsRepo)
val server = new Server(8080)
server.addBean(loginService)
val security = new ConstraintSecurityHandler()
server.setHandler(security)
val constraint = new Constraint()
constraint.setName("auth")
constraint.setAuthenticate(true)
constraint.setRoles(Array[String]("user", "admin"))
val mapping = new ConstraintMapping()
mapping.setPathSpec("/*")
mapping.setConstraint(constraint)
security.setConstraintMappings(Collections.singletonList(mapping))
security.setAuthenticator(new BasicAuthenticator())
security.setLoginService(loginService)
val mapper = prepareJacksonObjectMapper
val listAccountsController = new ContextHandler("/api/accounts")
listAccountsController.setHandler(new ListAccountsController(mapper, accountsRepository))
val importBankAccountsController = new ContextHandler("/api/bank-account-transactions/import")
importBankAccountsController.setHandler(new ImportBankAccountTransactionsController(mapper, bankAccountTransactionsRepo))
val contexts = new ContextHandlerCollection()
contexts.setHandlers(Array(listAccountsController, importBankAccountsController))
security.setHandler(contexts)
server.start()
server.join()
注意 listAccountsController
的上下文:/api/accounts
。当我卷曲 /api/accounts
时,我收到重定向到 /api/accounts/
(注意尾部斜线):
$ curl --silent --verbose --user francois:francois http://localhost:8080/api/accounts
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'francois'
> GET /api/accounts HTTP/1.1
> Host: localhost:8080
> Authorization: Basic ZnJhbmNvaXM6ZnJhbmNvaXM=
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Sun, 22 May 2016 03:54:44 GMT
< Location: http://localhost:8080/api/accounts/
< Content-Length: 0
< Server: Jetty(9.3.8.v20160314)
<
* Connection #0 to host localhost left intact
我尝试添加对 clearAliasChecks()
的调用,我不确定这是否与此有关。我也尝试将 mapping.setPathSpec("/*")
更改为 mapping.setPathSpec("/")
,因为我读了一个 answer on Tomcat not adding the trailing slash,但这可能并不适用于我。
我必须更改什么才能防止出现尾部斜线?
原因就是您定义上下文的方式。
A ContextHandler
是对一组资源的 "root",并且该根定义为始终是资源目录(在结构中)。
由于您定义了 ContextHandler("/api/accounts")
并访问了 /api/accounts
实施 "helps" 您通过使 /api/accounts/
成为正确的上下文根。
想象一下……
- 你有
val b = ContextHandler("/a/b")
- 您有
val a = ContextHandler("/a")
- 它实现了(内部)对子资源的支持 /b
- 如果您请求
/a/b
,您处于哪个上下文中? - 根据规格,您处于上下文 a
- 如果您请求
/a/b/
,那么您在上下文中 b
我使用的是Scala的嵌入式Jetty 9.3.8.v20160314(这里Scala是附带的,这是一个纯Jetty的问题),配置如下:
val loginService = new RepoLoginService(usersRepository, signInsRepo)
val server = new Server(8080)
server.addBean(loginService)
val security = new ConstraintSecurityHandler()
server.setHandler(security)
val constraint = new Constraint()
constraint.setName("auth")
constraint.setAuthenticate(true)
constraint.setRoles(Array[String]("user", "admin"))
val mapping = new ConstraintMapping()
mapping.setPathSpec("/*")
mapping.setConstraint(constraint)
security.setConstraintMappings(Collections.singletonList(mapping))
security.setAuthenticator(new BasicAuthenticator())
security.setLoginService(loginService)
val mapper = prepareJacksonObjectMapper
val listAccountsController = new ContextHandler("/api/accounts")
listAccountsController.setHandler(new ListAccountsController(mapper, accountsRepository))
val importBankAccountsController = new ContextHandler("/api/bank-account-transactions/import")
importBankAccountsController.setHandler(new ImportBankAccountTransactionsController(mapper, bankAccountTransactionsRepo))
val contexts = new ContextHandlerCollection()
contexts.setHandlers(Array(listAccountsController, importBankAccountsController))
security.setHandler(contexts)
server.start()
server.join()
注意 listAccountsController
的上下文:/api/accounts
。当我卷曲 /api/accounts
时,我收到重定向到 /api/accounts/
(注意尾部斜线):
$ curl --silent --verbose --user francois:francois http://localhost:8080/api/accounts
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'francois'
> GET /api/accounts HTTP/1.1
> Host: localhost:8080
> Authorization: Basic ZnJhbmNvaXM6ZnJhbmNvaXM=
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Sun, 22 May 2016 03:54:44 GMT
< Location: http://localhost:8080/api/accounts/
< Content-Length: 0
< Server: Jetty(9.3.8.v20160314)
<
* Connection #0 to host localhost left intact
我尝试添加对 clearAliasChecks()
的调用,我不确定这是否与此有关。我也尝试将 mapping.setPathSpec("/*")
更改为 mapping.setPathSpec("/")
,因为我读了一个 answer on Tomcat not adding the trailing slash,但这可能并不适用于我。
我必须更改什么才能防止出现尾部斜线?
原因就是您定义上下文的方式。
A ContextHandler
是对一组资源的 "root",并且该根定义为始终是资源目录(在结构中)。
由于您定义了 ContextHandler("/api/accounts")
并访问了 /api/accounts
实施 "helps" 您通过使 /api/accounts/
成为正确的上下文根。
想象一下……
- 你有
val b = ContextHandler("/a/b")
- 您有
val a = ContextHandler("/a")
- 它实现了(内部)对子资源的支持/b
- 如果您请求
/a/b
,您处于哪个上下文中? - 根据规格,您处于上下文a
- 如果您请求
/a/b/
,那么您在上下文中b