2014-07-01 2 views
1

PlayFramework 2.x에서 쿼리 문자열 매개 변수의 유효성을 검사하려면 어떻게해야합니까?PlayFramework에서 쿼리 문자열 매개 변수의 유효성을 검사하는 방법

# http://example.com/users?shift=0&limit=20 - take first 20 users 
GET /users   Users.list(shift: Int ?= 0, limit: Int ?= 20) 
내가 나를 위해 올바른 범위 내 이동과 제한을 유지하려는

, 예를 들어 제한 : 나는 순서에 대한 매우 일반적인 변화, 제한 (DROP, LIMIT) 매개 변수가, 내가 이 같은 경로가 있다고 가정 1에서 60까지, 사용자가 23979와 같이 제한을 설정하려고 시도하면 60으로 줄여야합니다. 필터가 작동하지 않아 라우터 이후에 발생합니다.

+2

그냥 PARAM 숫자 인 경우는, 필요한 범위를 맞는 경우도 때 사용자의 경우를 잡을 수 있도록 유효성을 검사합니다 간단한 방법을 만들 수 있습니다, 액션의 시작 부분을 확인 : 내 최종 구현은 다음과 같이 포함되어 있습니다 거기에 문자열 값을 삽입 할 것입니다 – biesior

답변

1

나는 행동의 시작 부분에서 유효성을 확인할 수있는 biesor의 의견을 좋아합니다. 그것이 가능하지 않다면, kfer38의 답변도 잘 작동합니다. 나는 또 다른 대답을 던지고 싶습니다. 그리고 그것은 Global 객체를 사용하고 있습니다. http://www.playframework.com/documentation/2.3.x/ScalaGlobal

리디렉션을 통해 전역 객체의 장점은 즉시 수행되며 오히려 당신의 실행 시간 (밀리 초)을 추가하는 리디렉션보다, 라우터를 재구성한다는 것입니다. 라우터를 만지기 전에 일을하는 것이 걱정스러운 것 같아서이 솔루션을 제공합니다. 이 같은

뭔가 작동합니다 :

object Global extends GlobalSettings { 
    override def onRouteRequest(request: RequestHeader): Option[Handler] = { 
    // string matching here to get the values 
    // rewrite values to what you want 
    super.onRouteRequest(request.copy(path = newPath)) 
    } 
} 

내가 예를 들어, "/"경로의 끝에서 제거보다는 정말 비효율적 인 리디렉션하려면이 옵션을 사용합니다. 또한 "/"와 일치하는 경로를 두 번 작성해야하는 번거 로움을 피하기 위해이 작업을 수행합니다.

+0

고마워요! 정말 좋은 접근 방법입니다. – selfsx

0

Users.list(shift: Int, limit: Int) 컨트롤러에서 제한 조건을 확인할 수 있습니다. 그런 다음 예외를 throw하는 대신 사용자 지정 값으로 리디렉션 할 수 있습니다. 전의. if (limit > 60) Redirect(routes.controllers.Users.list(shift, 60))

0

Michael's 접근 방식이 잘 작동하지만 몇 가지 흥미로운 점도 있습니다. 내가 쿼리는 액션 함수에 전달 된 인수를 필터링 onRouteRequest 최우선 PARAMS 필터링하지만, 요청 객체의 문자열 인수를 쿼리 할 경우 우리가 요청하면 /users?shift=-2 우리의 변화는

def users(shift: Int, limit: Int) = Action { req => 
    Logger.debug("shift: " + shift) 
    Logger.debug("shiftQS: " + req.getQueryString("shift")) 

을 여과하고 shiftQS되지는 않습니다! 그러나 Filter 만 사용하면 상황이 달라질 수 있습니다. 쿼리 문자열 매개 변수는 필터링 할 수 있지만 인수는 필터링 할 수 없습니다. 따라서 검색어 문자열을 필터링하려면 Play의 Filter을 추가해야합니다.

// Write your filter and mix it to Global 
object SeqFilter extends EssentialFilter { 
    def apply(next: EssentialAction): EssentialAction = new EssentialAction { 
    def apply(req: RequestHeader): Iteratee[Array[Byte], SimpleResult] = { 
     next(doFilter(req)) 
    } 
    } 

    def doFilter(req: RequestHeader): RequestHeader = { 
    if (/* queryString contains invalid parameters */) { 
     val qs = /* You filtered queryString */ 
     req.copy(queryString = qs) 
    } else { 
     req 
    } 
    } 
} 

// Alson use your filter in onRouteRequest in Global object 
override def onRouteRequest(req: RequestHeader): Option[Handler] = { 
    super.onRouteRequest(SeqFilter.doFilter(req)) 
} 
관련 문제