netty与http服务

http客户端

package httpClient;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by sff on 2017/10/10.
 */
public class HttpClientTest {

    public static void send(String url, String content) throws Exception{
        HttpClient httpClient = new HttpClient();
        httpClient.getParams().setContentCharset("UTF-8");
        PostMethod postMethod = new PostMethod(url);
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("Host", "****");
        headerMap.put("Accept-Encoding", "gzip");
        for (Map.Entry<String, String> entry : headerMap.entrySet()) {
            postMethod.addRequestHeader(entry.getKey(), entry.getValue());
        }
        StringRequestEntity entity = new StringRequestEntity(content, "text/plain", "UTF-8");
        postMethod.setRequestEntity(entity);
        try {
            int result = httpClient.executeMethod(postMethod);
            if (result == 200) {
                System.out.println("发送成功");
            } else{
                System.out.println("发送失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception{
        StringBuilder stringBuilder = new StringBuilder("发送内容:\n");
//        for(int i = 0; i < 1000; i++){
            stringBuilder.append(0).append(" ");
            for(int j = 0; j < 1000; j++){
                stringBuilder.append(j);
            }
            stringBuilder.append("\n");
//        }
        send("http://127.0.0.1:8088?", stringBuilder.toString());
    }
}

postMethod的setRequestEntity()方法是想post方法中放入参数,看requestEntity实现类有很多种


netty做http服务

netty

package httpServer;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
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.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
import logbus.agent.log.LogDefinition;
import logbus.agent.netty.codec.XDecoderFactory;
import logbus.agent.netty.codec.XEncoderFactory;
import logbus.agent.sink.Sink;
import logbus.agent.source.impl.server.netty.ServerSourceHandlerFactory;
import logbus.protocol.netty.XNetty;

import java.util.Map;

/**
 * http请求的netty服务器
 * Created by sff on 2017/10/9.
 */
public class HttpServerSourceNetty implements XNetty {
    /** 端口号 */
    private int port;

    // 分配用于处理事务的线程组数量
    protected static final int bisGroupSize = Runtime.getRuntime().availableProcessors();
    // 每个线程组中线程的数量
    protected static final int worGroupSize = 2;


    /**
     * 初始化
     * @param port
     * @param encrypt
     * @throws InterruptedException
     */
    public HttpServerSourceNetty(String groupName, String sourceName, int port, boolean encrypt) throws InterruptedException{
        this.port = port;
        try{
            start();
        } catch (InterruptedException e){
            String msg = new StringBuilder("name值为").append(sourceName).append(
                    "的source的server服务器开启失败").toString();
            LogDefinition.COMMON.error(msg, e);
            throw new InterruptedException(msg);
        }
    }

    @Override
    public void start() throws InterruptedException{
        EventLoopGroup boss = new NioEventLoopGroup(bisGroupSize);
        EventLoopGroup worker = new NioEventLoopGroup(worGroupSize);
        ServerBootstrap bootstrap = new ServerBootstrap();
        //group函数其实就是将parentGroup和ChildGroup进行赋值,其中parentGroup用于处理accept事件,ChildGroup用于处理accpt的Channel的IO事件。
        bootstrap.group(boss, worker);
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.option(ChannelOption.SO_BACKLOG, 128);
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception{
                ChannelPipeline p = socketChannel.pipeline();
                // server端发送的是httpResponse,所以要使用HttpResponseEncoder进行编码
                p.addLast(new HttpServerCodec());
                p.addLast("aggregator", new HttpObjectAggregator(64 * 1024 * 1024));
                p.addLast("chunkedWriter", new ChunkedWriteHandler());
                p.addLast(new HttpServerSourceHandlerFactory().getHandler());
            }
        });
        ChannelFuture f = bootstrap.bind(port).sync();
        if(f.isSuccess()){

        }
    }
    
}

netty处理的handler

package feedback.communicate.netty.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;

import java.net.HttpCookie;
import java.net.URI;
import java.util.List;
import java.util.Map;

/**
 * http server handler
 * Created by sff on 2018/4/20.
 */
public class HttpServerHandler extends ChannelInboundHandlerAdapter {

    public HttpServerHandler(){
        super();
    }

    private List<String> splitMultiCookies(String header) {
        List<String> cookies = new java.util.ArrayList<String>();
        int quoteCount = 0;
        int p, q;
        for (p = 0, q = 0; p < header.length(); p++) {
            char c = header.charAt(p);
            if (c == '"') quoteCount++;
            if (c == ';' && (quoteCount % 2 == 0)) {
                // it is comma and not surrounding by double-quotes
                cookies.add(header.substring(q, p));
                q = p + 1;
            }
        }
        cookies.add(header.substring(q));
        return cookies;
    }

    /**
     * 接收get请求的数据
     * @param ctx
     * @param msg
     */
    public void handler(ChannelHandlerContext ctx, Object msg) throws Exception{
        if (msg instanceof HttpRequest) {
            System.out.println("###################");
            FullHttpRequest request = (FullHttpRequest) msg;
            // 收取cookie
            String cookieHeader = request.headers().get(HttpHeaderNames.COOKIE);
            List<String> cookieStrs = splitMultiCookies(cookieHeader);
            for(int i = 0; i < cookieStrs.size(); i++) {
                List<HttpCookie> list = HttpCookie.parse(cookieStrs.get(i));
                for (int j = 0; j < list.size(); j++) {
                    System.out.println(list.get(j).toString());
                }
            }
            // if GET Method: should not try to create a HttpPostRequestDecoder
            if (request.method().equals(HttpMethod.GET)) {
                URI uri = new URI(request.uri());
                QueryStringDecoder decoderQuery = new QueryStringDecoder(request.getUri());
                Map<String, List<String>> uriAttributes = decoderQuery.parameters();
                System.out.println("GET内容:" + uri.getQuery());
            }
            //判断request请求是否是post请求
            if (request.method().equals(HttpMethod.POST)) {
                ByteBuf content = request.content();
                byte[] req = new byte[content.readableBytes()];
                content.readBytes(req);
                String resultStr = new String(req, "UTF-8");
                System.out.println("POST内容:" + resultStr);
                content.release();
            } else{
                request.release();
            }
            // 发送消息
            String r = "sff is a good man.";
            ByteBuf bf = ByteBufAllocator.DEFAULT.buffer(8*1024);
            bf.writeBytes(r.getBytes());
            HttpHeaders httpHeaders = new DefaultHttpHeaders();
            HttpCookie cookie1 = new HttpCookie("feedback", "sff");
            cookie1.setHttpOnly(true);
            HttpCookie cookie2 = new HttpCookie("session_id", "123456");
            HttpCookie cookie3 = new HttpCookie("tenant", "STULIB");
            httpHeaders.add(HttpHeaderNames.SET_COOKIE, cookie1); // add 是可以添加同名的对象,set会把同名的对象覆盖掉
            httpHeaders.add(HttpHeaderNames.SET_COOKIE, cookie2);
            httpHeaders.add(HttpHeaderNames.SET_COOKIE, cookie3);
            httpHeaders.set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            httpHeaders.set(HttpHeaderNames.CONTENT_LENGTH, bf.readableBytes());
            httpHeaders.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, bf);
            response.headers().set(httpHeaders);
            ctx.writeAndFlush(response);
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        handler(ctx, msg);
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // ignore
    }
}

FullHttpRequest的类里面可以查询header,body等数据


参考:Netty处理HTTP之GET,POST请求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值