子曰:“弟子,入则孝,出则弟,谨而信,凡爱众,而亲仁。行有余力,则以学文。”
为了更好的理解netty框架,所以就自己写了一个http服务器(少了一个session)
1 Http解码器和编码器
1 .1 http解码器接口
import java.io.BufferedReader;
import java.io.IOException;
public interface HttpDecode {
String decode(BufferedReader reader) throws IOException, Exception;
}
1.2 http编码器接口
import java.io.IOException;
import java.io.OutputStream;
public interface HttpEncode {
String encode(OutputStream out) throws IOException;
}
2 实现Http请求和响应 (request和response)
2.1 实现HttpRequest
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
public class HttpRequest {
private String requestLine;
private RequestHeader header;
private Map keyValue;
private String body;
public static final String GET = "GET";
public static final String POST = "POST";
//静态文件
private String resources;
public String getUri(){
String uris = requestLine.split(" ")[1];
if(uris.indexOf("?") != -1){
return uris.split("\\?")[0];
}else{
return uris;
}
}
/**
* 获取参数
* @return
*/
public String getParameter(String key) {
try {
if(keyValue.get(key) != null && !keyValue.get(key).equals("")){
return URLDecoder.decode(keyValue.get(key),"UTF-8");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
/**
* 初始化map
* @return
*/
public Map initMap(){
keyValue = new HashMap();
return keyValue;
}
public void removeMap(){
keyValue = null;
}
public String getRequestLine() {
return requestLine;
}
public void setRequestLine(String requestLine) {
this.requestLine = requestLine;
}
public RequestHeader getHeader() {
return header;
}
public void setHeader(RequestHeader header) {
this.header = header;
}
public String getResources() {
return resources;
}
public void setResources(String resources) {
this.resources = resources;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
2.2实现HttpResponse
public class HttpResponse {
private String write;
public String getWrite() {
return write;
}
public void setWrite(String write) {
this.write = write;
}
}
3 解析请求和响应
3.1 解析请求HttpRequestDecoder
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Method;
public class HttpRequestDecoder implements HttpDecode {
@Override
public String decode(BufferedReader reader) throws IOException, Exception{
if(reader != null){
HttpRequest request = Server.request;
request.setRequestLine(reader.readLine());
Class> clazz = Class.forName("com.wpixel.http.RequestHeader");
Object requestHeader = clazz.newInstance();
String str = "";
while((str = reader.readLine().trim()) != null && !str.trim().equals("")){
String[] split = str.split(": ");
String key = "set"+split[0].replaceAll("-", "");
Method method = clazz.getMethod(key, String.class);
method.invoke(requestHeader, split[1]);
}
Method method = clazz.getMethod("getContentLength");
String len = (String)method.invoke(requestHeader);
String body = "";
int g = 1;
if(len != null){
for (int i = 0; i < Integer.valueOf(len); i++) {
body += (char) reader.read();
}
}
request.setBody(body.toString());
Server.request.setHeader((RequestHeader)requestHeader);
}
return null;
}
}
3.2响应编码HttpResponseEncoder
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
public class HttpResponseEncoder implements HttpEncode {
@Override
public String encode(OutputStream out) throws IOException{
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Content-Type: text/html;charset=utf-8\r\n".getBytes());
out.write("Connection: Keep-Alive\r\n".getBytes());
out.write("\r\n".getBytes());
File file = new File(Server.response.getWrite());
InputStream in = new FileInputStream(file);
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
byte[] buffer = new byte[(int)(file.length())];
int len = 0;
while ((len = in.read(buffer)) != -1) {
byteOut.write(buffer, 0, len);
}
out.write(buffer);
return null;
}
}
4 定义一个http请求头demo类
public class RequestHeader {
private String host;
private String connection;
private String contentLength;
private String cacheControl;
private String accept;
private String origin;
private String upgradeInsecureRequests;
private String userAgent;
private String contentType;
private String referer;
private String acceptEncoding;
private String acceptLanguage;
private String pragma;
public String getContentLength() {
return contentLength;
}
public void setContentLength(String contentLength) {
this.contentLength = contentLength;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getReferer() {
return referer;
}
public void setReferer(String referer) {
this.referer = referer;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getConnection() {
return connection;
}
public void setConnection(String connection) {
this.connection = connection;
}
public String getCacheControl() {
return cacheControl;
}
public void setCacheControl(String cacheControl) {
this.cacheControl = cacheControl;
}
public String getAccept() {
return accept;
}
public void setAccept(String accept) {
this.accept = accept;
}
public String getUpgradeInsecureRequests() {
return upgradeInsecureRequests;
}
public void setUpgradeInsecureRequests(String upgradeInsecureRequests) {
this.upgradeInsecureRequests = upgradeInsecureRequests;
}
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public String getAcceptEncoding() {
return acceptEncoding;
}
public void setAcceptEncoding(String acceptEncoding) {
this.acceptEncoding = acceptEncoding;
}
public String getAcceptLanguage() {
return acceptLanguage;
}
public void setAcceptLanguage(String acceptLanguage) {
this.acceptLanguage = acceptLanguage;
}
public String getPragma() {
return pragma;
}
public void setPragma(String pragma) {
this.pragma = pragma;
}
}
5 定义一个数据传输通道
public class InitChannel {
static SocketChannel channel = null;
public InitChannel() {
}
protected void initSocketChannel(SocketChannel channel) throws Exception {
}
}
6 定义通道接口
public interface HttpSimpleHeader {
public void httpWrite() throws Exception;
}
7 整合http请求的业务处理 (get和post)
import java.util.Map;
public class SendAndRev implements HttpSimpleHeader {
@Override
public void httpWrite() throws Exception {
//初始化参数
Map initMap = Server.request.initMap();
String method = Server.request.getRequestLine().split(" ")[0];
if(method.equals(HttpRequest.GET)){
String path = Server.request.getRequestLine().split(" ")[1];
String[] split = path.split("\\?");
if(split.length > 1){
String parameter = split[1];
String[] parameters = parameter.split("\\&");
if(parameters.length != 0){
for (String string : parameters) {
if(string.split("=").length > 1){
initMap.put(string.split("\\=")[0], string.split("\\=")[1]);
}
}
}
}
Servlet.doGet(Server.request, Server.response);
}else if(method.equals(HttpRequest.POST)){
String body = Server.request.getBody();
String[] parameters = body.split("\\&");
if(parameters.length != 0){
for (String string : parameters) {
if(string.split("=").length > 1){
initMap.put(string.split("\\=")[0], string.split("\\=")[1]);
}
}
}
Servlet.doPost(Server.request, Server.response);
}
}
}
8 定义TCP连接
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServerBootstrap {
ServerSocket server = null;
InitChannel initChannel = null;
//使用线程池
ExecutorService threadPool = null;
public ServerBootstrap(){
threadPool = Executors.newFixedThreadPool(4);
}
public void childHandler(InitChannel initChannel) throws IOException{
this.initChannel = initChannel;
}
public void bind(int port) throws IOException{
server = new ServerSocket(port);
}
public void accept() throws Exception{
while(true){
Socket socket = server.accept();
Runnable runnable = () -> {
InputStream in = null;
OutputStream out = null;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
initChannel.initSocketChannel(new SocketChannel(in, out));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"结束");
};
threadPool.execute(runnable);
}
}
}
9 定义TCP通道
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
public class SocketChannel {
private InputStream in;
private OutputStream out;
public SocketChannel(InputStream in, OutputStream out){
this.in = in;
this.out = out;
}
//编码器
public void addEncode(HttpEncode encoder) throws IOException{
encoder.encode(out);
}
//解码器
public void addDecode(HttpDecode decoder) throws Exception{
decoder.decode(new BufferedReader(new InputStreamReader(in)));
}
public void addServer(HttpSimpleHeader header) throws Exception{
header.httpWrite();
}
}
10 servlet请求入口
import java.io.UnsupportedEncodingException;
public class Servlet {
public static void doGet(HttpRequest request, HttpResponse response) {
System.out.println("doGet");
String name3 = request.getParameter("name3");
String name4 = request.getParameter("name4");
System.out.println("name3:"+name3+";name4:"+name4);
response.setWrite(System.getProperty("user.dir")+request.getUri());
}
public static void doPost(HttpRequest request, HttpResponse response) throws UnsupportedEncodingException {
System.out.println("doPost");
String name1 = request.getParameter("name1");
String name2 = request.getParameter("name2");
System.out.println("name1:"+name1+";name2:"+name2);
response.setWrite(System.getProperty("user.dir")+request.getUri());
}
}
11 http服务启动类
public class Server {
public static HttpRequest request = null;
public static HttpResponse response = null;
public static ServerBootstrap bootstrap = null;
static{
request = new HttpRequest();
response = new HttpResponse();
}
public static void main(String[] args) {
System.out.println("启动服务器;端口8080!!!!!");
try {
bootstrap = new ServerBootstrap();
bootstrap.childHandler(new InitChannel(){
@Override
protected void initSocketChannel(SocketChannel sc) throws Exception {
sc.addDecode(new HttpRequestDecoder());
sc.addServer(new SendAndRev());
sc.addEncode(new HttpResponseEncoder());
}
});
bootstrap.bind(8080);
bootstrap.accept();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
12 新建一个网页 index.html
首页
This is my HTML page.
-----------------静态资源----------------------
-----------------post请求-----------------------
-----------------get请求-----------------------
总结
作者是一名自由程序员,住在上海,喜欢音乐、小说、旅行、以及编程。
P.S. 如果您喜欢这篇文章并且希望学习编程技术的话,请关注一下