诸如tomcat等web服务器中间件简化了我们web的开发成本,但有时候我们或许并不需要这么一个完备的服务器,只是希望做一个简单地处理或者做特殊用途的服务器。
本文将提供一个HTTP的服务器示例,采用Java的ServerSocket进行编码。随着计算机硬件的提升,以及Java地不断优化,使用Java网络编程实现web服务器在实际性能上已经开始可以跟C进行竞争。
以下代码分为两块:
1)HttpServer:主要包含一个ServerSocket,用于接收客户端请求。并通过线程池将请求从主线程剥离,分散到各个线程中去处理;
2)RequestHandler:实现了Runnable接口,将获取一个线程来处理各个请求;流的读取和响应遵循HTTP协议。
注意:编写Http服务器和一般的socket程序并没有太大不同,但是你需要遵循HTTP协议,这样对于采用HTTP协议的客户端或者其它服务器就可以直接进行HTTP请求来通讯。
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
/**
* Http服务器端示例,端口设置为8080,编码设置为UTF-8
* @author lay
* @date 2019-01-01
*/
public class HttpServer {
private static final int port = 8080;
/**
* 启动HTTP服务器
*/
public void start() throws IOException {
// 初始化线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
// 初始化服务器socket
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("ServerSocket启动完成");
while (true) {
// 阻塞等待socket连接
System.out.println("等待socket");
Socket socket = serverSocket.accept();
// 提交至线程池处理
executor.submit(new RequestHandler(socket));
System.out.println("提交线程池处理请求");
}
}
public static void main(String[] args) {
try {
new HttpServer().start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
import java.io.*;
import java.net.Socket;
/**
* 请求处理类
* @author lay
* @date 2019-01-01
*/
public class RequestHandler implements Runnable {
/**
* HTTP响应头
*/
private static final String response = "http/1.1 200 ok";
private static final String splitStr = "\r\n";
private Socket socket;
private BufferedReader reader;
private BufferedWriter writer;
public RequestHandler(Socket socket) throws IOException {
this.socket = socket;
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
}
/**
* 响应结果
* @param content 响应内容
* @throws IOException IO异常抛出
*/
public void sendResponse(String content) throws IOException {
writer.write(String.format("%s%s", response, splitStr));
writer.write(splitStr);
writer.write(content);
}
/**
* 获得请求
* @return 请求文本
* @throws IOException IO异常抛出
*/
public String getRequest() throws IOException {
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(splitStr);
// 空字符串
if (line.isEmpty()) {
break;
}
}
System.out.println("request:\r\n" + stringBuilder);
return stringBuilder.toString();
}
@Override
public void run() {
try {
String request = getRequest();
// 这里直接把请求数据响应回去
sendResponse(request);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
请求处理器这里直接将请求的HTTP内容返回回去了,如果你使用浏览器请求8080端口,你会看到如下内容:
不过浏览器会默认请求一个icon,所以针对一个URL地址会有两个请求
你可以在ico请求的时候返回一个二进制的ico文件流,它将显示在浏览器的tab上。
1)我们可以像tomcat一样去支持Java Servlet API
2)支持如GET、POST、PUT、DELETE等restful请求
3)将程序配置进行XML配置
4)增加管理界面
5)请求跟踪处理
6)缓存、非阻塞IO、通道来增加性能
来自:https://www.cnblogs.com/lay2017/p/10206505.html
Java 创建于 1995 年,目前有 134861 个网站使用 Java,如 ESPN、SnapDeal、阿里巴巴等。在其 24 年的发展历程中,Java 已经证明了自己是用于自定义软件开发的顶级通用编程语言
JSP和JSF这两种技术都基于Java,主要用于基于Web的应用程序。那么它们之间有什么区别?下面本篇文章就来给大家简单比较一下JSP和JSF,介绍JSP和JSF之间的区别有哪些,希望对大家有所帮助。
Java世界中存在许多工具,从Eclipse,NetBeans和IntelliJ IDEA等著名的IDE开始到Java开发人员应该知道的JVM分析和监视工具,如JConsole,VisualVM,Eclipse Memory Analyzer等。
本文是基于Java 8的HashMap进行分析,主要是介绍HashMap中的成员变量和类变量的用途,以及分析HashMap的数据结构。在HashMap中存在多个成员变量和类变量,搞清楚它们的用途有助于我们更深入了解HashMap,下面是它们的介绍:
执行完这条语句后,我们就会得到 id 为 1 的用户信息。那么对于这一条 SQL 语句,MySQL服务器做了哪些处理呢?这篇文章我们就一起打卡 MySQL 数据库中对 SQL 语句的处理逻辑。
代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。
拦截器功在对请求权限鉴定方面确实很有用处,在我所参与的这个项目之中,第三方的远程调用每个请求都需要参与鉴定,所以这样做非常方便,而且他是很独立的逻辑,这样做让业务逻辑代码很干净
泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
Java 堆空间:发生频率:5颗星造成原因1、无法在 Java 堆中分配对象 2、吞吐量增加 3、应用程序无意中保存了对象引用,对象无法被 GC 回收 4、应用程序过度使用 finalizer
在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得更多职位,那么你应该准备很多关于多线程的问题。面试官会问面试者很多令人混淆的Java线程问题
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!