http - simple server & client
程序员文章站
2022-06-05 18:20:48
...
Simple http server & client implementation by pure j2se.
http - client:
package eric.j2se.net.http; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.PrintWriter; import java.net.Socket; /** * <p> * A simple http client. * </p> * * @author eric * @date Jan 6, 2014 4:29:54 PM */ public class SimpleHttpClient { /** * send http request & get response, * * @param host * hostname or ip * @param path * path after host, format: "/xxx" * @param port * @return response string * @throws IOException * @throws InterruptedException */ public static String httpRequest(String host, String path, int port) throws IOException, InterruptedException { Socket client = new Socket(host, port); StringBuffer requestInfo = new StringBuffer(""); StringBuffer responseInfo = new StringBuffer(""); // prepare request info, requestInfo.append("GET " + path + " HTTP/1.1\n"); requestInfo.append("Host: " + host + "\n"); requestInfo.append("Connection: Close\n"); // send request, PrintWriter pw = new PrintWriter(client.getOutputStream(), true); pw.println(requestInfo.toString()); System.out.println("****** request - start ******"); System.out.println(requestInfo.toString()); System.out.println("****** request - end ******"); // get response info, LineNumberReader lnr = new LineNumberReader(new InputStreamReader(client.getInputStream())); String line; while ((line = lnr.readLine()) != null) { responseInfo.append(line + "\n"); } System.out.println("****** response - start ******"); System.out.println(responseInfo.toString()); System.out.println("****** response - end ******"); pw.close(); lnr.close(); client.close(); return responseInfo.toString(); } /****** test - start ******/ /** * test http request, */ public static void testHttpRequest() { try { httpRequest("localhost", "/index.html", 80); // sendRequest("www.google.com.hk", "/", 80); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { } /****** test - end ******/ }
http - server:
package eric.j2se.net.http; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Map; /** * <p> * A simple http server. * </p> * * @author eric * @date Jan 9, 2014 10:10:48 PM */ public interface HttpServer { /** * start server, */ void start(); /** * parse, get params, * * @param is * @return params * @throws IOException */ Map<String, String> parse(InputStream is) throws IOException; /** * read param from param string, * * @param paramStr * params string, format: name1=value1&name2=value2\ * @param isBody * whether the params from body, * * @return map of param key/value, */ Map<String, String> parseParam(String paramStr, boolean isBody); /** * send response * * @param os * @param paramMap */ void response(OutputStream os, Map<String, String> paramMap); /** * shutdown server, * * @throws IOException */ void terminate() throws IOException; }
package eric.j2se.net.http; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; /** * <p> * A simple http server implementation. * </p> * TODO ... add more feature * * @author eric * @date Jan 10, 2014 2:53:50 AM */ public class SimpleHttpServer implements HttpServer { private ServerSocket server; public SimpleHttpServer(int port, int backlog, String host) throws UnknownHostException, IOException { server = new ServerSocket(port, backlog, InetAddress.getByName(host)); } @Override public void start() { Socket socket = null; InputStream inStream = null; OutputStream outStream = null; Map<String, String> paramMap = null; while (true) { try { socket = server.accept(); // get input inStream = socket.getInputStream(); paramMap = parse(inStream); // paramMap = new HashMap(); // write output outStream = socket.getOutputStream(); response(outStream, paramMap); // close socket, this indicate the client that the response is finished, socket.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (inStream != null) { inStream.close(); } if (outStream != null) { outStream.close(); } if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } } @Override public Map<String, String> parse(InputStream is) throws IOException { Map<String, String> paramMap = new HashMap<String, String>(); LineNumberReader lr = new LineNumberReader(new InputStreamReader(is)); String inputLine = null; String method = null; String httpVersion = null; String uri = null; // read request line inputLine = lr.readLine(); String[] requestCols = inputLine.split("\\s"); method = requestCols[0]; uri = requestCols[1]; httpVersion = requestCols[2]; System.out.println("http version:\t" + httpVersion); // parse GET param if (uri.contains("?")) { paramMap.putAll(parseParam(uri.split("\\?", 2)[1], false)); } // read header while (StringUtils.isNotBlank(inputLine = lr.readLine())) { System.out.println("post header line:\t" + inputLine); } // read body - POST method if (method.toUpperCase().equals("POST")) { StringBuffer bodySb = new StringBuffer(); char[] bodyChars = new char[1024]; int len; // ready() make sure it will not block, while (lr.ready() && (len = lr.read(bodyChars)) > 0) { bodySb.append(bodyChars, 0, len); } paramMap.putAll(parseParam(bodySb.toString(), true)); System.out.println("post body:\t" + bodySb.toString()); } return paramMap; } @Override public Map<String, String> parseParam(String paramStr, boolean isBody) { String[] paramPairs = paramStr.trim().split("&"); Map<String, String> paramMap = new HashMap<String, String>(); String[] paramKv; for (String paramPair : paramPairs) { if (paramPair.contains("=")) { paramKv = paramPair.split("="); if (isBody) { // replace '+' to ' ', because in body ' ' is replaced by '+' automatically when post, paramKv[1] = paramKv[1].replace("+", " "); } paramMap.put(paramKv[0], paramKv[1]); } } return paramMap; } @Override public void response(OutputStream os, Map<String, String> paramMap) { String name = StringUtils.isBlank(paramMap.get("name")) ? "xxx" : paramMap.get("name"); PrintWriter pw = null; pw = new PrintWriter(os); pw.println("HTTP/1.1 200 OK"); pw.println("Content-type: text/html; Charset=UTF-8"); pw.println(""); pw.println("<h1>Hi <span style='color: #FFF; background: #000;'>" + name + "</span> !</h1>"); pw.println("<h4>current date: " + new Date() + "</h4>"); pw.println("<p>you can provide your name via a param called <span style='color: #F00; background: yellow;'>\"name\"</span>, in both GET and POST method.</p>"); pw.flush(); } @Override public void terminate() throws IOException { server.close(); } /****** test - start ******/ public static void main(String[] args) { testHttpServer(); } // test http server, public static void testHttpServer() { try { HttpServer server = new SimpleHttpServer(9090, 1, "localhost"); server.start(); } catch (IOException e) { e.printStackTrace(); } } /****** test - end ******/ }
推荐阅读
-
IBM HTTP Server 远程溢出漏洞
-
无法找到产品Microsoft SQL Server Native Client的安装程序包的解决方法Sqlncli.msi
-
Java虚拟机JVM之server模式与client模式的区别
-
HTTP_HOST 和 SERVER_NAME 的区别详解
-
无法找到产品Microsoft SQL Server Native Client的安装程序包的解决方法Sqlncli.msi
-
Node.js中的http请求客户端示例(request client)
-
python实现的udp协议Server和Client代码实例
-
HTTP 错误 500.19 - Internal Server Error解决办法详解
-
Python通过命令开启http.server服务器的方法
-
HTTP_HOST 和 SERVER_NAME 的区别详解