Apache Tomcat,首先要明确他们之间的关系,Apache是web服务器,Tomcat是应用服务器(Servlet容器),可以认为是Apache的扩展,也就是说Servlet由Tomcat进行处理。
现在我们要通过Socket技术实现Apache Web服务器的一些功能,比如:
------->并发访问(应用线程池)
------->处理GET请求
------->处理POST请求
------->可以部署静态web页面
功能演示如下图:
程序如下,大致就是监听客户端请求,然后使用线程池处理客户端请求,判断请求方式,向客户端展现服务器默认页面。客户端可以进行POST表单提交,服务器接收并作出反馈。可以部署静态页面到服务器,放到webapps文件下即可,访问方式为/hello.html主要应用技术:IO、多线程、Socket。
/**
* MyTomcat,多线程服务器
*
* @version 0.1
* @author Syskey
*
*/
public class MyApacheTomcat {
public static void main(String[] args) {
// 初始化线程池
ExecutorService pool = Executors.newFixedThreadPool(3);
try {
ServerSocket server = new ServerSocket(8080);
while (true) {
Socket client = server.accept(); // 开始监听
String ip = client.getInetAddress().getHostAddress();
int port = client.getPort();
System.out.println("client [" + ip + "] ::" + port + ":: --- connected");
pool.execute(new ClientTask(client)); // 使用线程池处理客户端请求
}
} catch (IOException e) {
throw new RuntimeException("服务器异常终止");
}
}
}
/**
* 负责处理客户端请求的任务类
* @author Syskey
*
*/
class ClientTask implements Runnable {
private Socket client;
private BufferedReader reader;
private BufferedWriter out;
public ClientTask(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
String ip = client.getInetAddress().getHostAddress();
/* 接收请求信息 */
reader = new BufferedReader(new InputStreamReader(client.getInputStream(), "GBK"));
// 读取第一行,获取消息头中的请求地址跟请求方式(GET | POST)
String line = reader.readLine();
System.out.println(line);
String resource = ""; // 请求地址
String method = ""; // 请求方式
if(line != null && !"".equals(line)) {
resource = line.substring(line.indexOf("/"), line.lastIndexOf("/")-5);
method = getMethod(line);
}
System.out.println("resource=" + resource);
System.out.println("method=" + method);
//
int contentLength = 0; // POST数据长度
while((line = reader.readLine()) != null) {
if("".equals(line))
break;
// System.out.println(line);
if(line.startsWith("Content-Length")) { // 取得Content-Length
contentLength = Integer.parseInt(line.substring(line.indexOf(':') + 1).trim());
}
}
// 取得POST表单提交的内容
String content = "";
if(contentLength > 0 && method.equals("POST")) {
System.out.println("POST -------------------- POST");
char[] buf = new char[contentLength];
for(int i = 0; i < contentLength; i++) {
buf[i] = (char) reader.read();
}
content = new String(buf);
System.out.print(URLDecoder.decode(content, "GBK"));
System.out.println();
}
System.out.println("请求 -------------------- 结束\n");
/*
* 在这可以进行判断(resource),默认发送以下数据(服务器主页)。 否则要什么给什么,没有就404
*/
/* 发送消息给客户端 */
out = new BufferedWriter(new OutputStreamWriter(
client.getOutputStream(), "GBK"));
if(!resource.equals("/")) { //不是默认资源
File file = new File("src/webapps" + resource); // 资源文件
System.out.println(file.getAbsolutePath());
if (file != null && file.exists()) {
BufferedReader bufReader =
new BufferedReader(
new InputStreamReader(new FileInputStream(file), "GBK"));
String req_resource = null;
while((req_resource = bufReader.readLine()) != null) {
out.write(req_resource);
}
bufReader.close();
} else { // 请求资源不存在,报404
out.write("404:出错啦!!!!!!!出门左拐,回到服务器主页");
}
} else {
out.write("<html>");
out.write("<head>");
out.write("<title>");
out.write("我的网站");
out.write("</title>");
out.write("</head>");
out.write("<body>");
out.write("<center><h1>你好," + ip + ",欢迎来访</h1></center>");
out.write("<form action='#' method='post'>");
out.write("<input type='text' name='username' />");
out.write("用户名<br/>");
out.write("<input type='password' name='password' />");
out.write("密码");
out.write("<input type='submit' value='Submit' />");
out.write("</form>");
if(method.equals("POST") && !"".equals(content)) { // POST请求,并且表单有数据
setPostValue(content); // 保存进Map集合
out.write("您的用户名是:" + URLDecoder.decode(getPostValue("username"), "GBK")
+ "\t密码是: " + URLDecoder.decode(getPostValue("password"), "GBK"));
}
out.write("</body>");
out.write("</html>");
}
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null)
out.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private Map<String, String> map; // 存放POST键值对信息
/**
* 保存键值对信息到Map集合
* @param content 原始POST消息
*/
private void setPostValue(String content) {
// String urlRegex = "(^|&|\\?)"+ name + "=([^&]*)(&|$)";
// username=1111&password=111
String[] keyValues = content.split("&");
map = new HashMap<String, String>();
for(String s : keyValues) {
String[] keyValue = s.split("="); //username=1111
map.put(keyValue[0], keyValue[1]);
}
}
/**
* 获取参数值
* @param name 参数名
* @return 参数值
*/
private String getPostValue(String name) {
if (map != null && !map.isEmpty())
return map.get(name);
return "";
}
/**
* 获取请求方式
* @param line 消息头第一行
* @return POST | GET
*/
private String getMethod(String line) {
Pattern pattern = Pattern.compile("^(GET|POST)\\b");
Matcher m = pattern.matcher(line);
if(m.find())
return m.group();
return "";
}
}
原创文章,转载请注明出处: http://blog.csdn.net/thinking_in_android