基于http协议实现netty客户端与tomcat之间的通信

平常我们都是使用netty搭建客户端以及搭建netty服务端实现通信,其实我们也可以使用netty搭建基于http协议的客户端实现与tomcat的通信。

代码案例:

服务端代码,本质就是一个对外发布的controller
package com.syx.controller;

import com.syx.entity.User;
import com.syx.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    UserService userService;

    @RequestMapping("/users")
    public Map<String,Object> findAllUser()
    {
        Map<String,Object> result = new HashMap<>();
        List<User> data = userService.findAllUser();
        result.put("returnCode","OK");
        result.put("IP",IpAddress());
        result.put("data",data);
        return result;
    }

    @RequestMapping("/findUser/{id}")
    public Map<String,Object> findUserById(@PathVariable String id){
        Map<String,Object> result = new HashMap<>();
        User data = userService.findUserById(id);
        result.put("returnCode","OK");
        result.put("IP",IpAddress());
        result.put("data",data);
        return result;
    }


    private static String IpAddress(){
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            return localHost.getHostAddress();
        }catch (UnknownHostException e){
            e.printStackTrace();
            return null;
        }
    }
 
}

客户端代码,基于http协议的netty客户端
package com.syx.client;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
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.*;
import io.netty.util.CharsetUtil;
import java.util.Map;

public class HttpClient {

    private int PORT;

    private String HOST;


    public HttpClient(int PORT, String HOST) {
        this.PORT = PORT;
        this.HOST = HOST;
    }

    public Map<String,Object> start(String uri) throws InterruptedException {
        //线程组
        EventLoopGroup group = new NioEventLoopGroup();

        //自定义处理器
        ClientHandler clientHandler = new ClientHandler(uri);
        try {
            //启动类
            Bootstrap bootstrap = new Bootstrap();

            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    //长连接
                    .option(ChannelOption.SO_KEEPALIVE, true)

                    .handler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel channel) throws Exception {

                            //包含编码器和解码器
                            channel.pipeline().addLast(new HttpClientCodec());

                            //聚合
                            channel.pipeline().addLast(new HttpObjectAggregator(1024 * 10 * 1024));

                            //解压
                            channel.pipeline().addLast(new HttpContentDecompressor());


                            channel.pipeline().addLast(clientHandler);
                        }
                    });

            ChannelFuture channelFuture = bootstrap.connect(HOST, PORT).sync();

            channelFuture.channel().closeFuture().sync();


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully();
        }

        //服务端返回的响应
        FullHttpResponse response = clientHandler.getMsg();
        ByteBuf content = response.content();
        String res = content.toString(CharsetUtil.UTF_8);
        return str2Map(res);
    }


    public static void main(String[] args) throws InterruptedException {
        Map<String, Object> res = new HttpClient(8080, "127.0.0.1").start("/user/users");

        if(res.containsKey("returnCode")){
            if("OK".equals(res.get("returnCode"))){
                String ip = (String) res.get("IP");
                if(ip!=null){

                    Map<String, Object> start = new HttpClient(8080, ip).start("/user/findUser/1201");

                    start.forEach((k,v)->{
                        System.out.println(k+" "+v);
                    });

                }

            }

        }

    }


    private Map<String,Object> str2Map(String str){
        Gson gson = new Gson();
        Map<String, Object> res = gson.fromJson(str, new TypeToken<Map<String, Object>>() {
        }.getType());
        return res;
    }
}

自定义处理器
package com.syx.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import java.net.URI;

/**
 * 客户端处理器
 */
public class ClientHandler extends ChannelInboundHandlerAdapter {

    private String uri;

    public ClientHandler(String uri) {
        this.uri = uri;
    }

    public ClientHandler() {
    }

    private FullHttpResponse msg;


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        FullHttpResponse response = (FullHttpResponse) msg;
        this.msg = response;
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        URI url = new URI(uri);
        //配置HttpRequest的请求数据和一些配置信息
        FullHttpRequest request = new DefaultFullHttpRequest(
                HttpVersion.HTTP_1_0, HttpMethod.GET, url.toASCIIString());

        request.headers()
                .set(HttpHeaderNames.CONTENT_TYPE, "text/plain;charset=UTF-8")
                //开启长连接
                .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE)
                //设置传递请求内容的长度
                .set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes());

        //发送数据
        ctx.writeAndFlush(request);
    }
    public FullHttpResponse getMsg() {
        return msg;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值