Development Tip

Play 프레임 워크에서 선택적 쿼리 매개 변수를 처리하는 방법

yourdevel 2020. 11. 11. 20:46
반응형

Play 프레임 워크에서 선택적 쿼리 매개 변수를 처리하는 방법


다음과 같은 URL을 제공하는 Scala에 이미 작동하는 Play 2.0 프레임 워크 기반 애플리케이션이 있다고 가정 해 보겠습니다.

http : // localhost : 9000 / birthdays

알려진 모든 생일 목록으로 응답합니다.

이제 선택적인 "시작"(날짜) 및 "끝"요청 매개 변수를 사용하여 결과를 제한하는 기능을 추가하여이를 향상시키고 싶습니다.

http : // localhost : 9000 / birthdays? from = 20120131 & to = 20120229

(여기서 날짜는 yyyyMMdd로 해석 됨)

내 질문은 특히 이러한 매개 변수가 모두 선택 사항이어야한다는 점을 감안할 때 Scala를 사용하여 Play 2.0에서 요청 매개 변수 바인딩 및 해석을 처리하는 방법입니다.

이러한 매개 변수가 "routes"사양에 어떻게 표현되어야합니까? 또는 응답하는 Controller 메서드가 요청 객체에서 매개 변수를 어떻게 든 선택해야합니까? 이를 수행하는 다른 방법이 있습니까?


선택적 매개 변수를 Option[String](또는 로 인코딩 Option[java.util.Date]하지만 직접 구현해야 함 QueryStringBindable[Date]) :

def birthdays(from: Option[String], to: Option[String]) = Action {
  // …
}

그리고 다음 경로를 선언하십시오.

GET   /birthday       controllers.Application.birthday(from: Option[String], to: Option[String])

자바 사용자를 위해 덜 깔끔한 방법은 기본값을 설정하는 것입니다.

GET  /users  controllers.Application.users(max:java.lang.Integer ?= 50, page:java.lang.Integer ?= 0)

그리고 컨트롤러에서

public static Result users(Integer max, Integer page) {...}

한 가지 더, 템플릿에서 페이지에 연결할 때마다 기본값을 반복해야합니다.

@routes.Application.users(max = 50, page = 0)

Julien의 대답에 추가로. 경로 파일 에 포함하지 않으려는 경우 .

RequestHeader를 사용하여 컨트롤러 메서드에서이 속성을 가져올 수 있습니다.

String from = request().getQueryString("from");
String to = request().getQueryString("to");

이렇게하면 원하는 요청 매개 변수가 제공되고 경로 파일이 깨끗하게 유지 됩니다.


다음은 F.Option을 사용하여 자바로 재 작성한 Julien의 예입니다. (재생 2.1에서 작동)

import play.libs.F.Option;
public static Result birthdays(Option<String> from, Option<String> to) {
  // …
}

노선:

GET   /birthday       controllers.Application.birthday(from: play.libs.F.Option[String], to: play.libs.F.Option[String])

임의의 쿼리 매개 변수를 문자열로 선택할 수도 있습니다 (유형 변환을 직접 수행해야 함).

public static Result birthdays(Option<String> from, Option<String> to) {
  String blarg = request().getQueryString("blarg"); // null if not in URL
  // …
}

선택적 쿼리 매개 변수의 경우 다음과 같이 할 수 있습니다.

경로 파일에서 API 선언

GET   /birthdays     controllers.Application.method(from: Long, to: Long)

API에 이러한 쿼리 매개 변수가 포함되어 있지 않은 경우 기본값을 제공 할 수도 있습니다.이 매개 변수에 자동으로 기본값을 할당합니다.

GET   /birthdays    controllers.Application.method(from: Long ?= 0, to: Long ?= 10)

컨트롤러 응용 프로그램 내부에 작성된 메서드에서이 매개 변수는 null기본값이 지정되지 않은 경우 값을 가지게 됩니다.


이 작업을 수행하는 방법에는 사용자 지정 QueryStringBindable. 이렇게 라우트에서 매개 변수를 다음과 같이 표현합니다.

GET /birthdays/ controllers.Birthdays.getBirthdays(period: util.Period)

기간의 코드는 다음과 같습니다.

public class Period implements QueryStringBindable<Period> {

  public static final String PATTERN = "dd.MM.yyyy";
  public Date start;

  public Date end;

  @Override
  public F.Option<Period> bind(String key, Map<String, String[]> data) {
      SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);

      try {
          start = data.containsKey("startDate")?sdf.parse(data.get("startDate")  [0]):null;
          end = data.containsKey("endDate")?sdf.parse(data.get("endDate")[0]):null;
      } catch (ParseException ignored) {
          return F.Option.None();
      }
      return F.Option.Some(this);
  }

  @Override
  public String unbind(String key) {
      SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
      return "startDate=" + sdf.format(start) + "&amp;" + "endDate=" + sdf.format(end);
  }

  @Override
  public String javascriptUnbind() {
      return null;
  }

  public void applyDateFilter(ExpressionList el) {
      if (this.start != null)
          el.ge("eventDate", this.start);
      if (this.end != null)
          el.le("eventDate", new DateTime(this.end.getTime()).plusDays(1).toDate());
  }

}

applyDateFilter is just a convienence method i use in my controllers if I want to apply date filtering to the query. Obviously you could use other date defaults here, or use some other default than null for start and end date in the bind method.

참고URL : https://stackoverflow.com/questions/9657163/how-to-handle-optional-query-parameters-in-play-framework

반응형