Play框架拾遺之五:其餘知識點

一、Job異步處理

Job能夠有結果返回:java

package jobs;
import play.jobs.*;

public class MyJob extends Job<String> {
  public String doJobWithResult() {
    // 執行一些業務邏輯
    return result;
  }
}

Job不只能夠設置啓動調用(用@OnApplicationStart),還中止時調用:編程

import play.jobs.*;

@OnApplicationStop
public class Bootstrap extends Job {
  public void doJob() {
    Fixture.deleteAll();
  }
}

若是但願Web應用啓動後,可以在執行Bootstrap Job的同時,又能很快地處理到來的請求,能夠爲@OnApplicationStart註解添加async=true屬性:@OnApplicationStart(async=true)。這樣應用程序開啓後,Bootstrap Job就會做爲後臺程序異步執行了。不只如此,全部的異步Job(async=true)也會在Web應用開啓以後同時運行。promise

@OnApplicationStart(async=true)
public class Bootstrap extends Job {
  public void doJob() {
    if(Page.count() == 0) {
      new Page("root").save();
      Logger.info("A root page has been created.");
    }
  }
}

Play的Job調度是使用Quartz庫的CRON表達式,後續會詳細介紹緩存

二、HTTP異步編程

Play容許臨時掛起HTTP請求。掛起的HTTP請求仍然保持鏈接,可是該請求的執行會被移出線程池並稍後進行嘗試。根據須要,Play能夠在一段固定的延時後恢復現場,繼續執行請求。dom

public static void generatePDF(Long reportId) {
  Promise<InputStream> pdf = new ReportAsPDFJob(report).now();
  InputStream pdfStream = await(pdf);
  renderBinary(pdfStream);
}

Play還提供了waitAll() ,waitAny(),waitEither()等方法。異步

public static void usePromise(){
  F.Promise<WS.HttpResponse> promise1=WS.url("http://domain1.com").getAsync();
  F.Promise<WS.HttpResponse> promise2=WS.url("http://domain2.com").getAsync();
  F.Promise<List<WS.HttpResponse>> promises = F.Promise.waitAll(promise1, promise2);
  await(promises);
  renderText("Execute finished");
}

三、驗證碼

Play中的play.libs.Images類提供了生成驗證碼的支持,操做也很是簡單。咱們能夠經過靜態方法Images.captacha()快速生成默認大小爲150*50的驗證碼圖片,也可使用Images.captacha(int width, int height)方法生成指定大小的驗證碼圖片。async

public static void captcha(){
  Images.Captcha captcha=Images.captcha(); //生成驗證碼圖片
  captcha.addNoise(); //增長澡點
  String code = captcha.getText("#ABCDEF"); //獲取文本內容
  captcha.setBackground("#E4EAFD"); //設置背景顏色
  renderBinary(captcha);
}

四、緩存

play.cache.Cache類提供了一系列訪問緩存的API,包含了完整的設置、替換和獲取數據的方法:memcached

public static void showProduct(String id) {
  Product product = Cache.get(id, Product.class);
  if(product == null) {
    product = Product.findById(id);
    Cache.set("product_"+id, product, "30mn");
  }
  render(product);
}

public static void addProduct(String name, int price) {
  Product product = new Product(name, price);
  product.save();
  showProduct(id);
}

public static void editProduct(String id, String name, int price) {
  Product product = Product.findById(id);
  product.name = name;
  product.price = price;
  Cache.set("product_"+id, product, "30mn");
  showProduct(id);
}

public static void deleteProduct(String id) {
  Product product = Product.findById(id);
  product.delete();
  Cache.delete("product_"+id);
  allProducts();
}

操做緩存的API中有不少方法是以safe做爲前綴的,如safeDelete,safeSet等。帶safe前綴的方法是阻塞的,而標準方法是非阻塞的,delete方法會當即返回結果,並無等待緩存對象是否被真正地物理刪除。所以,若是程序執行期間發生了錯誤(例如IO錯誤),緩存對象可能仍然存在,並無被刪除。若是操做須要確保緩存對象被刪除,可使用safeDelete方法:異步編程

Cache.safeDelete("product_"+id);

配置Memcachedurl

memcached=enabled
memcached.host=127.0.0.1:11211
相關文章
相關標籤/搜索