美文网首页
第4讲 HTTP请求

第4讲 HTTP请求

作者: 农民工进城 | 来源:发表于2018-05-14 13:44 被阅读0次

本章要点:

  • HTTP协议介绍
  • Netty HTTP入门开发
  • HTTP+XML应用开发
  • HTTP附件处理

4.1 HTTP协议介绍

HTTP即超文本传输协议,是建立在TCP传输协议之上的应用层协议。
其主要有以下特点:

  • 支持Client/Server模式
  • 简单:客户想服务器请求服务是,只能指定服务的URL,携带必要的请求参数或者消息体
  • 灵活:HTPP允许任何类型的参数对象,传输内容的类型有请求头Content-Type加以标记
  • 无状态:HTTP协议是无状态的,无状态是指协议对于事务处理没有记忆能力。

HTTP 请求包括以下三个部分:HTTP请求行、HTTP消息头、HTTP请求正文;方法有:GET、POST、PUT、DELETE等。同样HTTP 的响应也包括三个部分:状态行、消息报头、响应正文。

4.2 Netty HTTP入门开发

HttpServer 代码如下:

package com.bj58.wuxian.http;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;

public class HttpServer {
    public static void main(String[] args) {
        EventLoopGroup bossGroup=new NioEventLoopGroup();
        EventLoopGroup workerGroup=new NioEventLoopGroup();
        
        try {
            ServerBootstrap bootstrap=new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer<SocketChannel>() {

                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    //server端发送的是httpResponse,所以要使用HttpResponseEncoder进行编码
                    ch.pipeline().addLast(new HttpResponseEncoder());
                    // server端接收到的是httpRequest,所以要使用HttpRequestDecoder进行解码
                    ch.pipeline().addLast(new HttpRequestDecoder());
                    ch.pipeline().addLast(new HttpObjectAggregator(1024));
                    ch.pipeline().addLast(new HttpServerHanlder());
                }
            }).option(ChannelOption.SO_BACKLOG, 128)
            .childOption(ChannelOption.SO_KEEPALIVE, true);
            
            ChannelFuture f = bootstrap.bind(9999).sync();
            f.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    
    }
}

HttpServerHanlder代码:

package com.bj58.wuxian.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;

public class HttpServerHanlder extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("*********已连接*********");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         HttpRequest httpRequest = null;
         
        if (msg instanceof HttpRequest) {
            httpRequest = (HttpRequest) msg;
            System.out.println(httpRequest.uri());
        }

        if (msg instanceof HttpContent) {
            HttpContent httpContent = (HttpContent) msg;
            ByteBuf buf = httpContent.content();
            System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));
            buf.release();

            String res = "I am OK";
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK,
                    Unpooled.wrappedBuffer(res.getBytes("UTF-8")));
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
            response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            ctx.writeAndFlush(response);
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

}

HttpClient 代码如下:

package com.bj58.wuxian.http;

import java.net.URI;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;
import io.netty.handler.codec.http.HttpVersion;

public class HttpClient {

    public static void main(String[] args) {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(workerGroup).channel(NioSocketChannel.class).option(ChannelOption.SO_KEEPALIVE, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // 客户端接收到的是httpResponse响应,所以要使用HttpResponseDecoder进行解码
                            ch.pipeline().addLast(new HttpResponseDecoder());
                            // 客户端发送的是httprequest,所以要使用HttpRequestEncoder进行编码
                            ch.pipeline().addLast(new HttpRequestEncoder());
                            ch.pipeline().addLast(new HttpObjectAggregator(1024));
                            ch.pipeline().addLast(new HttpClientHandler());
                        }
                    });
            ChannelFuture f = bootstrap.connect("127.0.0.1", 9999).sync();

            URI uri = new URI("http://127.0.0.1:9999");
            String msg = "Are you ok?";
            DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
                    uri.toASCIIString(), Unpooled.wrappedBuffer(msg.getBytes("UTF-8")));

            // 构建http请求
            request.headers().set(HttpHeaderNames.HOST, "127.0.0.1");
            request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            request.headers().set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes());
            // 发送http请求
            f.channel().write(request);
            f.channel().flush();
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
}

HttpClientHandler 代码如下:

package com.bj58.wuxian.http;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponse;

public class HttpClientHandler extends ChannelInboundHandlerAdapter {

     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         System.out.println("**********client channelRead*********");
            if (msg instanceof HttpResponse) 
            {
                HttpResponse response = (HttpResponse) msg;
                System.out.println("CONTENT_TYPE:" + response.headers().get(HttpHeaderNames.CONTENT_TYPE));
            }
            if(msg instanceof HttpContent)
            {
                HttpContent content = (HttpContent)msg;
                ByteBuf buf = content.content();
                System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));
                buf.release();
            }
        }
}

HttpObjectAggregator解码器,它的作用是将多个消息转换成为单一的FullHttpRequest或者FullHttpResponse,原因是Http解码器在每个HTTP消息中会生成多个消息对象:

  • HTTPRequest/HttpResponse
  • HttpContent
  • LastHttpContent

**************未完待续******************

相关文章

  • 第4讲 HTTP请求

    本章要点: HTTP协议介绍 Netty HTTP入门开发 HTTP+XML应用开发 HTTP附件处理 4.1 H...

  • ajax

    记住readyState 4 整个请求过程已经完毕HTTP第4部分是字符串 客户端的JS发起请求(浏览器上的)...

  • http报文包含什么,以及如何查看

    HTTP请求包含4个部分 1.请求行 GET /3d-login/ HTTP/2 包含请求方法,路径,HTTP版本...

  • http请求知识

    HTTP 请求报文 HTTP 请求报文由请求行、请求头部、空行 和 请求包体 4 个部分组成,如下图所示: 常用的...

  • 《图解HTTP》- HTTP 首部 - 学习笔记(四)

    第6章 HTTP 首部 6.1 HTTP 报文首部 HTTP 请求报文在请求中,HTTP 报文由方法、URI、HT...

  • HTTP

    HTTP请求报文:1.请求行2.请求头3.请求空行4.请求体 HTTP响应报文:1.状态码2.响应头3.响应空行4...

  • JAVA服务通过URL下载文件

    概述 如何通过Java发送HTTP请求,通俗点讲,如何通过Java(模拟浏览器)发送HTTP请求。 Java有原生...

  • http请求与响应入门

    一、HTTP 请求: HTTP 请求的格式: 第1部分: 动词 路径 协议/版本 第2部分:Key1: value...

  • Pyhton网络请求库——urllib库

    Python内置HTTP请求库之urllib 其中包含的4个模块: -request:最基本的HTTP请求模块,用...

  • http 到 web 服务器链接过程

    1、建立连接 tcp 2、发送请求 http (header、cookie) 3、接收请求 4、处理请求 5、建立...

网友评论

      本文标题:第4讲 HTTP请求

      本文链接:https://www.haomeiwen.com/subject/xmlgrftx.html