RESTful 时需要考虑每种 HTTP Method 操作的业务含义,再也不是 GET 使用 URL, POST 提交表单这样简单的区别。http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html 定义有 GET, POST, PUT, HEAD, DELETE, PATCH, OPTIONS, TRACE, CONNECT 九种类型的 HTTP Method。
关于它们可能针对的业务含义就不多说了,而是如果要对每一种操作方法赋予一个颜色应该怎么去对应呢,比如一般 GET 不会有边际效应的操作可以选择绿色,或者蓝色。幸好我也不用多想,这里参考了 Swagger 的颜色方案,它支持除 OPTIONS, TRACE 和 CONNECT 之外的颜色配置,其实我也没用过这两种方法。
从 Play2 Swagger 中截图如下: Read More
- 因为写过类似下面的一段代码来实始化一个匿名实例看上面的
1package cc.unmi; 2 3public class Test { 4 public String name; 5 6 public static Test buildTest(final String name) { 7 Test test = new Test(){{ 8 this.name = name; //希望把 buildTest() 方法参数中的 name 赋给 this.name 9 }}; 10 System.out.println(test.name); // 仍然是 null 11 return test; 12 } 13}buildTest()方法中的this.name = name希望能把方法参数 final String name 中的 name 值赋值给 this.name, 但是无效,this.name = name 是在把自己赋给自己。 Read More - 对于一个 Java 方法 foo(int id, String name); 我们如何能在代码中获得形式参数名 id 和 name 呢?
我们知道通过反射 APIMethod.getGenericParameterTypes()可以获得方法的参数类型,但是对于参数名一般就是 arg0, arg1, arg2 ..., 因为 Java 编译时把形式参数名擦除了。所以对完全擦除了形式参数名的字节码应该是没办法了,但我们自己写的类还是有能力去管控的。
对于自己写的类,有两种办法获得形式参数名,分别是
1) Java8 的 -parameters 编译参数,然后用 Java8 新引入的反射 API Parameter
我们先在 Java8 下运行下面的代码 Read More - 作为编程,讲救效率自然是用各种 IDE,诸如 Idea, Eclipse, NetBeans 等。但平时总也离不开一款趁手的纯文本编辑器,如阅读各种语言的代码,简单编辑。我就经常会用 Sublime 这类工具的列编辑功能,奇怪于为何 IDE 们鲜有提供列编辑的特性的。
在 Mac 下的 TextEdit 其实是一款富文本编辑器,且未给编程带来任何便利。根据本人从开始扑向 Mac OS X 平台起到现在,选择过三款程序编辑器,它们分别是 TextMate, Sublime 和 Atom,前两为付费的,最后一个是免费的。
1. TextMate
最早听说很多人喜欢用它写 Ruby 程序,也不知是不是真的. TextMate 以其卓越的 Bundle 们驰行于天下。只是最近几年来它却裹足不前了,似乎失去了前进的方向,一直稳定在 1.5.11 版本上,2.0 已经 alpha 很久了. 其间好像思考过开源,出现在了 GitHub 上 https://github.com/textmate/textmate,少有维护。 Read More - Java 和 Scala 都支持变参方法, 写在最后的位置上,最基本的调用方式也都是一样的,一个个罗列过去。也可以传入数组参数,因为变参本质上就是一个数组,就是把 ... 开始位置到最后一个参数都收纳到数组中去,所以变参之所以要放在最后的位置上,且一个方法中最多只能有一个变参类型。
这里主要是对比 Scala 对变参方法的调用,基本调用法当然是没问题的,但是在传入数组作为变参的参数列表与 Java 相对时就稍有变化了。
另外提一下,如果想传入 List 作为变参列表,而不是整体作为变参的第一个元素就是调用集合的 toArray() 方法转换成一个数组传入。
下面看 Java 中对变参方法的调用,参数列表和数组1public class JavaVarArgs { 2 public static void main(String[] args) { 3 foo("a", "b", "c"); 4 foo(new String[]{"d", "e"}); 5 } 6 7 public static void foo(String...params) { 8 System.out.println(params + " : " + params.length); 9 for(String s: params) { 10 System.out.println(s); 11 } 12 } 13}
Read More - 伴随着 Play1, 我们原来使用的 JSON 库是 Gson. 回忆下 Gson 是怎么自定义序列化对象的 JSON 格式,大概是这样子的
GsonBuilder()..registerTypeHierarchyAdapter(Cat.class, new Cat());
然后 Cat 需要实现 JsonSerializer 的 serialize() 方法。
来到了 Play2 中,JSON 库变成了 Jackson,那么 Jackson 该如何为对象自定义 JSON 格式呢?
例如,默认时 Jackson 对 Map 类型输出的是一个 JSON 对象
Map("key1"->"value1", "key2"->"value2") 转换成 JSON 是 {"key1":"value1", "key2":"value2"}
当为适应某些客户端,对于 LinkedHashMap 类型,我们想要输出的是一个有序的 JSON 数组: [{"key1":"value1"},{"key2":"value2"}]
我们就应该自定义某些 Map 的序列化格式,实现方法有两种,addSerializer 和 @JsonSerialize,不管哪种方式都需事先具体化 JsonSerializer 类,并实现它的 serialize 抽象方法
所以我先来实现一个能序列化 Map 的 JsonArrayMapSerializer 类 Read More - sbt, 又是一种自动化构建工具,意为 Simple Build Tool,目前还难副其名,它管理依赖也是用的 Ivy。Scala 相关的项目一般会用它,如 Play2,所以需要来研究下它怎么自定义任务。
sbt 项目可以用 build.sbt 或 project/Build.scala 来定义项目,build.sbt 里写些简单的 settings 表达式,而 Build.scala 就强大,可以写 val, object 和方法定义。而且单个 Build.scala 可以定义多个项目,build.sbt 只用来定义当前项目。build.sbt 和 project/Build.scala 能同时存在,它们的内容会编译到一块。还有一个全局的 build.sbt 文件~/.sbt/build.sbt,这里控制所有的项目。
所以我们分别看在 project/Build.scala 和 build.sbt 中如何定义自己的 task
首先看 project/Build.scala,分别由两行完成1val mytask = taskKey[Unit]("This is my customized task") 2mytask := { println("Execute customized task")}
完整的一个 project/Build.scala 如下 Read More - 随着通用日志组件转入 Slf4j,logback 也变成了默认的日志实现,像 log4j 一样,logback.xml 中也可以使用系统属性或环境变量,如 ${catalina.home}。在 log4j.properties 中,如果变量在系统属性和环境变量中找不到的话默认为 "" 空字符串,而到了 logback.xml 中如果某个变量找不到默认就是 "变量名_IS_UNDEFINED" 了,这样就比较奇怪了。
那如何在没有配置 catalina.home 系统属性或环境变量时设置一个默认值呢,例如,没有 catalina.home 时取值为 ".",这时值日志文件的路径就是
./logs/unmi-%d{yyyy-MM-dd}.log
了,也就是生成中当前目录下的 logs 子目录中,这样算是很友好的方式。下面就来分析怎么一步步找到答案的,没耐心或是只求结果的话,直接滚屏到下面就行。
我们的问题是,对于下面那样的 logback.xml 配置: Read More
前注: 欢迎进到本页, 本篇写时较早, 而 Mac OS X 下 Docker 早不建议用 boot2docker 了, 取而代之的是 docker-machine. 请点击链接 Mac OS X 下安装使用 Docker (新) 查看最新安装过程与体验
云主机可以选择操作系统镜像快速创建主机,这比虚拟机更便捷了,我们本地也可以这么做了,因为有了 Docker 这个东西。它依赖于 LXC(Linux Container),能从网络上获得配置好的 Linux 镜像,非常容易在隔离的系统中运行自己的应用。也因为它的底层核心是个 LXC,所以在 Mac OS X 下需要在 VirtualBox 中跑一个精小的 LXC(这里是一个 Tiny Core Linux,完全在内存中运行,个头只约 24MB,启动时间小于 5 秒的 boot2docker) 虚拟机,构建在 VirtualBox 中。以后的通信过程就是 docker --> boot2docker --> container,端口或磁盘映射也是遵照这一关系。
理解了上面的关系,开始说说 Docker 安装过程
1. 安装 VirtualBox, 不多讲, 因要在它当中创建一个 boot2docker-vm 虚拟机
2. 安装 boot2dockerbrew install boot2docker
你也可以手工安装 Read More- 用过 PlayFramework 的都知道默认的路由器文件是 conf/routes,Play2 可以定义自己的 routes 文件。在默认的 application.conf 中有这么一段注释
# Router
# ~~~~~
# Define the Router object to use for this application.
# This router will be looked up first when the application is starting up,
# so make sure this is the entry point.
# Furthermore, it's assumed your route file is named properly.
# So for an application router like `conf/my.application.Router`,
# you may need to define a router file `my.application.routes`.
# Default to Routes in the root package (and `conf/routes`)
# application.router=my.application.Routes
也就是通过 application.router 可以定义自己的 routes 文件。上面的解释很容易把人搞混,问题在于何处是文件路径,何处是类路径,至少写着的 'conf/my.applicaton.Router 就是在混淆视听。对于上面的解释要明白下面几点 Read More