2017金砖会议之spark

前言


2017年金砖国家工商论坛组委会2日召开新闻发布会,介绍有关情况。论坛预期取得四方面成果:一是增强工商界加强互利合作的信心,二是增进工商界之间的交流合作,三是提出有价值的政策建议,四是拓展工商界参与全球经济治理的深度和广度。



spark简介


Spark(注意不要同Apache Spark混淆)的设计初衷是,可以简单容易地创建REST API或Web应用程序。它是一个灵活、简洁的框架,大小只有1MB。Spark允许用户自己选择设计应用程序的模板引擎以及选择最适合他们项目的库,比如,HTML解析功能就有Freemarker、Mustaches、Velocity、Jade、Handlebars、Pebble或Water等选项可供选择,而且很少需要配置或样板文件。不过,灵活简单的代价是,用户可选的功能减少。总之,Spark剔除了许多Java的臃肿之物,提供了一个最小化的、灵活的Web框架。但由于精简程度较高,它缺少了一些功能,不适合用于大型Web应用程序的开发。


使用示例

1.在pom.xml文件上加入依赖:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-core</artifactId>

<version>2.2</version>

</dependency>

2. 编写代码

import static spark.Spark.*;

public class HelloWorld {

public static void main(String[] args) {

get("/hello", (req, res) -> "Hello World");

}

}

3.允许代码且查看结果

http://localhost:4567/hello

是不是很简单?spark是最容易建立一个java web应用的开发框架,但它提供了对大多数类型的项目来说足够的功能。

停止服务器

  通过调用stop()方法,服务将关闭且会清理掉所有的路由信息。

路由

  一个spark应用的主要模块就是一组路由。路由有三部分组成:

    一个方法。(get,post,put,delete,head,trace,connect,options).

    一个路径。(例如/hello, /users/:name)

    一个回调。(request,response)->{}

  路由的匹配是按照路由的定义顺序匹配的。请求会触发第一个匹配的路由。

get("/", (request, response) -> {// .. Show something ..});

post("/", (request, response) -> {// .. Create something ..});

put("/", (request, response) -> {// .. Update something ..});

delete("/", (request, response) -> {// .. annihilate something ..});

options("/", (request, response) -> {// .. appease something ..

});

路由匹配模式可以包含命名参数,根据请求对象的参数方法来访问:

// matches "GET /hello/foo" and "GET /hello/bar"// request.params(":name") is ‘foo‘ or ‘bar‘

get("/hello/:name", (request, response) -> {

return "Hello: " + request.params(":name");

});

路由匹配模式也可以包含通配符参数。可以根据请求对象的通配符方法来访问:

// matches "GET /say/hello/to/world"// request.splat()[0] is ‘hello‘ and request.splat()[1] ‘world‘

get("/say/*/to/*", (request, response) -> {

return "Number of splat parameters: " + request.splat().length;
});

请求

  在处理方法中,请求参数提供了请求信息和功能:

request.body();               // request body sent by the client

request.cookies();            // request cookies sent by the client

request.contentLength();      // length of request body

request.contentType();        // content type of request.body

request.headers();            // the HTTP header list

request.headers("BAR");       // value of BAR header

request.attributes();         // the attributes list

request.attribute("foo");     // value of foo attribute

request.attribute("A", "V");  // sets value of attribute A to V

request.host();               // "example.com"

request.ip();                 // client IP address

request.pathInfo();           // the path info

request.params("foo");        // value of foo path parameter

request.params();             // map with all parameters

request.port();               // the server port

request.queryMap();           // the query map

request.queryMap("foo");      // query map for a certain parameter

request.queryParams("FOO");   // value of FOO query param

request.queryParams();        // the query param list

request.raw();                // raw request handed in by Jetty

request.requestMethod();      // The HTTP method (GET, ..etc)

request.scheme();             // "http"

request.session();            // session management

request.splat();              // splat (*) parameters

request.url();                // "http://example.com/foo"

request.userAgent();          // user agent

响应

  在处理方法中,响应参数提供了响应参数和功能:

response.body("Hello");        // sets content to Hello

response.header("FOO", "bar"); // sets header FOO with value bar

response.raw();                // raw response handed in by Jetty

response.redirect("/example"); // browser redirect to /example

response.status(401);          // set status code to 401

response.type("text/xml");     // set content type to text/xml


查询参数Map

  查询参数Map支持根据前缀将参数分组到map中。这可以对两组参数进行分组,如user[name]和user[age]一样。

request.queryMap().get("user", "name").value();

request.queryMap().get("user").get("name").value();

request.queryMap("user").get("age").integerValue();

request.queryMap("user").toMap()

Cookie

request.cookies();                              // get map of all request cookies

request.cookie("foo");                          // access request cookie by name

response.cookie("foo", "bar");                  // set cookie with a value

response.cookie("foo", "bar", 3600);            // set cookie with a max-age

response.cookie("foo", "bar", 3600, true);      // secure cookie

response.removeCookie("foo");                   // remove cookie

Session

  每个请求可以访问在服务端创建的session,提供了下面的方法来访问:

request.session(true)                            // create and return session

request.session().attribute("user")              // Get session attribute ‘user‘

request.session().attribute("user", "foo")       // Set session attribute ‘user‘

request.session().removeAttribute("user", "foo") // Remove session attribute ‘user‘

request.session().attributes()                   // Get all session attributes

request.session().id()                           // Get session id

request.session().isNew()                        // Check is session is new

request.session().raw()                          // Return servlet objec

停止

 

一个过滤器或者路由中快速停止一个请求的方法是:

halt();

  

你也可以在停止时,指定一个状态。

halt(401);

 或者:

halt("This is the body");

 

 或者

halt(401, "Go away!");


过滤器




  前置过滤器在请求处理前进行处理,可以读取请求,读取/修改响应。
  停止执行,使用halt方法:

before((request, response) -> {

boolean authenticated;

// ... check if authenticated

if (!authenticated) {

halt(401, "You are not welcome here");

}

});

后置过滤器在请求处理后进行,可以读取请求,读取/修改响应:

after((request, response) -> {

response.header("foo", "set by after filter");

});

  过滤器也可以匹配请求(可选的),此时只有当路径匹配时才进行处理:

before("/protected/*", (request, response) -> {

// ... check if authenticated

halt(401, "Go Away!");

});


直接跳转

  你可以使用redirect帮助方法将浏览器页面进行跳转。

response.redirect("/bar");

  你可以使用状态码3xx进行跳转:

response.redirect("/bar", 301); // moved permanentl


异常映射

  处理配置的所有的过滤器和路由的异常:

get("/throwexception", (request, response) -> {

throw new NotFoundException();

});

exception(NotFoundException.class, (e, request, response) -> {

response.status(404);

response.body("Resource not found");

});


静态文件

  使用staticFileLocation方法,你可以在classpath中指定一个文件夹为静态文件提供服务。

注意,公共目录不要包含在url中。一个文件/public/css/style.css访问路径为:http://{host}:{port}/css/style.css

staticFileLocation("/public"); // Static files

  还可以使用externalStaticFileLocationMethod在设置一个外部目录(不在classpath)为静态文件提供服务:

externalStaticFileLocation("/var/www/public"); // Static files


响应转换

  映射路由将处理方法转换成外部输出。可以通过扩展ResponseTransformer,传递它到映射方法来完成。下面是一个使用Gson将一个路由输出转换成json的示例:

import com.google.gson.Gson;

public class JsonTransformer implements ResponseTransformer {

private Gson gson = new Gson();

@Override

public String render(Object model) {

return gson.toJson(model);

}

}

使用上述类(MyMessage是一个有‘message’成员变量的bean):

get("/hello", "application/json", (request, response) -> {

return new MyMessage("Hello World");

}, new JsonTransformer());

你也可以使用java8的方法引用,因为ResponseTransformer是有一个方法的接口:

Gson gson = new Gson();

get("/hello", (request, response) -> new MyMessage("Hello World"), gson::toJson);


视图和模板

TemplateViewRoute由一个路径(url匹配的路径)和一个实现了render方法的模板引擎组成。

不用调用toString()方法返回的结果作为模板的实体,TemplateViewRoute返回调用render方法作为结果。

这种类型route的主要目的是提供一个创建通用和可复用的使用模板引擎渲染输出的组件。

Freemarker

使用Freemarkder模板引擎渲染对象到html。

maven依赖:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-template-freemarker</artifactId>

<version>2.0.0</version></dependency>

示例和源码在 GitHub上。

Mustache

使用Mustache模板引擎渲染对象到html。

Maven依赖如下:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-template-mustache</artifactId>

<version>1.0.0</version></dependency>

示例和源码在GitHub上。

Velocity

使用velocity模板引擎渲染对象到html。

Maven依赖如下:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-template-velocity</artifactId>

<version>2.0.0</version></dependency>

示例和源码在GitHub上。

Handlebars

使用Handlebar模板引擎渲染对象到html。

Maven依赖如下:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-template-handlebars</artifactId>

<version>1.0.0</version></dependency>

示例和源码在GitHub

jada

使用jada模板引擎渲染对象到html。

Maven依赖如下:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-template-jade</artifactId>

<version>1.0.0</version></dependency>

示例和源码在 GitHub

Pebble

使用pebble模板引擎渲染对象到html。

Maven依赖如下:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-template-pebble</artifactId>

<version>1.0.0</version></dependency>

示例和源码在 GitHub

Water

使用water模板引擎渲染对象到html。

Maven依赖如下:

<dependency>

<groupId>com.sparkjava</groupId>

<artifactId>spark-template-water</artifactId>

<version>1.0.0</version></dependency>

示例和源码在GitHub


内嵌的web服务器

  独立的Spark运行在一个嵌入的Jetty web服务器。


端口

默认情况下,Spark运行在4567端口。如果你想使用别的端口,使用port方法。在使用过滤器和路由时已经完成:

port(9090); // Spark will run on port 9090


安全

你可以通过secure方法来设置connection为安全的。这必须在所有路由映射之前完成:

secure(keystoreFile, keystorePassword, truststoreFile, truststorePassword);


线程池

可以非常容易的设置最大的线程数:

int maxThreads = 8;

threadPool(maxThreads);

还可以配置最新线程数和空闲过期时间:

int maxThreads = 8;int minThreads = 2;int timeOutMillis = 30000;

threadPool(maxThreads, minThreads, timeOutMillis);


等待初始化

使用awaitInitialization() 方法来检查服务器是否准备好,可以处理请求了。

这通常在一个独立的线程中来做,例如在服务器启动后运行一个健康监测模块。

这个方法将使当前线程处于等待状态直至Jetty服务器初始化完成。初始化等于的路由、过滤器。因此,若使用一个线程,请不要将该方法放到你定义的路由、过滤器之前。

awaitInitialization(); // Wait for server to be initialized

其它的web服务器

  为运行集群服务器(不是独立服务器),需要实现spark.servlet.SparkApplication。必须在init方法中初始化路由,下面的过滤器也必须在web.xml中配置:

<filter>

<filter-name>SparkFilter</filter-name>

<filter-class>spark.servlet.SparkFilter</filter-class>

<init-param>

<param-name>applicationClass</param-name>

<param-value>com.company.YourApplication</param-value>

</init-param></filter>

<filter-mapping>

<filter-name>SparkFilter</filter-name>

<url-pattern>/*</url-pattern></filter-mapping>

压缩

若请求/响应报文头中有此字段,压缩将会自动完成。

生成Javadoc

GitHub 上获取到源码后,运行下面的命令生成javadoc:

mvn javadoc:javadoc

生成结果放入到/target/site/apidocs目录下。

时间: 2024-10-03 08:50:31

2017金砖会议之spark的相关文章

实体经济是压舱“金砖”,蒙牛卢敏放想告诉世界什么?

9月3日,金砖国家领导人第九次会晤于厦门隆重举行,金砖五国以及埃及.几内亚.墨西哥.塔吉克斯坦.泰国的领导人齐聚厦门,共商未来合作发展大计.迄今规模最大的金砖国家工商论坛--2017年金砖国家工商论坛也同期开幕.论坛设置了贸易与投资.金融合作与发展.互联互通.蓝色经济四个议题,来自25个国家的1000多名工商界代表在现场就相关议题展开深入讨论. 在"金融合作与发展"专题研讨中,蒙牛集团CEO卢敏放语出惊人,接连抛出"实体经济是中国经济压舱的一块'金砖'"."

金砖、博鳌…… 为何他们都选择蒙牛?

最近蒙牛很忙,忙着到处开"见面会". 在今年的金砖国家系列活动.博鳌亚洲论坛以及"一带一路"里,总能和各种蒙牛撞上,而且还不是以广告或营销的形式. 就在刚刚过去的金砖国家领导人第九次会晤中,蒙牛旗下多个明星产品集中亮相,蒙牛集团CEO卢敏放也应邀参加2017年金砖国家工商论坛. 随后,光央视一家,就在<金砖之夜>.<环球财经连线>.<第一时间>.<经济信息联播>等节目中,连续4次播出了对卢敏放在论坛现场的新闻采访,其他

“金砖”发明者奥尼尔出任英国商务大臣

他由于较早看好新兴市场及其巨大经济潜力而在高盛(Goldman Sachs)声名鹊起.20年后,吉姆?奥尼尔(Jim O'Neill)被任命为政府部长,负责帮助英国应对东半球和南半球新兴国家的竞争.http://www.goodreads.com/topic/show/10178151 http://www.goodreads.com/topic/show/10178144 http://www.goodreads.com/topic/show/10178213 http://www.goodr

女 大三,抱金砖~呵~

寒假一回来,突然感觉一切都变了,到了大三下学期,出国的出国,考研的考研,找工作的找工作,突然意识到从这开始大家就完全走向了不同的道路了,每个人有每个人的梦想并在为了它而拼搏着. 我们告别了早上不想起就逃了第一节课,可以一直看电影,看电视剧的生活,现在的每天早上6:30起,乖乖吃早餐,乖乖上课,课余时间全部用来自习直到晚上1点多才睡觉,平时最多听听歌,电影什么的碰都不敢碰,因为害怕会让自己松懈,感觉回到了高三,不过唯一不一样的是以前是一班人一起奋斗,走一条被无数人走过并且保证正确的道路,那时除了学

次会议闭幕h

[推动解决"连家船"和"茅草房"问题] 未来房价发展趋势:一季度继续趋稳 "这里的企业离家近,回家照顾老人和小孩方便些,再说待遇也还不错!"他告诉笔者,自己已和怀化恒裕实业有限公司和蓝思科技达成了初步意向,回家后再仔细考虑一下. 冬季取暖.垃圾分类.畜禽粪便--看似简单的民生小事,却登上了中央财经领导小组第十四次会议的"议事台". 之后来到Gouvernement de Orléans市政厅美术馆,市长Martine Griv

《OD学spark》20160924scala基础

拓展: Hadoop 3.0 NameNode HA NameNode是Active NameNode是Standby可以有多个 HBase Cluster 单节点故障? HBaster -> BackMaster HRegionServer WEBUI 60010 Spark 课程安排分为两个部分: 第一部分:基础篇 SCALA:1天 SparkCore:2天 - MapReduce SparkSQL:1天 - Hive Shark = Hive on Spark 关键,企业中必用的,必须掌握

1702-03组-小组第二次会议

会议时间 2017 12 22 会议地点 华中科技大学图书馆 到场人员:1702-03组全体人员 分工如下所示: 主持人:任帅辉,负责组织评审会议: 讲解员:何俊超  负责介绍这次评审会议的测试产品: 作  者:刘威    测试工具讲解: 记录员:杜海鹏  记录缺陷和决议: 评审员:周政坤  主要负责评审工作产品:

长通道”再掀高潮j

当地工作人员介绍,今年团洲万亩油菜花海最佳观赏时期为本月下旬至3月下旬.最佳赏花地点推荐去团胜村,千亩以上完全盛开的油菜花连成了片,是畅游花海最好的地点. 樱花树:个人及家庭888元/年.株单位2688元/年.株 黄明与郭碧婷因拍摄<那片星空那片海>结缘,除了剧中两人感情甚笃是发小至交,戏外两人也是私交不错的好友.期待两人在<星空海>之后有更多精彩合作. 二期"老长沙"更是用情怀和专业探寻"文夕大火"之前的长沙痕迹.一砖一瓦,一井一铺,都无不

广东江门市委原常委王积俊涉嫌受贿行贿被公诉y

有"黄牛党"直接在票面价格上加上2000元出售,即便如此,球票仍十分抢手.图为2010年9月28日,香港,邵逸夫出席邵逸夫奖2010颁奖典礼.阿博特回应,他将"迅速.全面且有礼貌"地回信,并且对由所谓"监听"带来的尴尬表达"深切而由衷的遗憾".为应对连续数日居高不下的环境污染指数,杭州决定提前颁布<杭州市大气重污染应急预案(试行)>.中国社科院学者李新烽认为2012年底非洲华侨华人的总数已略超过100万.因此,充分