65.9K
CodeProject 正在变化。 阅读更多。
Home

用Java创建简单Web服务器 (1) - HTTP服务器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (7投票s)

2015年10月15日

CPOL

2分钟阅读

viewsIcon

229443

downloadIcon

4456

使用Java SDK创建一个简单的Http服务器并处理GET/POST请求

引言

本技巧介绍了一个简单的HTTP服务器类,您可以将其合并到您自己的项目中,它可以在本地工作或处理有限的并发请求。

背景

Http服务器绑定到一个IP地址和端口号,并监听传入的请求,然后向客户端返回响应。 简单的http服务器可以灵活地添加到复杂项目中,用于渲染HTML元素或充当后端服务器,甚至可以部署在客户端以驱动特定设备。 如果您正在寻找一个解决方案来创建一个简单的HTTP服务器,该服务器可以轻松嵌入到您的项目中并处理有限的Web请求,那么本技巧可以满足您的需求。

这是Http服务器实现的结构

Using the Code

自Java 1.6起,J2EE SDK中包含了一个内置的HTTP服务器。 可以在以下位置下载

可以使用四个步骤将一个简单的HTTP服务器添加到Java程序中

  • 构造一个HTTP服务器对象
  • 将一个或多个HTTP处理程序对象附加到HTTP服务器对象
  • 实现HTTP处理程序以处理GET/POST请求并生成响应
  • 启动HTTP服务器

1. 创建一个http服务器

HttpServer类提供了一个简单的高级Http服务器API,可用于构建嵌入式HTTP服务器。

int port = 9000;
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
System.out.println("server started at " + port);
server.createContext("/", new RootHandler());
server.createContext("/echoHeader", new EchoHeaderHandler());
server.createContext("/echoGet", new EchoGetHandler());
server.createContext("/echoPost", new EchoPostHandler());
server.setExecutor(null);
server.start();

2. 创建http处理程序

Http处理程序与http服务器关联以处理请求。 每个HttpHandler都注册一个上下文路径,该路径表示此服务器上的服务位置。 对已定义的URI路径的请求将映射到正确的http处理程序。 找不到处理程序的任何请求都将使用404响应拒绝。

创建根处理程序以显示服务器状态

public class RootHandler implements HttpHandler {

         @Override

         public void handle(HttpExchange he) throws IOException {
                 String response = "<h1>Server start success 
                 if you see this message</h1>" + "<h1>Port: " + port + "</h1>";
                 he.sendResponseHeaders(200, response.length());
                 OutputStream os = he.getResponseBody();
                 os.write(response.getBytes());
                 os.close();
         }
}

声明echoHeader处理程序以显示请求标头信息

public class EchoHeaderHandler implements HttpHandler {

         @Override
         public void handle(HttpExchange he) throws IOException {
                 Headers headers = he.getRequestHeaders();
                 Set<Map.Entry<String, List<String>>> entries = headers.entrySet();
                 String response = "";
                 for (Map.Entry<String, List<String>> entry : entries)
                          response += entry.toString() + "\n";
                 he.sendResponseHeaders(200, response.length());
                 OutputStream os = he.getResponseBody();
                 os.write(response.toString().getBytes());
                 os.close();
         }}

3. 处理Get和Post请求

客户端和服务器之间通过HTTP协议进行请求-响应有两种常用方法

  • GET - 从指定资源请求数据
  • POST - 提交要处理的数据到已识别的资源

在这里,您创建两个处理程序分别处理GET/POST方法。

声明echoGet处理程序以处理Get请求

public class EchoGetHandler implements HttpHandler {

         @Override

         public void handle(HttpExchange he) throws IOException {
                 // parse request
                 Map<String, Object> parameters = new HashMap<String, Object>();
                 URI requestedUri = he.getRequestURI();
                 String query = requestedUri.getRawQuery();
                 parseQuery(query, parameters);

                 // send response
                 String response = "";
                 for (String key : parameters.keySet())
                          response += key + " = " + parameters.get(key) + "\n";
                 he.sendResponseHeaders(200, response.length());
                 OutputStream os = he.getResponseBody();
                 os.write(response.toString().getBytes());

                 s.close();
         }
}

声明echoPost处理程序以处理Post请求

public class EchoPostHandler implements HttpHandler {

         @Override

         public void handle(HttpExchange he) throws IOException {
                 // parse request
                 Map<String, Object> parameters = new HashMap<String, Object>();
                 InputStreamReader isr = new InputStreamReader(he.getRequestBody(), "utf-8");
                 BufferedReader br = new BufferedReader(isr);
                 String query = br.readLine();
                 parseQuery(query, parameters);

                 // send response
                 String response = "";
                 for (String key : parameters.keySet())
                          response += key + " = " + parameters.get(key) + "\n";
                 he.sendResponseHeaders(200, response.length());
                 OutputStream os = he.getResponseBody();
                 os.write(response.toString().getBytes());
                 os.close();
         }
}

在这里,您声明一个static parseQuery()方法来解析请求参数

public static void parseQuery(String query, Map<String, 
	Object> parameters) throws UnsupportedEncodingException {

         if (query != null) {
                 String pairs[] = query.split("[&]");
                 for (String pair : pairs) {
                          String param[] = pair.split("[=]");
                          String key = null;
                          String value = null;
                          if (param.length > 0) {
                          key = URLDecoder.decode(param[0], 
                          	System.getProperty("file.encoding"));
                          }

                          if (param.length > 1) {
                                   value = URLDecoder.decode(param[1], 
                                   System.getProperty("file.encoding"));
                          }

                          if (parameters.containsKey(key)) {
                                   Object obj = parameters.get(key);
                                   if (obj instanceof List<?>) {
                                            List<String> values = (List<String>) obj;
                                            values.add(value);

                                   } else if (obj instanceof String) {
                                            List<String> values = new ArrayList<String>();
                                            values.add((String) obj);
                                            values.add(value);
                                            parameters.put(key, values);
                                   }
                          } else {
                                   parameters.put(key, value);
                          }
                 }
         }
}

4. 测试http服务器

/ 显示服务器状态,由RootHandler处理

/echoHeader显示标头信息,由EchoHeaderHandler处理。

/echoGetEchoGetHandler处理

/echoPostEchoPostHandler处理。

历史

  • 2015年10月15日:发布初始版本
  • 2015年10月19日:添加服务器测试
  • 2015年10月23日:更新源代码
© . All rights reserved.