微框架spark--api开发利器
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 authenticatedif (!authenticated) {halt(401, "You are not welcome here");} });
后置过滤器在请求处理后进行,可以读取请求,读取/修改响应:
after((request, response) -> {response.header("foo", "set by after filter"); });
过滤器也可以匹配请求(可选的),此时只有当路径匹配时才进行处理:
before("/protected/*", (request, response) -> {// ... check if authenticatedhalt(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();@Overridepublic 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
转载于:https://www.cnblogs.com/davidwang456/p/4655090.html
微框架spark--api开发利器相关推荐
- Spark API编程动手实战-08-基于IDEA使用Spark API开发Spark程序-01
2019独角兽企业重金招聘Python工程师标准>>> 创建一个Scala IDEA工程: 点击"Next": 点击"Finish"完成工程的 ...
- php 框架搭建,利用composer搭建一个PHP微框架(API微项目)
为什么搭建一个框架(搭建一个怎样的框架) 通过搭建一个框架更好的学习PHP 搭建一个专门用于构建API的微型框架. 微型框架基本上是一个封装的路由,用来转发HTTP请求至一个闭包,控制器,或方法等等, ...
- SAP API开发方法大全
Jerry之前的文章:**从SAP Leonardo到SAP Data Intelligence **曾经提到,SAP Leonardo Machine Learning Foundation的机器学 ...
- 最流行的轻量级php框架,GitHub - meolu/zan: zan 轻量级PHP微框架
zan 简介 [zan 赞] 是一个免费开源的,快速,简单的面向对象的,轻量级PHP微框架. 之所以开发这个框架,不是因为它的性能比Yaf好,也不是因为比ci,tp功能强大,仅仅是因为我想练习设计,它 ...
- SAP API 开发方法大全
Jerry之前的文章:**从SAP Leonardo到SAP Data Intelligence **曾经提到,SAP Leonardo Machine Learning Foundation的机器学 ...
- Re:从 0 开始的微服务架构--(三)微服务架构 API 的开发与治理--转
原文来自:聊聊架构公众号 前面的文章中有说到微服务的通信方式,Martin Folwer 先生在他对微服务的定义中也提到"每个服务运行在其独立的进程中,服务与服务间采用 轻量级的通信机制 互 ...
- 【核心API开发】Spark入门教程[3]
本教程源于2016年3月出版书籍<Spark原理.机制及应用> ,在此以知识共享为初衷公开部分内容,如有兴趣,请支持正版书籍. Spark综合了前人分布式数据处理架构和语言的优缺点,使用简 ...
- 微服务架构 API 的开发与治理
前面的文章中有说到微服务的通信方式,Martin Folwer 先生在他对微服务的定义中也提到"每个服务运行在其独立的进程中,服务与服务间采用 轻量级的通信机制 互相协作(通常是基于 HTT ...
- 【go-zero】go-zero开发环境 如何聚合所有api? caddy反向代理服务分发 微服务设计api聚合方法 best practice
帮助go-zero开发者聚合api 相关视频 一.go-zero 微服务整体架构 1.微服务的基本架构 2.go-zero 微服务的 api authrpc.api 文件 routes.go 文件 二 ...
- 视频教程-Web前端开发利器 SPRY框架之表单验证-JavaScript
Web前端开发利器 SPRY框架之表单验证 有17年互联网行业从业经验,始终在教学第一线,勇于创新,从有效教学,不断向高效教学转变.始终坚持"学生为主体,教师为主导:商业化案例,企业化情境& ...
最新文章
- 型网站的架构设计问题----大型高并发高负载网站的系统架构
- The source attachment does not contain the source for the file Activity.class
- xen虚拟化实战系列(六)之xen虚拟机破解密码
- Mysql 死锁过程及案例详解之清空缓存锁Flush Lock
- 如何替公司省下数千万勒索费用
- juqery-筛选器-找前后上下
- AS技巧合集「调试技巧篇」
- 考研复习 求解函数极限的方法全总结
- 【转】深入浅出的讲解傅里叶变换(真正的通俗易懂)
- 一款好用的插件——油猴子
- 如何用计算机抢座位,火车票可以自选座位啦!内附史上最强抢票攻略!
- 用tushare数据自定义期货大宗商品指数(3)
- git基于master创建新分支
- c# api接口管理
- oracle 基础语法(二)
- 脚本编写一个10秒的倒计时和1分10秒的倒计时
- SVG中年月日相关的表达式
- RabbitMQ-全面详解(学习总结---从入门到深化)
- 百度、Google.yahoo排名机制和优化规则
- Cisco AP-如何识别思科胖瘦AP
热门文章
- cad用计算机怎么计算坐标,如何测算CAD图纸坐标测算教程 CAD图纸的坐标怎么计算...
- python字符串查找数字_Python Regex - 在字符串中用逗号查找数字
- python运用实例视频_python爬视频实例
- 检测到目标服务器启用了trace方法_综述:目标检测中的多尺度检测方法
- python大神写的代码_初学Python,只会写简单的代码。手头有份Python代码,但是调用C模块生成的.pxd和.pyx文件,运行过程总报错,希望大神指点,调试前该做哪些工作呢?...
- 12无法使用otg_ios设备该如何选择U盘,以及U盘日常使用技巧
- Java项目如何改成maven_普通java项目改进为maven:ecplise
- 窗体皮肤ssk 跟背景图片冲突_夫西地酸+阿达帕林~我要好皮肤
- C++中多态的概念和意义
- 台式机计算机操作系统怎么看,电脑操作系统是32位还是64位的怎么查看