2012-07-13 25 views
17

Tôi biết từ Setting HTTP headers in Play 2.0 (scala)? rằng bạn có thể đặt tiêu đề phản hồi trên cơ sở từng trường hợp bằng cách thực hiện, ví dụ: Ok("hello").withHeaders(PRAGMA -> "no-cache").Chơi 2 - Đặt tiêu đề trên tất cả các câu trả lời?

Điều gì xảy ra nếu bạn muốn đặt tiêu đề đó hoặc một vài tiêu đề khác nhau, trên phản hồi từ tất cả các Tác vụ của bạn? Bạn sẽ không muốn lặp lại withHeaders ở mọi nơi. Và vì điều này giống với cấu hình ứng dụng hơn, bạn có thể không muốn tác giả Hành động phải sử dụng cú pháp khác để lấy tiêu đề (ví dụ: OkWithHeaders(...))

Điều tôi bây giờ là lớp Bộ điều khiển cơ sở trông giống như

class ContextController extends Controller { 
... 
def Ok(h: Html) = Results.Ok(h).withHeaders(PRAGMA -> "no-cache") 
} 

nhưng điều đó không cảm thấy hoàn toàn đúng. Nó cảm thấy như có nên có nhiều hơn một cách phong cách AOP của việc xác định các tiêu đề mặc định và có họ thêm vào mỗi phản ứng.

+1

Lưu ý rằng PRAGMA -> no-cache có thể sẽ không làm việc theo cách bạn dự định. Xem liên kết này: http://www.mnot.net/cache_docs/ Bạn có thể muốn sử dụng CACHE_CONTROL thay vì PRAGMA – andrewf

+0

'CACHE_CONTROL ->" max-age = 0 "' nên làm điều đó. – andrewf

Trả lời

8

Trong Global.scala của bạn, quấn mỗi cuộc gọi trong một hành động:

import play.api._ 
import play.api.mvc._ 
import play.api.Play.current 
import play.api.http.HeaderNames._ 

object Global extends GlobalSettings { 

    def NoCache[A](action: Action[A]): Action[A] = Action(action.parser) { request => 
    action(request) match { 
     case s: SimpleResult[_] => s.withHeaders(PRAGMA -> "no-cache") 
     case result => result 
    } 
    } 

    override def onRouteRequest(request: RequestHeader): Option[Handler] = { 
    if (Play.isDev) { 
     super.onRouteRequest(request).map { 
     case action: Action[_] => NoCache(action) 
     case other => other 
     } 
    } else { 
     super.onRouteRequest(request) 
    } 
    } 

} 

Trong trường hợp này, tôi chỉ gọi hành động trong chế độ dev, có ý nghĩa nhất đối với một hướng dẫn no-cache.

+0

Đáng yêu, cảm ơn bạn! Tôi đã vấp phải một giải pháp tương tự, nhưng đã gặp sự cố khi khớp với loại SimpleResult được tham số hóa mà không có cảnh báo trình biên dịch về việc xóa. Ngoài ra, lưu ý bình luận của tôi ở trên về PRAGMA là điều sai lầm để sử dụng cho bộ nhớ đệm. – andrewf

+0

Điều này giống như phản ứng tốt với tôi! – gimix

+0

@MariusSoutier - tôi đã thử giải pháp mà bạn đề xuất, nhưng vào thời gian chạy, tôi luôn nhận được _ "khác" _ và không phải là 'Hành động' tôi có thể sử dụng để thêm tiêu đề vào. loại _ "khác" _ tại thời gian chạy là: 'play.core.Router $ Routes $$ anon $ 4' bất kỳ ý tưởng về cách tôi có thể đối phó với nó? –

0

Có nhiều cách. Bạn có thể sử dụng action-composition. Sau đó, bạn phải khai báo tại mọi Controller mà bạn muốn đặt ở đây tiêu đề. Một tùy chọn khác là sử dụng GlobalSettings. Cũng có những giải pháp tương tự cho java.

+0

Tôi không thấy nơi bạn có thể làm điều này trong GlobalSettings, bạn có thể cụ thể hơn không? Dường như với tôi như bạn chỉ có móc vào yêu cầu, không phải là phản ứng. –

+0

Bạn cũng có thể tự mình thực hiện Hành động bình thường. Sau đó, tôi nghĩ rằng bạn có quyền truy cập vào đối tượng kết quả và ở đó bạn có thể làm điều đó. Chỉ là một ý tưởng, bởi vì tôi đang làm việc với java. Ở đó bạn có ngữ cảnh chứa đựng phản ứng. – niels

2

Cách dễ nhất để đạt được kiểm soát chi tiết là sử dụng các tác vụ được bao bọc. Trong trường hợp của bạn nó có thể là một cái gì đó như thế:

object HeaderWriter { 
    def apply(f: Request[AnyContent] => SimpleResult):Action[AnyContent] = { 
     Action { request => 
      f(request).withHeaders(PRAGMA -> "no-cache") 
     } 
    } 
} 

và sử dụng nó theo cách đó:

def doAction = HeaderWriter { request => 
    ... do any stuff your want ... 
    Ok("Thats it!") 
} 
14

Các chủ đề khá cũ bây giờ, nhưng với Play 2.1 nó thậm chí còn đơn giản hơn bây giờ. lớp Global.scala của bạn sẽ trông như thế này:

import play.api._ 
import play.api.mvc._ 
import play.api.http.HeaderNames._ 

/** 
* Global application settings. 
*/ 
object Global extends GlobalSettings { 

    /** 
    * Global action composition. 
    */ 
    override def doFilter(action: EssentialAction): EssentialAction = EssentialAction { request => 
    action.apply(request).map(_.withHeaders(
     PRAGMA -> "no-cache" 
    )) 
    } 
} 
Các vấn đề liên quan