国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Day 30: Play Framework —— Java開(kāi)發(fā)者的夢(mèng)想框架

Code4App / 2927人閱讀

摘要:通過(guò)如下命令發(fā)布控制臺(tái),運(yùn)行編寫(xiě)的默認(rèn)程序。默認(rèn)禁用,啟用它需要打開(kāi)并取消注釋以下行。啟用數(shù)據(jù)庫(kù)啟動(dòng)應(yīng)用程序的數(shù)據(jù)庫(kù),框架提供了內(nèi)置的數(shù)據(jù)庫(kù)的支持。當(dāng)用戶發(fā)出請(qǐng)求到,一個(gè)新的將被創(chuàng)建。方法為給定的獲取,把這個(gè)轉(zhuǎn)換成格式并返回響應(yīng)。

編者注:我們發(fā)現(xiàn)了有趣的系列文章《30天學(xué)習(xí)30種新技術(shù)》,正在翻譯,一天一篇更新,年終禮包。下面是第 30 天的內(nèi)容。


今天是最后一天,我決定學(xué)習(xí)一下 Play 框架。原本是想寫(xiě)關(guān)于Scala的,學(xué)習(xí)了幾個(gè)小時(shí)之后發(fā)現(xiàn)在一天之內(nèi)是不可能完成Scala的,所以今天會(huì)介紹一下Play框架的基本知識(shí),然后學(xué)習(xí)如何用它開(kāi)發(fā)應(yīng)用。

什么是 Play 框架?

Play是一個(gè)開(kāi)源的現(xiàn)代web框架,用于編寫(xiě)Java和Scala的可擴(kuò)展Web應(yīng)用程序。它通過(guò)自動(dòng)重載變化來(lái)提高生產(chǎn)力,由于設(shè)計(jì)的就是一個(gè)無(wú)狀態(tài)、無(wú)阻塞的架構(gòu),所以用Play框架來(lái)編寫(xiě)橫向擴(kuò)展Web應(yīng)用程序是很容易的。

為什么要用它?

我的原因是:

開(kāi)發(fā)人員生產(chǎn)力:我已經(jīng)寫(xiě)了8年的Java,但在過(guò)去的幾個(gè)月里我把更多的時(shí)間花在了Python和JavaScript (Node.js) 上。用動(dòng)態(tài)語(yǔ)言工作時(shí)最讓我吃驚的,就是用它編寫(xiě)程序的速度是如此之快。Java EE和Spring框架并不是快速原型和開(kāi)發(fā)的理想選擇,但在用Play框架時(shí),你更改一處刷新一下頁(yè)面,更新會(huì)立即出現(xiàn),而且它支持熱重載所有的Java代碼、模板等,可以讓你的迭代快很多。

天性使然:Play框架是建立在Netty之上的,所以它支持非阻塞I/O,這使得并行遠(yuǎn)程調(diào)用容易了很多,這一點(diǎn)對(duì)面向服務(wù)的架構(gòu)中的高性能應(yīng)用程序是很重要的。

支持Java和Scala:Play框架是一個(gè)真正的多語(yǔ)種Web框架,開(kāi)發(fā)者可以在項(xiàng)目中同時(shí)使用Java和Scala。

一流的REST JSON支持:它很容易編寫(xiě)基于REST的應(yīng)用。對(duì)HTTP路由有很好的支持,HTTP路由會(huì)將HTTP請(qǐng)求轉(zhuǎn)化為具體動(dòng)作;JSON編組/解組API是??目前的核心API,所以沒(méi)有必要加一個(gè)庫(kù)來(lái)做到這一點(diǎn)。

應(yīng)用類型案例

今天的介紹中,將開(kāi)發(fā)一個(gè)社交書(shū)簽應(yīng)用程序,它允許用戶發(fā)布和共享鏈接。你可以在這里查看正在運(yùn)行的該程序,因?yàn)檫@個(gè)和第22天的應(yīng)用是一樣的,所以請(qǐng)參閱之以便更好地了解這個(gè)案例。

開(kāi)發(fā)Play應(yīng)用

請(qǐng)參閱文檔以了解如何安裝Play框架,開(kāi)始應(yīng)用程序的開(kāi)發(fā)吧。

$ play new getbookmarks

       _
 _ __ | | __ _ _  _
| "_ | |/ _" | || |
|  __/|_|\____|\__ /
|_|            |__/

play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_25), http://www.playframework.com

The new application will be created in /Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks

What is the application name? [getbookmarks]
> 

Which template do you want to use for this new application? 

  1             - Create a simple Scala application
  2             - Create a simple Java application

> 2
OK, application getbookmarks is created.

Have fun!

如上鍵入命令后,該框架會(huì)問(wèn)幾個(gè)問(wèn)題。首先它要求有應(yīng)用程序的名稱,然后問(wèn)是否要?jiǎng)?chuàng)建一個(gè)Scala或Java應(yīng)用程序。默認(rèn)情況下,它會(huì)使用文件夾名稱作為應(yīng)用程序的名稱。

上面的命令將創(chuàng)建一個(gè)新的目錄getbookmarks并生成以下文件和目錄:

app 目錄包含如控制器 (controller) 、視圖 (view) 和模型 (model) 的應(yīng)用程序特定代碼。控制器包中有響應(yīng)URL路由的Java代碼,視圖目錄包含服務(wù)器端模板,模型目錄包含應(yīng)用程序的域模型。在此應(yīng)用中,域 (domain) 是一個(gè)Story類。

conf 目錄包含應(yīng)用程序配置和路由定義文件。

project 目錄包含構(gòu)建腳本,構(gòu)建系統(tǒng)是基于SBT的。

public 包含了如CSS、JavaScript和img目錄等的公共資源。

test 目錄包含應(yīng)用測(cè)試。

通過(guò)如下命令發(fā)布play控制臺(tái),運(yùn)行Play編寫(xiě)的默認(rèn)程序。

$ cd getbookmarks
$ play
[info] Loading project definition from /Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks/project
[info] Set current project to getbookmarks (in build file:/Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks/)
       _
 _ __ | | __ _ _  _
| "_ | |/ _" | || |
|  __/|_|\____|\__ /
|_|            |__/

play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_25), http://www.playframework.com

> Type "help play" or "license" for more information.
> Type "exit" or use Ctrl+D to leave this console.

[getbookmarks] $ run
[info] Updating {file:/Users/shekhargulati/dev/challenges/30days30technologies/day30/blog/getbookmarks/}getbookmarks...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.

--- (Running the application from SBT, auto-reloading is enabled) ---

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

現(xiàn)在可以在 http://localhost:9000 里運(yùn)行該應(yīng)用了。

創(chuàng)建Story域類

該應(yīng)用程序只有一個(gè)域類 (domain class),叫做story,創(chuàng)建一個(gè)新的包模型和Java類。

package models;

import play.db.ebean.Model;

import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Date;


@Entity
public class Story extends Model{

    @Id
    private String id;

    private String url;

    private String fullname;

    private Date submittedOn = new Date();

    private String title;
    private String text;
    private String image;


    public Story() {

    }

    public Story(String url, String fullname) {
        this.url = url;
        this.fullname = fullname;
    }

    public Story(String url, String fullname, String image, String text, String title) {
        this.url = url;
        this.fullname = fullname;
        this.title = title;
        this.text = text;
        this.image = image;
    }

   // Getter and Setter removed for brevity
}

上述代碼定義了一個(gè)簡(jiǎn)單的JPA實(shí)體,并使用 @Entity@Id JPA注解,Play用它自己的一個(gè)被稱作Ebean的ORM層,而且每一個(gè)實(shí)體類必須擴(kuò)展基本模型類。

Ebean默認(rèn)禁用,啟用它需要打開(kāi)application.conf并取消注釋以下行。

ebean.default="models.*"
啟用數(shù)據(jù)庫(kù)

啟動(dòng)應(yīng)用程序的數(shù)據(jù)庫(kù),Play框架提供了內(nèi)置的H2數(shù)據(jù)庫(kù)的支持。要啟用它,打開(kāi)application.conf文件,并取消如下兩行的注釋。

db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"

刷新瀏覽器會(huì)看到:

點(diǎn)擊Apply this script now將SQL的更改部署上去。

定義應(yīng)用程序的路由

今天講的應(yīng)用程序和第22天是一樣的,都有AngularJS后臺(tái)和REST后端,所以可以使用Play框架重寫(xiě)REST后臺(tái)和AngularJS后端,在conf/routes文件,復(fù)制并粘貼如下代碼。

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# Home page
GET         /                           controllers.Assets.at(path="/public", file="/index.html")
GET         /api/v1/stories             controllers.StoryController.allStories()
POST        /api/v1/stories             controllers.StoryController.submitStory()
GET         /api/v1/stories/:storyId    controllers.StoryController.getStory(storyId)

# Map static resources from the /public folder to the /assets URL path
GET         /assets/*file        controllers.Assets.at(path="/public", file)

上述代碼表示:

當(dāng)用戶發(fā)出一個(gè)GET請(qǐng)求到應(yīng)用程序的“/”URLindex.html將被渲染。

當(dāng)用戶發(fā)出一個(gè)GET請(qǐng)求到"/ api/v1/stories",將得到JSON格式的所有story。

當(dāng)用戶發(fā)出POST請(qǐng)求到"/ api/v1/stories",一個(gè)新的story將被創(chuàng)建。

當(dāng)用戶GET請(qǐng)求"/ api/v1/stories/123",id為123的story會(huì)被渲染。

創(chuàng)建Story控制器

在控制器包里創(chuàng)建一個(gè)Java類,將如下代碼粘貼進(jìn) StoryController.java 文件里。

package controllers;


import com.fasterxml.jackson.databind.JsonNode;
import models.Story;
import play.api.libs.ws.Response;
import play.api.libs.ws.WS;
import play.db.ebean.Model;
import play.libs.Json;
import play.mvc.BodyParser;
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Results;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;

import java.util.List;
import java.util.concurrent.TimeUnit;

public class StoryController {

    public static Result allStories(){
        List stories = new Model.Finder(String.class, Story.class).all();
        return Results.ok(Json.toJson(stories));
    }

    @BodyParser.Of(BodyParser.Json.class)
    public static Result submitStory(){
        JsonNode jsonNode = Controller.request().body().asJson();
        String url = jsonNode.findPath("url").asText();
        String fullname = jsonNode.findPath("fullname").asText();
        JsonNode response = fetchInformation(url);
        Story story = null;
        if(response == null){
            story = new Story(url,fullname);
        }else{
            String image = response.findPath("image").textValue();
            String text = response.findPath("text").textValue();
            String title = response.findPath("title").textValue();
            story = new Story(url,fullname, image , text , title);
        }
        story.save();
        return Results.created();
    }

    public static Result getStory(String storyId){
        Story story = new Model.Finder(String.class, Story.class).byId(storyId);
        if(story == null){
            return Results.notFound("No story found with storyId " + storyId);
        }
        return Results.ok(Json.toJson(story));
    }

    private static JsonNode fetchInformation(String url){
        String restServiceUrl = "http://gooseextractor-t20.rhcloud.com/api/v1/extract?url="+url;
        Future future = WS.url(restServiceUrl).get();
        try {
            Response result = Await.result(future, Duration.apply(30, TimeUnit.SECONDS));
            JsonNode jsonNode = Json.parse(result.json().toString());
            return jsonNode;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

}

上述代碼會(huì)操作:

它定義allStories()方法,該方法會(huì)找到數(shù)據(jù)庫(kù)中所有的story。它是使用Model.Finder API來(lái)做到這一點(diǎn)的,然后把story列表轉(zhuǎn)換成JSON格式并返回結(jié)果,返回HTTP狀態(tài)代碼200(即確定)。

submitStory()方法首先會(huì)從JSON讀取URL和全名的字段,然后發(fā)送GET請(qǐng)求到"http://gooseextractor-t20.rhcloud.com/api/v1/extract?url",這樣就會(huì)找出標(biāo)題、摘要以及已經(jīng)給定url的主要image。創(chuàng)建一個(gè)使用所有信息的story并保存在數(shù)據(jù)庫(kù)中,返回HTTP狀態(tài)代碼201(即創(chuàng)建)。

getStory()方法為給定的storyId獲取story,把這個(gè)story轉(zhuǎn)換成JSON格式并返回響應(yīng)。



可以從我的github倉(cāng)庫(kù)下載AngularJS前端,用其中一個(gè)庫(kù)更換公共目錄。

現(xiàn)在可以訪問(wèn)http://localhost:9000/看結(jié)果了。



30天系列的文章就此結(jié)束,非常感謝大家的持續(xù)關(guān)注,也希望你們能和SegmentFault一塊成長(zhǎng)。

So, see you next year. Oh~ Happy New Year to Y"all !


原文 Day 30: Play Framework--A Java Developer Dream Framework
翻譯整理 SegmentFault

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/64043.html

相關(guān)文章

  • Play framework源碼解析 Part1:Play framework 介紹、項(xiàng)目構(gòu)成及啟動(dòng)

    摘要:注本系列文章所用版本為介紹是個(gè)輕量級(jí)的框架,致力于讓程序員實(shí)現(xiàn)快速高效開(kāi)發(fā),它具有以下幾個(gè)方面的優(yōu)勢(shì)熱加載。在調(diào)試模式下,所有修改會(huì)及時(shí)生效。拋棄配置文件。約定大于配置。 注:本系列文章所用play版本為1.2.6 介紹 Play framework是個(gè)輕量級(jí)的RESTful框架,致力于讓java程序員實(shí)現(xiàn)快速高效開(kāi)發(fā),它具有以下幾個(gè)方面的優(yōu)勢(shì): 熱加載。在調(diào)試模式下,所有修改會(huì)及時(shí)...

    Riddler 評(píng)論0 收藏0
  • Play framework源碼解析 Part3:Play初始化與啟動(dòng)

    摘要:使用自建的類加載器主要是為了便于處理預(yù)編譯后的字節(jié)碼以及方便在模式下進(jìn)行即時(shí)的熱更新。 注:本系列文章所用play版本為1.2.6 在上一篇中,我們分析了play的2種啟動(dòng)方式,這一篇,我們來(lái)看看Play類的初始化過(guò)程 Play類 無(wú)論是Server還是ServletWrapper方式運(yùn)行,在他們的入口中都會(huì)運(yùn)行Play.init()來(lái)對(duì)Play類進(jìn)行初始化。那在解析初始化之前,我們先...

    xuxueli 評(píng)論0 收藏0
  • Day11 - 自定義視頻播放器

    摘要:自定義視頻播放器微信公眾號(hào)開(kāi)發(fā)企業(yè)級(jí)產(chǎn)品全棧開(kāi)發(fā)速成周末班首期班號(hào)正式開(kāi)班,歡迎搶座作者簡(jiǎn)介是推出的一個(gè)天挑戰(zhàn)。 Day11 - 自定義視頻播放器 (Node+Vue+微信公眾號(hào)開(kāi)發(fā))企業(yè)級(jí)產(chǎn)品全棧開(kāi)發(fā)速成周末班首期班(10.28號(hào)正式開(kāi)班,歡迎搶座) 作者:?liyuechun 簡(jiǎn)介:JavaScript30 是 Wes Bos 推出的一個(gè) 30 天挑戰(zhàn)。項(xiàng)目免費(fèi)提供了 30 個(gè)視...

    SKYZACK 評(píng)論0 收藏0
  • 30安卓程序員還有出路嗎,應(yīng)該怎么規(guī)劃?

    摘要:在舒伯的生涯階段里有個(gè)確立階段,歲歲。知識(shí)技術(shù)安卓程序員需要掌握編程語(yǔ)言應(yīng)用框架開(kāi)發(fā)工具等這些具體的知識(shí)和技術(shù)。技術(shù)能力與閱歷對(duì)安卓程序員來(lái)講,知識(shí)技術(shù)是一方面,是容易習(xí)得的,是較淺的層面。 大齡程序員的界定 老早網(wǎng)上有人說(shuō),安卓開(kāi)發(fā)干不過(guò)30歲,后來(lái)又有人說(shuō)干不過(guò)35歲,后來(lái)又有人說(shuō)干不過(guò)...

    不知名網(wǎng)友 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<