当前位置:Java -> 介绍Kilo
Kilo 是一个用于在Java中创建和消费RESTful和类RESTful网络服务的开源框架。它非常轻量级,只需要一个Java运行环境和一个Servlet容器。项目的名称来自航海中的K或Kilo旗,代表“我想与你通信”。
Kilo原先被称为“HTTP-RPC”,被创建作为其他占用更大空间且学习曲线更陡峭的框架的替代品。最近更改了名称以更好地反映项目当前的重点和意图。
本文概述了两个核心Kilo类,WebService
和WebServiceProxy
。
WebService
是用于网络服务的抽象基类。它扩展了类似的抽象HttpServlet
类,并在标准servlet API之上提供了一个薄的、面向REST的层。
例如,以下服务实现了一些简单的数学运算:
@WebServlet(urlPatterns = {"/math/*"}, loadOnStartup = 1)
@Description("Math example service.")
public class MathService extends WebService {
@RequestMethod("GET")
@ResourcePath("sum")
@Description("Calculates the sum of two numbers.")
public double getSum(
@Description("The first number.") double a,
@Description("The second number.") double b
) {
return a + b;
}
@RequestMethod("GET")
@ResourcePath("sum")
@Description("Calculates the sum of a list of numbers.")
public double getSum(
@Description("The numbers to add.") List<Double> values
) {
double total = 0;
for (double value : values) {
total += value;
}
return total;
}
}
RequestMethod
注解将HTTP动词(例如GET
或POST
)与服务方法或“处理程序”相关联。可选的ResourcePath
注解将处理程序与相对于Servlet的特定路径或“端点”相关联。如果未指定,则处理程序与Servlet自身相关。可选的Description
注解用于自动生成的服务文档中。
参数可以通过查询字符串、资源路径或请求体提供。它们也可以以表单数据的形式提交。 WebService
将值转换为预期类型,调用方法,并将返回值(如果有)以JSON形式写入输出流。
可以将多个方法与同一动词和路径相关联。 WebService
根据提供的参数值选择要执行的最佳方法。例如,这个请求将调用第一个方法:
GET /math/sum?a=2&b=4
而这个请求将调用第二个:
GET /math/sum?values=1&values=2&values=3
无论哪种情况,服务都会以响应返回值6。
路径变量(或“键”)在处理程序的资源路径中由“?”字符指定。例如,下面方法中的itemID
参数是由路径变量提供的:
@RequestMethod("GET")
@ResourcePath("items/?")
@Description("Returns detailed information about a specific item.")
public ItemDetail getItem(
@Description("The item ID.") Integer itemID
) throws SQLException { ... }
路径参数必须在方法签名中的查询参数之前。值根据声明顺序映射到方法参数。
请求体内容可以在POST
或PUT
处理程序的最后一个参数中声明。例如,该方法接受作为路径变量和ItemDetail
实例的请求体参数:
@RequestMethod("PUT")
@ResourcePath("items/?")
@Description("Updates an item.")
public void updateItem(
@Description("The item ID.") Integer itemID,
@Description("The updated item.") ItemDetail item
) throws SQLException { ... }
返回值转换成JSON格式如下:
String
: stringNumber
/数值类型: numberBoolean
/boolean
: booleanjava.util.Date
: 表示毫秒数的数值Iterable
: arrayjava.util.Map
: object此外,以下类型的实例会自动转换为它们的字符串表示形式:
Character
/char
Enum
java.time.TemporalAccessor
java.time.TemporalAmount
java.util.UUID
java.net.URL
所有其他值被假设为bean并被序列化为对象。
WebServiceProxy
类用于向服务器提交API请求。它提供以下两个构造函数:
public WebServiceProxy(String method, URL url) { ... }
public WebServiceProxy(String method, URL baseURL, String path, Object... arguments) throws MalformedURLException { ... }
第一个版本接受表示要执行的HTTP方法和所请求资源的URL的字符串。第二个版本接受HTTP方法、基本URL和相对路径(作为格式字符串,对其应用了可选的尾随参数)。
请求参数通过传递给setArguments()
方法的映射来指定。可以使用任何值作为参数,并通常使用其字符串表示形式进行编码。然而,Date
实例会自动转换为表示毫秒数的长整型值。此外,Collection
或数组实例表示多值参数,并且类似于HTML中的<select multiple>
标签。请求体内容可以通过setBody()
方法提供。
服务操作通过以下方法之一被调用:
public Object invoke() throws IOException { ... }
public <T> T invoke(Function<Object, ? extends T> transform) throws IOException { ... }
public <T> T invoke(ResponseHandler<T> responseHandler) throws IOException { ... }
第一个版本反序列化一个成功的JSON响应(如果有)。第二个应用一个转换到反序列化响应。第三个版本允许调用者提供自定义响应处理程序:
public interface ResponseHandler<T> {
T decodeResponse(InputStream inputStream, String contentType) throws IOException;
}
下面的代码演示了如何使用WebServiceProxy
来访问前面讨论的简单数学服务的操作:
// GET /math/sum?a=2&b=4
var webServiceProxy = new WebServiceProxy("GET", new URL("http://localhost:8080/kilo-test/math/sum"));
webServiceProxy.setArguments(mapOf(
entry("a", 4),
entry("b", 2)
));
System.out.println(webServiceProxy.invoke()); // 6.0
// GET /math/sum?values=1&values=2&values=3
var webServiceProxy = new WebServiceProxy("GET", new URL("http://localhost:8080/kilo-test/math/sum"));
webServiceProxy.setArguments(mapOf(
entry("values", listOf(1, 2, 3))
));
System.out.println(webServiceProxy.invoke()); // 6.0
还支持POST
、PUT
和DELETE
操作。
WebServiceProxy
还提供了以下方法,以便方便、类型安全地访问Web API:
public static <T> T of(Class<T> type, URL baseURL) { ... }
public static <T> T of(Class<T> type, URL baseURL, Consumer<WebServiceProxy> initializer) { ... }
两个版本都返回一个实现了给定接口的对象,用于向提供的URL提交请求。第二个版本接受的可选的初始化器将在每次服务调用之前被调用;例如,用于应用常见的请求头。
RequestMethod
和ResourcePath
注解如前面所述使用。代理方法必须包括一个throws子句,声明IOException
,以便调用者可以处理意外失败。例如:
public interface MathServiceProxy {
@RequestMethod("GET")
@ResourcePath("sum")
double getSum(double a, double b) throws IOException;
@RequestMethod("GET")
@ResourcePath("sum")
double getSum(List<Double> values) throws IOException;
}
下面展示了示例用法:
var mathServiceProxy = WebServiceProxy.of(MathServiceProxy.class, new URL("http://localhost:8080/kilo-test/math/"));
System.out.println(mathServiceProxy.getSum(4, 2)); // 6.0
System.out.println(mathServiceProxy.getSum(listOf(1.0, 2.0, 3.0))); // 6.0
本文介绍了Kilo框架,并简要概述了两个Kilo类WebService
和WebServiceProxy
。有关更多信息,请查看项目的 README。
推荐阅读: 百度面经(20)
本文链接: 介绍Kilo