Assuming you already know what content types are and what thy are used for lets look at sending some with undertow. What is a content type?
Content Type Handlers
text/plain
// @WhereAreAllMyAnnotations??
// @DecoupledLogicFromRoutingIsNice!
public static void helloWorldText(HttpServerExchange exchange) {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
exchange.getResponseSender().send("Hello World");
}
curl -v localhost:8080/helloWorldText
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /helloWorldText HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/plain
< Content-Length: 11
< Date: Tue, 10 Jan 2017 03:38:49 GMT
<
* Connection #0 to host localhost left intact
Hello World
text/html
public static void helloWorldHtml(HttpServerExchange exchange) {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/html");
exchange.getResponseSender().send("<h1>Hello World</h1>");
}
curl -v localhost:8080/helloWorldHtml
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /helloWorldHtml HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/html
< Content-Length: 20
< Date: Tue, 10 Jan 2017 03:41:07 GMT
<
* Connection #0 to host localhost left intact
<h1>Hello World</h1>
application/octet-stream
public static void helloWorldFileDownload(HttpServerExchange exchange) {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/octet-stream");
exchange.getResponseHeaders().put(Headers.CONTENT_DISPOSITION, "inline; filename=\"" + fileName + "\"");
exchange.getResponseSender().send("Hello World");
}
curl -v localhost:8080/helloWorldFileDownload
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /helloWorldFileDownload HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: application/octet-stream
< Content-Length: 11
< Content-Disposition: inline; filename="helloworld.txt"
< Date: Tue, 10 Jan 2017 03:41:38 GMT
<
* Connection #0 to host localhost left intact
Hello World
application/json
public static void helloWorldJson(HttpServerExchange exchange) {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
exchange.getResponseSender().send("{\"message\": \"Hello World\"}");
}
curl -v localhost:8080/helloWorldJson
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /helloWorldJson HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.49.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: application/json
< Content-Length: 26
< Date: Tue, 10 Jan 2017 03:42:16 GMT
<
* Connection #0 to host localhost left intact
{"message": "Hello World"}
Content Type Routes
/*
* Pretty clean am I right? Unless you REALLY REALLY love annotations
* and the magic that comes with them. Don't forget about the copious
* rabbit holes just trying to figure out what code executes because of
* the annotation. This approach all code is just a few clicks away in
* your IDE of choice. Your time is better spent writing code than pretending
* to be a CSI cyber crimes specialist ripping apart some code for a clue to
* whatever it does.
*/
public static final RoutingHandler ROUTES = new RoutingHandler()
.get("/helloWorldText", ContentTypeHandlers::helloWorldText)
.get("/helloWorldHtml", ContentTypeHandlers::helloWorldHtml)
.get("/helloWorldFileDownload", ContentTypeHandlers::helloWorldFileDownload)
.get("/helloWorldJson", ContentTypeHandlers::helloWorldJson)
.get("/helloWorldJsonSender", ContentTypeHandlers::helloWorldJsonSender)
;
Content Type Server
public static void main(String[] args) {
SimpleServer server = SimpleServer.simpleServer(ROUTES);
server.start();
}
Not very difficult, do we really need frameworks to handle this for us? Boilerplate? sure, but a few convenience functions and it goes away. Lets go ahead and make it check out ContentTypeSenders.java and its implementation at Senders.java
Reduce the Boilerplate!
public static void helloWorldJsonSender(HttpServerExchange exchange) {
Exchange.body().sendJson(exchange, "{\"message\": \"Hello World\"}");
}