设为首页 收藏本站
查看: 905|回复: 0

[经验分享] 微框架spark--api开发利器

[复制链接]

尚未签到

发表于 2017-2-28 11:53:12 | 显示全部楼层 |阅读模式
  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目录下。
  示例和教程
  示例可以从工程目录中获取GitHub
  说明书可以从Spark tutorial page获取。
  参考文献:
  【1】http://sparkjava.com/documentation.html
  【2】http://www.infoq.com/cn/news/2015/06/Java-Spark-Jodd-Ninja

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348425-1-1.html 上篇帖子: JFinal使用笔记1-部署demo项目到本地tomcat 下篇帖子: DUBBO本地搭建及小案例
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表