我最开始学习 Java web 编程是要去写一个 servlet, 重写里面的 service 方法,然后去配置 web.xml 文件,最后就是部署到 tomcat 或者 jetty 容器中并启动。后来就是使用一些框架,struts2 SpringMvc。今天我瞎翻 JDK 的源代码,发现可以用 com.sun.net.httpserver 包下提供的 API 很快速的创建 web 服务,它的创建方式和 golang 极其的类似。
HttpHandler
首先要实现 HttpHandler, 重写 handle 方法。
public class MyHandler implements HttpHandler {
@Override
public void handle(HttpExchange httpExchange) throws IOException {
}
}
创建 web 服务
创建 web 服务并注册前面创建的 handler,使用 handler 来处理请求。
public class Main {
public static void main(String[] args) {
try {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/web", new MyHandler());
// 使用默认的 excutor
server.setExecutor(null);
server.start();
} catch (IOException e) {
e.printStackTrace();
}
}
只要运行这个 main 方法,一个 web 服务就启动了,监听端口是 8000, 下面是我写了两个完整的例子。
GetHandler
package me.deweixu.handler;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import netscape.javascript.JSObject;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
/**
* Created by simeone
*
* @author: simeone
* @Date: 2018/5/19
*/
public class GetHandler implements HttpHandler {
@Override
public void handle(HttpExchange httpExchange) throws IOException {
System.out.println("Method: " + httpExchange.getRequestMethod());
String param = httpExchange.getRequestURI().getQuery();
System.out.println("Param:" + param);
httpExchange.sendResponseHeaders(200, 0);
OutputStream os = httpExchange.getResponseBody();
os.write(param.getBytes());
os.close();
}
}
PostHandler
package me.deweixu.handler;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
/**
* Created by simeone
*
* @author: simeone
* @Date: 2018/5/19
*/
public class PostHandler implements HttpHandler {
@Override
public void handle(HttpExchange httpExchange) throws IOException {
System.out.println("Method: " + httpExchange.getRequestMethod());
InputStream is = httpExchange.getRequestBody();
String response = is2string(is);
System.out.println("response: " + response);
is.close();
httpExchange.sendResponseHeaders(200, response.length());
Headers headers = httpExchange.getResponseHeaders();
headers.set("Content-Type", "application/json; charset=utf8");
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
private String is2string(InputStream is) throws IOException {
final int bufferSize = 1024;
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(is, "UTF-8");
for (; ; ) {
int rsz = in.read(buffer, 0, buffer.length);
if (rsz < 0)
break;
out.append(buffer, 0, rsz);
}
return out.toString();
}
}
Main
package me.deweixu;
import com.sun.net.httpserver.HttpServer;
import me.deweixu.handler.GetHandler;
import me.deweixu.handler.PostHandler;
import java.io.IOException;
import java.net.InetSocketAddress;
public class Main {
public static void main(String[] args) {
try {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/post", new PostHandler());
server.createContext("/get", new GetHandler());
server.setExecutor(null);
server.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试
# get
$ curl http://127.0.0.1:8000/get\?name\=simeone\&address\=beijing
name=simeone&address=beijing
# post
$ curl -H "Content-Type: application/json" -d '{"username":"simeone", "address":"beijing"}' http://127.0.0.1:8000/post
{"username":"simeone", "address":"beijing"}