【计算机网络之HTTP协议详解】

本文详细介绍了HTTP协议的特点,包括简单快速、支持客户端和服务器通信、无连接及无状态等。接着讲解了HTTP报文的结构,请求方法如GET、POST、PUT和DELETE等,以及HTTP响应码的不同类别。还展示了使用Java的HttpURLConnection进行HTTP网络编程的示例,包括文件下载和调用后台接口。最后,给出了自定义HTTP服务器的简单实现。

超文本传输协议(Hyper Text Transfer Protocol)用于规范在网络中对文本数据的传输,属于应用层协议,底层是基于TCP/IP协议。

目录

HTTP协议的特点

HTTP报文

HTTP请求方法

HTTP的响应码

HTTP网络编程

URL

HttpURLConnection

自定义HTTP服务器


HTTP协议的特点

  1. 简单和快速

  2. 支持客户端和服务器之间的通信

  3. 无连接,一旦客户端完成访问后,和服务器的连接就会断开

  4. 无状态,服务器不会保留客户端的数据

  5. 采用请求和响应模式,客户端向服务器发送请求,服务器发送响应给浏览器。

HTTP报文

客户端访问服务器时会发生请求报文,

格式如下:

响应报文格式:

HTTP请求方法

  • GET 数据会包含在URL里,不安全,对数据的长度有限制,适合于进行查询和搜索

  • POST 数据在后台发送,更加安全,对数据长度没有限制,适合于发送敏感数据

  • PUT 更新服务器资源

  • DELETE 请求删除资源

  • TRACE 跟踪服务器信息

  • OPTIONS 允许查看服务器的性能

  • HEAD 用于获取报头

  • CONNECT 将连接改为管道方式的代理服务器

HTTP的响应码

服务器告诉浏览器的响应结果

代码说明
1xx消息请求已被服务器接收,继续处理
2xx成功请求已成功被服务器接收、理解、并接受
3xx重定向需要后续操作才能完成这一请求
4xx请求错误请求含有词法错误或者无法被执行
5xx服务器错误服务器在处理某个正确请求时发生错误

常见响应码:

代码说明
200OK 请求成功
400Bad Request 请求有语法错误
401Unauthorized 请求未经授权
403Forbidden 服务器拒绝提供服务
404Not Found 请求资源不存在
405Method Not Found 请求方法不存在
500Internal Server Error 服务器发生错误
503Server Unavailable 服务器不能处理

HTTP网络编程

URL

统一资源定位系统(Uniform Resource Locator)是网络上用于指定信息位置的表示方法。

创建方法

URL url = new URL("资源的地址");

主要方法

URLConnection openConnection() 打开网络连接

HttpURLConnection

http连接

主要方法

代码说明
void disconnect()关闭连接
setRequestMethod(String method)设置请求方法
int getResponseCode()返回响应码
void setConnectTimeout(long time)设置连接超时
void setRequestProperty(String key,String value)设置请求头属性
InputStream getInputStream()获得输入流
OutputStream getOutputStream()获得输出流
void setDoOutput(boolean output)设置是否发送数据
long getContentLength()获得资源的长度

实现文件下载

/**
 * http文件下载
 */
public class DownloadDemo {
​
    public static final String DIR = "D:\\files\\";
​
    public static void download(String path){
        try {
            //创建URL对象
            URL url = new URL(path);
            //打开连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //设置连接超时
            conn.setConnectTimeout(5000);
            //请求方法
            conn.setRequestMethod("GET");
            //获得输入流
            //创建文件输出流
            String filename = UUID.randomUUID().toString().replace("-","") + ".jpg";
            try(InputStream in = conn.getInputStream();
                FileOutputStream out = new FileOutputStream(DIR + filename)){
                byte[] bytes = new byte[1024];
                int len = -1;
                while((len = in.read(bytes)) != -1){
                    out.write(bytes,0,len);
                }
            }catch (IOException ex){
                ex.printStackTrace();
            }
            System.out.println("文件下载完成");
            Runtime.getRuntime().exec("mspaint " + DIR + filename);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    public static void main(String[] args) {
        download("https://gimg2.baidu.com/image_search/2Fb906fe02aa964cdd95bb10f106e45bcd.png");
    }
}

调用后台接口

public class HttpDemo {
​
    public static void testGet(String sUrl){
        try {
            URL url = new URL(sUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(2000);
            if(conn.getResponseCode() == 200){
                //从输入流中读取出响应数据
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = null;
                while((line = in.readLine()) != null){
                    System.out.println(line);
                }
                in.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    public static void testPost(String sUrl,String args){
        try {
            URL url = new URL(sUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setConnectTimeout(2000);
            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            //向服务器发送参数
            conn.setDoOutput(true);
            OutputStream out = conn.getOutputStream();
            out.write(args.getBytes("UTF-8"));
            if(conn.getResponseCode() == 200){
                //从输入流中读取出响应数据
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = null;
                while((line = in.readLine()) != null){
                    System.out.println(line);
                }
                in.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    public static void testPut(String sUrl,String args){
        try {
            URL url = new URL(sUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("PUT");
            conn.setConnectTimeout(2000);
            conn.setRequestProperty("Content-Type","application/json");
            //向服务器发送参数
            conn.setDoOutput(true);
            OutputStream out = conn.getOutputStream();
            out.write(args.getBytes("UTF-8"));
            if(conn.getResponseCode() == 200){
                //从输入流中读取出响应数据
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = null;
                while((line = in.readLine()) != null){
                    System.out.println(line);
                }
                in.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    public static void testDelete(String sUrl){
        try {
            URL url = new URL(sUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("DELETE");
            conn.setConnectTimeout(2000);
            if(conn.getResponseCode() == 200){
                //从输入流中读取出响应数据
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = null;
                while((line = in.readLine()) != null){
                    System.out.println(line);
                }
                in.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    public static void main(String[] args) {
//        testPost("http://localhost:8001/person","id=-1&name=world&age=25&gender=男");
//        testPut("http://localhost:8001/person","{\"id\":12,\"name\":\"hello1\",\"age\":22,\"gender\":\"女\"}");
        testDelete("http://localhost:8001/person/13");
        testGet("http://localhost:8001/persons");
    }
}

自定义HTTP服务器

/**
 * 自定义Http服务器
 */
public class HttpServer {
​
    public static final int PORT = 8088;
    public static final String DIR = "D:\\html\\";
    //启动
    public void start(){
        System.out.println("启动服务器");
        try(ServerSocket serverSocket = new ServerSocket(PORT)){
            while (true){
                //获得浏览器的连接
                Socket socket = serverSocket.accept();
                //通过IO流获得请求报文的第一行
                try(BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))){
                    String line = in.readLine();
                    //解析出url
                    String url = null;
                    if(line != null){
                        String[] lines = line.split(" ");
                        if(lines.length > 2){
                            url = lines[1];
                        }
                    }
                    //判断文件是否存在
                    File file = new File(DIR + url);
                    if(file.exists()){
                        //存在,读取html代码
                        BufferedReader reader = new BufferedReader(new FileReader(file));
                        StringBuilder html = new StringBuilder();
                        String str = null;
                        while((str = reader.readLine()) != null){
                            html.append(str);
                        }
                        reader.close();
                        //发送响应报文,带html代码
                        StringBuilder resp = new StringBuilder();
                        resp.append("HTTP/1.1 200 OK\r\n");
                        resp.append("Content-Type: text/html; charset=UTF-8\r\n");
                        resp.append("Content-Length: " + html.toString().getBytes("UTF-8").length+"\r\n");
                        resp.append("\r\n");
                        resp.append(html.toString());
                        out.write(resp.toString());
                    }else{
                        //不存在就发送404响应报文
                        out.write("HTTP/1.1 404 NOT FOUND");
                    }
                    out.flush();
                }catch (IOException ex){
                    ex.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    public static void main(String[] args) {
        new HttpServer().start();
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值