http - simple server & client

10240 단어 server
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
"); requestInfo.append("Host: " + host + "
"); requestInfo.append("Connection: Close
"); // 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 + "
"); } 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 ******/
}

 

좋은 웹페이지 즐겨찾기