HOWTO¶
Chương này bao gồm một số thủ thuật nhỏ.
Basic authentication¶
Bạn có thể bảo vệ toàn bộ site hoặc chỉ action nào đó với basic authentication.
Ghi nhớ rằng Xitrum không hỗ trợ digest authentication vì nó cung cấp một cái nhìn sai về bảo mật. Từ đó làm cho digest authentication dễ bị tấn công man-in-the-middle. Để bảo mật tốt hơn, bạn nên sử dụng HTTPS (không cần sử dụng Apache hay Nginx như reverse proxy chỉ cần sử dụng HTTPS).
Cấu hình basic authentication cho toàn bộ site¶
Trong tệp config/xitrum.conf
:
"basicAuth": {
"realm": "xitrum",
"username": "xitrum",
"password": "xitrum"
}
Thêm basic authentication vào một action¶
import xitrum.Action
class MyAction extends Action {
beforeFilter {
basicAuth("Realm") { (username, password) =>
username == "username" && password == "password"
}
}
}
Load các tệp config¶
Tệp JSON¶
JSON thuận tiện cho việc sử dụng làm các tệp cấu hình với cấu trúc lồng nhau.
Lưu tệp cấu hình của bạn trong thư mục “config”. Thư mục này được đặt trong classpath ở chế độ phát triển bởi build.sbt và trong chế độ sản phẩm bởi script/runner (và script/runner.bat).
myconfig.json:
{
"username": "God",
"password": "Does God need a password?",
"children": ["Adam", "Eva"]
}
Load:
import xitrum.util.Loader
case class MyConfig(username: String, password: String, children: Seq[String])
val myConfig = Loader.jsonFromClasspath[MyConfig]("myconfig.json")
Ghi chú:
- Các key hoặc string phải được dùng dấu nháy kép
"
. - Hiện tại, bạn không thể viết comment trong tệp JSON
Tệp properties¶
Bạn cũng có thể các tệp property, nhưng bạn nên sử dụng JSON. Tệp property không phải typesafe, không hỗ trợ UTF-8 và các cấu trúc lồng nhau v.v.
myconfig.properties:
username = God
password = Does God need a password?
children = Adam, Eva
Load:
import xitrum.util.Loader
// Here you get an instance of java.util.Properties
val properties = Loader.propertiesFromClasspath("myconfig.properties")
Typesafe tệp cấu hình¶
Xitrum cũng bao gồm Akka mà Akka sử dụng thư viện cấu hình tạp bởi company called Typesafe. Chúng có thẻ tốt hơn tải các tệp cấu hình.
myconfig.conf:
username = God
password = Does God need a password?
children = ["Adam", "Eva"]
Load:
import com.typesafe.config.{Config, ConfigFactory}
val config = ConfigFactory.load("myconfig.conf")
val username = config.getString("username")
val password = config.getString("password")
val children = config.getStringList("children")
Serialize và deserialize¶
Để serialize thành Array[Byte]
:
import xitrum.util.SeriDeseri
val bytes = SeriDeseri.toBytes("my serializable object")
Để deserialize các byte ngược trở lại:
val option = SeriDeseri.fromBytes[MyType](bytes) // Option[MyType]
Nếu bạn muốn lưu tệp:
import xitrum.util.Loader
Loader.bytesToFile(bytes, "myObject.bin")
Để load từ file:
val bytes = Loader.bytesFromFile("myObject.bin")
Mã hóa dữ liệu¶
Để mã hóa dữ liệu mà bạn không cần giải mã sau đó (mã hóa một chiều), bạn có thể sử dụng MD5 hoặc những thuật toán tương tư.
Nếu bạn muốn giải mã về sau, bạn có thể sử dụng tiện ích mà Xitrum cung cấp:
import xitrum.util.Secure
// Array[Byte]
val encrypted = Secure.encrypt("my data".getBytes)
// Option[Array[Byte]]
val decrypted = Secure.decrypt(encrypted)
Bạn có thể sử dụng xitrum.util.UrlSafeBase64
để mã hóa và giải mã các dữ liệu nhị phân
thanh chuỗi thông thường (nhúng vào HTML để response chẳng hạn).
// String that can be included in URL, cookie etc.
val string = UrlSafeBase64.noPaddingEncode(encrypted)
// Option[Array[Byte]]
val encrypted2 = UrlSafeBase64.autoPaddingDecode(string)
Nếu bạn có thể phối hợp các quá trình bên trên trong một bước:
import xitrum.util.SeriDeseri
val mySerializableObject = new MySerializableClass
// String
val encrypted = SeriDeseri.toSecureUrlSafeBase64(mySerializableObject)
// Option[MySerializableClass]
val decrypted = SeriDeseri.fromSecureUrlSafeBase64[MySerializableClass](encrypted)
SeriDeseri
sử dụng Twitter Chill
để serialize và deserialize. Dữ liệu của bạn phải là serializable.
Bạn có thể chỉ rõ khóa (key) để mã hóa.
val encrypted = Secure.encrypt("my data".getBytes, "my key")
val decrypted = Secure.decrypt(encrypted, "my key")
val encrypted = SeriDeseri.toSecureUrlSafeBase64(mySerializableObject, "my key")
val decrypted = SeriDeseri.fromSecureUrlSafeBase64[MySerializableClass](encrypted, "my key")
Nếu bạn không chỉ rõ key nào, secureKey
trong tệp xitrum.conf
trong thư mục config
sẽ được sử dụng.
Nhiều site với cùng một tên miền¶
Nếu bạn muốn sử dụng một reverse proxy như Nginx để chạy nhiều site khác nhau tại cùng một tên miền:
http://example.com/site1/...
http://example.com/site2/...
Bạn có thể cấu hình baseUrl trong config/xitrum.conf
.
Trong mã JS, để có chính xác URL cho Ajax request, sử dụng withBaseUrl
trong xitrum.js.
# If the current site's baseUrl is "site1", the result will be:
# /site1/path/to/my/action
xitrum.withBaseUrl('/path/to/my/action')
Chuyển từ Markdown sang HTML¶
Nếu bạn đã cấu hình project để sử dụng Scalate template engine, Bạn chỉ cần phải làm như sau:
import org.fusesource.scalamd.Markdown
val html = Markdown("input")
Ngoài ra, bạn cần thêm thành phần phụ thuộc này vào tệp build.sbt
của project.
libraryDependencies += "org.fusesource.scalamd" %% "scalamd" % "1.6"
Theo dõi sự thay đổi của tệp¶
Bạn cần thiết lập callback cho StandardWatchEventKinds trên tệp và thư mục.
import java.nio.file.Paths
import xitrum.util.FileMonitor
val target = Paths.get("absolute_path_or_path_relative_to_application_directory").toAbsolutePath
FileMonitor.monitor(FileMonitor.MODIFY, target, { path =>
// Do some callback with path
println(s"File modified: $path")
// And stop monitoring if necessary
FileMonitor.unmonitor(FileMonitor.MODIFY, target)
})
FileMonitor
sử dụng
Schwatcher.
Thư mục tạm thời¶
Mặc định Xitrum project (xem tmpDir
trong xitrum.conf) sử dụng thư mục tmp
trong thư mục hoạt động hiện thời để lưu các tệp .scala generate bởi Scalate, các tệp
lớn sẽ được tải lên v.v.
Để lấy đường dẫn đến thư mục đó:
xitrum.Config.xitrum.tmpDir.getAbsolutePath
Tạo một tệp mới hoặc thư mục trong thư mục đó:
val file = new java.io.File(xitrum.Config.xitrum.tmpDir, "myfile")
val dir = new java.io.File(xitrum.Config.xitrum.tmpDir, "mydir")
dir.mkdirs()
Stream video¶
Có nhiều cách để steam video. Cách đơn giản nhất:
- Cung cấp tệp video .mp4 theo từng đoạn, người dùng có thể xem video trong khi tải về.
- Và sử dụng một HTTP server như Xitrum có hỗ trợ range requests, để người dùng có thể nhảy đến đoạn phim mà chưa được tải về.
Bạn có thể sử dụng MP4Box để tải nội dụng của tệp phim một các xen kẽ mỗi 0.5 giây:
MP4Box -inter 500 movie.mp4