You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+44-51Lines changed: 44 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,34 +9,27 @@ The project's name comes from the nautical _K_ or _Kilo_ flag, which means "I wi
9
9
10
10

11
11
12
-
This guide introduces the Kilo framework and provides an overview of its key features.
13
-
14
-
# Getting Kilo
15
-
Kilo is distributed via Maven Central:
16
-
17
-
*[org.httprpc:kilo-client](https://central.sonatype.com/artifact/org.httprpc/kilo-client/versions) - includes support for consuming web services, interacting with relational databases, and working with common file formats (Java 21 or later required)
18
-
*[org.httprpc:kilo-server](https://central.sonatype.com/artifact/org.httprpc/kilo-server/versions) - depends on client; includes support for creating web services (Jakarta Servlet 6.1 or later required)
19
-
20
-
# Kilo Classes
21
12
Classes provided by the Kilo framework include:
22
13
23
-
*[WebService](#webservice)
24
-
*[WebServiceProxy](#webserviceproxy)
25
-
*[JSONEncoder and JSONDecoder](#jsonencoder-and-jsondecoder)
26
-
*[TextEncoder and TextDecoder](#textencoder-and-textdecoder)
27
-
*[CSVEncoder and CSVDecoder](#csvencoder-and-csvdecoder)
28
-
*[TemplateEncoder](#templateencoder)
29
-
*[BeanAdapter](#beanadapter)
30
-
*[QueryBuilder and ResultSetAdapter](#querybuilder-and-resultsetadapter)
*[JSONEncoder and JSONDecoder](#jsonencoder-and-jsondecoder)
19
+
*[TextEncoder and TextDecoder](#textencoder-and-textdecoder)
20
+
*[CSVEncoder and CSVDecoder](#csvencoder-and-csvdecoder)
21
+
*[TemplateEncoder](#templateencoder)
22
+
*[BeanAdapter](#beanadapter)
23
+
*[QueryBuilder and ResultSetAdapter](#querybuilder-and-resultsetadapter)
24
+
*[ElementAdapter](#elementadapter)
25
+
*[Pipe](#pipe)
26
+
*[Collections](#collections)
27
+
*[Optionals](#optionals)
28
+
*[Iterables](#iterables)
29
+
30
+
Each is discussed in more detail below. Java 21 or later is required.
31
+
32
+
# WebService
40
33
`WebService` is an abstract base class for web services. It extends the similarly abstract `HttpServlet` class and provides a thin, REST-oriented layer on top of the standard [servlet API](https://jakarta.ee/specifications/servlet/6.1/).
41
34
42
35
For example, the following service implements some simple mathematical operations:
@@ -88,7 +81,7 @@ In either case, the service would return the value 6 in response.
88
81
89
82
The optional `Description` annotation is used to document a service implementation and is discussed in more detail [later](#api-documentation).
90
83
91
-
###Method Parameters
84
+
## Method Parameters
92
85
Method parameters may be any of the following types:
93
86
94
87
*`Byte`/`byte`
@@ -130,7 +123,7 @@ If a provided value cannot be coerced to the expected type, an HTTP 403 (forbidd
130
123
131
124
Note that service classes must be compiled with the `-parameters` flag so that parameter names are available at runtime.
132
125
133
-
####Required Parameters
126
+
### Required Parameters
134
127
Parameters that must be provided by the caller can be indicated by the `Required` annotation. For example, the following service method accepts a single required `owner` argument:
`List`, `Set`, and array parameters are implicitly required, since these values will never be `null` (though they may be empty). For all other parameter types, HTTP 403 will be returned if a required value is not provided.
144
137
145
-
####Custom Parameter Names
138
+
### Custom Parameter Names
146
139
The `Name` annotation can be used to associate a custom name with a method parameter. For example:
147
140
148
141
```java
@@ -164,7 +157,7 @@ This method could be invoked as follows:
164
157
GET /members?first_name=foo*&last_name=bar*
165
158
```
166
159
167
-
###Path Variables
160
+
## Path Variables
168
161
Path variables (or "keys") are specified by a "?" character in a handler's resource path. For example, the `itemID` argument in the method below is provided by a path variable:
169
162
170
163
```java
@@ -178,7 +171,7 @@ public ItemDetail getItem(
178
171
179
172
Path parameters must precede query parameters in the method signature and are implicitly required. Values are mapped to method arguments in declaration order.
180
173
181
-
###Body Content
174
+
## Body Content
182
175
Body content may be declared as the final parameter in a `POST` or `PUT` handler. For example, this method accepts an item ID as a path variable and an instance of `ItemDetail` as a body argument:
183
176
184
177
```java
@@ -193,7 +186,7 @@ public void updateItem(
193
186
194
187
Like path parameters, body parameters are implicitly required. By default, content is assumed to be JSON and is automatically converted to the appropriate type. A body parameter of type `Void` may be used to indicate that the handler will process the input stream [directly](#request-and-repsonse-properties).
195
188
196
-
###Return Values
189
+
## Return Values
197
190
Return values are converted to JSON as follows:
198
191
199
192
*`Number`/numeric primitive: number
@@ -222,15 +215,15 @@ By default, HTTP 200 (OK) is returned when a service method completes successful
222
215
223
216
If a service method returns `null`, an HTTP 404 (not found) response will be returned.
224
217
225
-
###Exceptions
218
+
## Exceptions
226
219
If an exception is thrown by a service method and the response has not yet been committed, the exception message (if any) will be returned as plain text in the response body. Error status is determined as follows:
227
220
228
221
*`IllegalArgumentException` or `UnsupportedOperationException` - HTTP 403 (forbidden)
229
222
*`NoSuchElementException` - HTTP 404 (not found)
230
223
*`IllegalStateException` - HTTP 409 (conflict)
231
224
* Any other exception - HTTP 500 (internal server error)
232
225
233
-
###Database Connectivity
226
+
## Database Connectivity
234
227
For services that require database connectivity, the following method can be used to obtain a JDBC connection object associated with the current invocation:
235
228
236
229
```java
@@ -241,7 +234,7 @@ The connection is opened via a data source identified by `getDataSourceName()`,
241
234
242
235
Auto-commit is disabled so an entire request will be processed within a single transaction. If the request completes successfully, the transaction is committed. Otherwise, it is rolled back.
243
236
244
-
###Request and Repsonse Properties
237
+
## Request and Repsonse Properties
245
238
The following methods provide access to the request and response objects associated with the current invocation:
246
239
247
240
```java
@@ -253,10 +246,10 @@ For example, a service might use the request to read directly from the input str
253
246
254
247
The response object can also be used to produce a custom result. If a service method commits the response by writing to the output stream, the method's return value (if any) will be ignored by `WebService`. This allows a service to return content that cannot be easily represented as JSON, such as image data.
255
248
256
-
###Inter-Service Communication
249
+
## Inter-Service Communication
257
250
A reference to any active service can be obtained via the `getInstance()` method of the `WebService` class. This can be useful when the implementation of one service depends on functionality provided by another service, for example.
258
251
259
-
###API Documentation
252
+
## API Documentation
260
253
An index of all active services can be found at the application's context root:
261
254
262
255
```
@@ -352,7 +345,7 @@ Deprecated elements will be identified as such in the output.
352
345
353
346
A JSON version of the generated documentation can be obtained by specifying an "Accept" type of "application/json" in the request headers. The response can be used to process an API definition programatically; for example, to generate client-side stub code.
354
347
355
-
##WebServiceProxy
348
+
# WebServiceProxy
356
349
The `WebServiceProxy` class is used to submit API requests to a server. It provides the following constructor, which accepts a string representing the HTTP method to execute and the URI of the requested resource:
`WebServiceProxy` additionally provides the following methods to facilitate convenient, type-safe access to web APIs:
422
415
423
416
```java
@@ -461,7 +454,7 @@ Path variables and body content are handled as described for [`WebService`](#web
461
454
462
455
Note that proxy types must be compiled with the `-parameters` flag so their method parameter names are available at runtime.
463
456
464
-
##JSONEncoder and JSONDecoder
457
+
# JSONEncoder and JSONDecoder
465
458
The `JSONEncoder` and `JSONDecoder` classes are used internally by `WebService` and `WebServiceProxy` to process request and response data. However, they can also be used directly by application logic. For example:
The `TemplateEncoder` class transforms an object hierarchy (known as a "data dictionary") into an output format using a [template document](template-reference.md). Template syntax is based loosely on the [Mustache](https://mustache.github.io) specification and supports most Mustache features. For example:
537
530
538
531
```java
@@ -571,7 +564,7 @@ the code would produce this output:
571
564
</html>
572
565
```
573
566
574
-
##BeanAdapter
567
+
# BeanAdapter
575
568
The `BeanAdapter` class provides access to Java bean properties and record components via the `Map` interface. For example:
576
569
577
570
```java
@@ -635,7 +628,7 @@ Note that concrete types are coerced "eagerly" (before the `coerce()` method ret
635
628
636
629
The `Required` and `Name` annotations introduced previously can also be used with bean properties.
637
630
638
-
##QueryBuilder and ResultSetAdapter
631
+
# QueryBuilder and ResultSetAdapter
639
632
The `QueryBuilder` class provides support for programmatically constructing and executing SQL queries. For example, given the following tables (adapted from the MySQL tutorial):
640
633
641
634
```sql
@@ -694,7 +687,7 @@ Temporal values (such as "birth" and "death" above) are automatically converted
694
687
*`java.sql.Date`/`LocalDate`
695
688
*`java.sql.Time`/`LocalTime`
696
689
697
-
###Schema Annotations
690
+
## Schema Annotations
698
691
`QueryBuilder` also offers a simplified approach to query construction using "schema annotations". For example, given these type definitions:
699
692
700
693
```java
@@ -763,7 +756,7 @@ order by last_name asc, first_name asc
763
756
764
757
Insert, update, and delete operations are also supported. See the [pet](kilo-test/src/main/java/org/httprpc/kilo/test/PetService.java), [catalog](kilo-test/src/main/java/org/httprpc/kilo/test/CatalogService.java), and [film](kilo-test/src/main/java/org/httprpc/kilo/test/FilmService.java) service examples for more information.
765
758
766
-
##ElementAdapter
759
+
# ElementAdapter
767
760
The `ElementAdapter` class provides access to the contents of an XML DOM `Element` via the `Map` interface. For example, the following markup might be used to represent the status of a bank account:
`ElementAdapter` also supports `put()` and `remove()` for modifying an element's contents.
872
865
873
-
##Pipe
866
+
# Pipe
874
867
The `Pipe` class provides a vehicle by which a producer thread can submit a sequence of values for retrieval by a consumer thread. It implements the `Iterable` interface and returns elements as they become available, blocking if necessary.
875
868
876
869
For example, the following code executes a SQL query that retrieves all rows from an `employees` table:
0 commit comments